예제 #1
0
파일: xcommon.c 프로젝트: abrauchli/allnet
/* 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!");	
}
예제 #3
0
 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);
    }
}
예제 #5
0
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();
}
예제 #6
0
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;
    }
}
예제 #7
0
/* ***************************************************
 * 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);			
}
예제 #8
0
파일: moo.c 프로젝트: Hayder-Hadi/umichmoo
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
}
예제 #9
0
파일: packet.c 프로젝트: aglqcs/P2P_CC
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;
}
예제 #10
0
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;
	}
}