📄 bt-lc.cc
字号:
to send. Here data could even be LMP or L2CAP signaling*/ intLinkController::pktSize(){ Packet* pkt = curr_reg_; if (firsttime_) { LMP* linkq = (LMP*)uptarget_; linkq->callback(); pkt = curr_reg_; firsttime_ = 0; } if (pkt) { hdr_bt* bt = HDR_BT(pkt); return (Payload[bt->type]); } else return 0;}Packet* LinkController::send(){ if (firsttime_) { LMP* linkq = (LMP*)uptarget_; linkq->callback(); firsttime_ = 0; } //Copy the packet and send the copy if (curr_reg_) { /* if the current register has a packet, copy it and send it off if transmission count is less than a threshold */ Packet* p = curr_reg_->copy(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); tx_cnt_++; if ((tx_cnt_ > 1) && (ch->ptype() == PT_EXP)) { //printf("Should not happen without ErrModel!\n"); //printf("Packet type %d and L_CH %d for am_addr %d retransmitted\n", bt->type, bt->ph.l_ch, bt->am_addr); tx_cnt_ = tx_thresh_+1; } if (tx_cnt_ <= tx_thresh_) { compose_pkt(p); return p; } /* if transmission count is exceeded, discard the packet. Yet to take care of discarding following segments of the same L2CAP packet, has to be implemented in the function 'flush_payload()' */ else { //flush_payload(); Packet::free(p); tx_cnt_ = 0; if (curr_reg_) { Packet::free(curr_reg_); curr_reg_ = 0; switch_reg(); } LMP* linkq = (LMP*)uptarget_; linkq->callback(); return 0; } } /* if there is no packet to send but a packet to acknowledge, send a NULL packet */ else if (ack_) { Packet* p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); bt->type = BT_NULL; ch->size() = NullSize; compose_pkt(p); return p; } return 0;}/* set ARQ related fields of the packet and am_addr_ */void LinkController::compose_pkt(Packet* p){ hdr_bt* bt = HDR_BT(p); bt->seqn= seq_; bt->arqn= ack_; bt->am_addr = am_addr_; ack_ = 0;}void LinkController::sendUp(Packet* p, Handler* h){ Scheduler& s = Scheduler::instance(); hdr_cmn* ch = HDR_CMN(p); hdr_bt* bt = HDR_BT(p); if (bt->type == BT_NULL) { //receive ack from a NULL packet if (bt->arqn) recvACK(); Packet::free(p); return; } else { //Discard duplicate packet ... if (bt->seqn == seq_old_) { ack_=1; // ... but see if it carries a new ACK if (bt->arqn) recvACK(); Packet::free(p); } else { //Handle corrupt packet if (ch->error()) { Packet::free(p); ack_=0; } //Handle valid data packet else { // set ack bit to acknowledge the packet ack_=1; // update sequence number seq_old_ = bt->seqn; // receive ACK if (bt->arqn) recvACK(); /* following block to make the slave side aware of its AM_ADDR through the connection request LMP PDU */ if (bt->ph.l_ch == 0x03) { uchar* data = p->accessdata(); if (data[0] == 51) am_addr_ = bt->am_addr; } // send to upper layer uptarget_->recv(p,h); } } }}/* Switch between current and next register, see Bluetooth baseband Specifications */void LinkController::switch_reg(){ Packet* temp; temp = curr_reg_; curr_reg_ = next_reg_; next_reg_ = temp;}void LinkController::flush_payload(){}//initialize ARQ related variables for the new connectionvoid LinkController::initialize(){ seq_ = ack_ = tx_cnt_ = 0; seq_old_ = 1; curr_reg_ = 0; next_reg_ = 0;}// receive acknowledgementvoidLinkController::recvACK() { //update next sequence number to be sent seq_ = 1-seq_; tx_cnt_ = 0; if (curr_reg_) Packet::free(curr_reg_); curr_reg_ = 0; switch_reg(); LMP* linkq = (LMP*)uptarget_; linkq->callback(); // cause LinkQueues (L2CAP or LMP) to send a packet as soon as it has one}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -