?? baseband.cc
字號:
lm_->Nfhs_++; lm_->tx_clock_ = CLKN; return; } else if (lm_->state_ == SLAVE_RESP) { /* Follow slave response page procedure */ if (lm_->newConnectionTimer_) { /* Send ID packet as an ack for the FHS packet recv from master */ lm_->sendIDPacket(lm_->bd_addr_); lm_->changeState(CONNECTION); lm_->pagerespTimer_ = 0; lm_->freeze_ = 0; lm_->Nsr_ = 0; } else { /* Send ID packet as an ack to the master's page message */ lm_->Nsr_ = 0; lm_->pagerespTimer_ = PageRespTO; lm_->sendIDPacket(lm_->bd_addr_); lm_->tx_clock_ = CLKN; return; } } /* * if the slave has been polled and clkmod4 corresponds * to the start of an odd slot send a response */ else if (lm_->polled_ && clkmod4 == 2) { if (lm_->newConnectionTimer_) { /* send ack to the 'first' poll packet by the master */ lm_->newConnectionTimer_ = 0; lm_->sendNULLPacket(lm_->am_addr_); } else if (lm_->state_ == CONNECTION) { /* get a packet from current register of link controller */ LinkController* lc = (LinkController*)(lm_->uptarget_); Packet* pkt = lc->send(); if (pkt) lm_->sendPacket(pkt); else lm_->sendNULLPacket(lm_->am_addr_); } /* replied to poll from master hence reset polled */ lm_->polled_ = 0; } } s.schedule (this, e, ClockTick);} voidBaseband::changeState(state_type state){ state_type old_state = state_; state_ = state; if (namTrace_) { BTNodeTrace* ns = (BTNodeTrace*)downtarget_; /* inform the nam trace object about state change * old state required for back-trace in nam */ ns->changeNodeColor(state, old_state); }} /* compose ID packet */ voidBaseband::sendIDPacket(int addr){ if (state_ == PAGE || state_ == INQUIRY) updateInqPageParam(); Packet* p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); ch->size() = IDSize; bt->type = BT_ID; ch->uid() = addr; sendPacket(p);}/* compose FHS packet */voidBaseband::sendFHSPacket(){ Packet* p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); bt->type = BT_FHS; ch->size() = FHSSize; bt->ph.data = new uchar[8]; FHS_payload* fhs = (FHS_payload*)(bt->ph.data); fhs->addr = bd_addr_; fhs->clock = clkn_ & 0xfffffffc; sendPacket(p);} /* compose POLL packet */voidBaseband::sendPOLLPacket(uchar am_addr){ Packet* p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); bt->type = BT_POLL; bt->am_addr = am_addr; ch->size() = PollSize; sendPacket(p);}/* compose NULL packet */voidBaseband::sendNULLPacket(uchar am_addr){ Packet* p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); bt->type = BT_NULL; bt->arqn = 0; bt->am_addr = am_addr; ch->size() = NullSize; sendPacket(p);}/* schedules the packet to be sent on * the appropriate hopping sequence */voidBaseband::sendPacket(Packet* p){ Scheduler& s = Scheduler::instance(); FH_sequence_type hop_type; int address; int clock, clockf; tddState_ = TRANSMIT; hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); ch->direction() = hdr_cmn::UP; // Change if (bt->type == BT_ID) txTimer_ = 1; else if (bt->type == 14 | bt->type == 15) txTimer_ = 10; else txTimer_ = (bt->type < 10) ? 2 : 6; switch (state_) { case INQUIRY: clock = clkn_; address = giac_; hop_type = inquiry_hopping; bt->am_addr = 0; // used for broadcast in animation break; case PAGE: clock = clke_; address = page_addr_; hop_type = page_hopping; bt->am_addr = 0; // used for broadcast in animation break; case INQ_RESP: clock = clkn_; address = giac_; hop_type = inquiry_response; bt->recvId_ = 0; // animation support assumes master = 0 break; case SLAVE_RESP: clock = clkn_; address = bd_addr_; hop_type = slave_response; bt->recvId_ = 0; // animation support break; case MASTER_RESP: clock = clke_; address = page_addr_; hop_type = master_response; bt->recvId_ = page_addr_; // animation support break; case CONNECTION: if (masterIndex_) { am_addr_ = bt->am_addr; bt->recvId_ = active_list_[bt->am_addr]; } clock = (masterIndex_) ? clkn_ : clk_; address = (masterIndex_) ? bd_addr_ : master_addr_; hop_type = channel_hopping; break; } if (ch->size() == 0) ch->size() = Payload[bt->type]; clockf = (freeze_) ? clkf_ : clock; bt->fs_ = FH_kernel(clock, clockf, hop_type, address); bt->dir = masterIndex_; bt->sendId_ = bd_addr_; bt->xpos_ = xpos_; bt->ypos_ = ypos_; s.schedule(&tx_handler_, p, PropDelay);}/* Finally send the packet */voidTxHandler::handle (Event* p){ lm_->downtarget_->recv((Packet*)p, lm_);}voidTDDHandler::handle (Event* p){ lm_->tddState_ = IDLE;}/* First bit of a packet received. All packets reach all nodes * because of broadcast. This is required for collision detection. */void Baseband::sendUp (Packet* p, Handler* h){ Scheduler& s = Scheduler::instance(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); int clock; int clockf; int address; int dest_addr; FH_sequence_type hop_type; uchar flag = 0; if (state_ == STANDBY) { Packet::free(p); return; } /* If no useful reception is taking place change the receiving frequency if required */ if (tddState_ == IDLE) { switch (state_) { case PAGE_SCAN: clock = clkn_; clockf = clkf_; address = bd_addr_; hop_type = page_scan; break; case PAGE: clock = clke_; clockf = clkf_; address = page_addr_; hop_type = page_hopping; break; case SLAVE_RESP: clock = clkn_; clockf = clkf_; address = bd_addr_; hop_type = slave_response; break; case MASTER_RESP: clock = clke_; clockf = clkf_; address = page_addr_; hop_type = master_response; break; case INQUIRY: clock = clkn_; clockf = clkf_; address = giac_; hop_type = inquiry_hopping; break; case INQ_SCAN: clock = clkn_; clockf = clkf_; address = giac_; hop_type = (freeze_) ? inquiry_response : inquiry_scan; break; case INQ_RESP: clock = clkn_; clockf = clkf_; address = giac_; hop_type = inquiry_response; break; case CONNECTION: clock = (masterIndex_) ? clkn_ : clk_; clockf = clock; address = (masterIndex_) ? bd_addr_ : master_addr_; hop_type = channel_hopping; break; } recv_freq_ = FH_kernel (clock, clockf, hop_type, address); } /* find if the packet is to be received */ if ((tddState_ == IDLE) && recv_filter(p)) { recv_start_ = s.clock(); tddState_ = RECEIVE;/*********************COLLISION DETECTION REMOVED***************** //find prospective interferers int len = potinterfererQ_->length(); for (Packet* pkt=potinterfererQ_->head(); pkt!=0 ; pkt=pkt->next_) { hdr_cmn* ch = HDR_CMN(pkt); hdr_bt* bt = HDR_BT(pkt); if (bt->fs_ == recv_freq_) interfererQ_->enque(pkt->copy()); } s.schedule(&recv_handler_, p, ch->size()*8.0/BandWidth);***********************.....FROM THIS VERSION*******************/ int num_ticks = (bt->type == BT_ID) ? 1 : 2*SlotSize[bt->type]; s.schedule(&recv_handler_, p, num_ticks*ClockTick-50*usec); } else Packet::free(p); /**************COLLISION DETECTION REMOVED...******************** else { Packet* pkt; if (tddState_ == RECEIVE && bt->fs_ == recv_freq_) { pkt = p->copy(); interfererQ_->enque(pkt); } // else it could be a potential interferer, put it in potential interferer queue potinterfererQ_->enque(p); s.schedule(&int_recv_handler_, p, ch->size()*8.0/BandWidth); }***********************.....FROM THIS VERSION*******************/}/* Used to determine the received packet is at the listening freq and valid * This will be more useful with multiple piconets */intBaseband::recv_filter (Packet* p){ hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); int access_code; int flag; flag = (bt->fs_ == recv_freq_); if (!flag) return flag; switch(bt->type) { case BT_ID: access_code = ch->uid(); flag &= ((state_ == INQ_SCAN && access_code == giac_) || (state_ == INQ_RESP && access_code == giac_) || (state_ == PAGE_SCAN && access_code == dac_) || (state_ == PAGE && access_code == page_addr_) || (state_ == MASTER_RESP && access_code == page_addr_)); break; case BT_FHS: flag &= ((state_ == INQUIRY) || (state_ == SLAVE_RESP)); break; case BT_POLL: flag &= (state_ == CONNECTION && masterIndex_ == 0); flag &= (am_addr_ == 0 || bt->am_addr == am_addr_); break; default: flag &= (tddState_ == IDLE); flag &= (bt->am_addr == am_addr_ || bt->am_addr == 0); break; } return flag;} /* valid packet completely received */voidRecvHandler::handle(Event* e) { Scheduler& s = Scheduler::instance(); Tcl& tcl = Tcl::instance(); Packet* p = (Packet*)e; hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); int access_code; FHS_payload* fhs; int addr, clock; lm_->tddState_ = IDLE;/*********************COLLISION DETECTION REMOVED***************** int len = lm_->interfererQ_->length(); // empty interferer Q for (int i=0; i<len; i++) { Packet* pkt = lm_->interfererQ_->deque(); Packet::free(pkt); }***********************.....FROM THIS VERSION*******************/ // calulate distance between Rx and Tx double dist = sqrt(pow((lm_->xpos_-bt->xpos_), 2)+pow((lm_->ypos_-bt->ypos_), 2)); //evaluate loss probability for the packet //handle packet if received without error double fer = lm_->calcLossProb(bt->type, dist); fer = (bt->type == BT_ID) ? 0.0 : fer; if (Random::uniform() > fer) { if (bt->ph.l_ch == 0x03) { lm_->polled_ = 1; lm_->uptarget_->recv(p,lm_); return; } switch (bt->type) { case BT_ID: if (lm_->state_ == INQ_SCAN) { if (lm_->freeze_ == 0) { /* start a new inquiry response session * freeze clock to be used for the rest of the * session as the current value of the native * clock */ lm_->inqrespTimer_ = InqRespTO; lm_->freeze_ = 1; lm_->clkf_ = lm_->clkn_; lm_->Nfhs_ = 0; } /* start backoff timer for upto 1024 slots and go to previous state */ cout.precision(8); //cout.setf(ios_base::scientific,ios_base::floatfield); printf("INQ_MSG ****-->%d\t CLKN: %-10d clock: %10e\n", lm_->bd_addr_, lm_->clkn_, s.clock()); lm_->changeState(lm_->prev_state_); int rand = (int)Random::uniform(1, MaximumBackoff); lm_->inqbackoffTimer_ = rand; } else if (lm_->state_ == INQ_RESP) { /* First inquiry message received after backoff. * sync to master clock by setting the next transmission * event at exactly 625usec after we started * receiving the inquiry ID packet */ printf("INQ_MSG AFTER BO *-->%d\t CLKN: %-10d clock: %10e \n", lm_->bd_addr_, lm_->clkn_, s.clock()); s.schedule(&(lm_->clk_handler_), &(lm_->clk_ev_), SlotTime - (s.clock() - lm_->recv_start_)); lm_->tx_clock_ = CLK; } else if (lm_->state_ == PAGE_SCAN) { /* Page message received, sync to master clock * by setting the next transmission event at * exactly 625 usec after we started receiving * the page ID packet */ lm_->freeze_ = 1; lm_->clkf_ = lm_->clkn_; lm_->changeState(SLAVE_RESP); lm_->tx_clock_ = CLK; printf("PAGE_MSG ****-->%d\t CLKN: %-10d clock: %10e\n", lm_->bd_addr_, lm_->clkn_, s.clock()); s.schedule(&(lm_->clk_handler_), &(lm_->clk_ev_), SlotTime - (s.clock() - lm_->recv_start_)); } else if (lm_->state_ == PAGE) { /* Received a valid page response, freeze the estimated clock * for rest of the paging procedure */ lm_->freeze_ = 1; lm_->clkf_ = lm_->clke_; lm_->changeState(MASTER_RESP); printf("PAGE_ACK %d-->%d\t\t CLKN: %-10d clock: %10e\n", ch->uid(), lm_->bd_addr_, lm_->clkn_, s.clock()); printf("MASTER FROZEN\t\t CLKE: %-10d \n", lm_->clke_); } else if (lm_->state_ == MASTER_RESP) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -