Esempio n. 1
0
//=======================================================
//       FUNCTION:   Set_Nav
//       PURPOSE:    Update the NAV process.
//======================================================= 	
    void Set_Nav(MobileNode *node, unsigned int duration_ns) {     
        WGNTime now;
        WGNTime new_nav;
		unsigned int time_dif;
		WGNflag flag;

		now = GetTime();
		new_nav = LocalTimeAdd(now, duration_ns);
		// if there is already a exiting NAV process, update the NAV ending time.
		if (Timer_SwitchSign(node, NAV_TIMER) == ON) {	
			time_dif = LocalTimeMinus(new_nav, node->nodeMac->nodeTimer->nav_timer->end_time);
		    //if the new NAV last longer than the current one
			if(time_dif > 0) {           
                NAVTimer_Stop(node);
				flag = EventDestroy(node->Id, NAVTimeOut);
			    if (flag == FALSE) {
				    printf("[Set_Nav]:: Error, Can not find the entry which will be destroyed!\n");
				    exit(1);
			    }
                NAVTimer_Start(node, duration_ns);
            }
		}
		//else create a new NAV process.
		else 
		   NAVTimer_Start(node, duration_ns);
		
		//The change of the NAV state can impact on the backoff process. 
		CheckBFTimer(node);
    }
Esempio n. 2
0
    void recvACK(MobileNode *node) {
		WGNflag idle;
		WGNflag flag;

        if (GetTxStatus(node) != MAC_SEND) {
			return;
        }  
        TXTimer_Stop(node);		
		flag = EventDestroy(node->Id, TXTimeOut);
		if (flag == FALSE) {
			printf("[recvACK]:: Error, Can not find the entry which will be destroyed!\n");
			exit(1);
		}        

        // The successful reception of the ACK frame implies
        // the successful DATA transmission.  Hence, Short/Long 
		// Retry Counter and the CW should be reset.
        if (IsOverRTSThreshold(node->nodeMac->pktTx) == FALSE)	{
            RstSRCounter(node);
		}
        else
           RstLRCounter(node);
		
		Reset_cw(node);
	    Dot11FrameFree(node->nodeMac->pktTx);
		node->nodeMac->pktTx = NULL;
		
		// Backoff before accessing the medium to transmit again.		        
        idle = CheckIfChannelIdle(node);
        BFTimer_Start(node,idle); 
        tx_resume(node);
    }   
Esempio n. 3
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedDeinit
 *
 *  DESCRIPTION
 *      Deinitialise the scheduler.
 *
 *  RETURNS
 *      void
 *
 *----------------------------------------------------------------------------*/
void SchedDeinit(void *data)
{
    SchedulerInstanceType *inst;
    inst = (SchedulerInstanceType *) data;

    if (instance != inst) {
        return;
    }

    if (inst != NULL) {
        uint8 i;

        for (i = 0; i < _SCHED_MAX_SEGMENTS; i ++) {
            if (inst->thread[i].inUse) {
                MessageQueueEntryType *msg, *msgNext;

                for (msg = inst->thread[i].messageFreeList;
                     msg;
                     msg = msgNext) {
                    msgNext = msg->next;
                    MemFree(msg);
                    msg = NULL;
                }

                MemFree(inst->thread[i].tasks);
                inst->thread[i].tasks = NULL;
                MutexDestroy(&inst->thread[i].qMutex);
                EventDestroy(&inst->thread[i].eventHandle);
            }
        }

        MutexDestroy(&inst->bgMutex);
        EventDestroy(&inst->eventHandle);

        instance = NULL;
        MemFree(inst);
        inst = NULL;
    }
}
static void readLog(EventProc proc)
{
  while (TRUE) {
    Event event;
    Res res;

    res = EventRead(&event, proc);
    if (res == ResFAIL) break; /* eof */
    if (res != ResOK) error("Truncated log");
    eventTime = event->any.clock;
    EventRecord(proc, event, eventTime);
    EventReplay(event, eventTime);
    EventDestroy(proc, event);
  }
}
Esempio n. 5
0
//=======================================================
//       FUNCTION:   CheckBFTimer		
//       PURPOSE:    Manage the state convert of the backoff timer
//======================================================= 
    void CheckBFTimer(MobileNode *node) {
		WGNflag flag;
		//Resume to the back off process once the channel becomes free.
        if ((CheckIfChannelIdle(node) == TRUE) && (Timer_PauseSign(node,BF_TIMER) == TRUE)) {
            BFTimer_Resume(node);
        } 
		//Stop the back off process once the channel becomes busy.
		if ((CheckIfChannelIdle(node) == FALSE) && (Timer_SwitchSign(node,BF_TIMER) == ON) && (Timer_PauseSign(node,BF_TIMER) == FALSE)) {
            BFTimer_Pause(node);
 			flag = EventDestroy(node->Id, BFTimeOut);
			if (flag == FALSE) {
				printf("[CheckBFTimer]:: Error, Can not find the entry which will be destroyed!\n");
				exit(1);
			}
        }
    }
Esempio n. 6
0
  void recvCTS(MobileNode *node) {
		WGNflag flag;
		
		if(GetTxStatus(node) != MAC_RTS) {
           return;
        }
		Dot11FrameFree(node->nodeMac->pktRts);
		node->nodeMac->pktRts = NULL;
		TXTimer_Stop(node);
 	    flag = EventDestroy(node->Id, TXTimeOut);
	    if (flag == FALSE) {
		    printf("[recvCTS]:: Error, Can not find the entry which will be destroyed!\n")	;
			exit(1);
		}

	    //According to the IEEE spec 9.2.4, The successful reception 
		//of the CTS packet can lead to the reset of the short retry counter
		//but not the contension window size. 
        RstSRCounter(node);
        tx_resume(node);        
    }
Esempio n. 7
0
//=======================================================
//       FUNCTIONS:  recv@ 
//       PURPOSE:     Process the frame based on its type
//======================================================= 
  void recvRTS(MobileNode *node) { 
		WGNflag flag;

		if( GetTxStatus(node) != MAC_IDLE) {
            return;
        }

        //If the node is responding with someone else and ignores this RTS.
        if (PktRspIsEmpty(node) == FALSE) {
            return;
        }
		SendCTS(node, node->nodeMac->pktRx);

        //Stop deferral process that invoked by the frame which is ready to sent.
        if (Timer_SwitchSign(node, DF_TIMER) == ON) {
			DFTimer_Stop(node);
 			flag = EventDestroy(node->Id, DFTimeOut);
			if (flag == FALSE) {
				printf("[recvRTS]:: Error, Can not find the entry which will be destroyed!\n");
				exit(1);
			 }
		}
        tx_resume(node);        
  }
Esempio n. 8
0
    void recvDATA(MobileNode *node) {
		WGN_802_11_Mac_Frame *frame;
		unsigned int *temp;
		unsigned int seq_no;
		unsigned int srcid;
		WGNflag found;
		WGNflag flag;
		int i;

        if (CheckIfIsBroadCastPkt(node->nodeMac->pktRx) == FALSE) {	          
			if (IsOverRTSThreshold(node->nodeMac->pktRx) == TRUE) {
                if (GetTxStatus(node) == MAC_CTS) {
                    Dot11FrameFree(node->nodeMac->pktRsp);
					node->nodeMac->pktRsp = NULL;
                    TXTimer_Stop(node);
 			        flag = EventDestroy(node->Id, TXTimeOut);
			        if (flag == FALSE) {
				        printf("[recvDATA]:: Error, Can not find the entry which will be destroyed!\n");
				        exit(1);
			        }
                    //RstSRCounter(node);                              
                    //Reset_cw(node);                                
                }
                else {
                    return;
                }
                SendACK(node, node->nodeMac->pktRx);
                tx_resume(node);
            }
            else {
				//if the node is in the corresponsing with others it will simply 
				//drop the incoming packet.           
				if(PktRspIsEmpty(node) == FALSE) {
                    return;
                }
                SendACK(node, node->nodeMac->pktRx);
                if(Timer_SwitchSign(node, TX_TIMER) == OFF) {
                    tx_resume(node);
				}
				else {
				    //seems ok, but be carefull when debug!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				}
            }
        }
        
        //Frame duplication checking procedure.
	    srcid = node->nodeMac->pktRx->pseudo_header->srcid;
		seq_no = node->nodeMac->pktRx->pseudo_header->sc.sc_sequence;
		temp = node->nodeMac->mac_buffer;
		temp = &(temp[(srcid-1) * MAC_DUP_CHK_BUF_SIZE]);
		found = FALSE;
		// If the packet is a retried one, check whether it is a duplicated one or not.
		if (node->nodeMac->pktRx->pseudo_header->fc.fc_retry == 1) {
             for(i=0;(i<MAC_DUP_CHK_BUF_SIZE)&&(found==FALSE);i++) {
		           if(temp[i] == seq_no) {
			           found = TRUE;
					   return;
			       }
		     }
		}
		//if the incoming packet is a new one, insert it to the buffer
		if (found == FALSE) {
		    temp[node->nodeMac->mac_buf_index[srcid-1]]= seq_no;
			//update the index. the index should always point to the position of the 
			//eariest incoming packet
			node->nodeMac->mac_buf_index[srcid-1] = (node->nodeMac->mac_buf_index[srcid-1] + 1) % MAC_DUP_CHK_BUF_SIZE;
		}
		
		frame = node->nodeMac->pktRx;
		node->nodeMac->pktRx = NULL;       
		//ship the frame to the uplayer (Logic Link Layer)
		MacUpPortSend(node, frame);
    }
Esempio n. 9
0
//=======================================================
//       FUNCTION:  Collision
//       PURPOSE:   Handle the collisions
//=======================================================
void Collision(MobileNode *node, WGN_802_11_Mac_Frame *frame)  {
	WGNflag flag;

	switch(GetRxStatus(node)) {
	    case MAC_RECV:
		    SetRxStatus(node, MAC_COLL);
		    // NOTE: NO BREAK here!!! 
	    case MAC_COLL:
            // Update the RXTimeout time 		
		    if(SecToNsec(Frame_Time(node, frame)) > RXTimer_Remain(node)) {
			   RXTimer_Stop(node);
			   flag = EventDestroy(node->Id, RXTimeOut);
			   if (flag == FALSE) {
				   printf("[Collision]:: Error, Can not find the entry which will be destroyed!\n");
				   exit(1);
			   }
			   switch(GetFcSubtype(node->nodeMac->pktRx)) {
                   case MAC_SUBTYPE_RTS:
			     	    node->nodeStats->RtsDropForCollision += 1;
                        break;
                   case MAC_SUBTYPE_CTS:
					    node->nodeStats->CtsDropForCollision += 1;
                        break;
                   case MAC_SUBTYPE_ACK:
					    node->nodeStats->AckDropForCollision += 1;
                        break;
			       case MAC_SUBTYPE_DATA:
					    node->nodeStats->DataDropForCollision += 1;
                        break;
                   default:
                        printf("[Collision]:: Error, Invalid subtype!\n");
					    exit(1);
               }

			   Dot11FrameFree(node->nodeMac->pktRx);
			   node->nodeMac->pktRx = NULL;
			   node->nodeMac->pktRx = frame;
			   frame = NULL;
			   RXTimer_Start(node, SecToNsec(RX_Time(node)));
			   //here we need not mark the frame with collision error, it will be drop after 
			   //reception for the MAC rx state of MAC_COLL
		    }
		    else {
			   switch(GetFcSubtype(frame)) {
                   case MAC_SUBTYPE_RTS:
			     	    node->nodeStats->RtsDropForCollision += 1;
                        break;
                   case MAC_SUBTYPE_CTS:
					    node->nodeStats->CtsDropForCollision += 1;
                        break;
                   case MAC_SUBTYPE_ACK:
					    node->nodeStats->AckDropForCollision += 1;
                        break;
			       case MAC_SUBTYPE_DATA:
					    node->nodeStats->DataDropForCollision += 1;
                        break;
                   default:
                        printf("[Collision]:: Error, Invalid frame subtype!\n");
					    exit(1);
               }
			   Dot11FrameFree(frame);
		    }
		    break;
	    default:
			printf("[Collision]:: Error, unpredictable rx status comes out!\n");
    }
}
static void readLog(EventProc proc)
{
  EventCode c;
  Word bucketLimit = bucketSize;
  char *styleConv = NULL; /* suppress uninit warning */

  /* Print event count header. */
  if (reportEvents) {
    if (style == '\0') {
      printf("  bucket:");
      for(c = 0; c <= EventCodeMAX; ++c)
        if (eventEnabled[c])
          printf("  %04X", (unsigned)c);
      printf("   all\n");
    }
  }

  /* Init event counts. */
  for(c = 0; c <= EventCodeMAX; ++c)
    totalEventCount[c] = 0;
  clearBucket();

  /* Init style. */
  switch (style) {
  case '\0':
    styleConv = " %8lX"; break;
  case 'C':
    styleConv = ", %lu"; break;
  case 'L':
    styleConv = " %lX"; break;
  default:
    error("Unknown style code '%c'", style);
  }

  while (TRUE) { /* loop for each event */
    char *eventFormat;
    int argCount, i;
    Event event;
    EventCode code;
    Res res;

    /* Read and parse event. */
    res = EventRead(&event, proc);
    if (res == ResFAIL) break; /* eof */
    if (res != ResOK) error("Truncated log");
    eventTime = event->any.clock;
    code = EventGetCode(event);

    /* Output bucket, if necessary, and update counters */
    if (bucketSize != 0 && eventTime >= bucketLimit) {
      reportBucketResults(bucketLimit-1);
      clearBucket();
      do {
        bucketLimit += bucketSize;
      } while (eventTime >= bucketLimit);
    }
    if (reportEvents) {
      ++bucketEventCount[code];
      ++totalEventCount[code];
    }

    /* Output event. */
    if (verbose) {
      eventFormat = EventCode2Format(code);
      argCount = strlen(eventFormat);
      if (eventFormat[0] == '0') argCount = 0;

      if (style == 'L') putchar('(');

      switch (style) {
      case '\0': case 'L': {
        printf("%-19s", EventCode2Name(code));
      } break;
      case 'C':
        printf("%u", (unsigned)code);
        break;
      }

     switch (style) {
     case '\0':
       printf(" %8lu", (ulong)eventTime); break;
     case 'C':
       printf(", %lu", (ulong)eventTime); break;
     case 'L':
       printf(" %lX", (ulong)eventTime); break;
     }

     switch (event->any.code) {
     case EventLabel: {
       switch (style) {
       case '\0': case 'C': {
         EventString sym = LabelText(proc, event->aw.w1);
         printf((style == '\0') ? " %08lX " : ", %lu, ",
                (ulong)event->aw.a0);
         if (sym != NULL) {
           printStr(sym, (style == 'C'));
         } else {
           printf((style == '\0') ? "sym %05lX" : "sym %lX\"",
                  (ulong)event->aw.w1);
         }
       } break;
       case 'L': {
         printf(" %lX %lX", (ulong)event->aw.a0, (ulong)event->aw.w1);
       } break;
       }
     } break;
     case EventMeterValues: {
       switch (style) {
       case '\0': {
         if (event->pddwww.w3 == 0) {
           printf(" %08lX        0      N/A      N/A      N/A      N/A",
                  (ulong)event->pddwww.p0);
         } else {
           double mean = event->pddwww.d1 / (double)event->pddwww.w3;
           /* .stddev: stddev = sqrt(meanSquared - mean^2), but see */
           /* <code/meter.c#limitation.variance>. */
           double stddev = sqrt(fabs(event->pddwww.d2
                                     - (mean * mean)));
           printf(" %08lX %8u %8u %8u %#8.3g %#8.3g",
                  (ulong)event->pddwww.p0, (uint)event->pddwww.w3,
                  (uint)event->pddwww.w4, (uint)event->pddwww.w5,
                  mean, stddev);
         }
         printAddr(proc, (Addr)event->pddwww.p0);
       } break;
       case 'C': {
         putchar(',');
         printAddr(proc, (Addr)event->pddwww.p0);
         printf(", %.10G, %.10G, %u, %u, %u",
                event->pddwww.d1, event->pddwww.d2,
                (uint)event->pddwww.w3, (uint)event->pddwww.w4,
                (uint)event->pddwww.w5);
       } break;
       case 'L': {
         printf(" %lX %#.10G %#.10G %X %X %X", (ulong)event->pddwww.p0,
                event->pddwww.d1, event->pddwww.d2,
                (uint)event->pddwww.w3, (uint)event->pddwww.w4,
                (uint)event->pddwww.w5);
       } break;
       }
     } break;
     case EventPoolInit: { /* pool, arena, class */
       printf(styleConv, (ulong)event->ppp.p0);
       printf(styleConv, (ulong)event->ppp.p1);
       /* class is a Pointer, but we label them, so call printAddr */
       if (style != 'L') {
         if (style == 'C') putchar(',');
         printAddr(proc, (Addr)event->ppp.p2);
       } else
         printf(styleConv, (ulong)event->ppp.p2);
     } break;
     default:
       for (i = 0; i < argCount; ++i) {
         switch(code) {
#include "eventdef.h"
#undef RELATION
         }
       }
     }

      if (style == 'L') putchar(')');
      putchar('\n');
      fflush(stdout);
    }
    processEvent(proc, event, eventTime);
    EventDestroy(proc, event);
  } /* while(!feof(input)) */

  /* report last bucket (partial) */
  if (bucketSize != 0) {
    reportBucketResults(eventTime);
  }
  if (reportEvents) {
    /* report totals */
    switch (style) {
    case '\0': {
      printf("\n     run:");
    } break;
    case 'L': {
      printf("(t");
    } break;
    case 'C': {
      printf("%lu", eventTime+1);
    } break;
    }
    reportEventResults(totalEventCount);

    /* explain event codes */
    if (style == '\0') {
      printf("\n");
      for(c = 0; c <= EventCodeMAX; ++c)
        if (eventEnabled[c])
          printf(" %04X %s\n", (unsigned)c, EventCode2Name(c));
      if (bucketSize == 0)
        printf("\nevent clock stopped at %lu\n", (ulong)eventTime);
    }
  }
}