PROCESS_THREAD(usb_eth_process, ev , data) { PROCESS_BEGIN(); usb_register_request_handler(&cdc_eth_request_hook); usb_setup(); usb_set_ep_event_process(DATA_OUT, process_current); usb_set_global_event_process(process_current); uip_fw_default(&usbethif); uip_setethaddr(default_uip_ethaddr); uip_arp_init(); while(1) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_EXIT) break; if (ev == PROCESS_EVENT_POLL) { unsigned int events = usb_get_global_events(); if (events) { if (events & USB_EVENT_CONFIG) { if (usb_get_current_configuration() != 0) { printf("Configured\n"); usb_setup_bulk_endpoint(DATA_IN); usb_setup_bulk_endpoint(DATA_OUT); usb_setup_interrupt_endpoint(INTERRUPT_IN); init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); #if 0 { static const uint8_t foo[4] = {0x12,0x34,0x56,0x78}; xmit_buffer[0].next = NULL; xmit_buffer[0].left = sizeof(foo); xmit_buffer[0].flags = USB_BUFFER_SHORT_END; xmit_buffer[0].data = &foo; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); } #endif } else { usb_disable_endpoint(DATA_IN); usb_disable_endpoint(DATA_OUT); usb_disable_endpoint(INTERRUPT_IN); } } } events = usb_get_ep_events(DATA_OUT); if (events & USB_EP_EVENT_NOTIFICATION) { uip_len = sizeof(recv_data) - recv_buffer.left; /* printf("Received: %d bytes\n", uip_len); */ memcpy(uip_buf, recv_data, uip_len); #if UIP_CONF_IPV6 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); tcpip_input(); } else #endif /* UIP_CONF_IPV6 */ if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if (uip_len > 0) { memcpy(xmit_data, uip_buf, uip_len); xmit_buffer[0].next = NULL; xmit_buffer[0].data = xmit_data; xmit_buffer[0].left = uip_len; xmit_buffer[0].flags = USB_BUFFER_SHORT_END; usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]); /* printf("Sent: %d bytes\n", uip_len); */ } } init_recv_buffer(); usb_submit_recv_buffer(DATA_OUT, &recv_buffer); } } } PROCESS_END(); }
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; }