示例#1
0
/**
 * @brief read a message from an open file desctriptor.
 * @param fd the file desctriptor to read from
 * @returns a pointer to the readed message, or NULL on error.
 */
message *read_message(int fd) {
  struct message *res;
  
  res = malloc(sizeof(struct message));
  
  if(!res) {
    print( ERROR, "malloc: %s", strerror(errno) );
    return NULL;
  }
  
  memset(res, 0, sizeof(struct message));
  
  if(!read_wrapper(fd, &(res->head), sizeof(struct msg_header))) {
    if(res->head.size) {
      res->data = read_chunk(fd, res->head.size);
      if(res->data) {
#ifndef NDEBUG
        print( DEBUG, "received a message (fd=%d)", fd );
        dump_message(res);
#endif
        return res;
      }
    } else {
      print( ERROR, "received a 0-length message" );
      dump_message(res);
    }
  }
  
  free(res);
  return NULL;
}
示例#2
0
void *connection_worker(void *arg) {
  msg_node *mn;
  message *msg;
  conn_node *c;
  
  c=(conn_node *) arg;
  
#ifndef NDEBUG
  print( DEBUG, "started (fd=%d, tid=%lu)", c->fd, pthread_self() );
#endif
  
  pthread_mutex_lock(&(c->incoming.control.mutex));
  
  while(c->incoming.control.active || c->incoming.list.head) {
    
    while(!(c->incoming.list.head) && c->incoming.control.active) {
      pthread_cond_wait(&(c->incoming.control.cond), &(c->incoming.control.mutex));
    }
    
    mn = (msg_node *) queue_get(&(c->incoming.list));
    
    if(!mn)
      continue;
    
    pthread_mutex_unlock(&(c->incoming.control.mutex));
    
    msg = mn->msg;
    
    if(IS_CTRL(msg)) {
      if(on_control_request(c, msg)) {
        print( ERROR, "cannot handle the following control message" );
        dump_message(msg);
      }
    } else {
      if(on_child_message(c, msg)) {
        print( ERROR, "cannot handle the following message" );
        dump_message(msg);
      }
    }
    
    free_message(msg);
    free(mn);
    
    pthread_mutex_lock(&(c->incoming.control.mutex));
  }
  
  pthread_mutex_unlock(&(c->incoming.control.mutex));
  
  pthread_mutex_lock(&(c->control.mutex));
  c->worker_done=1;
  pthread_mutex_unlock(&(c->control.mutex));
  
  pthread_cond_broadcast(&(c->control.cond));
  
  send_me_to_graveyard();
  
  return 0;
}
示例#3
0
/**
 * @brief handle a command request.
 * @param c the connection that send @p msg
 * @param msg the request ::message
 * @returns 0 on success, -1 on error.
 */
int on_command_request(conn_node *c, message *msg) {
  message *reply;
  
  switch(msg->data[0]) {
    case CMD_START:
      reply = on_cmd_start(c, msg);
      break;
    case CMD_SIGNAL:
      reply = on_cmd_signal(c, msg);
      break;
    default:
      print( ERROR, "unknown command '%02hhX'", msg->data[0] );
      reply = NULL;
      break;
  }
  
  if(!reply)
    return 0;
  
  if(enqueue_message(&(c->outcoming), reply)) {
    print( ERROR, "cannot enqueue message" );
    dump_message(reply);
    free_message(reply);
    return -1;
  }
  return 0;
}
示例#4
0
/**
 * @brief notify the command receiver that a chid printed a line on it's stderr.
 * @param c the child hat generated @p line
 * @param line the line received from the child stderr
 * @returns 0 on success, -1 on error.
 */
int on_cmd_stderr(child_node *c, char *line) {
  message *m;
  struct cmd_stderr_info *stderr_info;
  size_t len;
  uint16_t seq;
  
  seq = get_sequence(&(c->conn->ctrl_seq), &(c->conn->control.mutex));
  
  len = strlen(line) + 1;
  
  m = create_message(seq, sizeof(struct cmd_stderr_info) + len, CTRL_ID);
  
  if(!m) {
    print(ERROR, "cannot create messages");
    return -1;
  }
  
  stderr_info = (struct cmd_stderr_info *) m->data;
  stderr_info->cmd_action = CMD_STDERR;
  stderr_info->id = c->id;
  memcpy(stderr_info->line, line, len);
  
  if(enqueue_message(&(c->conn->outcoming), m)) {
    print(ERROR, "cannot enqueue messages");
    dump_message(m);
    free_message(m);
    return -1;
  }
  
  return 0;
}
示例#5
0
static void
dump_value(struct pbc_rmessage *m, const char *key, int type, int idx, int level) {
	int i;
	for (i=0;i<level;i++) {
		printf("  ");
	}
	printf("%s",key);
	if (type & PBC_REPEATED) {
		printf("[%d]",idx);
		type -= PBC_REPEATED;
	}
	printf(" : ");

	uint32_t low;
	uint32_t hi;
	double real;
	const char *str;

	switch(type) {
	case PBC_INT:
		low = pbc_rmessage_integer(m, key, i, NULL);
		printf("%d", (int) low);
		break;
	case PBC_REAL:
		real = pbc_rmessage_real(m, key , i);
		printf("%lf", real);
		break;
	case PBC_BOOL:
		low = pbc_rmessage_integer(m, key, i, NULL);
		printf("%s", low ? "true" : "false");
		break;
	case PBC_ENUM:
		str = pbc_rmessage_string(m, key , i , NULL);
		printf("[%s]", str);
		break;
	case PBC_STRING:
		str = pbc_rmessage_string(m, key , i , NULL);
		printf("'%s'", str);
		break;
	case PBC_MESSAGE:
		printf("\n");
		dump_message(pbc_rmessage_message(m, key, i),level+1);
		return;
	case PBC_FIXED64:
		low = pbc_rmessage_integer(m, key, i, &hi);
		printf("0x%8x%8x",hi,low);
		break;
	case PBC_FIXED32:
		low = pbc_rmessage_integer(m, key, i, NULL);
		printf("0x%x",low);
		break;
	default:
		printf("unkown");
		break;
	}

	printf("\n");
}
示例#6
0
/**
 * @brief read from a connection
 */
void *connection_reader(void *arg) {
  
  struct message *msg;
  conn_node *c;
  
  c=(conn_node *) arg;
  
#ifndef NDEBUG
  print( DEBUG, "started (fd=%d, tid=%lu)", c->fd, pthread_self() );
#endif
  
  while((msg = read_message(c->fd))) {
    pthread_mutex_lock(&(c->control.mutex));
    
    while(c->freeze) {
      pthread_cond_wait(&(c->control.cond), &(c->control.mutex));
    }
    
    pthread_mutex_unlock(&(c->control.mutex));
    
    if(enqueue_message(&(c->incoming), msg)) {
      print( ERROR, "cannot enqueue received message" );
      dump_message(msg);
      free_message(msg);
    }
  }
  
  stop_connection(c);
  
  pthread_mutex_lock(&(c->control.mutex));
  while(!c->writer_done || !c->worker_done) {
    pthread_cond_wait(&(c->control.cond), &(c->control.mutex));
  }
  pthread_mutex_unlock(&(c->control.mutex));
  
  pthread_mutex_lock(&(connections.control.mutex));
  list_del(&(connections.list), (node *)c);
  pthread_mutex_unlock(&(connections.control.mutex));
  
  pthread_cond_broadcast(&(connections.control.cond));
  
  close(c->fd);

#ifndef NDEBUG
  print( DEBUG, "connection closed (fd=%d)", c->fd );
#endif
  
  // add me to the death list
  send_me_to_graveyard();
  
  free_connection(c);
  
  return 0;
}
示例#7
0
/**
 * @brief send handlers definitions
 * @param conn the ::connection to send these definitions
 * @returns 0 on success, -1 on error.
 */
int send_handlers_list(conn_node *conn) {
    handler *h;
    message *m;
    struct hndl_list_info *handlers_info;
    struct hndl_info *handler_info;
    int ret;
    size_t array_size;

    ret=-1;
    array_size=0;

    for(h=(handler *) handlers.head; h; h=(handler *) h->next) {
        array_size += sizeof(struct hndl_info);
        array_size += strlen(h->name) +1;
    }

    m = create_message(get_sequence(&(conn->ctrl_seq), &(conn->control.mutex)),
                       sizeof(struct hndl_list_info) + array_size,
                       CTRL_ID);

    if(!m) {
        print( ERROR, "cannot create messages" );
        goto exit;
    }

    handlers_info = (struct hndl_list_info *) m->data;
    handlers_info->hndl_code = HNDL_LIST;

    handler_info = handlers_info->list;

    for(h=(handler *) handlers.head; h; h=(handler *) h->next) {
        handler_info->id = h->id;
        handler_info->have_stdin = h->have_stdin;
        handler_info->have_stdout = h->have_stdout;

        strcpy(handler_info->name, h->name);

        handler_info = (struct hndl_info *) (
                           ((char *) handler_info) + sizeof(struct hndl_info) + strlen(h->name) + 1);
    }

    if(enqueue_message(&(conn->outcoming), m)) {
        print( ERROR, "cannot enqueue message" );
        dump_message(m);
        free_message(m);
    } else {
        ret = 0;
    }

exit:

    return ret;
}
示例#8
0
/**
 * @brief send a message to the @p fd file descriptor
 * @param fd the file descritor to write on
 * @param msg the message to send
 * @returns 0 on success, -1 on error.
 */
int send_message(int fd, message *msg) {
  if(write_wrapper(fd, &(msg->head), sizeof(struct msg_header)))
    return -1;
  if(write_wrapper(fd, msg->data, msg->head.size))
    return -1;

#ifndef NDEBUG
  print( DEBUG, "message sent (fd=%d)", fd );
  dump_message(msg);
#endif

  return 0;
}
示例#9
0
/**
 * @brief notify the command receiver that a child has exited
 * @param c the terminated child
 * @param status the child status returned by waitpid()
 * @returns 0 on success, -1 on error.
 */
int on_child_done(child_node *c, int status) {
  struct message *msg;
  struct cmd_end_info *end_info;
  struct cmd_died_info *died_info;
  uint16_t seq;
  
  seq = get_sequence(&(c->conn->ctrl_seq), &(c->conn->control.mutex));
  
  if(WIFEXITED(status)) {
    msg = create_message(seq, sizeof(struct cmd_end_info), CTRL_ID);
  } else {
    msg = create_message(seq, sizeof(struct cmd_died_info), CTRL_ID);
  }
  
  if(!msg) {
    print( ERROR, "cannot create messages" );
    return -1;
  }
  
  if(WIFEXITED(status)) {
    end_info = (struct cmd_end_info *) msg->data;
    end_info->cmd_action = CMD_END;
    end_info->id = c->id;
    end_info->exit_value = WEXITSTATUS(status);
  } else {
    died_info = (struct cmd_died_info *) msg->data;
    died_info->cmd_action = CMD_DIED;
    died_info->id = c->id;
    
    if(WIFSIGNALED(status)) {
      died_info->signal = WTERMSIG(status);
    } else {
      print(ERROR, "child exited unexpectly. status=%0*X", (int) sizeof(int), status);
      died_info->signal = 0;
    }
  }
  
  if(enqueue_message(&(c->conn->outcoming), msg)) {
    print( ERROR, "cannot enqueue messages" );
    dump_message(msg);
    free_message(msg);
    return -1;
  }
  
  return 0;
}
示例#10
0
static void
dump(const char *proto, const char * message, struct pbc_slice *data) {
	struct pbc_env * env = pbc_new();
	struct pbc_slice pb;
	read_file(proto, &pb);
	int r = pbc_register(env, &pb);
	if (r!=0) {
		fprintf(stderr, "Can't register %s\n", proto);
		exit(1);
	}
	struct pbc_rmessage * m = pbc_rmessage_new(env , message , data);
	if (m == NULL) {
		fprintf(stderr, "Decode message %s fail\n",message);
		exit(1);
	}
	dump_message(m,0);
}
示例#11
0
void *reader(void *arg) {
  message *m;
  
  while((m = read_message(sockfd))) {
    if(enqueue_message(&(incoming_messages), m)) {
      LOGE("%s: cannot enqueue messages", __func__);
      dump_message(m);
      free_message(m);
      break;
    }
  }
  
  control_deactivate(&(incoming_messages.control));
  
  LOGI("%s: quitting", __func__);
  
  return 0;
}
示例#12
0
static void recv_evt(mrp_transport_t *t, void *data, uint32_t type_id,
                     void *user_data)
{
    client_t  *c   = (client_t *)user_data;
    srs_msg_t *req = (srs_msg_t *)data;

    MRP_UNUSED(t);

    dump_message(data, type_id);

    switch (req->type) {
    case SRS_REQUEST_REGISTER:
        register_client(c, &req->reg_req);
        break;

    case SRS_REQUEST_UNREGISTER:
        unregister_client(c, &req->bye_req);
        break;

    case SRS_REQUEST_FOCUS:
        request_focus(c, &req->focus_req);
        break;

    case SRS_REQUEST_RENDERVOICE:
        request_voice(c, &req->voice_req);
        break;

    case SRS_REQUEST_CANCELVOICE:
        cancel_voice(c, &req->voice_ccl);
        break;

    case SRS_REQUEST_QUERYVOICES:
        query_voices(c, &req->voice_qry);
        break;

    default:
        break;
    }

}
示例#13
0
static int adsi_prog(struct ast_channel *chan, const char *script)
{
	struct adsi_script *scr;
	int x, bytes;
	unsigned char buf[1024];

	if (!(scr = compile_script(script)))
		return -1;

	/* Start an empty ADSI Session */
	if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
		return -1;

	/* Now begin the download attempt */
	if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
		/* User rejected us for some reason */
		ast_verb(3, "User rejected download attempt\n");
		ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name);
		ast_free(scr);
		return -1;
	}

	bytes = 0;
	/* Start with key definitions */
	for (x = 0; x < scr->numkeys; x++) {
		if (bytes + scr->keys[x].retstrlen > 253) {
			/* Send what we've collected so far */
			if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
				ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
				return -1;
			}
			bytes =0;
		}
		memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
		bytes += scr->keys[x].retstrlen;
#ifdef DUMP_MESSAGES
		dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
#endif
	}
	if (bytes) {
		if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
			ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
			return -1;
		}
	}

	bytes = 0;
	/* Continue with the display messages */
	for (x = 0; x < scr->numdisplays; x++) {
		if (bytes + scr->displays[x].datalen > 253) {
			/* Send what we've collected so far */
			if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
				ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
				return -1;
			}
			bytes =0;
		}
		memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
		bytes += scr->displays[x].datalen;
#ifdef DUMP_MESSAGES
		dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
#endif
	}
	if (bytes) {
		if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
			ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
			return -1;
		}
	}

	bytes = 0;
	/* Send subroutines */
	for (x = 0; x < scr->numsubs; x++) {
		if (bytes + scr->subs[x].datalen > 253) {
			/* Send what we've collected so far */
			if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
				ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
				return -1;
			}
			bytes =0;
		}
		memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
		bytes += scr->subs[x].datalen;
#ifdef DUMP_MESSAGES
		dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
#endif
	}
	if (bytes) {
		if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
			ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
			return -1;
		}
	}

	bytes = 0;
	bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
	bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
	if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
		return -1;
	if (ast_adsi_end_download(chan)) {
		/* Download failed for some reason */
		ast_verb(3, "Download attempt failed\n");
		ast_log(LOG_NOTICE, "Download failed on %s\n", chan->name);
		ast_free(scr);
		return -1;
	}
	ast_free(scr);
	ast_adsi_unload_session(chan);
	return 0;
}
示例#14
0
/**
 * @brief handle a start command request.
 * @param msg the request ::message.
 * @param conn the connection that send the @p message
 * @returns a reply message on success, NULL on error.
 */
message *on_cmd_start(conn_node *conn, message *msg) {
  struct cmd_start_data *data;
  char *cmd;
  handler *h;
  child_node *c;
  int pin[2],pout[2],perr[2],pexec[2];
  int i;
  struct cmd_start_info *request_info;
  struct cmd_started_info *reply_info;
  pid_t pid;
  uint16_t seq;
  
  c = NULL;
  cmd = NULL;
  // ensure to set piped fd to invalid one,
  // or close(2) will close unexpected fd. ( like our stdin if 0 )
  pin[0] = pin[1] = pout[0] = pout[1] = perr[0] = perr[1] = pexec[0] = pexec[1] = -1;
  request_info = (struct cmd_start_info *)msg->data;
  data=NULL;
  pid = 0;
  seq = msg->head.seq;
  
  c = create_child(conn);
  if(!c) {
    print( ERROR, "cannot craete a new child" );
    goto start_fail;
  }
  
  for(h=(handler *)handlers.head;h && h->id != request_info->hid;h=(handler *)h->next);
  c->handler = h;
  
  if(!c->handler) {
    print( ERROR, "handler #%d not found", request_info->hid );
    goto start_fail;
  }
  
  cmd = (char *)c->handler->argv0;
  
  data = extract_start_data(msg, (cmd ? 1 : 0));
  if(!data) {
    print( ERROR, "cannot extract data" );
    goto start_fail;
  }
  
  if(cmd) {
    data->argv[0] = cmd;
  }
  
  if(pipe2(pexec, O_CLOEXEC)) {
    print( ERROR, "exec pipe: %s", strerror(errno) );
    goto start_fail;
  }
  
  if(h->have_stdin && pipe(pin)) {
    print( ERROR, "input pipe: %s", strerror(errno) );
    goto start_fail;
  }
  
  if(h->have_stdout && pipe(pout)) {
    print( ERROR, "output pipe: %s", strerror(errno) );
    goto start_fail;
  }
  
  if(pipe(perr)) {
    print( ERROR, "error pipe: %s", strerror(errno));
    goto start_fail;
  }
  
  
  if((pid = fork()) < 0) {
    print( ERROR, "fork: %s", strerror(errno) );
    goto start_fail;
  } else if(!pid) {
    // child
    close(pexec[0]);
    close(pin[1]);
    close(pout[0]);
    close(perr[0]);
    
    if(pin[0] == -1 || pout[1] == -1) {
      i= open("/dev/null", O_RDWR);
      
      if(pin[0] == -1)
        pin[0] = dup(i);
      if(pout[1] == -1)
        pout[1] = dup(i);
      
      close(i);
    }
    
    if(h->workdir && chdir(h->workdir)) {
      print ( ERROR, "chdir: %s", strerror(errno));
      goto error;
    }
    
    dup2(pin[0], STDIN_FILENO);
    
    close(pin[0]);
    
    dup2(pout[1], STDOUT_FILENO);
    
    close(pout[1]);
    
    dup2(perr[1], STDERR_FILENO);
    
    close(perr[1]);
    
    cmd = data->env_start;
    
    while(cmd) {
      if(putenv(cmd)) {
        print( ERROR, "putenv(\"%s\"): %s", cmd, strerror(errno));
        goto error;
      }
      cmd=string_array_next(msg, request_info->data, cmd);
    }
    
    execvp(data->argv[0], data->argv);
    print( ERROR, "execvp: %s", strerror(errno));
    
    error:
    
    write(pexec[1], "!", 1);
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    close(pexec[1]);
    exit(-1);
  } else {
    // parent
    close(pexec[1]);
    close(pin[0]);
    close(pout[1]);
    close(perr[1]);
    
    free_start_data(data);
    data = NULL;
    
    if(read(pexec[0], &i, 1)) {
      waitpid(pid, NULL, 0);
      goto start_fail;
    }
#ifndef NDEBUG
    print( DEBUG, "successfully started a child for '%s' (pid=%d)", h->name, pid );
#endif
    close(pexec[0]);
  }
  
  c->pid = pid;
  
  if(h->have_stdin)
    c->stdin_fd = pin[1];
  
  if(h->have_stdout)
    c->stdout_fd = pout[0];
  
  c->stderr_fd = perr[0];
  
  pthread_mutex_lock(&(conn->children.control.mutex));
  if(pthread_create(&(c->tid), NULL, &handle_child, c)) {
    i=errno;
    pthread_mutex_unlock(&(conn->children.control.mutex));
    print( ERROR, "pthread_craete: %s", strerror(i) );
    goto start_fail;
  }
  list_add(&(conn->children.list), (node *)c);
  pthread_mutex_unlock(&(conn->children.control.mutex));
  
  pthread_cond_broadcast(&(conn->children.control.cond));
  
  msg = create_message(seq, sizeof(struct cmd_started_info), CTRL_ID);
  
  if(!msg) {
    print( ERROR, "cannot create messages" );
    goto start_fail;
  }
  
  reply_info = (struct cmd_started_info *)msg->data;
  reply_info->cmd_action = CMD_STARTED;
  reply_info->id = c->id;
  
  return msg;
  
  start_fail:
  if(c)
    free(c);
  if(data)
    free_start_data(data);
  // no care about EBADF, ensure to close all opened fd
  close(pexec[0]);
  close(pexec[1]);
  close(pin[0]);
  close(pin[1]);
  close(pout[0]);
  close(pout[1]);
  close(perr[0]);
  close(perr[1]);
  
  if(msg)
    dump_message(msg);
  
  if(pid)
    kill(pid, 9);
  
  msg = create_message(seq, sizeof(struct cmd_fail_info), CTRL_ID);
  
  if(!msg) {
    print( ERROR, "cannot create messages" );
    return NULL;
  }
  
  ((struct cmd_fail_info *)msg->data)->cmd_action = CMD_FAIL;
  return msg;
}
示例#15
0
文件: main.c 项目: gammadean/vista
int main(int argc, char *argv[])
{
	uint8_t byte[100];
	uint8_t message[256];
	
	int fd = serialport_init();

	//write(fd, "X", 1);

	int state = 0; // Wait for a recognized pattern
	int msgOffset = 0;
	int needed = 0;
	int index;		
	
	int logFd = open("vistalog.bin", (O_CREAT | O_RDWR), (S_IRUSR | S_IWUSR));
	//int txtFd = open("vistalog.txt", (O_CREAT | O_RDWR), (S_IRUSR | S_IWUSR));
	
	while(1)
	{
		ssize_t size = read(fd, byte, 100);
		
		if (size < 0)
			printf("Read error\n");
		if (size == 0)
			continue;
		

		//printf("%zu:", size);
		int rc = write(logFd, byte, size);
		if (rc == -1)
			printf("Log write failure\n");
		
#if 0
		int rc = write(logFd, byte, size);
		if (rc == -1)
			printf("Log write failure\n");
#endif
		
#if 1
		struct timeval time;
		gettimeofday(&time, NULL);
		printf("[%ld.%06ld]", time.tv_sec, time.tv_usec);
		dump_message(byte, size);
		printf("\n");
#else
		for (index = 0; index < size; index++)
		{
			//printf(" %02X", byte[index]);

			switch (state)
			{
			case 0:  // No message
				if (byte[index] == 0xF7)
				{
					// Keypad message
					state = 1;  // Read message
					needed = 44;
					//printf("state = Read keypad message header (%d)\n", needed);
					message[0] = 0xF7;
					msgOffset = 1;
				}
				else if (byte[index] == 0x9E)
				{
					// 9E message, whatever that is
					state = 1;  // Read message
					needed = 4;
					//printf("state = Read 9E message (%d)\n", needed);
					message[0] = 0x9E;
					msgOffset = 1;
				}
				else if (byte[index] == 0xF6)
				{
					// Appears to be a keypress message but without any indication of what key was pressed, maybe byte 1 is keypad address
					state = 1;  // Read message
					needed = 3;
					message[0] = 0xF6;
					msgOffset = 1;
				}
				else if (byte[index] == 0x00)
				{
					// Keep looking
				}
				else
				{
					printf("Unknown message type (0x%02X)\n", byte[index]);					
				}
				break;
				
			case 1:
				message[msgOffset] = byte[index];
				msgOffset++;
				needed--;
				
				if (needed == 0)
				{
					//printf("Read needed bytes...\n");
					// Entire message received
					struct timeval time;
					gettimeofday(&time, NULL);
#if 0
					time_t ltime; /* calendar time */
					ltime=time(NULL); /* get current cal time */
					char timeStr[256];
					strftime(timeStr, sizeof(timeStr), "", localtime(&ltime)));
#endif
					printf("[%ld.%06ld]", time.tv_sec, time.tv_usec);

					// Handle message
					if (message[0] == 0xF7)
					{
						// keypad message
						printf("Keypad : ");
						dump_message(message, 12);
						message[msgOffset - 1] = 0x00;
						message[12] &= 0x7F;  // The upper bit has some unknown meaning, masked for display
						printf("'%s'\n", &(message[12]));
						write_html((char *)&(message[12]));
					}
					else if (message[0] == 0x9E)
					{
						printf("9E : ");
						dump_message(message, msgOffset);
						printf("\n");
					}
					else if (message[0] == 0xF6)
					{
						printf("Keypress : ");
						dump_message(message, msgOffset);
						printf("\n");
					}
					else
					{
						printf("Trying to process unknown message type (0x%02X)\n", message[0]);
					}
					
					state = 0; // Wait for known message pattern
					msgOffset = 0;
					needed = 0;
				}
			}
			
			//printf("\n");
		}
#endif
	}

	return EXIT_SUCCESS;
}
示例#16
0
/**
 * @brief read from a child stdout.
 * @param c the child from read to
 * @returns 0 on success, -1 on error
 */
int read_stdout(child_node *c) {
  int count;
  int ret;
  char *buff;
  char *line;
  message *m;
  
  buff = malloc(STDOUT_BUFF_SIZE);
    
  if(!buff) {
    print( ERROR, "malloc: %s", strerror(errno));
    return -1;
  }
  
  ret = 0;
  
  if(c->handler->raw_output_parser) { // parse raw bytes
    while((count=read(c->stdout_fd, buff, STDOUT_BUFF_SIZE)) > 0) {
      if(c->handler->raw_output_parser(c, buff, count)) {
        ret = -1;
        break;
      }
    }
  } else if(c->handler->output_parser) { // parse lines
    while(!ret && (count=read(c->stdout_fd, buff, STDOUT_BUFF_SIZE)) > 0) {
      if(append_to_buffer(&(c->output_buff), buff, count)) {
        ret = -1;
        continue;
      }
      while((line = get_line_from_buffer(&(c->output_buff)))) {
        m = c->handler->output_parser(line);
        if(m) {
          m->head.id = c->id;
          m->head.seq = c->seq + 1;
          
#ifdef BROADCAST_EVENTS
          if(broadcast_message(m)) {
            print( ERROR, "cannot broadcast messages.");
#else
          if(enqueue_message(&(c->conn->outcoming), m)) {
            print( ERROR, "cannot enqueue messages.");
#endif
            dump_message(m);
            free_message(m);
            ret = -1;
            // events not sent are not fatal, just a missed event.
            // while in raw connection a missed message will de-align the output/input.
            // this is why a "break;" is missing here
          } else {
            c->seq++;
          }
        }
        free(line);
      }
    }
  } else { // send raw bytes
    while((count=read(c->stdout_fd, buff, STDOUT_BUFF_SIZE)) > 0) {
      m = create_message(c->seq + 1, count, c->id);
      if(!m) {
        buff[MIN(count, STDOUT_BUFF_SIZE -1)] = '\0';
        print( ERROR, "cannot send the following output: '%s'", buff);
        ret = -1;
        break;
      }
      memcpy(m->data, buff, count);
      if(enqueue_message(&(c->conn->outcoming), m)) {
        print( ERROR, "cannot enqueue messages.");
        dump_message(m);
        free_message(m);
        ret = -1;
        break;
      } else {
        c->seq++;
      }
    }
  }
  
  if(count<0) {
    print( ERROR, "read: %s", strerror(errno));
    ret = -1;
  }
  
  free(buff);
  
  release_buffer(&(c->output_buff));
  
  return ret;
}
示例#17
0
static void route_result(cJSON* result)
{
    cJSON* cjson_current;
    size_t i;
    for (cjson_current = result->child; cjson_current; cjson_current = cjson_current->next)
    {
        if (strcmp(cJSON_GetObjectItem(cjson_current, "poll_type")->valuestring, "message") == 0)
        {
            cJSON* cjson_value = cJSON_GetObjectItem(cjson_current, "value");
            ullong from_uin = cJSON_GetObjectItem(cjson_value, "from_uin")->valuedouble;
            ullong number = get_friend_number(from_uin);
            msg_content_array_t content = fetch_content(cJSON_GetObjectItem(cjson_value, "content"));
            dump_message(number, str_from("friend_message"), &content);
#ifdef _DEBUG
            {
                char* str = msg_content_array_to_json_object_string(&content, "content");
                fprintf(stdout, "Received message from: %llu\nContent: %s\n", number, str);
                fflush(stdout);
                free(str);
            }
#endif

            for (i = 0; i < robot.received_message_funcs_count; ++i) robot.received_message_funcs[i](from_uin, number, &content);
            msg_content_array_free(&content);
        }
        else if (strcmp(cJSON_GetObjectItem(cjson_current, "poll_type")->valuestring, "group_message") == 0)
        {
            cJSON* cjson_value = cJSON_GetObjectItem(cjson_current, "value");
            ullong from_uin = cJSON_GetObjectItem(cjson_value, "from_uin")->valuedouble;
            ullong number = get_group_number(cJSON_GetObjectItem(cjson_value, "group_code")->valuedouble);
            msg_content_array_t content = fetch_content(cJSON_GetObjectItem(cjson_value, "content"));
            dump_message(number, str_from("group_message"), &content);
#ifdef _DEBUG
            {
                char* str = msg_content_array_to_json_object_string(&content, "content");
                fprintf(stdout, "Received group_message from: %llu\nContent: %s\n", number, str);
                fflush(stdout);
                free(str);
            }
#endif

            for (i = 0; i < robot.received_group_message_funcs_count; ++i) robot.received_group_message_funcs[i](from_uin, number, &content);
            msg_content_array_free(&content);
        }
        else
        {
            bson_t document;
            bson_t content;
            bson_error_t error;
            time_t t;
            char* ptr = cJSON_PrintUnformatted(cjson_current);
            mongoc_collection_t* collection = mongoc_database_get_collection(robot.mongoc_database, "unprocessed");

            time(&t);
            if (!bson_init_from_json(&content, ptr, strlen(ptr), &error))
            {
                MONGOC_WARNING("%s\n", error.message);
                return;
            }
            bson_init(&document);
            BSON_APPEND_TIME_T(&document, "time", t);
            BSON_APPEND_DOCUMENT(&document, "content", &content);
            if (!mongoc_collection_insert(collection, MONGOC_INSERT_NONE, &document, NULL, &error)) MONGOC_WARNING("%s\n", error.message);
            bson_destroy(&document);
            bson_destroy(&content);
        }
    }
}