/* handle an incoming packet, acking it if it is a data packet for us * returns the message length > 0 if this was a valid data message from a peer. * if it gets a valid key, returns -1 (details below) * Otherwise returns 0 and does not fill in any of the following results. * * if it is a data or ack, it is saved in the xchat log * if it is a valid data message from a peer or a broadcaster, * fills in verified and broadcast * fills in contact, message (to point to malloc'd buffers, must be freed) * if not broadcast, fills in desc (also malloc'd), sent (if not null) * and duplicate. * if verified and not broadcast, fills in kset. * the data message (if any) is null-terminated * * if kcontact and ksecret1 are not NULL, assumes we are also looking * for key exchange messages sent to us matching either of ksecret1 or * (if not NULL) ksecret2. If such a key is found, returns -1. * there are two ways of calling this: * - if the user specified the peer's secret, first send initial key, * then call handle_packet with our secret in ksecret1 and our * peer's secret in ksecret2. * - otherwise, put our secret in ksecret1, make ksecret2 and kaddr NULL, * and handle_packet is ready to receive a key. * In either case, if a matching key is received, it is saved and a * response is sent (if a response is a duplicate, it does no harm). * kmax_hops specifies the maximum hop count of incoming acceptable keys, * and the hop count used in sending the key. * * if subscription is not null, listens for a reply containing a key * matching the subscription, returning -2 if a match is found. */ int handle_packet (int sock, char * packet, int psize, char ** contact, keyset * kset, char ** message, char ** desc, int * verified, time_t * sent, int * duplicate, int * broadcast, char * kcontact, char * ksecret1, char * ksecret2, int kmax_hops, char * subscription, unsigned char * addr, int nbits) { if (! is_valid_message (packet, psize)) return 0; struct allnet_header * hp = (struct allnet_header *) packet; int hsize = ALLNET_SIZE (hp->transport); if (psize < hsize) return 0; #ifdef DEBUG_PRINT if (hp->hops > 0) /* not my own packet */ print_packet (packet, psize, "xcommon received", 1); #endif /* DEBUG_PRINT */ if (hp->message_type == ALLNET_TYPE_ACK) { handle_ack (sock, packet, psize, hsize); return 0; } if (hp->message_type == ALLNET_TYPE_CLEAR) { /* a broadcast packet */ if ((subscription != NULL) && (addr != NULL)) { int sub = handle_sub (sock, hp, packet + hsize, psize - hsize, subscription, addr, nbits); #ifdef DEBUG_PRINT printf ("handle_sub (%d, %p, %p, %d, %s, %p, %d) ==> %d\n", sock, hp, packet + hsize, psize - hsize, subscription, addr, nbits, sub); #endif /* DEBUG_PRINT */ if (sub > 0) /* received a key in response to our subscription */ return sub; } #ifdef DEBUG_PRINT else printf ("subscription %p, addr %p, did not call handle_sub\n", subscription, addr); #endif /* DEBUG_PRINT */ return handle_clear (hp, packet + hsize, psize - hsize, contact, message, verified, broadcast); } if (hp->message_type == ALLNET_TYPE_DATA) /* an encrypted data packet */ return handle_data (sock, hp, packet + hsize, psize - hsize, contact, kset, message, desc, verified, sent, duplicate, broadcast); if (hp->message_type == ALLNET_TYPE_KEY_XCHG) return handle_key (sock, hp, packet + hsize, psize - hsize, kcontact, ksecret1, ksecret2, kmax_hops); return 0; }
static EVENT_HANDLER(physical_ready){ //printf("PR called!\n"); int link; FRAME f; size_t length = sizeof(FRAME); CHECK(CNET_read_physical(&link, (char*)&f, &length)); printf("Packet received from %d, via %d\n", f.payload.source, f.payload.dest); //DATA LINK LAYER - check if checksum matches int cs = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char*)&f, (int)length) != cs){ printf("Bad Checksum - ignoring frame!\n"); return; } switch(f.payload.kind){ case RT_DATA : update_table(link, f, length); break; case DL_DATA : handle_data(link, f, length); break; case DL_ACK : handle_ack(link, f.payload); break; default : printf("The world is not enough!\n"); break; } //printf("Packet successfully processed!"); }
void on_message(connection_ptr connection,message::data_ptr msg) { wscmd::cmd command = wscmd::parse(msg->get_payload()); std::cout << "msg: " << msg->get_payload() << std::endl; if (command.command == "ack") { handle_ack(connection,command); } else { broadcast_message(msg); } }
void DataFlash_MAVLink::remote_log_block_status_msg(mavlink_channel_t chan, mavlink_message_t* msg) { mavlink_remote_log_block_status_t packet; mavlink_msg_remote_log_block_status_decode(msg, &packet); if(packet.status == 0){ handle_retry(packet.seqno); } else{ handle_ack(chan, msg, packet.seqno); } }
void DataFlash_MAVLink::remote_log_block_status_msg(mavlink_channel_t chan, mavlink_message_t* msg) { mavlink_remote_log_block_status_t packet; mavlink_msg_remote_log_block_status_decode(msg, &packet); if (!semaphore->take_nonblocking()) { return; } if(packet.status == 0){ handle_retry(packet.seqno); } else{ handle_ack(chan, msg, packet.seqno); } semaphore->give(); }
void handle_message(message_t* msg, node_t* sender) { node_update_time(&sender->time); switch(msg->type) { case 'M': handle_normal(msg, sender); break; case 'A': handle_ack((message_t*)msg, sender); break; case 'H': // Received heartbeat break; default: PRINT("Unknown type"); break; } }
/* *************************************************** * Function: handle_network_data * *************************************************** * A packet has arrived. If its an ACK packet, call a helper * function that deals with acks. If the packet has data or it's * a FIN packet, then add the packet to the receiver buffer only * if it fits in the receiving window. If it doesn't fit, * drop the packet. If it fits, send an acknowledgement. */ static void handle_network_data(mysocket_t sd, context_t *ctx) { char *pkt = (char *)calloc(1, (TH_MAX_OFFSET*sizeof(uint32_t)) + STCP_MSS); size_t total_length = network_recv(sd, pkt); struct tcphdr* hdr = (struct tcphdr *)pkt; ctx->recv_win = MIN(hdr->th_win, CWIN); if (hdr->th_flags & TH_ACK) { handle_ack(hdr, sd, ctx); } size_t data_length = total_length - TCP_DATA_START(hdr); if (data_length>0 || (hdr->th_flags & TH_FIN)) { our_dprintf("Received %d bytes of data with seq: %d, last ack sent: %d\n", data_length, hdr->th_seq, ctx->last_ack_sent); /* Does the packet fit in the receiving window?*/ if ((hdr->th_seq + data_length)<=(ctx->last_ack_sent + RWIN)) { add_to_recv_buffer(ctx, pkt, total_length); if (hdr->th_seq == ctx->last_ack_sent){ /* The packet arrived in order. We can remove all in-order * packets from the receive buffer now */ our_dprintf("Packet In Order. Handling buffer\n"); handle_recv_buffer(sd, ctx); } else { if (hdr->th_seq > ctx->last_ack_sent) { our_dprintf("This packet is out of order. Adding to recv buffer\n"); } } send_ack(sd, ctx); } else { our_dprintf("Packet outside receiver buffer. Dropping!!!\n"); } } free(pkt); }
int main(void) { //*******************************Timer setup********************************** WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer P1SEL = 0; P2SEL = 0; P1IE = 0; P1IFG = 0; P2IFG = 0; DRIVE_ALL_PINS // set pin directions correctly and outputs to low. // Check power on bootup, decide to receive or sleep. if(!is_power_good()) sleep(); RECEIVE_CLOCK; #if DEBUG_PINS_ENABLED #if USE_2618 DEBUG_PIN5_LOW; #endif #endif #if ENABLE_SLOTS // setup int epc epc = ackReply[2]<<8; epc |= ackReply[3]; // calculate RN16_1 table for (Q = 0; Q < 16; Q++) { rn16 = epc^Q; lfsr(); if (Q > 8) { RN16[(Q<<1)-9] = __swap_bytes(rn16); RN16[(Q<<1)-8] = rn16; } else { RN16[Q] = rn16; } } #endif TACTL = 0; asm("MOV #0000h, R9"); // dest = destorig; #if READ_SENSOR init_sensor(); #endif #if !(ENABLE_SLOTS) queryReplyCRC = crc16_ccitt(&queryReply[0],2); queryReply[3] = (unsigned char)queryReplyCRC; queryReply[2] = (unsigned char)__swap_bytes(queryReplyCRC); #endif #if SENSOR_DATA_IN_ID // this branch is for sensor data in the id ackReply[2] = SENSOR_DATA_TYPE_ID; state = STATE_READ_SENSOR; timeToSample++; #else ackReplyCRC = crc16_ccitt(&ackReply[0], 14); ackReply[15] = (unsigned char)ackReplyCRC; ackReply[14] = (unsigned char)__swap_bytes(ackReplyCRC); #endif #if ENABLE_SESSIONS initialize_sessions(); #endif state = STATE_READY; setup_to_receive(); while (1) { // TIMEOUT! reset timer if (TAR > 0x256 || delimiterNotFound) // was 0x1000 { if(!is_power_good()) { sleep(); } #if SENSOR_DATA_IN_ID // this branch is for sensor data in the id if ( timeToSample++ == 10 ) { state = STATE_READ_SENSOR; timeToSample = 0; } #elif SENSOR_DATA_IN_READ_COMMAND if ( timeToSample++ == 10 ) { state = STATE_READ_SENSOR; timeToSample = 0; } #else #if !(ENABLE_READS) if(!is_power_good()) sleep(); #endif inInventoryRound = 0; state = STATE_READY; #endif #if ENABLE_SESSIONS handle_session_timeout(); #endif #if ENABLE_SLOTS if (shift < 4) shift += 1; else shift = 0; #endif setup_to_receive(); } switch (state) { case STATE_READY: { inInventoryRound = 0; ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// // @ short distance has slight impact on performance else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // got >= 22 bits, and it's not the beginning of a select. just reset. ////////////////////////////////////////////////////////////////////// else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } break; } case STATE_ARBITRATE: { ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // got >= 22 bits, and it's not the beginning of a select. just reset. ////////////////////////////////////////////////////////////////////// //else if ( bits >= NUM_QUERY_BITS ) else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // this state handles query, queryrep, queryadjust, and select commands. ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { handle_queryrep(STATE_REPLY); delimiterNotFound = 1; } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { handle_queryadjust(STATE_REPLY); setup_to_receive(); } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// // @ short distance has slight impact on performance else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command break; } case STATE_REPLY: { // this state handles query, query adjust, ack, and select commands /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { #if ENABLE_READS handle_ack(STATE_ACKNOWLEDGED); setup_to_receive(); #elif SENSOR_DATA_IN_ID handle_ack(STATE_ACKNOWLEDGED); delimiterNotFound = 1; // reset #else // this branch for hardcoded query/acks handle_ack(STATE_ACKNOWLEDGED); //delimiterNotFound = 1; // reset setup_to_receive(); #endif } ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { // i'm supposed to stay in state_reply when I get this, but if I'm // running close to 1.8v then I really need to reset and get in the // sleep, which puts me back into state_arbitrate. this is complete // a violation of the protocol, but it sure does make everything // work better. - polly 8/9/2008 handle_query(STATE_REPLY); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { do_nothing(); state = STATE_ARBITRATE; setup_to_receive(); } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { handle_queryadjust(STATE_REPLY); delimiterNotFound = 1; } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command else if ( bits >= MAX_NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) != 0xA0 ) && ( ( cmd[0] & 0xF0 ) != 0x80 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } break; } case STATE_ACKNOWLEDGED: { // responds to query, ack, request_rn cmds // takes action on queryrep, queryadjust, and select cmds ///////////////////////////////////////////////////////////////////// // process the REQUEST_RN command ////////////////////////////////////////////////////////////////////// if ( bits >= NUM_REQRN_BITS && ( cmd[0] == 0xC1 ) ) { #if 1 handle_request_rn(STATE_OPEN); setup_to_receive(); #else handle_request_rn(STATE_READY); delimiterNotFound = 1; #endif } #if 1 ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); delimiterNotFound = 1; } /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// // this code doesn't seem to get exercised in the real world. if i ever // ran into a reader that generated an ack in an acknowledged state, // this code might need some work. //else if ( bits == 20 && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) else if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { handle_ack(STATE_ACKNOWLEDGED); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { // in the acknowledged state, rfid chips don't respond to queryrep // commands do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYADJ_BITS && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryadjust command ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // process the NAK command ////////////////////////////////////////////////////////////////////// else if ( bits >= 10 && ( cmd[0] == 0xC0 ) ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the READ command ////////////////////////////////////////////////////////////////////// // warning: won't work for read addrs > 127d if ( bits == NUM_READ_BITS && ( cmd[0] == 0xC2 ) ) { handle_read(STATE_ARBITRATE); state = STATE_ARBITRATE; delimiterNotFound = 1 ; } // FIXME: need write, kill, lock, blockwrite, blockerase ////////////////////////////////////////////////////////////////////// // process the ACCESS command ////////////////////////////////////////////////////////////////////// if ( bits >= 56 && ( cmd[0] == 0xC6 ) ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1 ; } #endif else if ( bits >= MAX_NUM_READ_BITS ) { state = STATE_ARBITRATE; delimiterNotFound = 1 ; } #if 0 // kills performance ... else if ( bits >= 44 ) { do_nothing(); state = STATE_ARBITRATE; delimiterNotFound = 1; } #endif break; } case STATE_OPEN: { // responds to query, ack, req_rn, read, write, kill, access, // blockwrite, and blockerase cmds // processes queryrep, queryadjust, select cmds ////////////////////////////////////////////////////////////////////// // process the READ command ////////////////////////////////////////////////////////////////////// // warning: won't work for read addrs > 127d if ( bits == NUM_READ_BITS && ( cmd[0] == 0xC2 ) ) { handle_read(STATE_OPEN); // note: setup_to_receive() et al handled in handle_read } ////////////////////////////////////////////////////////////////////// // process the REQUEST_RN command ////////////////////////////////////////////////////////////////////// else if ( bits >= NUM_REQRN_BITS && ( cmd[0] == 0xC1 ) ) { handle_request_rn(STATE_OPEN); setup_to_receive(); } ////////////////////////////////////////////////////////////////////// // process the QUERY command ////////////////////////////////////////////////////////////////////// if ( bits == NUM_QUERY_BITS && ( ( cmd[0] & 0xF0 ) == 0x80 ) ) { handle_query(STATE_REPLY); delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the QUERYREP command ////////////////////////////////////////////////////////////////////// else if ( bits == NUM_QUERYREP_BITS && ( ( cmd[0] & 0x06 ) == 0x00 ) ) { do_nothing(); state = STATE_READY; setup_to_receive(); } // queryrep command ////////////////////////////////////////////////////////////////////// // process the QUERYADJUST command ////////////////////////////////////////////////////////////////////// else if ( bits == 9 && ( ( cmd[0] & 0xF8 ) == 0x48 ) ) { do_nothing(); state = STATE_READY; delimiterNotFound = 1; } // queryadjust command /////////////////////////////////////////////////////////////////////// // process the ACK command /////////////////////////////////////////////////////////////////////// else if ( bits == NUM_ACK_BITS && ( ( cmd[0] & 0xC0 ) == 0x40 ) ) { handle_ack(STATE_OPEN); delimiterNotFound = 1; } ////////////////////////////////////////////////////////////////////// // process the SELECT command ////////////////////////////////////////////////////////////////////// else if ( bits >= 44 && ( ( cmd[0] & 0xF0 ) == 0xA0 ) ) { handle_select(STATE_READY); delimiterNotFound = 1; } // select command ////////////////////////////////////////////////////////////////////// // process the NAK command ////////////////////////////////////////////////////////////////////// else if ( bits >= 10 && ( cmd[0] == 0xC0 ) ) { handle_nak(STATE_ARBITRATE); delimiterNotFound = 1; } break; } case STATE_READ_SENSOR: { #if SENSOR_DATA_IN_READ_COMMAND read_sensor(&readReply[0]); // crc is computed in the read state RECEIVE_CLOCK; state = STATE_READY; delimiterNotFound = 1; // reset #elif SENSOR_DATA_IN_ID read_sensor(&ackReply[3]); RECEIVE_CLOCK; ackReplyCRC = crc16_ccitt(&ackReply[0], 14); ackReply[15] = (unsigned char)ackReplyCRC; ackReply[14] = (unsigned char)__swap_bytes(ackReplyCRC); state = STATE_READY; delimiterNotFound = 1; // reset #endif break; } // end case } // end switch } // while loop }
data_packet_list_t *handle_packet(data_packet_t *packet, bt_config_t* config, int sockfd, packet_tracker_t *p_tracker){ /* read a incoming packet, return a list of response packets */ packet->header.magicnum = ntohs(packet->header.magicnum); packet->header.header_len = ntohs(packet->header.header_len); packet->header.packet_len = ntohs(packet->header.packet_len); packet->header.seq_num = ntohl(packet->header.seq_num); packet->header.ack_num = ntohl(packet->header.ack_num); printf("RECV handle_packet() type == %d length = %d socket = %d\n", packet->header.packet_type,packet->header.packet_len,sockfd ); if( packet->header.packet_type == 3 ){ printf("|||| RECV packet with type = DATA seq = %d\n", packet->header.seq_num); } if(packet->header.packet_type == 4){ printf("|||| RECV packet with type = ACK ack = %d\n", packet->header.ack_num); } if(packet->header.packet_type == 0){ /* if incoming packet is a WHOHAS packet */ /* scan the packet datafiled to fetch the hashes and get the count */ int count = packet->data[0]; printf("WHOHAS %d chunks\n", count); int i; char local_has[100]; char data[1500]; memset(data, 0 ,1500); int reply_count = 0; char * chunkfile = config->has_chunk_file; if ( read_chunkfile(chunkfile, local_has) < 0 ){ printf("Can not locate local chunkfile = %s\n", chunkfile); return NULL; } int find = -1; for(i = 0;i < count; i ++){ int hash_start = 4 + 20 * i; int j; char request_chunk[20]; for(j = hash_start; j < hash_start + 20; j ++){ /* if I have the chunck locally */ request_chunk[j - hash_start] = packet->data[j]; } if( 1 == find_in_local_has(request_chunk, local_has) ){ printf("find a valid local hash [%s]\n", request_chunk); find = 1; for( j = 0;j < 20;j ++){ data[reply_count + j] = request_chunk[j]; } reply_count += 20; } } data[reply_count] = '\0'; if( find == -1){ return NULL; } else{ data_packet_list_t *ret = (data_packet_list_t *)malloc(sizeof(data_packet_list_t)); ret->packet = init_packet(1, data, reply_count); ret->next = NULL; return ret; } } else if( packet->header.packet_type == 1 ){ /* if the incoming packet is an IHAVE packet */ /* here one qustions are what if mutiple nodes declare he has the requested chunk */ data_packet_list_t *ret = NULL; int count = packet->data[0]; int i; printf("starting IHAVE, %d chunks\n", count); for(i = 0;i < count; i ++){ /* for each hash value generate a GET packet */ /* each GET packet will only contain ONE hash value*/ /* TODO(cp2): add a data structrue to record which node has this chunk */ char data[21]; memset(data, 0 , 21); int j; for(j = 0;j < 20;j ++ ){ data[j] = packet->data[4 + 20 * i + j]; } int offset = get_off_set_from_master_chunkfile(data, config); printf("IHAVE registing for chunk = %d \n", offset); /* add node selection here */ /* based on node id, find the address of this node */ bt_peer_t *node; node = config->peers; while(node != NULL){ // Don't send request to itself printf("%d \n", node->id); if(node->id == sockfd){ break; } node = node->next; } if(node == NULL){ printf("Can not locate the node exiting\n"); exit(0); } printf("In node check offset = %d node_id = %d\n", offset,sockfd); /* for this chunk if I never use this node before, use this node, otherwise return*/ chunk_owner_list_t *p; for( p = file_manager.already_used; p != NULL; p = p->next){ if( p->offset == offset ){ if( p->address->sin_family == node->addr.sin_family && p->address->sin_port == node->addr.sin_port && p->address->sin_addr.s_addr == node->addr.sin_addr.s_addr){ } } } // after decide the node that I will be talking to, init the recv list // if decide to use this node { if( offset == -1){ printf("Can not init the recv_buffer with hash = %s\n", data); continue; } printf("DEBUG init recv_buffer with offset = %d\n", offset); if ( -1 == init_recv_buffer(offset,sockfd)){ printf("Can not allocate recv_buffer\n"); continue; } chunk_owner_list_t *new_element = (chunk_owner_list_t *)malloc(sizeof(chunk_owner_list_t)); new_element->address = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); new_element->offset = offset; new_element->address->sin_family = node->addr.sin_family; new_element->address->sin_port = node->addr.sin_port; new_element->address->sin_addr.s_addr = node->addr.sin_addr.s_addr; if( NULL == file_manager.already_used){ file_manager.already_used = new_element; new_element->next = NULL; } else{ new_element->next = file_manager.already_used; file_manager.already_used = new_element; } printf("Generating GET packet to nodeid = %d\n", sockfd); data[20] = '\0'; if ( ret == NULL ){ ret = (data_packet_list_t *)malloc( sizeof(data_packet_list_t)); ret->packet = init_packet(2, data, 20); ret->next = NULL; } else{ data_packet_t *packet = init_packet(2, data, 20); data_packet_list_t *new_block = (data_packet_list_t *)malloc( sizeof(data_packet_list_t)); new_block->packet = packet; new_block->next = ret; ret = new_block; } memset(data, 0 , 20); /* uodate the timer for this chunk */ for(j = 0;j < file_manager.chunk_count; j ++){ if( file_manager.offset[j] == offset ){ break; } } file_manager.timer[j] = time(NULL); } return ret; } else if( packet->header.packet_type == 2 ){ /* if the incoming packet is an GET packet */ /* start transmit of the data */ char hash[21]; memcpy(hash, packet->data, 20); hash[20] = '\0'; char *data = get_data_from_hash(hash, config); int offset = get_off_set_from_master_chunkfile(hash, config); /* init the flow control machine for sending back the data */ init_datalist(sockfd, offset,data); /* and call the first send */ data_packet_list_t *ret = send_data(sockfd); return ret; } else if ( packet->header.packet_type == 3 ){ /* if the incoming packet is an DATA packet */ //int offset = packet->header.ack_num; int offset; printf("Before recv_data seq = %d\n", packet->header.seq_num); data_packet_list_t *ret = recv_data(packet, sockfd, &offset); int j; for(j = 0;j < file_manager.chunk_count; j ++){ if( file_manager.offset[j] == offset ){ break; } } file_manager.timer[j] = time(NULL); /* this datapacket may be the last packet, check if it is then write back to disk */ printf("DEBUG after recv_data()\n"); check_file_manager(config); printf("DEBUG after check_file_manager()\n"); return ret; } else if( packet->header.packet_type == 4){ /* if the incoming packet is an ACK packet */ //int offset = packet->header.seq_num; data_packet_list_t *ret = handle_ack(sockfd , packet->header.ack_num - 1, p_tracker); return ret; } else{ /* TODO(for next checkpoint) : if incoming packet is other packets*/ printf("ERROR: INVALID PACKET TYPE = %d\n", packet->header.packet_type); } return NULL; }
void process_messages() { #ifdef UART0_DISCONNECT_ON_DTR if ((PORT_UART0_DTR & (1 << PIN_UART0_DTR))) { if (state == StateConnected) { send_error(ErrorDisconnect, 0); } uart0_flush(); return; } #endif MessageParseResult res; while ((res = message_parse()) == ParseOk) { switch (message.identifier) { case IdAckMessage: handle_ack(); break; case IdInitMessage: handle_init(); break; case IdFootSwitchMessage: handle_footswitch(); break; case IdInterlockResetMessage: handle_int_reset(); break; case IdServoCtrlMessage: handle_servo_ctrl(); break; case IdDockingLimitMessage: handle_docking_limit(); break; case IdErrorMessage: handle_error(); break; case IdDockingTareMessage: handle_docking_tare(); break; case IdSettingsMessage: handle_settings(); break; default: send_error(ErrorUnhandled, message.sequence); return; } } switch (res) { case ParseNotEnoughData: // buffer empty, done break; // case ParseInvalidIdentifier: // fall // case ParseInvalidSizeError: // fall // case ParseChecksumError: // fall default: send_error(ErrorParser, 0); break; } }