📄 wimaxctrlagent.cc
字号:
/* This class contains the control agent located in IEEE 802.16 BS responsible * for synchronization between BSs. * This software was developed at the National Institute of Standards and * Technology by employees of the Federal Government in the course of * their official duties. Pursuant to title 17 Section 105 of the United * States Code this software is not subject to copyright protection and * is in the public domain. * NIST assumes no responsibility whatsoever for its use by other parties, * and makes no guarantees, expressed or implied, about its quality, * reliability, or any other characteristic. * <BR> * We would appreciate acknowledgement if the software is used. * <BR> * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING * FROM THE USE OF THIS SOFTWARE. * </PRE></P> * @author rouil */#include "wimaxctrlagent.h"#include "mac802_16.h" #include "bsscheduler.h"#define MYNUM Address::instance().print_nodeaddr(addr())int hdr_wimaxbs::offset_;/** * Tcl hook for Packet definitions */static class WimaxBSHeaderClass : public PacketHeaderClass {public: WimaxBSHeaderClass() : PacketHeaderClass("PacketHeader/WIMAXBS", sizeof(hdr_wimaxbs)) { bind_offset(&hdr_wimaxbs::offset_); }} class_wimaxbshdr;/** * Tcl hook for agent */static class WimaxCtrlAgentClass : public TclClass {public: WimaxCtrlAgentClass() : TclClass("Agent/WimaxCtrl") {} TclObject* create(int, const char*const*) { return (new WimaxCtrlAgent()); }} class_wimaxctrlagent;/* * Handler for timer expiration */void UpdateTimer::expire (Event*){ a_->sendUpdate();}/* * Handler for response timer expiration */void ScanRspTimer::expire (Event*){ a_->agent()->send_scan_response(a_->cid());}/* * Creates a Wimax controler agent * Initializes the agent and bind variable to be accessible in TCL */WimaxCtrlAgent::WimaxCtrlAgent() : Agent(PT_WIMAXBS), mac_(0), updatetimer_ (this){ nbmapentry_=0; LIST_INIT (&scan_req_head_); //bind attributes bind ("adv_interval_", &adv_interval_); bind ("default_association_level_", &defaultlevel_); bind ("synch_frame_delay_", &synch_frame_delay_); //schedule first update updatetimer_.sched (Random::uniform(0, UPDATE_JITTER));}/* * Interface with TCL interpreter * @param argc The number of elements in argv * @param argv The list of arguments * @return TCL_OK if everything went well else TCL_ERROR */int WimaxCtrlAgent::command(int argc, const char*const* argv){ Tcl& tcl= Tcl::instance(); if (argc == 3) { // set the Minimum interval between two RAs if (strcmp(argv[1], "set-mac") == 0) { mac_ = (Mac802_16*) TclObject::lookup(argv[2]); ((BSScheduler*)mac_->getScheduler())->setCtrlAgent (this); return TCL_OK; } else if (strcmp(argv[1], "add-neighbor") == 0) { //the parameter is the mac, and we also extract the node Mac802_16 *tmp = (Mac802_16 *) TclObject::lookup(argv[2]); if (nbmapentry_ == MAX_MAP_ENTRY) { fprintf (stderr, "Table size exceeding. Increase MAX_MAP_ENTRY\n"); } tcl.evalf ("%s get-node", argv[2]); Node *tmpNode = (Node *) TclObject::lookup(tcl.result()); //add entry maptable_[nbmapentry_][0] = tmp->addr(); maptable_[nbmapentry_][1] = tmpNode->address(); debug ("Adding neighbor %s (mac %d) in %s\n", Address::instance().print_nodeaddr(tmpNode->address()), tmp->addr(), MYNUM); nbmapentry_++; return TCL_OK; } } return (Agent::command(argc, argv));}/* * Send an update (DCD/UCD) to all neighboring BSs */void WimaxCtrlAgent::sendUpdate (){ //get the DCD/UCD message to include in the update Packet *dcd = mac_->getScheduler()->map_->getDCD(); Packet *ucd = mac_->getScheduler()->map_->getUCD(); //allocate data to store information mac802_16_dcd_frame *dcdframe = (mac802_16_dcd_frame*) dcd->accessdata(); mac802_16_ucd_frame *ucdframe = (mac802_16_ucd_frame*) ucd->accessdata(); Packet *p = allocpkt(); hdr_ip *iph = HDR_IP(p); hdr_wimaxbs *rh = HDR_WIMAXBS(p); hdr_cmn *hdrc = HDR_CMN(p); rh->getType() = WIMAX_BS_ADV; hdrc->size() = HDR_CMN(dcd)->size()+HDR_CMN(ucd)->size(); //TBD: remove double header //set content rh->macAddr() = mac_->addr(); p->allocdata (sizeof (mac802_16_dcd_frame)+sizeof (mac802_16_ucd_frame)); unsigned char *data = p->accessdata(); memcpy (data, dcdframe, sizeof (mac802_16_dcd_frame)); memcpy (data+sizeof (mac802_16_dcd_frame), ucdframe, sizeof (mac802_16_ucd_frame)); Packet *tmpPkt; for (int i = 0; i < nbmapentry_ ; i++) { tmpPkt = p->copy(); iph = HDR_IP(tmpPkt); //set packet destination iph->daddr() = maptable_[i][1]; iph->dport() = port(); debug ("At %f in node %s, send update to node %s\n", NOW, MYNUM,Address::instance().print_nodeaddr(iph->daddr())); debug ("frame number=%d\n", dcdframe->frame_number); send(tmpPkt, 0); } //reschedule timer updatetimer_.resched (adv_interval_);}/* * Process received packet * @param p The packet received * @param h The handler that sent the packet */void WimaxCtrlAgent::recv(Packet* p, Handler *h){ assert (p); hdr_wimaxbs *rh = HDR_WIMAXBS(p); switch (rh->getType()) { case WIMAX_BS_ADV: processUpdate (p); break; case WIMAX_BS_SYNCH_REQ: process_synch_request (p); break; case WIMAX_BS_SYNCH_RSP: process_synch_response (p); break; default: fprintf (stderr, "Unknown message type in WimaxCtrlAgent\n"); } Packet::free (p);}/* * Process received packet * @param p The update received * @param h The handler that sent the packet */void WimaxCtrlAgent::processUpdate(Packet* p){ debug ("At %f in node %s, WimaxCtrlAgent received update message from %s\n", NOW, MYNUM, Address::instance().print_nodeaddr(HDR_IP(p)->saddr())); hdr_wimaxbs *rh = HDR_WIMAXBS(p); NeighborEntry *entry = mac_->getScheduler()->nbr_db_->getNeighbor(rh->macAddr()); //check if we know about this neighbor bool found = false; for (int i = 0; i < nbmapentry_ ; i++) { if (maptable_[i][1]==HDR_IP(p)->saddr()) found = true; } assert (found); if (entry==NULL) { debug ("\tNew neighbor detected...add entry for mac %d\n", rh->macAddr()); entry = new NeighborEntry (rh->macAddr()); mac_->getScheduler()->nbr_db_->addNeighbor(entry); } //update entry unsigned char *data = p->accessdata(); mac802_16_dcd_frame *dcdframe = (mac802_16_dcd_frame *)malloc (sizeof (mac802_16_dcd_frame)); mac802_16_ucd_frame *ucdframe = (mac802_16_ucd_frame *)malloc (sizeof (mac802_16_ucd_frame)); memcpy (dcdframe, data, sizeof (mac802_16_dcd_frame));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -