/*************************************************************** * * hotpotato.c * * The hotpotato cnet example from section 6 * of "Getting Started With cnet," Jeff Ondich, 2000. * ***************************************************************/ #include #include #include #include "hotpotato.h" /* Global variables. */ int frameNumber = 0; /* Event handler implementations. */ void reboot_node( CnetEvent event, CnetTimer timer, CnetData data ) { CNET_set_handler( EV_APPLICATIONREADY, on_app_ready, 0 ); CNET_set_handler( EV_PHYSICALREADY, on_phys_ready, 0 ); if( nodeinfo.nodenumber == 0 ) CNET_enable_application( ALLNODES ); (void)srand( (int)time(NULL) ); } void on_app_ready( CnetEvent event, CnetTimer timer, CnetData data ) { int link; int length = MAX_MESSAGE_SIZE; Frame f; /* Get the message and disable the application layer. */ CHECK( CNET_read_application( &(f.destination), f.data, &length ) ); CHECK( CNET_disable_application( ALLNODES ) ); /* Send the message on its way. */ f.hops = 0; f.source = nodeinfo.address; f.frameID = ++frameNumber; length += FRAME_HEADER_SIZE; link = ((int)rand() % nodeinfo.nlinks) + 1; CHECK( CNET_write_physical_reliable( link, (char *)(&f), &length ) ); printf( "Originating frame #%d from %s bound for %ld\n", f.frameID, nodeinfo.nodename, f.destination ); } void on_phys_ready( CnetEvent ev, CnetTimer timer, CnetData data ) { int link; int length = MAX_MESSAGE_SIZE + FRAME_HEADER_SIZE; Frame f; CHECK( CNET_read_physical( &link, (char *)(&f), &length ) ); f.hops++; if( f.destination == nodeinfo.address ) { length -= FRAME_HEADER_SIZE; CHECK( CNET_write_application( f.data, &length ) ); printf( "Delivering frame #%d to %s after %d hops\n", f.frameID, nodeinfo.nodename, f.hops ); } else { link = (rand() % nodeinfo.nlinks) + 1; CHECK( CNET_write_physical_reliable( link, (char *)(&f), &length ) ); printf( "\tFrame #%d passing through %s on %dth hop\n", f.frameID, nodeinfo.nodename, f.hops ); } }