void cc200_datalink_from_physical(cc200_frame_t frame, int link) { uint32_t alleged_checksum = frame.checksum; frame.checksum = 0; uint32_t actual_checksum = CNET_crc32( (void *) &frame, sizeof(frame) ); if (alleged_checksum == actual_checksum) { switch (frame.kind) { case CC200_DATA: CC200_PRINT( "data " CC200_SEQ CC200_FROM CC200_LINK, frame.sequence_number, link ); cc200_datalink_ack(frame.sequence_number, link); if ( frame.sequence_number == cc200_next_data_seq_expected[link] ) { cc200_next_data_seq_expected[link] ^= 1; cc200_network_from_datalink(frame.payload); } break; case CC200_ACK: CC200_PRINT( "ACK " CC200_SEQ CC200_FROM CC200_LINK, frame.sequence_number, link ); if ( frame.sequence_number == cc200_next_ack_seq_expected[link] ) { CC200_PRINT( "stopping timer %" PRId32 " for " CC200_LINK, cc200_link_timer_vector[link], link ); CC200_CHECK( CNET_stop_timer( cc200_link_timer_vector[link] ) ); cc200_list_node_free( cc200_list_remove( cc200_frame_queue[link], cc200_frame_queue[link]->head ) ); cc200_next_ack_seq_expected[link] ^= 1; if (cc200_frame_queue[link]->count > 0) { cc200_datalink_data_next(link); } } break; } } else { CC200_PRINT("bad frame" CC200_FROM CC200_LINK, link); } }
static EVENT_HANDLER(physical_ready) { FRAME f; size_t len; int link, checksum; len = sizeof(FRAME); CHECK(CNET_read_physical(&link, (char *)&f, &len)); checksum = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char *)&f, len) != checksum) { return; // bad checksum, ignore frame } switch (f.kind) { case ACK : if(f.seq == ackexpected) { CNET_stop_timer(lasttimer); ackexpected = 1-ackexpected; CNET_enable_application(ALLNODES); } break; case DATA : if(f.seq == frameexpected) { len = f.len; CHECK(CNET_write_application((char *)&f.msg, &len)); frameexpected = 1-frameexpected; } transmit_frame(NULL, ACK, 0, f.seq); break; } }
static void frame_arrived(CnetEvent ev, CnetTimerID timer, CnetData data) { if(strcmp(nodeinfo.nodename,"Dehradun")==0 ){ char *ack=(char *)malloc(48*sizeof(char)); int link; int seq_check; size_t length=48; CNET_stop_timer(id); CHECK(CNET_read_physical(&link, ack, &length)); seq_check = ((int)(ack[0]))-48; if(seq_check == ((SN+1)%2)){ printf("\n Acknowledgement received "); flag_sen=1; count++; SN= count%2; } } else if(strcmp(nodeinfo.nodename,"KGP")==0 ){ char *frame=(char *)malloc(64*sizeof(char)); char *tobchecked=(char *)calloc(9,sizeof(char)); size_t length=64; int link; int i=0; printf("\n Receiving....."); CHECK(CNET_read_physical(&link, frame, &length)); for(i=1;i<9;i++){ tobchecked[i]=frame[i]; } if((strcmp(check,tobchecked))==0){ flag_rec = 1; if(RN==((int)frame[0])-48){ printf("\nSUCCESSFULLY RECEIVED %u bytes", length); RN=(RN+1)%2; flag_sen=1; } else{ printf("\n The SN mismatches !"); } transmit_frame(); //for the acknowledgement printf("\n The frame is valid"); } else { printf("\n The frame is either lost or error"); } } }
static EVENT_HANDLER(ready_physical) { if(nodetype != RECEIVER) { ACK_FRAME f; int link; size_t length; length = sizeof(ACK_FRAME); CHECK(CNET_read_physical(&link, (char*) &f, &length)); uint16_t check = f.check; f.check = 0; if(CNET_ccitt((unsigned char*) &f, sizeof(ACK_FRAME)) != check) return; if(f.sequence <= 0) { // SREJ FRAME printf("\t\t\t\tSREJ received, sequence=%d\n", -f.sequence); f.sequence = -f.sequence; CNET_stop_timer(timer); trans_frame_state[f.sequence] = ACK_WAIT; frame_send(&(t_window[f.sequence].message), t_window[f.sequence].length, f.sequence); } else { // RECVREADY FRAME printf("\t\t\t\tACK received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_recv + 1)%(MAXSEQ + 1); i != f.sequence - 1; i = (i + 1) % (MAXSEQ + 1)) trans_frame_state[i] = ACK_RECEIVED; last_ack_recv = f.sequence - 1; trans_frame_state[f.sequence-1] = ACK_RECEIVED; CNET_stop_timer(timer_wait); if(packets_sent >= 10000) { if(time_end == 0) time_end = nodeinfo.time_of_day.sec; } else { packets_sent++; CNET_enable_application(ALLNODES); } } } else { FRAME_DATA f; size_t length; int link; int checksum; length = sizeof(FRAME_DATA); CHECK(CNET_read_physical(&link, (char*) &f, &length)); checksum = f.checksum; f.checksum = 0; if(CNET_ccitt((unsigned char*) &f, CHECK_BYTES) != checksum) { // bad checksum, ignore frame printf("\t\t\t\tBAD checksum - frame ignored\n"); ack_send(last_ack_sent + 1, SREJ); printf("Requesting to send frame %d\n",last_ack_sent+1); return; } recv_frame_status[f.sequence] = RECEIVED; printf("\t\t\t\tDATA received, sequence=%d\n", f.sequence); int i; for(i = (last_ack_sent + 1) % (MAXSEQ + 1); i != f.sequence; i = (i + 1) % (MAXSEQ + 1)) { if(recv_frame_status[i] != RECEIVED) break; } if(i == f.sequence) ack_send(f.sequence + 1, RECVREADY); } }
void stop_walking(void) { CNET_stop_timer(tid); paused = true; }
void start_walking(void) { CNET_stop_timer(tid); tid = CNET_start_timer(EV_WALKING, WALK_FREQUENCY, 0); }
static void ack_received(FRAME frame, int link) { FRAME tempFrame; int first, second, third, fourth; // PRINT ACKOWLEDGEMENT MESSAGE printf("\n\t\t\t\t\tACK RECEIVED\n"); printf("\t\t\t\t\tIN LINK:%d\n", link); printf("\t\t\t\t\tSEQ NO:\t%d\n", frame.seq); // ENSURE ACK NUMBER IS BETWEEN ACK EXPECTED AND NEXT FRAME TO SEND if (between(ackExpected[link - 1], frame.seq, nextFrameToSend[link - 1])) { // LOOP UNTIL ACKEXPECTED IS ONE MORE THAN THE SEQNUM OF THE ACK while (between(ackExpected[link - 1], frame.seq, nextFrameToSend[link - 1])) { // STOP THE TIMER FOR THAT FRAME TO PREVENT A TIMEOUT CNET_stop_timer(timers[link - 1][ackExpected[link - 1]]); // INCREMENT ACKEXPECTED AND DECREASE NUMBER IN WINDOW inc(&ackExpected[link - 1]); numInWindow[link - 1] -= 1; } } else { // ERRORS SHOULD ALL BE CAUGHT BEFORE THIS // STILL CHECK REGARDLESS, AS A FAILSAFE printf("\n\t\t\t\t\tERROR: OUTSIDE WINDOW BOUNDS\n"); } // ENSURE WINDOW SIZE IS VALID AND BUFFER IS NOT EMPTY while (numInWindow[link - 1] < MAX_SEQ && numInBuffer[link - 1] > 0) { // ADD FRAMES FROM THE BUFFER TO THE WINDOW printf("\t\t\t\t\tSENDING FRAME FROM BUFFER\n"); // REMOVE FRAME FROM THE FRONT OF THE BUFFER tempFrame = buffer[link - 1][bufferBounds[link - 1][0]]; inc(&bufferBounds[link - 1][0]); numInBuffer[link - 1] -= 1; // STORE THE FRAME FROM THE BUFFER IN THE WINDOW tempFrame.seq = nextFrameToSend[link - 1]; window[link - 1][nextFrameToSend[link - 1]] = tempFrame; numInWindow[link - 1] += 1; // TRANSMIT THE FRAME FROM THE BUFFER (NOW IN THE WINDOW) tempFrame.link = get_route(tempFrame.destNode); transmit_frame(tempFrame); inc(&nextFrameToSend[link - 1]); } // IF ALL LINK WINDOWS NOT FULL AND ALL BUFFER'S EMPTY // THIS KEEPS EFFICIECNY AS HIGH AS POSSIBLE first = ( numInBuffer[0] == 0 ) && ( numInWindow[0] < MAX_SEQ ); second = ( numInBuffer[1] == 0 ) && ( numInWindow[1] < MAX_SEQ ); third = ( numInBuffer[2] == 0 ) && ( numInWindow[2] < MAX_SEQ ); fourth = ( numInBuffer[3] == 0 ) && ( numInWindow[3] < MAX_SEQ ); // REENABLE APPLICATION LAYER TO GENERATE MESSAGES AGAIN if ( first && second && third && fourth ) { CHECK(CNET_enable_application(ALLNODES)); for ( int ii = 0; ii < nodeinfo.nlinks; ii++ ) CNET_set_LED(ii, "green" ); } print_buffers(link); }
void stop_association(void) { CNET_stop_timer(ass_tid); }
void stop_timeout(void) { CNET_stop_timer(timeout_tid); }
void stop_talking(void) { CNET_stop_timer(talk_tid); }
///Worker Method ///Called when we receive data from one of our data link layers. ///Handles association with AP's and propagation of frames to other layers. static void up_from_dll(int link, const char *data, size_t length) { //fprintf(stdout, "\t%s: Received frame from dll on link\n", nodeinfo.nodename); if (length > sizeof(struct nl_packet)) { printf("\t%s: %zu is larger than a nl_packet! ignoring.\n",nodeinfo.nodename, length); return; } //Treat this frame as a network layer packet. struct nl_packet packet; memset(&packet, 0, sizeof(packet)); memcpy(&packet, data, length); fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address); fprintf(stdout, "\t%s: Received frame from dll on link %d\n\tfrom node %" PRId32 " for node %" PRId32 ".\n",nodeinfo.nodename, link, packet.src, packet.dest); uint32_t checksum = packet.checksum; packet.checksum = 0; fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename); printFRAMEKIND(packet.type); fprintf(stdout,"\n"); if (CNET_crc32((unsigned char *)&packet, sizeof(packet)) != checksum) { fprintf(stdout, "\tChecksum failed.\n"); //return; } if (packet.dest != nodeinfo.address) { fprintf(stdout, "\tThat's not for me.\n"); fprintf(stdout, "\tPacket dest %i: \n\t %s's src: %i\n", packet.dest, nodeinfo.nodename, nodeinfo.address); fprintf(stdout, "\tPacket src %i: \n", packet.src); return; } // Check if we've seen this packet rece ntly. for (size_t i = 0; i < PACKET_MEMORY_LENGTH; ++i) { if (seen_checksums[i] == checksum) { fprintf(stdout, "\tI seem to have seen this recently.\n"); return; } } // Remember the checksum of this packet. seen_checksums[next_seen_checksum++] = checksum; next_seen_checksum %= PACKET_MEMORY_LENGTH; fprintf(stdout,"\t%s has received a nl_packet of type ",nodeinfo.nodename); printFRAMEKIND(packet.type); fprintf(stdout,"\n"); struct nl_packet assRequest; switch (packet.type) { case NL_DATA : fprintf(stdout, "\nDATA FRAME FOR %i @ %i, seq=%d \n", packet.dest, nodeinfo.address, packet.seq); if(packet.seq == frameexpected) { fprintf(stdout, "\tDATA Up to the application layer!\n"); size_t payload_length = packet.length; CHECK(CNET_write_application(packet.data, &payload_length)); frameexpected = 1 - frameexpected; } else { fprintf(stdout, "\tignored...\n"); } struct nl_packet ackPacket = (struct nl_packet){ .src = nodeinfo.address, .dest = packet.src, .length = NL_MAXDATA, .type = NL_ACK }; memcpy(ackPacket.data,nodeinfo.nodename,sizeof(nodeinfo.nodename)); ackPacket.seq = packet.seq; ackPacket.checksum = CNET_crc32((unsigned char *)&ackPacket, sizeof(ackPacket)); fprintf(stdout, "\tTransmitting an acknowledgement packet, seq = %i!*********************\n", ackPacket.seq); fprintf(stdout, "\n ackpacket src:%i dest:%i\n",ackPacket.src, ackPacket.dest); if(ackPacket.dest > 133) exit(0); transmit(&ackPacket); break; case NL_ACK : //CANCEL THE TIMEOUT FUNCTION AS WE HAVE RECEIVED THE ACKNOWLEEDGEMENT EXPECTED //If it has the expected sequence number if(packet.seq == ackexpected) { printf("\t\t\t\t**************ACK received, seq=%d\n", packet.seq); CHECK(CNET_stop_timer(data_timeout)); ackexpected = 1-ackexpected; CHECK(CNET_enable_application(ALLNODES)); } break; case NL_ASSREQ : if(timeAPset == false) { if(isAss == false) { fprintf(stdout, "\n%s is now associated with ap link %i\n", nodeinfo.nodename,packet.src); CHECK(CNET_stop_timer(probe_timer)); assRequest.type = NL_ASSREQ; assRequest.dest = packet.src; assRequest.src = nodeinfo.address; assRequest.length = NL_MAXDATA; assRequest.checksum = CNET_crc32((unsigned char *)&assRequest, sizeof(assRequest)); fprintf(stdout, "\ttoSend is of frame type "); printFRAMEKIND(toSend->type); fprintf(stdout, "\n"); fprintf(stdout, "\n%s Is ASSOCIATED!**********\n",nodeinfo.nodename); if(assRequest.dest > 133) exit(0); //DOING THINGS timeAPset = true; isAss = true; transmit(&assRequest); CHECK(CNET_enable_application(ALLNODES)); } else { fprintf(stderr, "HOLY CRAP BATMAN! I'M REASSOCIATING!\n"); //exit(EXIT_FAILURE);; isAss = true; CHECK(CNET_stop_timer(probe_timer)); } timeAPset = nodeinfo.time_of_day.sec; } break; default : fprintf(stdout, "\tFollowing default\n"); exit(0); // Send this packet to the application layer. fprintf(stdout, "\tUp to the application layer!\n"); size_t payload_length = packet.length; CHECK(CNET_write_application(packet.data, &payload_length)); break; } } ///Event Handler ///Called when this mobile node's application layer has generated a new message. ///Proceeds to transmit the generated message. static EVENT_HANDLER(application_ready) { fprintf(stdout, "\t%s's application later ready, creating new message.\n\t Max data: %i, Type: %" PRId32".\n",nodeinfo.nodename, NL_MAXDATA, NL_DATA); toSend->src = nodeinfo.address; toSend->length = NL_MAXDATA; toSend->type = NL_DATA; toSend->seq = nextframetosend; printf( " THE NEXT FRAME TO SEND IS %i\n", nextframetosend); struct nl_packet temp = (struct nl_packet){ .src = nodeinfo.address, .length = NL_MAXDATA, }; //update toSend CHECK(CNET_read_application(&temp.dest, temp.data, &temp.length)); memcpy(&(toSend->dest),&temp.dest,sizeof(temp.dest)); memcpy(&(toSend->data), &temp.data, temp.length); toSend->length = temp.length; fprintf(stdout, "\ntoSend dest:%i\n", toSend->dest); fprintf(stdout, "\tAppready: toSend is of frame type "); printFRAMEKIND(toSend->type); fprintf(stdout, "\n"); toSend->checksum = CNET_crc32((unsigned char *)&toSend, sizeof(toSend)); fprintf(stdout, "\t%s: Generated message for % " PRId32 ",\n\t attempting to transmit\n",nodeinfo.nodename, toSend->dest); CHECK(CNET_disable_application(ALLNODES)); transmit(toSend); if(toSend->type != NL_DATA) { fprintf(stderr, "\t%s toSend is not DATA!\n",nodeinfo.nodename); exit(0); } // CNET_start_timer(EV_TIMER2, 1, 0); nextframetosend = 1-nextframetosend; fprintf(stdout, "\tPacket transmitted successfully.\n"); } ///Event Handler ///Creates a new probe packet and sends it to transmit for propagation. ///This packet is used to discover access points and find an appropriate one ///for association. ///It then starts a timer to ensure that if there is no response, an additional ///probe is sent after a period of time. ///The timer is stopped once an acknowledgement is received and the mobile device ///is considered 'associated' with an access point. static EVENT_HANDLER(probe) { probe_timer = CNET_start_timer(EV_TIMER3, 5000000, 0); fprintf(stdout, "\n%s Probing...\n", nodeinfo.nodename); struct nl_packet packet = (struct nl_packet){ .src = nodeinfo.address, .length = NL_MAXDATA, }; memcpy(packet.data,nodeinfo.nodename,sizeof(nodeinfo.nodename)); packet.type = NL_PROBE; packet.checksum = CNET_crc32((unsigned char *)&packet, sizeof(packet)); //create broadcast address CnetNICaddr wifi_dest; CHECK(CNET_parse_nicaddr(wifi_dest, "ff:ff:ff:ff:ff:ff")); uint16_t packet_length = NL_PACKET_LENGTH(packet); CHECK(CNET_disable_application(ALLNODES)); dll_wifi_write(dll_states[1], wifi_dest, (char *)&packet, packet_length); } static EVENT_HANDLER(timeouts) { printf("timeout, seq=%d\n", ackexpected); transmit(toSend); }