void DecodeCallBack::onPDU ( const PDU& pdu) { switch (pdu.channel()) { case PDU::other: break; case PDU::le: break; case PDU::bccmd: onBCCMDResponse(pdu); break; case PDU::hq: onHQRequest(pdu); break; case PDU::dm: break; case PDU::hciCommand: onHCIEvent(pdu); break; case PDU::hciACL: onHCIACLData(pdu); break; case PDU::hciSCO: onHCISCOData(pdu); break; case PDU::l2cap: break; case PDU::rfcomm: break; case PDU::sdp: break; case PDU::debug: onDebug(pdu); break; case PDU::upgrade: break; case PDU::vm: onVMData(pdu); break; case PDU::bcsp_channel_count: break; case PDU::lmp_debug: onLMPdebug(pdu); break; default: break; } }
// Send a PDU that requires HCI tunnelling for manufacturer extensions void BlueCoreTransportImplementation::sendTunnel ( const PDU& aPacket ) { if (tunnel) { uint8 data[HCI_TUNNEL_HEADER_SIZE+HCI_TUNNEL_MAX_PAYLOAD]; size_t offset = 0; while ( offset < aPacket.size() ) { size_t lLength = aPacket.size() - offset; while (1) { // Calculate the payload length and descriptor uint8 descriptor = aPacket.channel(); if (offset == 0) descriptor |= HCI_TUNNEL_FIRST; if (HCI_TUNNEL_MAX_PAYLOAD < lLength) lLength = HCI_TUNNEL_MAX_PAYLOAD; if (offset + lLength == aPacket.size()) descriptor |= HCI_TUNNEL_LAST; // Build and send the HCI command for this fragment data[0] = uint8(HCI_TUNNEL_COMMAND & 0xff); data[1] = uint8(HCI_TUNNEL_COMMAND >> 8); data[2] = uint8(lLength + 1); data[3] = descriptor; memcpy(data + HCI_TUNNEL_HEADER_SIZE, aPacket.data() + offset, lLength); PDU p(PDU::hciCommand, data, HCI_TUNNEL_HEADER_SIZE + lLength); if (pdu_size_forbidden(p)) { // can't send pdu of this length. try one size smaller. --lLength; } else { sendpdu(p); break; } } offset += lLength; } } }
static bool ignoresFlowControl ( const PDU& pdu ) { switch ( pdu.channel() ) { case PDU::hciCommand : { HCICommandPDU cmd ( pdu.data() , pdu.size() ); switch ( cmd.get_op_code() ) { case HCI_ACCEPT_CONNECTION_REQ: case HCI_REJECT_CONNECTION_REQ: case HCI_LINK_KEY_REQ_REPLY: case HCI_LINK_KEY_REQ_NEG_REPLY: case HCI_PIN_CODE_REQ_REPLY: case HCI_PIN_CODE_REQ_NEG_REPLY: case HCI_ACCEPT_SYNCHRONOUS_CONN_REQ: case HCI_REJECT_SYNCHRONOUS_CONN_REQ: case HCI_IO_CAPABILITY_RESPONSE: case HCI_USER_CONFIRMATION_REQUEST_REPLY: case HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY: case HCI_USER_PASSKEY_REQUEST_REPLY: case HCI_USER_PASSKEY_REQUEST_NEG_REPLY: case HCI_REMOTE_OOB_DATA_REQUEST_REPLY: case HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY: case HCI_IO_CAPABILITY_REQUEST_NEG_REPLY: case HCI_RESET: case HCI_HOST_NUM_COMPLETED_PACKETS: case HCI_ULP_LONG_TERM_KEY_REQUESTED_REPLY: case HCI_ULP_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY: case 0xFC00: return true; break; default: break; } break; } default: break; }; return false; }
void H4Queues::addNewPacket(const PDU &pdu, uint8 h4HeaderByte, bool needCallback) { #ifdef H4_MULTIQUEUE int queuenum; // Search for an ordered Q of this type, if none is found then // queuenum is left at the last unordered Q. for (queuenum = 0; queuenum < H4_NUM_ORDERED_QUEUES; ++queuenum) if (queue[queuenum].pktType == pdu.channel()) break; #endif CriticalSection::Lock here(cs); #ifdef H4_MULTIQUEUE queue[queuenum].list.push(H4_QUEUE::QueueItem(pdu, h4HeaderByte, needCallback)); #else queue.list.push(H4_QUEUE::QueueItem(pdu, h4HeaderByte, needCallback)); #endif ++packetCount; }
/*virtual*/ void BCSPH5Transport::recvOther(const PDU &aPacket) { recvData(aPacket.channel(), aPacket.data(), aPacket.size()); }