int main(int argc, char * argv[]) { int i = 0; int j = 0; char *state_table[] = { #include "packet_names.h" }; struct gps_packet_t lexer; packet_init(&lexer); for (i = 0; i < 7; i++) { printf("Sentence no %d\n", i); for(j = 0; j < strlen(nmea[i]); j++) { lexer.inbuffer[lexer.inbuflen] = nmea[i][j]; lexer.inbuflen++; if(lexer.inbuflen % 10 == 0) packet_parse(&lexer); } lexer.inbuffer[lexer.inbuflen] = '\r'; lexer.inbuflen++; lexer.inbuffer[lexer.inbuflen] = '\n'; lexer.inbuflen++; } packet_parse(&lexer); return 0; }
int main(int argc, const char *argv[]) { packet_t *packet; uint8_t *bytes; size_t length; /* Create a SYN */ packet = packet_create_syn(0x1234, 0x0000, 0x0000); packet_print(packet); /* Convert it to bytes and free the original */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a MSG */ packet = packet_create_msg(0x1234, 0x0000, 0x0001, (uint8_t*)"AAAAA", 5); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); safe_free(bytes); /* Create a FIN */ packet = packet_create_fin(0x1234); packet_print(packet); /* Convert it to bytes and free the orignal */ bytes = packet_to_bytes(packet, &length); packet_destroy(packet); safe_free(bytes); /* Parse the bytes from the old packet to create a new one */ packet = packet_parse(bytes, length); packet_print(packet); packet_destroy(packet); print_memory(); return 0; }
static int packet_wait2(SSH_SESSION *session, int type, int blocking) { int rc = SSH_ERROR; enter_function(); do { rc = packet_read2(session); if (rc != SSH_OK) { leave_function(); return rc; } if (packet_translate(session) != SSH_OK) { leave_function(); return SSH_ERROR; } switch (session->in_packet.type) { case SSH2_MSG_DISCONNECT: packet_parse(session); ssh_log(session, SSH_LOG_PACKET, "received disconnect packet"); leave_function(); return SSH_ERROR; case SSH2_MSG_CHANNEL_WINDOW_ADJUST: case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_REQUEST: case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_CLOSE: packet_parse(session); break; case SSH2_MSG_IGNORE: break; default: if (type && (type != session->in_packet.type)) { ssh_set_error(session, SSH_FATAL, "packet_wait2(): Received a %d type packet, but expected a %d\n", session->in_packet.type, type); leave_function(); return SSH_ERROR; } leave_function(); return SSH_OK; } if (blocking == 0) { leave_function(); return SSH_OK; //shouldn't it return SSH_AGAIN here ? } } while(1); leave_function(); return SSH_OK; }
packet_t packet_copy(packet_t p) { packet_t np; np = packet_parse(packet_raw(p), packet_len(p)); np->to = p->to; np->from = p->from; np->out = p->out; return np; }
static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx) { float temperature, humidity; struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; struct sr_analog_encoding encoding; struct sr_analog_meaning meaning; struct sr_analog_spec spec; struct dev_context *devc; GSList *l; int ret; (void)idx; devc = sdi->priv; ret = packet_parse((const char *)buf, idx, &temperature, &humidity); if (ret < 0) { sr_err("Failed to parse packet."); return SR_ERR; } sr_analog_init(&analog, &encoding, &meaning, &spec, 3); /* Common values for both channels. */ packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.num_samples = 1; /* Temperature. */ l = g_slist_copy(sdi->channels); l = g_slist_remove_link(l, g_slist_nth(l, 1)); meaning.channels = l; meaning.mq = SR_MQ_TEMPERATURE; meaning.unit = SR_UNIT_CELSIUS; /* TODO: Use C/F correctly. */ analog.data = &temperature; sr_session_send(sdi, &packet); g_slist_free(l); /* Humidity. */ if (mic_devs[idx].has_humidity) { l = g_slist_copy(sdi->channels); l = g_slist_remove_link(l, g_slist_nth(l, 0)); meaning.channels = l; meaning.mq = SR_MQ_RELATIVE_HUMIDITY; meaning.unit = SR_UNIT_PERCENTAGE; analog.data = &humidity; sr_session_send(sdi, &packet); g_slist_free(l); } devc->num_samples++; return SR_OK; }
static int packet_wait1(SSH_SESSION *session, int type, int blocking) { enter_function(); ssh_log(session, SSH_LOG_PROTOCOL, "packet_wait1 waiting for %d", type); do { if ((packet_read1(session) != SSH_OK) || (packet_translate(session) != SSH_OK)) { leave_function(); return SSH_ERROR; } ssh_log(session, SSH_LOG_PACKET, "packet_wait1() received a type %d packet", session->in_packet.type); switch (session->in_packet.type) { case SSH_MSG_DISCONNECT: packet_parse(session); leave_function(); return SSH_ERROR; case SSH_SMSG_STDOUT_DATA: case SSH_SMSG_STDERR_DATA: case SSH_SMSG_EXITSTATUS: if (channel_handle1(session,type) < 0) { leave_function(); return SSH_ERROR; } break; case SSH_MSG_DEBUG: case SSH_MSG_IGNORE: break; /* case SSH2_MSG_CHANNEL_CLOSE: packet_parse(session); break;; */ default: if (type && (type != session->in_packet.type)) { ssh_set_error(session, SSH_FATAL, "packet_wait1(): Received a %d type packet, but expected %d\n", session->in_packet.type, type); leave_function(); return SSH_ERROR; } leave_function(); return SSH_OK; } if (blocking == 0) { leave_function(); return SSH_OK; } } while(1); leave_function(); return SSH_OK; }
packet_t crypt_delineize_1a(crypt_t c, packet_t p) { packet_t line; unsigned char iv[16], hmac[32]; crypt_1a_t cs = (crypt_1a_t)c->cs; memset(iv,0,16); memcpy(iv+12,p->body+16+4,4); hmac_256(cs->keyIn,16,p->body+16+4,p->body_len-(16+4),hmac); fold3(hmac,hmac); if(memcmp(hmac,p->body+16,4) != 0) return packet_free(p); aes_128_ctr(cs->keyIn,p->body_len-(16+4+4),iv,p->body+16+4+4,p->body+16+4+4); line = packet_parse(p->body+16+4+4, p->body_len-(16+4+4)); packet_free(p); return line; }
static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx) { struct sr_datafeed_packet packet; struct sr_datafeed_analog_old analog; struct dev_context *devc; struct center_info info; GSList *l; int i, ret; devc = sdi->priv; memset(&analog, 0, sizeof(struct sr_datafeed_analog_old)); memset(&info, 0, sizeof(struct center_info)); ret = packet_parse(buf, idx, &info); if (ret < 0) { sr_err("Failed to parse packet."); return SR_ERR; } /* Common values for all 4 channels. */ packet.type = SR_DF_ANALOG_OLD; packet.payload = &analog; analog.mq = SR_MQ_TEMPERATURE; analog.unit = (info.celsius) ? SR_UNIT_CELSIUS : SR_UNIT_FAHRENHEIT; analog.num_samples = 1; /* Send the values for T1 - T4. */ for (i = 0; i < NUM_CHANNELS; i++) { l = NULL; l = g_slist_append(l, g_slist_nth_data(sdi->channels, i)); analog.channels = l; analog.data = &(info.temp[i]); sr_session_send(sdi, &packet); g_slist_free(l); } devc->num_samples++; return SR_OK; }
packet_t crypt_deopenize_1a(crypt_t self, packet_t open) { unsigned char secret[uECC_BYTES], iv[16], b64[uECC_BYTES*2*2], hash[32]; packet_t inner, tmp; crypt_1a_t cs = (crypt_1a_t)self->cs; if(open->body_len <= (4+40)) return NULL; inner = packet_new(); if(!packet_body(inner,NULL,open->body_len-(4+40))) return packet_free(inner); // get the shared secret to create the iv+key for the open aes if(!uECC_shared_secret(open->body+4, cs->id_private, secret)) return packet_free(inner); crypt_hash(secret,uECC_BYTES,hash); fold1(hash,hash); memset(iv,0,16); iv[15] = 1; // decrypt the inner aes_128_ctr(hash,inner->body_len,iv,open->body+4+40,inner->body); // load inner packet if((tmp = packet_parse(inner->body,inner->body_len)) == NULL) return packet_free(inner); packet_free(inner); inner = tmp; // generate secret for hmac if(inner->body_len != uECC_BYTES*2) return packet_free(inner); if(!uECC_shared_secret(inner->body, cs->id_private, secret)) return packet_free(inner); // verify hmac_256(secret,uECC_BYTES,open->body+4,open->body_len-4,hash); fold3(hash,hash); if(memcmp(hash,open->body,4) != 0) return packet_free(inner); // stash the hex line key w/ the inner util_hex(open->body+4,40,b64); packet_set_str(inner,"ecc",(char*)b64); return inner; }
/* * Find the first packet in "in", delete it from "in", and return it as * a struct. Return NULL if "in" contains no packet. Always delete * leading non-packet data from "in". */ static struct packet *packet_extract(Octstr *in, SMSCConn *conn) { Octstr *packet; int size, i; static char s[4][4] = { { 0x01, 0x0b, 0x00, 0x00 }, { 0x01, 0x00, 0x00, 0x00 }, { 0x00, 0x04, 0x00, 0x00 }, { 0x00, 0x09, 0x00, 0x00 } }; /* msgtype, oper, 0, 0 */ char known_bytes[4]; if (octstr_len(in) < 10) return NULL; octstr_get_many_chars(known_bytes, in, 4, 4); /* Find s, and delete everything up to it. */ /* If packet starts with one of s, it should be good packet */ for (i = 0; i < 4; i++) { if (memcmp(s[i], known_bytes, 4) == 0) break; } if (i >= 4) { error(0, "OISD[%s]: wrong packet", octstr_get_cstr(conn->id)); octstr_dump(in, 0); return NULL; } /* Find end of packet */ size = (octstr_get_char(in, 9) << 8) | octstr_get_char(in, 8); if (size + 10 > octstr_len(in)) return NULL; packet = octstr_copy(in, 0, size + 10); octstr_delete(in, 0, size + 10); return packet_parse(packet); }
/* decode_packet(Type,Bin,Options) Returns: {ok, PacketBodyBin, RestBin} {more, PacketSz | undefined} {error, invalid} */ BIF_RETTYPE decode_packet_3(BIF_ALIST_3) { unsigned max_plen = 0; /* Packet max length, 0=no limit */ unsigned trunc_len = 0; /* Truncate lines if longer, 0=no limit */ int http_state = 0; /* 0=request/response 1=header */ int packet_sz; /*-------Binaries involved: ------------------*/ byte* bin_ptr; /*| orig: original binary */ byte bin_bitsz; /*| bin: BIF_ARG_2, may be sub-binary of orig */ /*| packet: prefix of bin */ char* body_ptr; /*| body: part of packet to return */ int body_sz; /*| rest: bin without packet */ struct packet_callback_args pca; enum PacketParseType type; Eterm* hp; Eterm* hend; ErlSubBin* rest; Eterm res; Eterm options; int code; char delimiter = '\n'; if (!is_binary(BIF_ARG_2) || (!is_list(BIF_ARG_3) && !is_nil(BIF_ARG_3))) { BIF_ERROR(BIF_P, BADARG); } switch (BIF_ARG_1) { case make_small(0): case am_raw: type = TCP_PB_RAW; break; case make_small(1): type = TCP_PB_1; break; case make_small(2): type = TCP_PB_2; break; case make_small(4): type = TCP_PB_4; break; case am_asn1: type = TCP_PB_ASN1; break; case am_sunrm: type = TCP_PB_RM; break; case am_cdr: type = TCP_PB_CDR; break; case am_fcgi: type = TCP_PB_FCGI; break; case am_line: type = TCP_PB_LINE_LF; break; case am_tpkt: type = TCP_PB_TPKT; break; case am_http: type = TCP_PB_HTTP; break; case am_httph: type = TCP_PB_HTTPH; break; case am_http_bin: type = TCP_PB_HTTP_BIN; break; case am_httph_bin: type = TCP_PB_HTTPH_BIN; break; case am_ssl_tls: type = TCP_PB_SSL_TLS; break; default: BIF_ERROR(BIF_P, BADARG); } options = BIF_ARG_3; while (!is_nil(options)) { Eterm* cons = list_val(options); if (is_tuple(CAR(cons))) { Eterm* tpl = tuple_val(CAR(cons)); Uint val; if (tpl[0] == make_arityval(2) && term_to_Uint(tpl[2],&val) && val <= UINT_MAX) { switch (tpl[1]) { case am_packet_size: max_plen = val; goto next_option; case am_line_length: trunc_len = val; goto next_option; case am_line_delimiter: if (type == TCP_PB_LINE_LF && val <= 255) { delimiter = (char)val; goto next_option; } } } } BIF_ERROR(BIF_P, BADARG); next_option: options = CDR(cons); } pca.bin_sz = binary_size(BIF_ARG_2); ERTS_GET_BINARY_BYTES(BIF_ARG_2, bin_ptr, pca.bin_bitoffs, bin_bitsz); if (pca.bin_bitoffs != 0) { pca.aligned_ptr = erts_alloc(ERTS_ALC_T_TMP, pca.bin_sz); erts_copy_bits(bin_ptr, pca.bin_bitoffs, 1, pca.aligned_ptr, 0, 1, pca.bin_sz*8); } else { pca.aligned_ptr = bin_ptr; } packet_sz = packet_get_length(type, (char*)pca.aligned_ptr, pca.bin_sz, max_plen, trunc_len, delimiter, &http_state); if (!(packet_sz > 0 && packet_sz <= pca.bin_sz)) { if (packet_sz < 0) { goto error; } else { /* not enough data */ Eterm plen = (packet_sz==0) ? am_undefined : erts_make_integer(packet_sz, BIF_P); Eterm* hp = HAlloc(BIF_P,3); res = TUPLE2(hp, am_more, plen); goto done; } } /* We got a whole packet */ body_ptr = (char*) pca.aligned_ptr; body_sz = packet_sz; packet_get_body(type, (const char**) &body_ptr, &body_sz); ERTS_GET_REAL_BIN(BIF_ARG_2, pca.orig, pca.bin_offs, pca.bin_bitoffs, bin_bitsz); pca.p = BIF_P; pca.res = THE_NON_VALUE; pca.string_as_bin = (type == TCP_PB_HTTP_BIN || type == TCP_PB_HTTPH_BIN); code = packet_parse(type, (char*)pca.aligned_ptr, packet_sz, &http_state, &packet_callbacks_erl, &pca); if (code == 0) { /* no special packet parsing, make plain binary */ ErlSubBin* body; Uint hsz = 2*ERL_SUB_BIN_SIZE + 4; hp = HAlloc(BIF_P, hsz); hend = hp + hsz; body = (ErlSubBin *) hp; body->thing_word = HEADER_SUB_BIN; body->size = body_sz; body->offs = pca.bin_offs + (body_ptr - (char*)pca.aligned_ptr); body->orig = pca.orig; body->bitoffs = pca.bin_bitoffs; body->bitsize = 0; body->is_writable = 0; hp += ERL_SUB_BIN_SIZE; pca.res = make_binary(body); } else if (code > 0) { Uint hsz = ERL_SUB_BIN_SIZE + 4; ASSERT(pca.res != THE_NON_VALUE); hp = HAlloc(BIF_P, hsz); hend = hp + hsz; } else { error: hp = HAlloc(BIF_P,3); res = TUPLE2(hp, am_error, am_invalid); goto done; } rest = (ErlSubBin *) hp; rest->thing_word = HEADER_SUB_BIN; rest->size = pca.bin_sz - packet_sz; rest->offs = pca.bin_offs + packet_sz; rest->orig = pca.orig; rest->bitoffs = pca.bin_bitoffs; rest->bitsize = bin_bitsz; /* The extra bits go into the rest. */ rest->is_writable = 0; hp += ERL_SUB_BIN_SIZE; res = TUPLE3(hp, am_ok, pca.res, make_binary(rest)); hp += 4; ASSERT(hp==hend); (void)hend; done: if (pca.aligned_ptr != bin_ptr) { erts_free(ERTS_ALC_T_TMP, pca.aligned_ptr); } BIF_RET(res); }
/** * @brief Reads data from a channel. * * @param channel The channel to read from. * * @param dest The destination buffer which will get the data. * * @param count The count of bytes to be read. * * @param is_stderr A boolean value to mark reading from the stderr flow. * * @return The number of bytes read, 0 on end of file or SSH_ERROR on error. * * @warning The read function using a buffer has been renamed to * channel_read_buffer(). */ int channel_read(CHANNEL *channel, void *dest, u32 count, int is_stderr) { SSH_SESSION *session = channel->session; BUFFER *stdbuf = channel->stdout_buffer; u32 len; enter_function(); if (count == 0) { leave_function(); return 0; } if (is_stderr) { stdbuf=channel->stderr_buffer; } /* * We may have problem if the window is too small to accept as much data * as asked */ ssh_log(session, SSH_LOG_PROTOCOL, "Read (%d) buffered : %d bytes. Window: %d", count, buffer_get_rest_len(stdbuf), channel->local_window); if (count > buffer_get_rest_len(stdbuf) + channel->local_window) { if (grow_window(session, channel, count - buffer_get_rest_len(stdbuf)) < 0) { leave_function(); return -1; } } /* block reading if asked bytes=0 */ while (buffer_get_rest_len(stdbuf) == 0 || buffer_get_rest_len(stdbuf) < count) { if (channel->remote_eof && buffer_get_rest_len(stdbuf) == 0) { leave_function(); return 0; } if (channel->remote_eof) { /* Return the resting bytes in buffer */ break; } if (buffer_get_rest_len(stdbuf) >= count) { /* Stop reading when buffer is full enough */ break; } if ((packet_read(session)) != SSH_OK || (packet_translate(session) != SSH_OK)) { leave_function(); return -1; } packet_parse(session); } if (channel->local_window < WINDOWLIMIT) { if (grow_window(session, channel, 0) < 0) { leave_function(); return -1; } } len = buffer_get_rest_len(stdbuf); /* Read count bytes if len is greater, everything otherwise */ len = (len > count ? count : len); memcpy(dest, buffer_get_rest(stdbuf), len); buffer_pass_bytes(stdbuf,len); leave_function(); return len; }
static int wait_auth_status(SSH_SESSION *session,int kbdint){ int err=SSH_AUTH_ERROR; int cont=1; STRING *auth; u8 partial=0; int todo = 0; char *auth_methods = NULL; enter_function(); while(cont){ if(packet_read(session)) break; if(packet_translate(session)) break; switch(session->in_packet.type){ case SSH2_MSG_USERAUTH_FAILURE: auth = buffer_get_ssh_string(session->in_buffer); if(!auth || buffer_get_u8(session->in_buffer,&partial)!=1 ){ ssh_set_error(session,SSH_FATAL, "invalid SSH_MSG_USERAUTH_FAILURE message"); leave_function(); return SSH_AUTH_ERROR; } auth_methods = string_to_char(auth); if(partial) { err=SSH_AUTH_PARTIAL; ssh_set_error(session,SSH_NO_ERROR,"partial success, authentications that can continue : %s", auth_methods); } else { err=SSH_AUTH_DENIED; ssh_set_error(session,SSH_REQUEST_DENIED,"Access denied. authentications that can continue : %s", auth_methods); session->auth_methods = 0; if (strstr(auth_methods, "password") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_PASSWORD; } if (strstr(auth_methods, "keyboard-interactive") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE; } if (strstr(auth_methods, "publickey") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY; } if (strstr(auth_methods, "hostbased") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED; } } free(auth); free(auth_methods); cont=0; break; case SSH2_MSG_USERAUTH_PK_OK: /* SSH monkeys have defined the same number for both */ /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */ /* which is not really smart; */ /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */ if(kbdint){ err=SSH_AUTH_INFO; cont=0; break; } /* continue through success */ case SSH2_MSG_USERAUTH_SUCCESS: err=SSH_AUTH_SUCCESS; cont=0; break; case SSH2_MSG_USERAUTH_BANNER: { STRING *banner=buffer_get_ssh_string(session->in_buffer); if(!banner){ ssh_say(1,"The banner message was invalid. continuing though\n"); break; } ssh_say(2,"Received a message banner\n"); if(session->banner) free(session->banner); /* erase the older one */ session->banner=banner; break; } default: packet_parse(session); break; } } leave_function(); return err; }
static int wait_auth_status(ssh_session session, int kbdint) { char *auth_methods = NULL; ssh_string auth; int rc = SSH_AUTH_ERROR; int cont = 1; uint8_t partial = 0; enter_function(); while (cont) { if (packet_read(session) != SSH_OK) { break; } if (packet_translate(session) != SSH_OK) { break; } switch (session->in_packet.type) { case SSH2_MSG_USERAUTH_FAILURE: auth = buffer_get_ssh_string(session->in_buffer); if (auth == NULL || buffer_get_u8(session->in_buffer, &partial) != 1) { ssh_set_error(session, SSH_FATAL, "Invalid SSH_MSG_USERAUTH_FAILURE message"); leave_function(); return SSH_AUTH_ERROR; } auth_methods = string_to_char(auth); if (auth_methods == NULL) { ssh_set_error(session, SSH_FATAL, "Not enough space"); string_free(auth); leave_function(); return SSH_AUTH_ERROR; } if (partial) { rc = SSH_AUTH_PARTIAL; ssh_set_error(session, SSH_NO_ERROR, "Partial success. Authentication that can continue: %s", auth_methods); } else { rc = SSH_AUTH_DENIED; ssh_set_error(session, SSH_REQUEST_DENIED, "Access denied. Authentication that can continue: %s", auth_methods); session->auth_methods = 0; if (strstr(auth_methods, "password") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_PASSWORD; } if (strstr(auth_methods, "keyboard-interactive") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE; } if (strstr(auth_methods, "publickey") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY; } if (strstr(auth_methods, "hostbased") != NULL) { session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED; } } string_free(auth); SAFE_FREE(auth_methods); cont = 0; break; case SSH2_MSG_USERAUTH_PK_OK: /* SSH monkeys have defined the same number for both */ /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */ /* which is not really smart; */ /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */ if (kbdint) { rc = SSH_AUTH_INFO; cont = 0; break; } /* continue through success */ case SSH2_MSG_USERAUTH_SUCCESS: rc = SSH_AUTH_SUCCESS; cont = 0; break; case SSH2_MSG_USERAUTH_BANNER: { ssh_string banner; banner = buffer_get_ssh_string(session->in_buffer); if (banner == NULL) { ssh_log(session, SSH_LOG_PACKET, "The banner message was invalid. Continuing though\n"); break; } ssh_log(session, SSH_LOG_PACKET, "Received a message banner\n"); string_free(session->banner); /* erase the older one */ session->banner = banner; break; } default: packet_parse(session); break; } } leave_function(); return rc; }
NBBOOL session_data_incoming(session_t *session, uint8_t *data, size_t length) { /* Parse the packet to get the session id */ packet_t *packet = packet_parse(data, length, session->options); /* Set to TRUE if data was properly ACKed and we should send more right away. */ NBBOOL send_right_away = FALSE; /* Suck in any data we can from the driver. */ poll_for_data(session); /* Print packet data if we're supposed to. */ if(packet_trace) { printf("INCOMING: "); packet_print(packet, session->options); } if(session->is_ping) { /* This only returns if the receive is bad. */ driver_data_received(session->driver, (uint8_t*)packet->body.ping.data, strlen(packet->body.ping.data)); } else { switch(session->state) { case SESSION_STATE_NEW: if(packet->packet_type == PACKET_TYPE_SYN) { LOG_INFO("In SESSION_STATE_NEW, received SYN (ISN = 0x%04x)", packet->body.syn.seq); session->their_seq = packet->body.syn.seq; session->options = (options_t) packet->body.syn.options; session->state = SESSION_STATE_ESTABLISHED; /* Since we established a valid session, we can send stuff right away. */ session->last_transmit = 0; session->missed_transmissions = 0; send_right_away = TRUE; } else if(packet->packet_type == PACKET_TYPE_MSG) { LOG_WARNING("In SESSION_STATE_NEW, received unexpected MSG (ignoring)"); } else if(packet->packet_type == PACKET_TYPE_FIN) { /* TODO: I shouldn't exit here. */ LOG_FATAL("In SESSION_STATE_NEW, received FIN: %s", packet->body.fin.reason); exit(0); } else { /* TODO: I shouldn't exit here. */ LOG_FATAL("Unknown packet type: 0x%02x", packet->packet_type); exit(1); } break; case SESSION_STATE_ESTABLISHED: if(packet->packet_type == PACKET_TYPE_SYN) { LOG_WARNING("In SESSION_STATE_ESTABLISHED, recieved SYN (ignoring)"); } else if(packet->packet_type == PACKET_TYPE_MSG) { LOG_INFO("In SESSION_STATE_ESTABLISHED, received a MSG"); /* Validate the SEQ */ if(packet->body.msg.options.normal.seq == session->their_seq) { /* Verify the ACK is sane */ uint16_t bytes_acked = packet->body.msg.options.normal.ack - session->my_seq; /* If there's still bytes waiting in the buffer.. */ if(bytes_acked <= buffer_get_remaining_bytes(session->outgoing_buffer)) { /* Since we got a valid response back, the connection isn't dying. */ session->missed_transmissions = 0; /* Reset the retransmit counter since we got some valid data. */ if(bytes_acked > 0) { /* Only reset the counter if we want to re-transmit * right away. */ if(transmit_instantly_on_data) { session->last_transmit = 0; session->missed_transmissions = 0; send_right_away = TRUE; } } /* Increment their sequence number */ session->their_seq = (session->their_seq + packet->body.msg.data_length) & 0xFFFF; /* Remove the acknowledged data from the buffer */ buffer_consume(session->outgoing_buffer, bytes_acked); /* Increment my sequence number */ if(bytes_acked != 0) { session->my_seq = (session->my_seq + bytes_acked) & 0xFFFF; } /* Print the data, if we received any, and then immediately receive more. */ if(packet->body.msg.data_length > 0) { driver_data_received(session->driver, packet->body.msg.data, packet->body.msg.data_length); } } else { LOG_WARNING("Bad ACK received (%d bytes acked; %d bytes in the buffer)", bytes_acked, buffer_get_remaining_bytes(session->outgoing_buffer)); } } else { LOG_WARNING("Bad SEQ received (Expected %d, received %d)", session->their_seq, packet->body.msg.options.normal.seq); } } else if(packet->packet_type == PACKET_TYPE_FIN) { LOG_FATAL("In SESSION_STATE_ESTABLISHED, received FIN: %s - closing session", packet->body.fin.reason); session->last_transmit = 0; session->missed_transmissions = 0; session_kill(session); } else { LOG_FATAL("Unknown packet type: 0x%02x - closing session", packet->packet_type); session_kill(session); } break; default: LOG_FATAL("Wound up in an unknown state: 0x%x", session->state); packet_destroy(packet); session_kill(session); exit(1); } } packet_destroy(packet); return send_right_away; }
int main(int argc, char *argv[]) { int ret, len; context *pctx; input *in; char buf[512]; int send = 0, backgroud = 0, i; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "tcp")) { send = 1; } if (!strcmp(argv[i], "deamon")) { backgroud = 1; } } if (backgroud) daemon_mode(); pctx = calloc(1, sizeof(context)); if (pctx == NULL) { DBG("error allocating context\n"); return -ENOMEM; } if(signal(SIGINT, fatal_signal) == SIG_ERR) { DBG("could not register signal handler\n"); return -EINVAL; } // create syslog openlog("iMX28-UVC", LOG_PID | LOG_CONS, LOG_USER); // get params from flash ret = params_load(); if (ret < 0) { fprintf(stderr, "load nvram params failed...\n"); } // open manage serial, 1152008N1 ret = serial_init(NULL); if (ret < 0) { fprintf(stderr, "serial_init failed\n"); free(pctx); closelog(); return -1; } // register input video stream ret = input_init(pctx, UVCDEV); if (ret < 0) { fprintf(stderr, "input_init failed, exit\n"); goto exit; } if (send) { // register output video stream ret = output_init("192.168.0.99", 5500); // tcp if (ret < 0 ) { goto exit; } } ret = input_run(pctx); if (ret < 0) { goto exit; } if (send) ret = output_run(pctx->in); in = pctx->in; while (!stop && in) { /* save_jpeg(in->buf, in->size); */ /* allow others to access the global buffer again */ /* sys_if_test(); */ len = recv_packet(buf, sizeof(buf)); if (len > 0) { hex_dump("SP0 RECV:", buf, len); packet_parse(pctx, buf, len); } } /* wait for signals */ pause(); if (send) output_stop(); exit: if (pctx->in->buf) free(pctx->in->buf); free(pctx); closelog(); serial_exit(); DBG("%s:Exit\n", __func__); return 0; }