void starttimer(int AorB,float increment) // AorB; /* A or B is trying to stop timer */ { struct event *q; struct event *evptr; ////char *malloc(); if (TRACE>2) printf(" START TIMER: starting timer at %f\n",time_local); /* be nice: check to see if timer is already started, if so, then warn */ /* for (q=evlist; q!=NULL && q->next!=NULL; q = q->next) */ for (q=evlist; q!=NULL ; q = q->next) if ( (q->evtype==TIMER_INTERRUPT && q->eventity==AorB) ) { printf("Warning: attempt to start a timer that is already started\n"); return; } /* create future event for when timer goes off */ evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtime = time_local + increment; evptr->evtype = TIMER_INTERRUPT; evptr->eventity = AorB; insertevent(evptr); }
void generate_next_arrival() { double x,log(),ceil(); struct event *evptr; if (TRACE>2) printf(" GENERATE NEXT ARRIVAL: creating new arrival\n"); x = lambda*jimsrand()*2; /* x is uniform on [0,2*lambda] */ /* having mean of lambda */ evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtime = time + x; evptr->evtype = FROM_LAYER5; if (BIDIRECTIONAL && (jimsrand()>0.5) ) evptr->eventity = B; else evptr->eventity = A; insertevent(evptr); }
/************************** TOLAYER2 ***************/ void toLayer2( struct RoutePacket packet ) { struct RoutePacket *mypktptr; struct event *evptr, *q; float lastime; int i; // be nice: check if source and destination id's are reasonable if (packet.sourceid < 0 || packet.sourceid > NumberOfNodes ) { printf("WARNING: illegal source id in your packet, ignoring packet!\n"); return; } if (packet.destid < 0 || packet.destid > NumberOfNodes ) { printf("WARNING: illegal dest id in your packet, ignoring packet!\n"); return; } if (packet.sourceid == packet.destid) { printf("WARNING: source and destination id's the same, ignoring packet!\n"); return; } if (ConnectCosts[packet.sourceid][packet.destid] == INFINITY) { printf("WARNING: source and destination not connected, ignoring packet!\n"); return; } // make a copy of the packet student just gave me since he/she may decide // to do something with the packet after we return back to him/her * mypktptr = (struct RoutePacket *) malloc(sizeof(struct RoutePacket)); mypktptr->sourceid = packet.sourceid; mypktptr->destid = packet.destid; for (i = 0; i < NumberOfNodes; i++) mypktptr->mincost[i] = packet.mincost[i]; if (TraceLevel>2) { printf(" TOLAYER2: source: %d, dest: %d\n costs:", mypktptr->sourceid, mypktptr->destid); for (i=0; i < NumberOfNodes; i++) printf("%d ",mypktptr->mincost[i]); printf("\n"); } // create future event for arrival of packet at the other side evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtype = FROM_LAYER2; // packet will pop out in layer3 evptr->eventity = packet.destid; // event occurs at other entity evptr->rtpktptr = mypktptr; // save ptr to my copy of packet // finally, compute the arrival time of packet at the other end. // medium can not reorder, so make sure packet arrives between 1 and 10 // time units after the latest arrival time of packets // currently in the medium on their way to the destination lastime = clocktime; for (q=evlist; q!=NULL ; q = q->next) if ( (q->evtype == FROM_LAYER2 && q->eventity == evptr->eventity) ) lastime = q->evtime; evptr->evtime = lastime + 2.*GetRandomNumber(); if (TraceLevel>2) printf(" TOLAYER2: scheduling arrival on other side\n"); insertevent(evptr); } // End of toLayer2
////////////////////////////////////////////////////////////////////// // init() // This routine initializes lots of parameters and variables used // throughout the simulation. ////////////////////////////////////////////////////////////////////// void init() { int i, j, found; float sum, avg; struct event *evptr; FILE *fp; // Used for the configuration file srand(9999); // init random number generator sum = 0.0; // test random number generator for students for (i = 0; i < 1000; i++) sum = sum + GetRandomNumber(); // should be uniform in [0,1] avg = sum/1000.0; if (avg < 0.25 || avg > 0.75) { printf("It is likely that random number generation on your machine\n" ); printf("is different from what this emulator expects. Please take\n"); printf("a look at the routine jimsrand() in the emulator code. Sorry. \n"); exit(0); } clocktime = 0.0; // initialize time to 0.0 // Load in node information from the configuration file fp = fopen( filename, "r" ); if ( fp == NULL ) { printf("Unable to open the configuration file %s\n", filename ); exit(0); } // We only expect ONE value on the first line, but guard against // someone having MORE than one number. found = fscanf( fp, "%d, %d", &NumberOfNodes, &i ); if ( found != 1 ) { // We expect 1 number on the first line printf( "First line of file should contain number of nodes\n"); exit(0); } if (NumberOfNodes < 2 || NumberOfNodes > MAX_NODES ) { printf( "Error reading %s configuration file - number of nodes\n", filename ); exit(0); } // Initialize the array so illegal nodes have infinite cost for ( i = 0; i < MAX_NODES; i++ ) for ( j = 0; j < MAX_NODES; j++ ) ConnectCosts[i][j] = INFINITY; // Now load in the nodes and costs from the file for ( i = 0; i < NumberOfNodes; i++ ) { found = fscanf( fp, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d", &ConnectCosts[i][0], &ConnectCosts[i][1], &ConnectCosts[i][2], &ConnectCosts[i][3], &ConnectCosts[i][4], &ConnectCosts[i][5], &ConnectCosts[i][6], &ConnectCosts[i][7], &ConnectCosts[i][8], &ConnectCosts[i][9] ); if ( found != NumberOfNodes ) { printf("We expected to see %d node costs on this line but found %d\n", NumberOfNodes, found ); exit(0); } } fclose(fp); // We're all done // Call each of the nodes so they can initialize their stuff rtinit0(); rtinit1(); rtinit2(); rtinit3(); /* initialize future link changes */ if (LINKCHANGES == 1) { evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtime = 10000.0; evptr->evtype = LINK_CHANGE; evptr->eventity = -1; evptr->rtpktptr = NULL; insertevent(evptr); evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtype = LINK_CHANGE; evptr->evtime = 20000.0; evptr->rtpktptr = NULL; insertevent(evptr); } } // End of init()
/************************** TOLAYER3 ***************/ void tolayer3(int AorB,struct pkt packet) { struct pkt *mypktptr; struct event *evptr,*q; ////char *malloc(); float lastime, x, jimsrand(); int i; ntolayer3++; /* simulate losses: */ if (jimsrand() < lossprob) { nlost++; if (TRACE>0) printf(" TOLAYER3: packet being lost\n"); return; } /* make a copy of the packet student just gave me since he/she may decide */ /* to do something with the packet after we return back to him/her */ mypktptr = (struct pkt *)malloc(sizeof(struct pkt)); mypktptr->seqnum = packet.seqnum; mypktptr->acknum = packet.acknum; mypktptr->checksum = packet.checksum; for (i=0; i<20; i++) mypktptr->payload[i] = packet.payload[i]; if (TRACE>2) { printf(" TOLAYER3: seq: %d, ack %d, check: %d ", mypktptr->seqnum, mypktptr->acknum, mypktptr->checksum); for (i=0; i<20; i++) printf("%c",mypktptr->payload[i]); printf("\n"); } /* create future event for arrival of packet at the other side */ evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtype = FROM_LAYER3; /* packet will pop out from layer3 */ evptr->eventity = (AorB+1) % 2; /* event occurs at other entity */ evptr->pktptr = mypktptr; /* save ptr to my copy of packet */ /* finally, compute the arrival time of packet at the other end. medium can not reorder, so make sure packet arrives between 1 and 10 time units after the latest arrival time of packets currently in the medium on their way to the destination */ lastime = time_local; /* for (q=evlist; q!=NULL && q->next!=NULL; q = q->next) */ for (q=evlist; q!=NULL ; q = q->next) if ( (q->evtype==FROM_LAYER3 && q->eventity==evptr->eventity) ) lastime = q->evtime; evptr->evtime = lastime + 1 + 9*jimsrand(); /* simulate corruption: */ if (jimsrand() < corruptprob) { ncorrupt++; if ( (x = jimsrand()) < .75) mypktptr->payload[0]='Z'; /* corrupt payload */ else if (x < .875) mypktptr->seqnum = 999999; else mypktptr->acknum = 999999; if (TRACE>0) printf(" TOLAYER3: packet being corrupted\n"); } if (TRACE>2) printf(" TOLAYER3: scheduling arrival on other side\n"); insertevent(evptr); }