static EVENT_HANDLER(ready_app) { CnetAddr dest; int num_unack = next_frame - last_ack_recv; if(num_unack==(MAXSEQ+1)/2){ timer_wait = CNET_start_timer(EV_TIMER1, TIMEOUT, 0); CNET_disable_application(ALLNODES); return; } if(num_unack<0){ num_unack=MAXSEQ; } // if(trans_frame_state[next_frame%((MAXSEQ+1)/2)] == ACK_WAIT) // { // timer_wait = CNET_start_timer(EV_TIMER1, TIMEOUT, 0); // CNET_disable_application(ALLNODES); // return; // } trans_frame_state[next_frame] = ACK_WAIT; size_t length = MAX_MESSAGE_SIZE; CHECK(CNET_read_application(&dest, (char*) last_msg, &length)); frame_send(last_msg, length, next_frame); next_frame = (next_frame + 1) % (MAXSEQ + 1); }
/* down_to_network() RECEIVES NEW MESSAGES FROM THE APPLICATION LAYER AND PREPARES THEM FOR TRANSMISSION TO OTHER NODES. */ static EVENT_HANDLER(down_to_network) { //printf("down_to_network\n"); NL_PACKET p; p.length = sizeof(p.msg); //printf("p.length = %d, MAX_MESSAGE_SIZE = %d", p.length, MAX_MESSAGE_SIZE); CHECK(CNET_read_application(&p.dest, p.msg, &p.length)); CNET_disable_application(p.dest); p.src = nodeinfo.address; p.kind = NL_DATA; //p.hopcount = 0; memset(p.traveled_hops, -1, MAXHOPS*sizeof(int)); p.traveled_hops[0] = nodeinfo.nodenumber; p.traveled_hops_count = 1; p.trans_time = 0; p.seqno = NL_nextpackettosend(p.dest); p.pieceNumber = 0; p.pieceEnd = 0; p.checksum = CNET_ccitt((unsigned char *) (p.msg), p.length); lastPacket = &p; update_last_packet(&p); printf("Packet generated at host %d, des %d\n\n", nodeinfo.address, p.dest); flood3((char *) &p, PACKET_SIZE(p), 0, 0); }
static EVENT_HANDLER(application_ready){ MSG msg; size_t msgLength = MAX_MESSAGE_SIZE; CHECK(CNET_read_application(&msg.dest, &msg.data, &msgLength)); //printf("Message read from application layer %s, destined for address %d\n", msg.data, msg.dest); push_message(msg, msgLength + sizeof(CnetAddr)); }
/* down_to_network() RECEIVES NEW MESSAGES FROM THE APPLICATION LAYER AND PREPARES THEM FOR TRANSMISSION TO OTHER NODES. */ static EVENT_HANDLER( down_to_network) { NL_PACKET p; p.length = sizeof(p.msg); CHECK(CNET_read_application(&p.dest, p.msg, &p.length)); CNET_disable_application(p.dest); p.src = nodeinfo.address; p.kind = NL_DATA; p.seqno = NL_nextpackettosend(p.dest); p.hopcount = 0; p.pieceNumber = 0; p.pieceEnd = 0; p.src_packet_length = (int) p.length; p.checksum = CNET_ccitt((unsigned char *) (p.msg), p.src_packet_length); p.trans_time = 0; p.is_resent = 0; //lastPacket = &p; printf( "packet generated, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n\n", nodeinfo.address, p.dest, p.seqno, p.length, p.checksum); flood((char *) &p, PACKET_SIZE(p), 0, 0); update_last_packet(&p); }
static void down_to_transport(CnetEvent ev, CnetTimer timer, CnetData data) { /* our packet */ TR_PACKET p; /* destination address to pass to network layer */ CnetAddr temp; p.length = sizeof(p.msg); CHECK(CNET_read_application(&temp, p.msg, &p.length)); CNET_disable_application(temp); /* establish sequence number */ unsigned long seq = getSequence(temp); if( seq == -1) { addAddress(temp,0); p.sequence_number = 0; } else { unsigned long newseq = seq + p.length; setSequence(temp,newseq); p.sequence_number = newseq; } p.checksum = checksum_crc32( ((char*)&p)+sizeof(unsigned int) , TR_PACKET_SIZE(p) - sizeof(unsigned int)); down_to_network( (char*)&p , TR_PACKET_SIZE(p) , temp); /* enqueuePacket((char*)&p, TR_PACKET_SIZE(p), temp); */ CNET_start_timer(EV_TIMER1, 1000, (CnetData)1); }
/** * aplication_ready() event-handler. * * Handler is called when the application is ready to create a new message. * It reads a new message from the application and passes it to the transport layer. */ static EVENT_HANDLER(application_ready) { CnetAddr destaddr; size_t length = sizeof(msg); CHECK(CNET_read_application(&destaddr, msg, &length)); link_transmit(1, msg, length); }
static EVENT_HANDLER(application_ready){ MSG msg; size_t len = sizeof(MSG); CHECK(CNET_read_application(&msg.dest, &msg.data, &len)); queue_add(msg_queue, &msg, len + MESSAGE_HEADER_SIZE); if(queue_nitems(msg_queue) == MAX_MSG_QUEUE_SIZE){ CHECK(CNET_disable_application(ALLNODES)); app_enabled = false; } }
static EVENT_HANDLER(application_ready) { CnetAddr destaddr; lastlength = sizeof(MSG); CHECK(CNET_read_application(&destaddr, (char *)lastmsg, &lastlength)); CNET_disable_application(ALLNODES); transmit_frame(lastmsg, DATA, lastlength, nextframetosend); nextframetosend = 1-nextframetosend; }
static void transport_down(CnetEvent ev, CnetTimerID timer, CnetData data) { int destination; // ALLOCATE MEMORY FOR MESSAGE SO WE CAN PASS ARRAY ON THE HEAP char* msg = (char*)malloc(MAX_MESSAGE_SIZE * sizeof(char)); size_t msgLength = MAX_MESSAGE_SIZE * sizeof(char); // READ THE MESSAGE FROM THE APPLICATION LAYER AND THROW DOWN CHECK(CNET_read_application( &destination, msg, &msgLength )); network_down( msg, msgLength, destination ); }
static EVENT_HANDLER(application_ready) { CnetAddr destaddr; char buffer[MAX_MESSAGE_SIZE]; size_t length; /* Firstly, indicate the maximum sized message we are willing to receive */ length = sizeof(buffer); /* Accept the message from the Application Layer. We will be informed of the message's destination address and length and buffer will be filled in. */ CNET_read_application(&destaddr, buffer, &length); printf("\tI have a message of %4d bytes for address %d\n", length, (int)destaddr); }
/* down_to_network() RECEIVES NEW MESSAGES FROM THE APPLICATION LAYER AND PREPARES THEM FOR TRANSMISSION TO OTHER NODES. */ static EVENT_HANDLER( down_to_network) { NL_PACKET p; NL_PACKET test; p.length = sizeof(p.msg); CHECK(CNET_read_application(&p.dest, p.msg, &p.length)); CNET_disable_application(p.dest); p.src = nodeinfo.address; p.kind = NL_DATA; p.seqno = NL_nextpackettosend(p.dest); p.hopcount = 0; p.pieceStartPosition = 0; p.pieceEnd = 0; p.src_packet_length = (int) p.length; p.checksum = CNET_crc32((unsigned char *) (p.msg), p.src_packet_length); p.piece_checksum = CNET_crc32((unsigned char *) (p.msg), p.src_packet_length); p.trans_time = 0; p.is_resent = 0; test.src = nodeinfo.address; test.dest = p.dest; test.kind = NL_TEST; test.hopcount = 0; test.seqno = 0; test.min_mtu = INT_MAX; test.length = 0; test.pieceStartPosition = 0; test.src_packet_length = PACKET_HEADER_SIZE; test.checksum = 0; test.piece_checksum = 0; test.trans_time = 0; test.is_resent = 0; NL_updatelastsendtest(&test); update_last_packet(&p); flood_test((char *) &test, PACKET_HEADER_SIZE, 0, 0); //TODO: please inform the mtu from src to dest by using pathfinder packet //size_t mtu_from_src_to_dest = 96; //piece_to_flood((char *) &p, mtu_from_src_to_dest); }
///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); }