/** * @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; }
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; }
/** * @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; }
/** * @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; }
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"); }
/** * @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; }
/** * @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; }
/** * @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; }
/** * @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; }
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); }
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; }
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; } }
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; }
/** * @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; }
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(<ime))); #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; }
/** * @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; }
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); } } }