📄 bsfc-queue.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* By Pablo Martin and Paula Ballester, * Strathclyde University, Glasgow. * June, 2003.*//* Copyright (c) 2003 Strathclyde University of Glasgow, Scotland. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code and binary code must contain * the above copyright notice, this list of conditions and the following * disclaimer. * * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed at Strathclyde University of * Glasgow, Scotland. * * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior written * permission. * STRATHCLYDE UNIVERSITY OF GLASGOW, MAKES NO REPRESENTATIONS * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software * is provided "as is" without express or implied warranty of any kind.*/#include "bsfc-queue.h"#include <stdio.h>/* Timers */void BsFCTimer::start(Packet *p, double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, p, rtime);} void BsFCTimer::stop(Packet *p){ Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel((Event *)p); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void BsFCTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; queue_->bsfcHandler(e);}// TCL Classstatic class BsFCQueueClass : public TclClass {public: BsFCQueueClass() : TclClass("Queue/DropTail/BsFCQueue") {} TclObject* create(int, const char*const*) { return (new BsFCQueue); }} class_BsFCQueue;int BsFCQueue::verbose_ = {0};// ContructorBsFCQueue::BsFCQueue() : DropTail(), qTimer_(this), callback_(0){ int i; ip_nodeb_ = -1; tti_ = TTI; // set tti_ to 10 ms intr = intr_ ; // for timer for (i=0; i<MAX_NUM_UE; i++) { users_[i].bytes_per_tti_ = 0; users_[i].dest_ = -1; users_[i].len_ = 0; } bind("verbose_",&verbose_); qTimer_.start((Packet *) (& intr_), 0); // start timer}int BsFCQueue::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "callback") == 0) { callback_ = (NsObject*) TclObject::lookup(argv[2]); assert(callback_); return (TCL_OK); } } return DropTail::command(argc, argv);}void BsFCQueue::recv(Packet* p, Handler*){ hdr_cmn *ch = HDR_CMN(p); if (ch->channel_t() == DTCH) { // if the packet is user data if (q_->length() < limit()) // check if the queue is full q_->enque(p); // enque the packet else drop(p); // queue full, drop the packet } else { target_->recv(p, this); // signalling } return;}// returns position in users_[] for a UEint BsFCQueue::find(nsaddr_t dir){ int id; for (id=0; id < MAX_NUM_UE; id++){ if (users_[id].dest_ == dir){ return (id); // UE found } } return(-1); // UE not found}// register and de-register for a UEvoid BsFCQueue::reg(nsaddr_t dir, double l){ int id, len; id = find(dir); if (l == 0) { // send upwards all the packets stored in the queue belonging to the UE len = q_->length(); if (verbose_) printf("Nodeb %d at %f IFQ: Pkts going up because of handover procedure or because of end of tx\n", ip_nodeb_, NOW); Scheduler& s = Scheduler::instance(); while (len > 0) { Packet * prov = q_->deque(); struct hdr_ip *ihprov = HDR_IP(prov); struct hdr_cmn *chprov = HDR_CMN(prov); if (ihprov->daddr()== users_[id].dest_) { chprov->channel_t() = DTCH; chprov->direction() = hdr_cmn::UP; chprov->ptype() = PT_CBR; ihprov->ttl() = 200; s.schedule(callback_, prov->copy(), 0.001); Packet::free(prov); } else { q_->enque(prov); } --len; } users_[id].bytes_per_tti_ = 0; users_[id].dest_ = -1; users_[id].len_ = 0; return; } if (id < 0) { // UE not registered, proceed for (id=0; id < MAX_NUM_UE; id++){ if (users_[id].dest_ < 0) { users_[id].dest_ = dir; break; } } } // update users_[] fields for the UE users_[id].bytes_per_tti_ = l; users_[id].len_ = 0; return;}// handler of BsFCTimer, executed each tti_void BsFCQueue::bsfcHandler(Event *e){ int l, id; // Restart timer for next tti. qTimer_.start((Packet *)e, tti_); l = q_->length(); while (l > 0) { // fo through all the queue Packet * prov = q_->deque(); struct hdr_cmn *chprov = HDR_CMN(prov); struct hdr_ip *ihprov = HDR_IP(prov); id = find(ihprov->daddr()); // find the UE for the packet users_[id].len_ -= chprov->size(); // update len if (users_[id].len_ < users_[id].bytes_per_tti_) { // allow to tx this packet if (verbose_) printf("Nodeb %d at %f IFQ: ***************** pkt for %d with size: %d free space: %f and uid: %d, bytes_tti %f\n", ip_nodeb_, NOW, ihprov->daddr(), chprov->size(), users_[id].len_, chprov->uid(), users_[id].bytes_per_tti_); users_[id].len_ += chprov->size(); // update len target_->recv(prov->copy(), this); // transmit the packet downwards Packet::free(prov); } else { // enqueue again the packet q_->enque(prov); } --l; } // update len in each tti. for (id=0; id < MAX_NUM_UE; id++) { if ((users_[id].dest_ != -1) && (users_[id].len_ > 0)) { users_[id].len_ -= users_[id].bytes_per_tti_; if (users_[id].len_ < 0) users_[id].len_ = 0; } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -