Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Code for simulating stop and wait protocol in cnet. Solution #include #include #

ID: 3638628 • Letter: C

Question

Code for simulating stop and wait protocol in cnet.

Explanation / Answer

#include #include #include typedef enum { DL_DATA, DL_ACK } FRAMEKIND; typedef struct { char data[MAX_MESSAGE_SIZE]; } MSG; typedef struct { FRAMEKIND kind; /* only ever DL_DATA or DL_ACK */ unsigned int len; /* the length of the msg field only */ int checksum; /* checksum of the whole frame */ int seq; /* only ever 0 or 1 */ MSG msg; } FRAME; #define FRAME_HEADER_SIZE (sizeof(FRAME) - sizeof(MSG)) #define FRAME_SIZE(f) (FRAME_HEADER_SIZE + f.len) static MSG *lastmsg; static unsigned int lastlength = 0; static CnetTimerID lasttimer = NULLTIMER; static int ackexpected = 0; static int nextframetosend = 0; static int frameexpected = 0; static void transmit_frame(MSG *msg, FRAMEKIND kind, unsigned int length, int seqno) { FRAME f; int link = 1; f.kind = kind; f.seq = seqno; f.checksum = 0; f.len = length; switch (kind) { case DL_ACK : printf("ACK transmitted, seq=%d ", seqno); break; case DL_DATA: { CnetTime timeout; printf(" DATA transmitted, seq=%d ", seqno); memcpy(&f.msg, (char *)msg, (int)length); timeout = FRAME_SIZE(f)*((CnetTime)8000000 / linkinfo[link].bandwidth) + linkinfo[link].propagationdelay; lasttimer = CNET_start_timer(EV_TIMER1, 3 * timeout, 0); break; } } length = FRAME_SIZE(f); f.checksum = CNET_ccitt((unsigned char *)&f, (int)length); CHECK(CNET_write_physical(link, (char *)&f, &length)); } static void application_ready(CnetEvent ev, CnetTimerID timer, CnetData data) { CnetAddr destaddr; lastlength = sizeof(MSG); CHECK(CNET_read_application(&destaddr, (char *)lastmsg, &lastlength)); CNET_disable_application(ALLNODES); printf("down from application, seq=%d ", nextframetosend); transmit_frame(lastmsg, DL_DATA, lastlength, nextframetosend); nextframetosend = 1-nextframetosend; } static void physical_ready(CnetEvent ev, CnetTimerID timer, CnetData data) { FRAME f; unsigned int 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, (int)len) != checksum) { printf(" BAD checksum - frame ignored "); return; /* bad checksum, ignore frame */ } switch (f.kind) { case DL_ACK : if(f.seq == ackexpected) { printf(" ACK received, seq=%d ", f.seq); CNET_stop_timer(lasttimer); ackexpected = 1-ackexpected; CNET_enable_application(ALLNODES); } break; case DL_DATA : printf(" DATA received, seq=%d, ", f.seq); if(f.seq == frameexpected) { printf("up to application "); len = f.len; CHECK(CNET_write_application((char *)&f.msg, &len)); frameexpected = 1-frameexpected; } else printf("ignored "); transmit_frame((MSG *)NULL, DL_ACK, 0, f.seq); break; } } static void draw_frame(CnetEvent ev, CnetTimerID timer, CnetData data) { CnetDrawFrame *df = (CnetDrawFrame *)data; FRAME *f = (FRAME *)df->frame; switch (f->kind) { case DL_ACK : df->colour[0] = (f->seq == 0) ? CN_RED : CN_PURPLE; df->pixels[0] = 10; sprintf(df->text, "%d", f->seq); break; case DL_DATA : df->colour[0] = (f->seq == 0) ? CN_RED : CN_PURPLE; df->pixels[0] = 10; df->colour[1] = CN_GREEN; df->pixels[1] = 30; sprintf(df->text, "data=%d", f->seq); break; } } static void timeouts(CnetEvent ev, CnetTimerID timer, CnetData data) { if(timer == lasttimer) { printf("timeout, seq=%d ", ackexpected); transmit_frame(lastmsg, DL_DATA, lastlength, ackexpected); } } static void showstate(CnetEvent ev, CnetTimerID timer, CnetData data) { printf( " ackexpected = %d nextframetosend = %d frameexpected = %d ", ackexpected, nextframetosend, frameexpected); } void reboot_node(CnetEvent ev, CnetTimerID timer, CnetData data) { if(nodeinfo.nodenumber > 1) { fprintf(stderr,"This is not a 2-node network! "); exit(1); } lastmsg = malloc(sizeof(MSG)); CHECK(CNET_set_handler( EV_APPLICATIONREADY, application_ready, 0)); CHECK(CNET_set_handler( EV_PHYSICALREADY, physical_ready, 0)); CHECK(CNET_set_handler( EV_DRAWFRAME, draw_frame, 0)); CHECK(CNET_set_handler( EV_TIMER1, timeouts, 0)); CHECK(CNET_set_handler( EV_DEBUG0, showstate, 0)); CHECK(CNET_set_debug_string( EV_DEBUG0, "State")); if(nodeinfo.nodenumber == 1) CNET_enable_application(ALLNODES); }