/******************************************************* For midterm 2, Winter 2000, CS337, Jeff Ondich flood.c This program implements a very simple flooding algorithm. Here's what happens: 1. All nodes start up, and node 0 starts a timer. 2. When the timer expires, node 0 sends its own frame, containing only the "Howdy" message and a hop count, to all its neighbors. 3. Upon receiving a frame, any node will increment its own "gFramesArrived" counter, and increment the incoming frame's hop count. If this is the first time the flooded frame has arrived, the node stores the frame. If the frame's hop count is smaller than MAX_HOP_COUNT, the node passes copies of the frame to all of its neighbors. 4. When a node shuts down, it announces whether the frame arrived at all, how many times it arrived, and the number of hops it took for the first copy of the frame to arrive. *******************************************************/ #include #define MAX_HOP_COUNT 8 typedef struct { int hopCount; char message[20]; } Frame; void on_physical_ready( CnetEvent ev, CnetTimer ts, CnetData data ); void on_flood_timer( CnetEvent ev, CnetTimer ts, CnetData data ); void on_shut_down( CnetEvent ev, CnetTimer ts, CnetData data ); Frame gFrame; int gFramesArrived = 0; void reboot_node( CnetEvent ev, CnetTimer ts, CnetData data ) { CNET_set_handler( EV_PHYSICALREADY, on_physical_ready, 0 ); CNET_set_handler( EV_TIMER1, on_flood_timer, 0 ); CNET_set_handler( EV_SHUTDOWN, on_shut_down, 0 ); gFrame.hopCount = 0; strcpy( gFrame.message, "No frame arrived." ); if( nodeinfo.nodenumber == 0 ) CNET_start_timer( EV_TIMER1, 100, 0 ); } /********************************************************* on_physical_ready Processes an in-coming frame. *********************************************************/ void on_physical_ready( CnetEvent ev, CnetTimer ts, CnetData data ) { int link; int length = sizeof( Frame ); Frame f; /* Get the frame and record its appearance,... */ CHECK( CNET_read_physical( &link, (char *)(&f), &length ) ); gFramesArrived++; /* ...increment its hop count,... */ (f.hopCount)++; /* ...accept it if this is the first time it has arrived here,... */ if( gFramesArrived == 1 ) gFrame = f; /* ...and ship it out if it has not gotten to MAX_HOP_COUNT. */ if( f.hopCount < MAX_HOP_COUNT ) { for( link=1; link <= nodeinfo.nlinks; link++ ) { length = sizeof( Frame ); CHECK( CNET_write_physical_reliable( link, (char *)(&f), &length )); } } } /********************************************************* on_flood_timer Only gets called once, for node 0. This is the signal for node 0 to flood a frame with an initial hop count of 0. *********************************************************/ void on_flood_timer( CnetEvent ev, CnetTimer ts, CnetData data ) { Frame f; int link, length; fprintf( stderr, "%s sending initial frame.\n\n", nodeinfo.nodename ); f.hopCount = 0; strcpy( f.message, "Howdy." ); for( link=1; link <= nodeinfo.nlinks; link++ ) { length = sizeof( Frame ); CHECK( CNET_write_physical_reliable( link, (char *)(&f), &length )); } } /********************************************************* on_shut_down Reports on the number of copies of the flooded frame that arrived, and the number of times it arrived. *********************************************************/ void on_shut_down( CnetEvent ev, CnetTimer ts, CnetData data ) { fprintf( stderr, "%s\n\tFrame message: %s\n", nodeinfo.nodename, gFrame.message ); if( gFramesArrived > 0 ) { fprintf( stderr, "\tFrame first arrived after %d hops.\n", gFrame.hopCount ); fprintf( stderr, "\t%d copies of the frame arrived.\n\n", gFramesArrived ); } else fprintf( stderr, "\n\n" ); }