static void ignore_receive_data(urg_t *urg, int timeout) { char buffer[BUFFER_SIZE]; int n; if (urg->is_sending == URG_FALSE) { return; } do { n = connection_readline(&urg->connection, buffer, BUFFER_SIZE, timeout); } while (n >= 0); urg->is_sending = URG_FALSE; }
static void test(struct connection_pool *p, int id) { int i=0; while (i<5) { int handle = id; const char * line = connection_readline(p, handle, "\n", NULL); if (line == NULL) { line = connection_poll(p,1000,&handle,NULL); } if (line) { printf("%d %d: %s\n",i,handle, line); connection_write(p,handle,"readline\n",9); ++i; } else { if (handle) { printf("Close %d\n",handle); return; } } } i=0; while (i<5) { int handle = id; uint8_t * buffer = connection_read(p, handle, 8); if (buffer == NULL) { buffer = connection_poll(p,1000,&handle,NULL); } if (buffer) { int j; printf("%d %d: ",i,handle); for (j=0;j<8;j++) { printf("%02x ",buffer[j]); } printf("\n"); connection_write(p,handle,"readblock\n",10); ++i; } else { if (handle) { printf("Close %d\n", handle); return; } } } }
void protocol_update(run_t *run) { char line_buffer[CONNECTION_READLINE_BUFFER_SIZE]; int line_size; command_type_t command_type; line_size = connection_readline(line_buffer, CONNECTION_READLINE_BUFFER_SIZE); command_type = parse_received_command(line_buffer, line_size); // コマンドのパース処理 switch (command_type) { case OP_Command: handle_OP_command(run); break; case TD_Command: handle_TD_command(run, line_buffer); break; case SA_Command: handle_SA_command(run); break; case ST_Command: handle_ST_command(run); break; case WV_Command: handle_WV_command(run, line_buffer); break; case Unknown_Command: // !!! エラー応答を返す break; } }
message *connection_read_msg(connection *conn) { message_line *line = NULL; message *result = NULL; message *msg = NULL; char line_buf[MAXLINE]; int bytes_need, i; while (1) { if (conn->current_msg == NULL) { if ((conn->current_msg = create_http_message()) == NULL) { fprintf(stderr, "No memory for new request\n"); return NULL; } } if (conn->current_msg->stage == MSG_ABORT) { result = conn->current_msg; conn->current_msg = NULL; return result; } if (conn->current_msg->stage == MSG_BODY) { if (conn->current_msg->body_buf == NULL) { if ((conn->current_msg->body_buf = (char *)malloc(conn->current_msg->body_size)) == NULL) { conn->current_msg->stage = MSG_ABORT; continue; } } msg = conn->current_msg; bytes_need = msg->body_size - msg->body_read; if (bytes_need <= conn->buf_size) { memcpy(msg->body_buf + msg->body_read, conn->buf, bytes_need); msg->body_read += bytes_need; for (i = bytes_need; i < conn->buf_size; i++) conn->buf[i-bytes_need] = conn->buf[i]; conn->buf_size = conn->buf_size - bytes_need; msg->stage = MSG_DONE; } else { memcpy(msg->body_buf + msg->body_read, conn->buf, conn->buf_size); msg->body_read += conn->buf_size; conn->buf_size = 0; } if (conn->current_msg->stage == MSG_DONE) { result = conn->current_msg; conn->current_msg = NULL; return result; } if (conn->buf_size == 0) { break; } continue; } if (connection_readline(conn, line_buf) == 0) { /* Can't read more lines from current buffer */ if (conn->buf_size == MAXLINE) { /* message line length > MAXLINE */ conn->current_msg->stage = MSG_ABORT; continue; } break; } if (conn->current_msg->stage == MSG_LINE) { if ((line = create_message_line(line_buf)) == NULL) { conn->current_msg->stage = MSG_ABORT; continue; } message_add_line(conn->current_msg, line); if (line_buf[0] == '\r' && line_buf[1] == '\n') { /* Message lines have been fully received */ if (conn->current_msg->body_size > 0) { conn->current_msg->stage = MSG_BODY; continue; } else { conn->current_msg->stage = MSG_DONE; result = conn->current_msg; conn->current_msg = NULL; return result; } } if (strstr(line_buf, "Content-Length:") == line_buf) { sscanf(line_buf, "Content-Length: %d", &(conn->current_msg->body_size)); if (conn->current_msg->body_size > MAX_BODY_SIZE) { conn->current_msg->stage = MSG_ABORT; continue; } if (conn->current_msg->body_size < 0) { conn->current_msg->stage = MSG_ABORT; continue; } } } } return result; }
// 受信した応答の行数を返す static int scip_response(urg_t *urg, const char* command, const int expected_ret[], int timeout, char *receive_buffer, int receive_buffer_max_size) { char *p = receive_buffer; char buffer[BUFFER_SIZE]; int filled_size = 0; int line_number = 0; int ret = URG_UNKNOWN_ERROR; int write_size = (int)strlen(command); int n = connection_write(&urg->connection, command, write_size); if (n != write_size) { return set_errno_and_return(urg, URG_SEND_ERROR); } if (p) { *p = '\0'; } do { n = connection_readline(&urg->connection, buffer, BUFFER_SIZE, timeout); if (n < 0) { return set_errno_and_return(urg, URG_NO_RESPONSE); } else if (p && (line_number > 0) && (n < (receive_buffer_max_size - filled_size))) { // エコーバックは完全一致のチェックを行うため、格納しない memcpy(p, buffer, n); p += n; *p++ = '\0'; filled_size += n; } if (line_number == 0) { // エコーバック文字列が、一致するかを確認する if (strncmp(buffer, command, write_size - 1)) { return set_errno_and_return(urg, URG_INVALID_RESPONSE); } } else if (n > 0 && !(line_number == 1 && n == 1)) { // エコーバック以外の行のチェックサムを評価する(SCIP 1.1 応答の場合は無視する) char checksum = buffer[n - 1]; if ((checksum != scip_checksum(buffer, n - 1)) && (checksum != scip_checksum(buffer, n - 2))) { return set_errno_and_return(urg, URG_CHECKSUM_ERROR); } } // ステータス応答を評価して、戻り値を決定する if (line_number == 1) { if (n == 1) { // SCIP 1.1 応答の場合は、正常応答とみなす ret = 0; } else if (n != 3) { return set_errno_and_return(urg, URG_INVALID_RESPONSE); } else { int i; int actual_ret = strtol(buffer, NULL, 10); for (i = 0; expected_ret[i] != EXPECTED_END; ++i) { if (expected_ret[i] == actual_ret) { ret = 0; break; } } } } ++line_number; } while (n > 0); return (ret < 0) ? ret : (line_number - 1); }
int urg_raw_readline(urg_t *urg, char *data, int max_data_size, int timeout) { return connection_readline(&urg->connection, data, max_data_size, timeout); }