?? baseband.cc
字號:
/* Received ack of the FHS packet */ lm_->changeState(CONNECTION); lm_->pagerespTimer_ = 0; // Reset Page Response timer lm_->clke_ = 0; lm_->Nmr_ = 0; lm_->freeze_ = 0; lm_->newConnectionTimer_ = NewConnectionTimeout; // And set the New Connection Timer printf("FHS_ACK %d-->%d\t\t CLKN: %-10d clock: %10e\n", ch->uid(), lm_->bd_addr_, lm_->clkn_, s.clock()); } break; case BT_FHS: fhs = (FHS_payload*)(bt->ph.data); addr = fhs->addr; clock = fhs->clock; if (lm_->state_ == INQUIRY) { /* FHS packet received at the master with clock and address information */ uchar new_response = 1; printf("FHS_PKT %d-->%d\t\t CLKN: %-10d clock: %10e\n", addr, lm_->bd_addr_, lm_->clkn_, s.clock()); /* Find if the packet corresponds to a new device discovery */ for (int i=0; i<lm_->addr_vec_.size(); i++) { if (lm_->addr_vec_[i]->addr == addr) new_response = 0; } if (new_response) { /* store the info received to be sent to BThost */ FHS_payload* info = new FHS_payload; info->addr = addr; info->clock = (lm_->clkn_ & 0xfffffffc) - clock; lm_->addr_vec_.push_back(info); if (lm_->addr_vec_.size() == lm_->numResponses_) { /* If the specified number of responses in the * HCI_Inquiry command have been received, * send HCI_Inquiry_Result with the info collected * so far and stop further inquiry */ lm_->inqTimer_ = 0; lm_->initInqPageParam(); lm_->changeState(STANDBY); lm_->bthost_->HCI_Inquiry_Result(lm_->addr_vec_); // Check } } } else if (lm_->state_ == SLAVE_RESP) { /* FHS packet received from the master, send a packet * 625usec after we started receiving the packet */ lm_->master_addr_ = addr; lm_->clk_ = clock + 1; lm_->newConnectionTimer_ = NewConnectionTimeout; lm_->tx_clock_ = CLK; printf("FHS_PKT %d-->%d\t\t CLKN: %-10d clock: %10e\n", addr, lm_->bd_addr_, lm_->clkn_, s.clock()); s.schedule(&(lm_->clk_handler_), &(lm_->clk_ev_), SlotTime - 5*usec - (s.clock() - lm_->recv_start_)); } break; case BT_POLL: if (lm_->newConnectionTimer_) { /* First poll received by a slave * used here to find its am_addr */ lm_->am_addr_ = bt->am_addr; } //printf("POLL %d-->%d\t\t CLK: %-10d clock: %10e\n", lm_->master_addr_, lm_->bd_addr_, lm_->clk_, s.clock()); /* remember to reply at the next odd slot boundary */ lm_->polled_ = 1; break; case BT_NULL: if (lm_->newConnectionTimer_) { /* Ack for the first poll packet sent to a slave received * at the master. It is safe to bring it in the piconet now */ lm_->newConnectionTimer_ = 0; lm_->active_list_[bt->am_addr] = lm_->page_addr_; lm_->numACLlinks_++; lm_->new_am_addr_ = 0; printf("POLL_ACK %d-->%d\t\t CLK: %-10d clock: %10e\n", lm_->page_addr_, lm_->bd_addr_, lm_->clkn_, s.clock()); /* create first LMP message to be sent to the new * slave. This is also the first packet that is sent * using stop and wait ARQ at the link controller */ lm_->linkq_[bt->am_addr-1]->sendLMPCommand(51,0); } else { /* Null packets don't contain data but might contain * ack hence link controller needs to know about it */ if (lm_->masterIndex_ == 0) lm_->polled_ = 1; lm_->uptarget_->recv(p,this); } break; default: if (lm_->masterIndex_ == 0) { // Remember to respond in the next odd slot lm_->polled_ = 1; } //printf("RECV TYPE %d\t --> %5d\n", bt->type, lm_->bd_addr_); lm_->uptarget_->recv(p, this); return; } } else if (lm_->drop_) lm_->drop_->recv(p,lm_); else Packet::free(p);} /* the interfering packet has been completely received * safe to remove it from potential interferer queue * Used for multiple piconets only */voidInterfererHandler::handle(Event* e) { Packet* p = (Packet*) e; lm_->potinterfererQ_->remove(p); Packet::free(p);} void Baseband::updateInqPageParam (){ int n; n = (state_ == INQUIRY) ? Ninq : Npage; // Time to change train if ( numId_ == TrainSize ) { numId_ = 0; // reset numpackets numTrainsSent_++; if ( numTrainsSent_ == n ) { numTrainsSent_ = 0; trainType_ = (trainType_ == A) ? B : A; } } numId_++;}voidBaseband::handleInqRespTO(){ inqbackoffTimer_ = 0; inqscanTimer_ = -TinqScan; changeState(prev_state_); freeze_ = 0; Nfhs_ = 0;}voidBaseband::initInqPageParam(){ numId_ = 0; trainType_ = A; numTrainsSent_ = 0;} voidBaseband::getAM_ADDR(){ int i; for (i=1; (active_list_[i]!=0 && i<8); i++) ; new_am_addr_ = i;} uchar Baseband::FH_kernel(int CLK, int CLK_frozen, FH_sequence_type FH_sequence_t, int BD_addr) /*CLK can be Master clk, or clkn, or clke, the esimate of paged unit's clk by the paging unit, CLK_frozen is the frozen value of the clock when page/inquiry message is received. this is same as CLK, if CLK is not frozen*/{ uchar ip1_ADD_32, ip2_ADD_32, ip2_EXOR1, ip1_EXOR2, ip2_EXOR2; uchar ip2_ADD_79, ip3_ADD_79, ip4_ADD_79; uint ip3_PERM; uchar FH_frequency; uchar Xp_or_i, Xp_or_i_rs, Xprm, Xi, k_off; /*see BT specification for the meaning of these*/ uchar temp = (uchar) BD_addr; /*********the following part evaluates the inputs to each block***** *******************************************************************/ uchar CLK_1 = ((uchar)(CLK >> 1)) & 0x01; uchar CLK_12to16 = ((uchar)(CLK >> 12)) & 0x1f; uchar CLK_frozen_12to16 = ((uchar)(CLK_frozen >> 12)) & 0x1f; uchar CLK_0_2to4 = (CLK & 0x01) + ((CLK>>1) & 0x0e); uchar CLK_frozen_0_2to4 = (CLK_frozen & 0x01) + ((CLK_frozen>>1) & 0x0e); if (trainType_ == A) k_off = 24; else k_off = 8; ip2_ADD_32 = ((uchar)(BD_addr >> 23)) & 0x1f; ip2_EXOR1 = ((uchar)(BD_addr >> 19)) & 0x0f; ip2_EXOR2 = (temp & 0x01) + ((temp>>1) & 0x02) + ((temp>>2) & 0x04) + ((temp>>3) & 0x08) + (((uchar)(BD_addr>>4)) & 0x10); ip3_PERM = ((uint)(BD_addr >> 10)) & 0x01ff; ip2_ADD_79 = (uchar)(((BD_addr >> 1) & 0x01) + ((BD_addr >> 2) & 0x02) + ((BD_addr >> 3) & 0x04) + ((BD_addr >> 4) & 0x08) + ((BD_addr >> 5) & 0x10) + ((BD_addr >> 6) & 0x20) + ((BD_addr >> 7) & 0x40)) & 0x7f; ip3_ADD_79 = (uchar) 0; switch (FH_sequence_t) { case page_hopping: Xp_or_i = (CLK_12to16 + k_off +((CLK_0_2to4 - CLK_12to16) % 16)) % 32; ip1_ADD_32 = Xp_or_i & 0x1f; ip1_EXOR2 = CLK_1; ip4_ADD_79 = (uchar)(32 * CLK_1); break; case page_scan: ip1_ADD_32 = CLK_12to16; ip1_EXOR2 = (uchar) 0; ip4_ADD_79 = (uchar) 0; break; case slave_response: Xp_or_i_rs = (CLK_frozen_12to16 + Nsr_) % 32; ip1_ADD_32 = Xp_or_i_rs & 0x1f; if (tddState_ == TRANSMIT) { ip1_EXOR2 = (uchar) 1; ip4_ADD_79 = (uchar) 32; } else { ip1_EXOR2 = (uchar) 0; ip4_ADD_79 = (uchar) 0; } break; case master_response: Xprm = (CLK_frozen_12to16 + k_off +((CLK_frozen_0_2to4 - CLK_frozen_12to16) % 16) + Nmr_) % 32; ip1_ADD_32 = Xprm & 0x1f; if (tddState_ == TRANSMIT) { ip1_EXOR2 = (uchar) 0; ip4_ADD_79 = (uchar) 0; } else { ip1_EXOR2 = (uchar) 1; ip4_ADD_79 = (uchar) 32; } break; case inquiry_hopping: Xp_or_i = (CLK_12to16 + k_off +((CLK_0_2to4 - CLK_12to16) % 16)) % 32; Xp_or_i = (CLK_0_2to4 < CLK_12to16) ? (Xp_or_i+16)%32 : Xp_or_i; ip1_ADD_32 = Xp_or_i & 0x1f; ip1_EXOR2 = CLK_1; ip4_ADD_79 = (uchar)(32 * CLK_1); break; case inquiry_scan: ip1_ADD_32 = CLK_12to16; ip1_EXOR2 = (uchar) 0; ip4_ADD_79 = (uchar) 0; break; case inquiry_response: Xp_or_i_rs = (CLK_frozen_12to16 + Nfhs_) % 32; ip1_ADD_32 = Xp_or_i_rs & 0x1f; if (tddState_ == TRANSMIT) { ip1_EXOR2 = (uchar) 1; ip4_ADD_79 = (uchar) 32; } else { ip1_EXOR2 = (uchar) 0; ip4_ADD_79 = (uchar) 0; } break; case channel_hopping: uchar CLK_2to6 = (uchar)(CLK >> 2) & 0x1f; ip1_ADD_32 = CLK_2to6; ip1_EXOR2 = CLK_1; ip4_ADD_79 = (uchar)(32 * CLK_1); uchar CLK_21to25 = (uchar)(CLK >> 21) & 0x1f; ip2_ADD_32 = EXOR_5(ip2_ADD_32, CLK_21to25); uchar CLK_16to20 = (uchar)(CLK >> 16) & 0x1f; ip2_EXOR2 = EXOR_5(ip2_EXOR2, CLK_16to20); uint CLK_7to15 = (uint)(CLK >> 7) & 0x01ff; ip3_PERM = EXOR_9(ip3_PERM, CLK_7to15); int CLK_7to27 = (int)(CLK >> 7) & 0x001fffff; ip3_ADD_79 = (uchar)((16 * CLK_7to27) % 79) & 0x7f; break; } /*********this completes the external inputs to each block********** *******************************************************************/ uchar ip1_EXOR1 = ADD_mod32(ip1_ADD_32, ip2_ADD_32); uchar ip1_PERM = EXOR_5(ip1_EXOR1, ip2_EXOR1); uchar ip2_PERM = EXOR_5(ip1_EXOR2, ip2_EXOR2); uchar ip1_ADD_79 = PERM(ip1_PERM, ip2_PERM, ip3_PERM); FH_frequency = ADD_mod79(ip1_ADD_79, ip2_ADD_79, ip3_ADD_79, ip4_ADD_79); return (FH_frequency);}uchar Baseband::ADD_mod32(uchar ip1, uchar ip2) { return (((uchar)(((int)((ip1 & 0x1f) + (ip2 & 0x1f))) % 32)) & 0x1f);} uchar Baseband::ADD_mod79(uchar ip1, uchar ip2, uchar ip3, uchar ip4) { return (((uchar)(((int)((ip1 & 0x1f) + (ip2 & 0x7f) + (ip3 & 0x7f) + (ip4 & 0x7f))) % 79)) & 0x7f);} uchar Baseband::EXOR_5(uchar ip1, uchar ip2){ uchar ip1_c= ~ip1; uchar ip2_c= ~ip2; return (((ip1 & ip2_c) | (ip1_c & ip2)) & 0x1f);}uchar Baseband::EXOR_9(uint ip1, uint ip2){ uint ip1_c= ~ip1; uint ip2_c= ~ip2; return (((ip1 & ip2_c) | (ip1_c & ip2)) & 0x01ff);}voidBaseband::BFLY(uchar ctrl, uchar& ip1, uchar& ip2){ if (((int)(ctrl & 0x01)) == 1) { uchar temp=ip1; ip1 = ip2; ip2 = temp; } return;}uchar Baseband::PERM(uchar ip1, uchar ip2, uint ip3){ uchar z[5], p[14], op; for (int i=0; i<5; i++) z[i] = (ip1 >> i) & 0x01; for (int i=0; i<14; i++) { if (i<9) p[i] = (uchar)((ip3 >> i) & 0x0001); else p[i] = (ip2 >> (i-9)) & 0x01; } for (int stage_bfly=1; stage_bfly<8; stage_bfly++){ switch (stage_bfly) { case 1: BFLY(p[13], z[0], z[3]); BFLY(p[12], z[1], z[2]); break; case 2: BFLY(p[11], z[1], z[3]); BFLY(p[10], z[2], z[4]); break; case 3: BFLY(p[9], z[0], z[3]); BFLY(p[8], z[1], z[4]); break; case 4: BFLY(p[7], z[0], z[2]); BFLY(p[6], z[3], z[4]); break; case 5: BFLY(p[5], z[0], z[4]); BFLY(p[4], z[1], z[3]); break; case 6: BFLY(p[3], z[1], z[2]); BFLY(p[2], z[3], z[4]); break; case 7: BFLY(p[1], z[0], z[1]); BFLY(p[0], z[2], z[3]); break; } } op = z[0]; op = op + ((z[1] << 1) & 0x02); op = op + ((z[2] << 2) & 0x04); op = op + ((z[3] << 3) & 0x08); op = op + ((z[4] << 4) & 0x10); return (op); }voidBaseband::HCI_Create_Connection (int bd_addr, int clock_offset){ // Create Request for connection and enque it in request queue ConnectionRequest* cr = new ConnectionRequest; cr->bd_addr = bd_addr; cr->clock_offset = clock_offset; requestQ_->push(cr);} voidBaseband::HCI_Inquiry (long inqtimeout, int num_responses){ numResponses_ = num_responses; changeState(INQUIRY); inqTimer_ = inqtimeout;}doubleBaseband::calcLossProb (bt_packet_type type, double dist) { dist = (dist>MaxDist) ? MaxDist : dist; int index = (int)(floor(dist/DistStepSize)); return (FERvsDist[type][index]);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -