⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac-802_16-fsm.cc

📁 OPNET 中的Wimax模块, 主要用于wimax 无线网络仿真,以及普通无线网络仿真.
💻 CC
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** * WiMAX module * * Copyright (C) 2008 Juliana Freitag Borin, Flavio Kubota and Nelson L. * S. da Fonseca - wimaxgroup@lrc.ic.unicamp.br * * This program is a free result: you can redistribute it and/or modify * it under the terms of the UOL Public License Version 1 or (at your * option) any later version. The license terms are available at * http://bolsapesquisa.uol.com.br/lpu.jhtm. * *   This file contains implementation of state machines for the three  *   types of service-flows * * * Revisions: *   $A0: 07/16/04: added look_at_queue method so we can examine the packets *                  wiating in the SS upstream queue. *                  And added filterACKPackets(Packet *pkt, char tbindex) *                  to support ACK suppresion. *                  Note:  ACK_SUPPRESSION must be 1 to enable this. * *   $A1: 08/11/04: added a print_short_map_list to dump the map contents  *                  in the SSMAP.out file. The following two defines are needed: *                       #define DUMPSSP 1:  enable dump *                       #define DUMPSSID 2 :  ss_id identifing the SS to watch *   $A2: 02/17/05: upstream rate control (Viraj) *   $A3: 03/23/05: Were deleting the MAP packet too early....only messed up *                  when multiple flows at a SS are active. *   $A4: 04/30/05: Added TIMINGS.dat trace.  See timingsTrace() in mac-802_16-ss.cc *                  For further details. Search for TIMINGS for all code changed. *   $A5: 03/15/06: (J. Freitag) included non-real-time service      *   $A6: 04/03/06: (J. Freitag) included downlink QoS scheduling services *   $A7: 09/19/06: (J. Freitag) included incremental bandwidth request *   $A8: 10/18/06: (J. Freitag) When a request timer is stopped, the event must *                  be deleted from the ReqList  *   $A9: 04/27/07: (J. Freitag) included the ertPS service in the uplink direction *   $A10:07/16/07: (J. Freitag) included the ertPS service in the downlink direction            *   $A11:08/13/07: (J. Freitag) excluded the DataGrantPending, since in the 802.16 standard *                  the SSs has no knowledge about the pending grants in the BS queues.  *   $A12:08/13/07: (J. Freitag) changed the back_off method in order to make the state *                  transitions inside the FSM wich has called it.      *   $A13:08/13/07: (J. Freitag) included the T16 timeout defined in the 802.16 standard.  **********************************************************************//*! \file mac-802_16-FSM.cc   This file contains implementation of state machines for the three types of service-flows *//*===============================INCLUDE HEADER FILES====================*/#include "mac-802_16.h"//#define WATCH_SSID 3 /*If not 0, we will do special tracing of events/data for this part. SS*/#define ACK_SUPPRESSION 0 /* If not 0, we will do ack suppression 			     for multiple ACKs for a TCP cx that 			     are waiting for an upstream transmission 			     opportunity */#define DUMPSSMAP 0 /* If set to > 0, then we will dump a MAP to the SSMAP.out file */#define DUMPSSID 0//$A2#define US_RATE_CONTROL 1//If defined, adds printf's//#define TRACE_ME 1//This will dump timing info//#define TIMINGS 1/*===========================END INCLUDE HEADER FILES====================*//*========================UGS STATE MACHINE FUNCTIONS===================*//************************************************************************* tbindex denotes the service-flow entry on which packet has been mapped*************************************************************************//*! \param tbindex denotes the service-flow entry on which packet has been mapped */int Mac802_16SS::ugs_idle(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d) UGS_IDLE state \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id);    switch(e)     {    case PKT_ARRIVAL:      //insert_pkt(p,tbindex);      UpFlowTable[tbindex].state = UGS_DECISION;      UpFlowTable[tbindex].pkt = p;      ugs_decision(tbindex, PKT_ARRIVAL, p);      break;                case MAP_ARRIVAL:      UpdateAllocationTable(tbindex);      UpdateJitter(tbindex);      if (UpFlowTable[tbindex].debug)	{	  printf("SS%d(flow-id %d):ugs_idle(%lf): MAP arrived, new state: %d \n", 	       ss_id,UpFlowTable[tbindex].upstream_record.flow_id, 	       Scheduler::instance().clock(), UpFlowTable[tbindex].state);	  printf("SS%d(flow-id %d) Allocation table \n",		 ss_id,UpFlowTable[tbindex].upstream_record.flow_id);	  print_alloclist(tbindex);	}      //printf("\nAllocation table for flow %d\n",      //UpFlowTable[tbindex].upstream_record.flow_id);      //print_alloclist(tbindex);      break;          default:      printf("SS%d(flow-id %d)UGS-IDLE state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);        break;    }  return 1;}/**************************************************************************************************************************************************/	int Mac802_16SS::ugs_decision(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d) UGS_DECISION state \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id);    switch(e)     {    case PKT_ARRIVAL:      if (!CanBeSent(UpFlowTable[tbindex].alloc_list,p,tbindex)){	UpFlowTable[tbindex].state = UGS_WAITFORMAP;	}      else 	{	  UpFlowTable[tbindex].state = UGS_TOSEND;	  ugs_tosend(tbindex, SEND_PKT, p);	}      break;          default:      printf("SS%d(flow-id %d)UGS-DECISION state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;         }  return 1;}/*************************************************************************** Function: int Mac802_16SS::ugs_waitformap(char tbindex, EventType e, Packet* p)** Explanation:*    This is called when certain events occur while a UGS flow is waiting*    for a MAP.** Inputs:** Outputs:***************************************************************************//*!  This is called when certain events occur while a UGS flow is waiting for a MAP. */int Mac802_16SS::ugs_waitformap(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d):ugs_waitformap(%lf) UGS_WAITFORMAP state (tbindex=%d)\n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id,	   Scheduler::instance().clock(),(int)tbindex);    switch(e)     {    case PKT_ARRIVAL:      insert_pkt(p,tbindex);      break;          case MAP_ARRIVAL:      UpdateAllocationTable(tbindex);      UpdateJitter(tbindex);      if (UpFlowTable[tbindex].debug) {        printf("SS%d(flow-id %d):ugs_waitformap(%lf): MAP ARRIVAL \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id,	   Scheduler::instance().clock());        print_alloclist(tbindex);      }      if (CanBeSent(UpFlowTable[tbindex].alloc_list,p,tbindex))	{	  UpFlowTable[tbindex].state = UGS_TOSEND;	  ugs_tosend(tbindex, SEND_PKT, p);	}      break;          default:      printf("SS%d(flow-id %d)UGS-WAITFORMAP state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;          }  return 1;}/**************************************************************************************************************************************************/int Mac802_16SS::ugs_tosend(char tbindex, EventType e, Packet* p){  double etime, current_time;  struct hdr_cmn *ch = HDR_CMN(p);  struct hdr_ip *chip = HDR_IP(p);  Packet* t;    current_time = Scheduler::instance().clock();  if (UpFlowTable[tbindex].debug)    printf("SS%d(%lf)(flow-id %d) UGS_TOSEND state \n",	   ss_id,current_time,UpFlowTable[tbindex].upstream_record.flow_id);    switch(e)     {    case SEND_PKT:      etime = timer_expiration(tbindex, p,DATA_GRANT);            if (etime == -1.0)	{	  printf("SS%d(flow-id %d) Timer expiration error: exiting..\n",		 ss_id,UpFlowTable[tbindex].upstream_record.flow_id);	  exit(1);	}            current_time = Scheduler::instance().clock();      //printf("Starting snd timer..\n");      mhSSSend_.start((Packet *) (&UpFlowTable[tbindex].intr), etime );      insert_sndlist(current_time + etime, tbindex);      break;          case PKT_ARRIVAL:            insert_pkt(p,tbindex);      break;          case MAP_ARRIVAL:      UpdateAllocationTable(tbindex);      UpdateJitter(tbindex);      if (UpFlowTable[tbindex].debug)         printf("SS%d(%lf)(flow-id %d) UGS_TOSEND MAP \n",	   ss_id,current_time,UpFlowTable[tbindex].upstream_record.flow_id);      //printf("\nAllocation table for flow %d\n",      //UpFlowTable[tbindex].upstream_record.flow_id);      //print_alloclist(tbindex);      break;          case SEND_TIMER:      //deque_pkt(tbindex);      SendData(p,tbindex);      UpFlowTable[tbindex].pkt = 0;            if ((len_queue(UpFlowTable[tbindex].packet_list)) > 0)	{	  UpFlowTable[tbindex].state = UGS_DECISION;	  t = deque_pkt(tbindex);	  struct hdr_cmn *ch = HDR_CMN(t);	  UpFlowTable[tbindex].pkt = t;	  ugs_decision(tbindex, PKT_ARRIVAL, t);	}	      else	UpFlowTable[tbindex].state = UGS_IDLE;       break;                default:      printf("SS%d(flow-id %d) UGS-TOSEND state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;    }  return 1;}/*======================END UGS STATE MACHINE FUNCTIONS===================*/				/*======================RT-POLL STATE MACHINE FUNCTIONS===================*//*************************************************************************tbindex denotes the service-flow entry on which packet has been mapped*************************************************************************//*! \param tbindex denotes the service-flow entry on which packet has been mapped */int Mac802_16SS::rtpoll_idle(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d) RTPOLL_IDLE state \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id);    switch(e)     {    case PKT_ARRIVAL:      //insert_pkt(p,tbindex);      UpFlowTable[tbindex].state = RTPOLL_DECISION;      UpFlowTable[tbindex].pkt = p;      rtpoll_decision(tbindex, PKT_ARRIVAL, p);      break;                case MAP_ARRIVAL:      UpdateAllocationTable(tbindex);      //printf("\nAllocation table for flow %d\n",      //UpFlowTable[tbindex].upstream_record.flow_id);      //print_alloclist(tbindex);      break;          default:      printf("SS%d(flow-id %d)RTPOLL-IDLE state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;    }  return 1;}/**************************************************************************************************************************************************/	int Mac802_16SS::rtpoll_decision(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d) RTPOLL_DECISION state \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id);    switch(e)     {    case PKT_ARRIVAL:      if (! CanBeSent(UpFlowTable[tbindex].alloc_list,p,tbindex))	{	  if (!CanUnicastReqBeSent(tbindex))	    UpFlowTable[tbindex].state = RTPOLL_WAITFORMAP;	  else 	    {	      UpFlowTable[tbindex].state = RTPOLL_TOSENDREQ;	      rtpoll_tosendreq(tbindex,SEND_UREQ, p);	    }	}      else 	{	  UpFlowTable[tbindex].state = RTPOLL_TOSEND;	  rtpoll_tosend(tbindex, SEND_PKT, p);	}      break;          default:      printf("SS%d(flow-id %d)RTPOLL-DECISION state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;          }  return 1;}/**************************************************************************************************************************************************/int Mac802_16SS::rtpoll_waitformap(char tbindex, EventType e, Packet* p){  if (UpFlowTable[tbindex].debug)    printf("SS%d(flow-id %d) RTPOLL_WAITFORMAP state \n",	   ss_id,UpFlowTable[tbindex].upstream_record.flow_id);	  switch(e)     {    case PKT_ARRIVAL:      insert_pkt(p,tbindex);      break;          case MAP_ARRIVAL:      UpdateAllocationTable(tbindex);      //printf("\nAllocation table for flow %d\n",      //UpFlowTable[tbindex].upstream_record.flow_id);      //print_alloclist(tbindex);            if ( CanBeSent(UpFlowTable[tbindex].alloc_list,p,tbindex))	{	  UpFlowTable[tbindex].state = RTPOLL_TOSEND;	  rtpoll_tosend(tbindex, SEND_PKT, p);	}      else if ( CanUnicastReqBeSent(tbindex))	{	  UpFlowTable[tbindex].state = RTPOLL_TOSENDREQ;	  rtpoll_tosendreq(tbindex, SEND_UREQ, p);	}      break;          default:      printf("SS%d(flow-id %d)RTPOLL-WAITFORMAP state error: Unknown event received\n",	     ss_id,UpFlowTable[tbindex].upstream_record.flow_id);      break;          }  return 1;}/**************************************************************************************************************************************************/int Mac802_16SS::rtpoll_tosend(char tbindex, EventType e, Packet* p){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -