?? mac-802_16-fsm.cc
字號:
/*************************************************************************** * 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 + -