📄 lmp.cc
字号:
static class LMPClass : public TclClass {public: LMPClass() : TclClass ("LMP") {} TclObject* create(int,const char*const*) { return (new LMP()); }} class_lmp;LMP::LMP() : callback_(0) , am_addr_(0){ bind("master_", &master_); bind("am_addr_", (int*)(&am_addr_)); lmpq_ = new PacketQueue(); l2capq_ = new PacketQueue();}int LMP::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "bthost") == 0) { bthost_ = (BTHost*)TclObject::lookup(argv[2]); return (TCL_OK); } } if (argc == 3) { if (strcmp(argv[1], "sched") == 0) { sched_ = (BT_DRRScheduler*)TclObject::lookup(argv[2]); return (TCL_OK); } } if (argc == 3) { if (strcmp(argv[1], "tbf") == 0) { tbf_ = (LBF*)TclObject::lookup(argv[2]); return (TCL_OK); } } return (BiConnector::command(argc, argv));}void LMP::callback(){ // Give priority to LMP traffic Packet* p = lmpq_->deque(); if (!p) p = l2capq_->deque(); if (!p) { /* if there is no packet in either queue, remember that it has already been asked for a packet by the lower layer */ callback_ = 1; if (!master_ && am_addr_) { L2CAP* l2cap = (L2CAP*)(uptarget_); l2cap->callback(am_addr_-1); p = l2capq_->deque(); } } if (p) downtarget_->recv(p,this);}/* L2CAP or LMP packet going down the stack */voidLMP::sendDown(Packet* p, Handler* h){ hdr_bt* bt = HDR_BT(p); bt->am_addr = am_addr_; uchar l_ch = bt->ph.l_ch; /* if the lower layer has already asked for a packet send it down */ if (callback_) { callback_ = 0; downtarget_->recv(p,this); } // else enque it in the proper queue based on logical channel number else if (l_ch == 0x03) lmpq_->enque(p); else l2capq_->enque(p);}// Create an LMP PDUvoidLMP::sendLMPCommand(uchar opcode, uchar content){ Packet* p = Packet::alloc(2); hdr_bt* bt = HDR_BT(p); hdr_cmn* ch = HDR_CMN(p); uchar* data = p->accessdata(); data[0] = opcode; data[1] = content; bt->type = BT_DM1; ch->size() = Payload[bt->type]; bt->ph.l_ch = 0x03; sendDown(p,0);} // BTHost accepts the connectionvoidLMP::HCI_accept_connection_request (){ sendLMPCommand(3,51);} // BTHost requires a change in the packet size usedvoidLMP::HCI_change_connection_packet_type (uchar packet_type){ packetType_ = packet_type;} // BTHost requires QoS setupvoidLMP::HCI_QoS_Setup (flowSpec* qos){ // find if the QoS can be supported by the scheduler uchar result = sched_->mapQoS(am_addr_-1, qos, &qoslm_); if (result) { tbf_->setParameters(qos); sendLMPCommand(42, qoslm_.polling_interval); } else bthost_->HCI_QoS_Setup_Complete_Event(-1, BT_NULL);}voidLMP::sendUp (Packet* p, Handler* h) { hdr_bt* bt = HDR_BT(p); uchar am_addr = bt->am_addr; if (bt->ph.l_ch == 0x03) { uchar* data = p->accessdata(); switch (data[0]) { case 51: // inform bthost about connection request from remote host am_addr_ = am_addr; printf("LMP_HOST_CONNECT_REQ\t AM_ADDR: %-10d\n", am_addr_); bthost_->HCI_ConnectionRequestEvent(am_addr -1); break; case 42: // accept QoS required, could change this later to // negotiation printf("LMP_QOS_REQ\t\t AM_ADDR: %-10d\n", am_addr_); sendLMPCommand(3,42); break; case 3: printf("LMP_ACCEPTED\t\t AM_ADDR: %-8d", am_addr_); if (data[1] == 51) { // connection request has been accepted // inform bthost that connection is now // established printf("ACCEPTED PDU: LMP_HOST_CONNECTION_REQ\n"); bthost_->HCI_Connection_Complete_Event(am_addr-1); } if (data[1] == 42) { // QoS request accepted from remote side // inform bthost that proposed QoS was // accepted printf("ACCEPTED PDU: LMP_QOS_REQ\n"); bthost_->HCI_QoS_Setup_Complete_Event(am_addr-1, qoslm_.packet_type); } break; } Packet::free(p); } else uptarget_->recv(p,h);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -