Loading system/main/shim/entry.cc +4 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ bluetooth::shim::IHciLayer* bluetooth::shim::GetHciLayer() { return GetGabeldorscheStack()->GetHciLayer(); } bluetooth::shim::IL2cap* bluetooth::shim::GetL2cap() { return GetGabeldorscheStack()->GetL2cap(); } bluetooth::shim::IPage* bluetooth::shim::GetPage() { return GetGabeldorscheStack()->GetPage(); } system/main/shim/entry.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ bluetooth::shim::IDiscoverability* GetDiscoverability(); bluetooth::shim::IConnectability* GetConnectability(); bluetooth::shim::IInquiry* GetInquiry(); bluetooth::shim::IHciLayer* GetHciLayer(); bluetooth::shim::IL2cap* GetL2cap(); bluetooth::shim::IPage* GetPage(); } // namespace shim Loading system/main/shim/l2c_api.cc +160 −114 Original line number Diff line number Diff line Loading @@ -23,18 +23,21 @@ static bluetooth::shim::L2cap shim_l2cap; /** * Classic Service Registration APIs */ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, tL2CAP_APPL_INFO* p_cb_info, tL2CAP_APPL_INFO* callbacks, bool enable_snoop) { if (L2C_INVALID_PSM(client_psm)) { LOG_ERROR(LOG_TAG, "%s Invalid classic psm:0x%04x", __func__, client_psm); return 0; } if ((p_cb_info->pL2CA_ConfigCfm_Cb == nullptr) || (p_cb_info->pL2CA_ConfigInd_Cb == nullptr) || (p_cb_info->pL2CA_DataInd_Cb == nullptr) || (p_cb_info->pL2CA_DisconnectInd_Cb == nullptr)) { if ((callbacks->pL2CA_ConfigCfm_Cb == nullptr) || (callbacks->pL2CA_ConfigInd_Cb == nullptr) || (callbacks->pL2CA_DataInd_Cb == nullptr) || (callbacks->pL2CA_DisconnectInd_Cb == nullptr)) { LOG_ERROR(LOG_TAG, "%s Invalid classic callbacks psm:0x%04x", __func__, client_psm); return 0; Loading @@ -43,7 +46,7 @@ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, /** * Check if this is a registration for an outgoing-only connection. */ bool is_outgoing_connection_only = p_cb_info->pL2CA_ConnectInd_Cb == nullptr; bool is_outgoing_connection_only = callbacks->pL2CA_ConnectInd_Cb == nullptr; uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm, is_outgoing_connection_only); Loading @@ -53,13 +56,13 @@ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, __func__, client_psm, psm); return 0; } shim_l2cap.Classic().RegisterPsm(psm, p_cb_info); shim_l2cap.Classic().RegisterPsm(psm, callbacks); LOG_INFO(LOG_TAG, "%s classic client_psm:0x%04x psm:0x%04x", __func__, client_psm, psm); // TODO(cmanton) Register this service with GD // TODO(cmanton) Fake out a config negotiator shim_l2cap.Register(psm, callbacks, enable_snoop); return psm; } Loading Loading @@ -107,23 +110,68 @@ void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) { shim_l2cap.Le().DeallocatePsm(psm); } /** * Classic Connection Oriented Channel APIS */ uint16_t bluetooth::shim::L2CA_ErtmConnectReq(uint16_t psm, const RawAddress& p_bd_addr, const RawAddress& raw_address, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd addr:%s p_ertm_info:%p", __func__, psm, p_bd_addr.ToString().c_str(), p_ertm_info); return 0; CHECK(p_ertm_info == nullptr) << "UNIMPLEMENTED set enhanced retransmission mode config"; return shim_l2cap.Connect(psm, raw_address); } uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { return bluetooth::shim::L2CA_ErtmConnectReq(psm, p_bd_addr, nullptr); const RawAddress& raw_address) { return bluetooth::shim::L2CA_ErtmConnectReq(psm, raw_address, nullptr); } bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd " "p_ertm_info:%p", __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status, p_ertm_info); return false; } bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status) { return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL); } bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; } bool bluetooth::shim::L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; } bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; } bool bluetooth::shim::L2CA_DisconnectRsp(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; } /** * Le Connection Oriented Channel APIs */ uint16_t bluetooth::shim::L2CA_RegisterLECoc(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd p_cb_info:%p", __func__, psm, p_cb_info); tL2CAP_APPL_INFO* callbacks) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd callbacks:%p", __func__, psm, callbacks); return 0; } Loading Loading @@ -158,52 +206,51 @@ bool bluetooth::shim::L2CA_GetPeerLECocConfig(uint16_t lcid, return false; } /** * Channel Data Writes */ bool bluetooth::shim::L2CA_SetConnectionCallbacks( uint16_t local_cid, const tL2CAP_APPL_INFO* callbacks) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s lcid:%hd callbacks:%p", __func__, local_cid, callbacks); return false; } bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd " "p_ertm_info:%p", __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status, p_ertm_info); return false; uint16_t cid, const tL2CAP_APPL_INFO* callbacks) { return shim_l2cap.SetCallbacks(cid, callbacks); } bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status) { return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL); uint8_t bluetooth::shim::L2CA_DataWriteEx(uint16_t cid, BT_HDR* bt_hdr, uint16_t flags) { if (shim_l2cap.IsCongested(cid)) { return L2CAP_DW_CONGESTED; } bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; bool write_success = false; switch (flags) { case L2CAP_FLUSHABLE_CH_BASED: write_success = shim_l2cap.Write(cid, bt_hdr); break; case L2CAP_FLUSHABLE_PKT: write_success = shim_l2cap.WriteFlushable(cid, bt_hdr); break; case L2CAP_NON_FLUSHABLE_PKT: write_success = shim_l2cap.WriteNonFlushable(cid, bt_hdr); break; } bool bluetooth::shim::L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; return write_success ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED; } bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { return bluetooth::shim::L2CA_DataWriteEx(cid, p_data, L2CAP_FLUSHABLE_CH_BASED); } bool bluetooth::shim::L2CA_DisconnectRsp(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; /** * L2cap Layer APIs */ uint8_t bluetooth::shim::L2CA_SetDesireRole(uint8_t new_role) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Ping APIs */ bool bluetooth::shim::L2CA_Ping(const RawAddress& p_bd_addr, tL2CA_ECHO_RSP_CB* p_callback) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s p_callback:%p", __func__, Loading @@ -218,18 +265,9 @@ bool bluetooth::shim::L2CA_Echo(const RawAddress& p_bd_addr, BT_HDR* p_data, return false; } bool bluetooth::shim::L2CA_GetIdentifiers(uint16_t lcid, uint16_t* rcid, uint16_t* handle) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout, bool is_global) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } /** * Link APIs */ bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout, tBT_TRANSPORT transport) { Loading @@ -237,11 +275,6 @@ bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, return false; } uint8_t bluetooth::shim::L2CA_SetDesireRole(uint8_t new_role) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } uint16_t bluetooth::shim::L2CA_LocalLoopbackReq(uint16_t psm, uint16_t handle, const RawAddress& p_bd_addr) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading @@ -254,30 +287,6 @@ bool bluetooth::shim::L2CA_SetAclPriority(const RawAddress& bd_addr, return false; } bool bluetooth::shim::L2CA_FlowControl(uint16_t cid, bool data_enabled) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SendTestSFrame(uint16_t cid, uint8_t sup_type, uint8_t back_track) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetChnlDataRate(uint16_t cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetFlushTimeout(const RawAddress& bd_addr, uint16_t flush_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading @@ -297,11 +306,9 @@ bool bluetooth::shim::L2CA_GetBDAddrbyHandle(uint16_t handle, return false; } uint8_t bluetooth::shim::L2CA_GetChnlFcrMode(uint16_t lcid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Fixed Channel APIs */ bool bluetooth::shim::L2CA_RegisterFixedChannel(uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading Loading @@ -334,13 +341,9 @@ bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t fixed_cid, return false; } bool bluetooth::shim::L2CA_SetFixedChannelTout(const RawAddress& rem_bda, uint16_t fixed_cid, uint16_t idle_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } /** * Channel Configuration API */ bool bluetooth::shim::L2CA_GetCurrentConfig( uint16_t lcid, tL2CAP_CFG_INFO** pp_our_cfg, tL2CAP_CH_CFG_BITS* p_our_cfg_bits, tL2CAP_CFG_INFO** pp_peer_cfg, Loading @@ -356,25 +359,59 @@ bool bluetooth::shim::L2CA_GetConnectionConfig(uint16_t lcid, uint16_t* mtu, return false; } bool bluetooth::shim::L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda) { /** * Channel hygiene APIs */ bool bluetooth::shim::L2CA_GetIdentifiers(uint16_t lcid, uint16_t* rcid, uint16_t* handle) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { bool bluetooth::shim::L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout, bool is_global) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_FlowControl(uint16_t cid, bool data_enabled) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SendTestSFrame(uint16_t cid, uint8_t sup_type, uint8_t back_track) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetChnlDataRate(uint16_t cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_GetChnlFcrMode(uint16_t lcid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { bool bluetooth::shim::L2CA_SetFixedChannelTout(const RawAddress& rem_bda, uint16_t fixed_cid, uint16_t idle_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_DataWriteEx(uint16_t cid, BT_HDR* p_data, uint16_t flags) { bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } Loading @@ -384,3 +421,12 @@ uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid, LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Misc APIs */ bool bluetooth::shim::L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } system/main/shim/l2cap.cc +96 −0 Original line number Diff line number Diff line Loading @@ -13,8 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "bt_shim_l2cap" #include "main/shim/l2cap.h" #include "main/shim/entry.h" #include "main/shim/shim.h" #include "osi/include/allocator.h" #include "osi/include/log.h" constexpr size_t kBtHdrSize = sizeof(BT_HDR); bool bluetooth::shim::PsmData::IsPsmAllocated(uint16_t psm) const { return psm_to_callback_map.find(psm) != psm_to_callback_map.end(); Loading Loading @@ -115,3 +122,92 @@ uint16_t bluetooth::shim::L2cap::GetNextDynamicClassicPsm() { } return classic_dynamic_psm_; } void bluetooth::shim::L2cap::Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info, bool enable_snoop) { LOG_DEBUG(LOG_TAG, "Registering service psm:%hd", psm); std::chrono::system_clock::time_point two_seconds = std::chrono::system_clock::now() + std::chrono::seconds(2); std::promise<void> register_completed; auto completed = register_completed.get_future(); bluetooth::shim::GetL2cap()->RegisterService(psm, enable_snoop, std::move(register_completed)); completed.wait(); if (std::future_status::ready != completed.wait_until(two_seconds)) { LOG_WARN(LOG_TAG, "Timed out registering service to psm:%hd", psm); } } uint16_t bluetooth::shim::L2cap::Connect(uint16_t psm, const RawAddress& raw_address) { LOG_DEBUG(LOG_TAG, "Requesting connection to psm:%hd address:%s", psm, raw_address.ToString().c_str()); std::chrono::system_clock::time_point two_seconds = std::chrono::system_clock::now() + std::chrono::seconds(2); std::promise<uint16_t> connect_completed; auto completed = connect_completed.get_future(); bluetooth::shim::GetL2cap()->Connect(psm, raw_address.ToString(), std::move(connect_completed)); if (std::future_status::ready == completed.wait_until(two_seconds)) { return completed.get(); } LOG_WARN(LOG_TAG, "Timed out connecting to psm:%hd address:%s", psm, raw_address.ToString().c_str()); return 0; } bool bluetooth::shim::L2cap::IsCongested(uint16_t cid) const { LOG_WARN(LOG_TAG, "UNIMPLEMENTED checking congestion on a channel"); return false; } bool bluetooth::shim::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->Write(cid, data, len); } bool bluetooth::shim::L2cap::WriteFlushable(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->WriteFlushable(cid, data, len); } bool bluetooth::shim::L2cap::WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->WriteNonFlushable(cid, data, len); } bool bluetooth::shim::L2cap::SetCallbacks(uint16_t cid, const tL2CAP_APPL_INFO* callbacks) { LOG_ASSERT(cid_to_callback_map_.find(cid) != cid_to_callback_map_.end()) << "Registering multiple channel callbacks cid:" << cid; cid_to_callback_map_[cid] = callbacks; bluetooth::shim::GetL2cap()->SetOnReadDataReady( cid, [this](uint16_t cid, std::vector<const uint8_t> data) { LOG_INFO(LOG_TAG, "Got data on cid:%hd len:%zd", cid, data.size()); BT_HDR* bt_hdr = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize)); std::copy(data.begin(), data.end(), bt_hdr->data); bt_hdr->len = data.size(); cid_to_callback_map_[cid]->pL2CA_DataInd_Cb(cid, bt_hdr); }); bluetooth::shim::GetL2cap()->SetOnClose(cid, [this, &cid](int error_code) { LOG_DEBUG(LOG_TAG, "Channel closed cid:%hd", cid); cid_to_callback_map_[cid]->pL2CA_DisconnectInd_Cb(cid, true); }); return true; } void bluetooth::shim::L2cap::ClearCallbacks(uint16_t cid) { LOG_ASSERT(cid_to_callback_map_.find(cid) == cid_to_callback_map_.end()) << "Clearing callbacks that do not exist cid:" << cid; cid_to_callback_map_.erase(cid); } system/main/shim/l2cap.h +12 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,17 @@ class L2cap { uint16_t ConvertClientToRealPsm(uint16_t psm); void RemoveClientPsm(uint16_t client_psm); void Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info, bool enable_snoop); uint16_t Connect(uint16_t psm, const RawAddress& raw_address); bool Write(uint16_t cid, BT_HDR* bt_hdr); bool WriteFlushable(uint16_t cid, BT_HDR* bt_hdr); bool WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr); bool IsCongested(uint16_t cid) const; bool SetCallbacks(uint16_t cid, const tL2CAP_APPL_INFO* client_callbacks); void ClearCallbacks(uint16_t cid); private: uint16_t GetNextVirtualPsm(uint16_t real_psm); Loading @@ -71,6 +82,7 @@ class L2cap { uint16_t classic_virtual_psm_; std::unordered_map<uint16_t, uint16_t> client_psm_to_real_psm_map_; std::unordered_map<uint16_t, const tL2CAP_APPL_INFO*> cid_to_callback_map_; }; } // namespace shim Loading Loading
system/main/shim/entry.cc +4 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ bluetooth::shim::IHciLayer* bluetooth::shim::GetHciLayer() { return GetGabeldorscheStack()->GetHciLayer(); } bluetooth::shim::IL2cap* bluetooth::shim::GetL2cap() { return GetGabeldorscheStack()->GetL2cap(); } bluetooth::shim::IPage* bluetooth::shim::GetPage() { return GetGabeldorscheStack()->GetPage(); }
system/main/shim/entry.h +1 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ bluetooth::shim::IDiscoverability* GetDiscoverability(); bluetooth::shim::IConnectability* GetConnectability(); bluetooth::shim::IInquiry* GetInquiry(); bluetooth::shim::IHciLayer* GetHciLayer(); bluetooth::shim::IL2cap* GetL2cap(); bluetooth::shim::IPage* GetPage(); } // namespace shim Loading
system/main/shim/l2c_api.cc +160 −114 Original line number Diff line number Diff line Loading @@ -23,18 +23,21 @@ static bluetooth::shim::L2cap shim_l2cap; /** * Classic Service Registration APIs */ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, tL2CAP_APPL_INFO* p_cb_info, tL2CAP_APPL_INFO* callbacks, bool enable_snoop) { if (L2C_INVALID_PSM(client_psm)) { LOG_ERROR(LOG_TAG, "%s Invalid classic psm:0x%04x", __func__, client_psm); return 0; } if ((p_cb_info->pL2CA_ConfigCfm_Cb == nullptr) || (p_cb_info->pL2CA_ConfigInd_Cb == nullptr) || (p_cb_info->pL2CA_DataInd_Cb == nullptr) || (p_cb_info->pL2CA_DisconnectInd_Cb == nullptr)) { if ((callbacks->pL2CA_ConfigCfm_Cb == nullptr) || (callbacks->pL2CA_ConfigInd_Cb == nullptr) || (callbacks->pL2CA_DataInd_Cb == nullptr) || (callbacks->pL2CA_DisconnectInd_Cb == nullptr)) { LOG_ERROR(LOG_TAG, "%s Invalid classic callbacks psm:0x%04x", __func__, client_psm); return 0; Loading @@ -43,7 +46,7 @@ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, /** * Check if this is a registration for an outgoing-only connection. */ bool is_outgoing_connection_only = p_cb_info->pL2CA_ConnectInd_Cb == nullptr; bool is_outgoing_connection_only = callbacks->pL2CA_ConnectInd_Cb == nullptr; uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm, is_outgoing_connection_only); Loading @@ -53,13 +56,13 @@ uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm, __func__, client_psm, psm); return 0; } shim_l2cap.Classic().RegisterPsm(psm, p_cb_info); shim_l2cap.Classic().RegisterPsm(psm, callbacks); LOG_INFO(LOG_TAG, "%s classic client_psm:0x%04x psm:0x%04x", __func__, client_psm, psm); // TODO(cmanton) Register this service with GD // TODO(cmanton) Fake out a config negotiator shim_l2cap.Register(psm, callbacks, enable_snoop); return psm; } Loading Loading @@ -107,23 +110,68 @@ void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) { shim_l2cap.Le().DeallocatePsm(psm); } /** * Classic Connection Oriented Channel APIS */ uint16_t bluetooth::shim::L2CA_ErtmConnectReq(uint16_t psm, const RawAddress& p_bd_addr, const RawAddress& raw_address, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd addr:%s p_ertm_info:%p", __func__, psm, p_bd_addr.ToString().c_str(), p_ertm_info); return 0; CHECK(p_ertm_info == nullptr) << "UNIMPLEMENTED set enhanced retransmission mode config"; return shim_l2cap.Connect(psm, raw_address); } uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { return bluetooth::shim::L2CA_ErtmConnectReq(psm, p_bd_addr, nullptr); const RawAddress& raw_address) { return bluetooth::shim::L2CA_ErtmConnectReq(psm, raw_address, nullptr); } bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd " "p_ertm_info:%p", __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status, p_ertm_info); return false; } bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status) { return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL); } bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; } bool bluetooth::shim::L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; } bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; } bool bluetooth::shim::L2CA_DisconnectRsp(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; } /** * Le Connection Oriented Channel APIs */ uint16_t bluetooth::shim::L2CA_RegisterLECoc(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd p_cb_info:%p", __func__, psm, p_cb_info); tL2CAP_APPL_INFO* callbacks) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd callbacks:%p", __func__, psm, callbacks); return 0; } Loading Loading @@ -158,52 +206,51 @@ bool bluetooth::shim::L2CA_GetPeerLECocConfig(uint16_t lcid, return false; } /** * Channel Data Writes */ bool bluetooth::shim::L2CA_SetConnectionCallbacks( uint16_t local_cid, const tL2CAP_APPL_INFO* callbacks) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s lcid:%hd callbacks:%p", __func__, local_cid, callbacks); return false; } bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status, tL2CAP_ERTM_INFO* p_ertm_info) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd " "p_ertm_info:%p", __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status, p_ertm_info); return false; uint16_t cid, const tL2CAP_APPL_INFO* callbacks) { return shim_l2cap.SetCallbacks(cid, callbacks); } bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid, uint16_t result, uint16_t status) { return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL); uint8_t bluetooth::shim::L2CA_DataWriteEx(uint16_t cid, BT_HDR* bt_hdr, uint16_t flags) { if (shim_l2cap.IsCongested(cid)) { return L2CAP_DW_CONGESTED; } bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; bool write_success = false; switch (flags) { case L2CAP_FLUSHABLE_CH_BASED: write_success = shim_l2cap.Write(cid, bt_hdr); break; case L2CAP_FLUSHABLE_PKT: write_success = shim_l2cap.WriteFlushable(cid, bt_hdr); break; case L2CAP_NON_FLUSHABLE_PKT: write_success = shim_l2cap.WriteNonFlushable(cid, bt_hdr); break; } bool bluetooth::shim::L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd p_cfg:%p", __func__, cid, p_cfg); return false; return write_success ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED; } bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { return bluetooth::shim::L2CA_DataWriteEx(cid, p_data, L2CAP_FLUSHABLE_CH_BASED); } bool bluetooth::shim::L2CA_DisconnectRsp(uint16_t cid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s cid:%hd ", __func__, cid); return false; /** * L2cap Layer APIs */ uint8_t bluetooth::shim::L2CA_SetDesireRole(uint8_t new_role) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Ping APIs */ bool bluetooth::shim::L2CA_Ping(const RawAddress& p_bd_addr, tL2CA_ECHO_RSP_CB* p_callback) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s p_callback:%p", __func__, Loading @@ -218,18 +265,9 @@ bool bluetooth::shim::L2CA_Echo(const RawAddress& p_bd_addr, BT_HDR* p_data, return false; } bool bluetooth::shim::L2CA_GetIdentifiers(uint16_t lcid, uint16_t* rcid, uint16_t* handle) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout, bool is_global) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } /** * Link APIs */ bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout, tBT_TRANSPORT transport) { Loading @@ -237,11 +275,6 @@ bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, return false; } uint8_t bluetooth::shim::L2CA_SetDesireRole(uint8_t new_role) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } uint16_t bluetooth::shim::L2CA_LocalLoopbackReq(uint16_t psm, uint16_t handle, const RawAddress& p_bd_addr) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading @@ -254,30 +287,6 @@ bool bluetooth::shim::L2CA_SetAclPriority(const RawAddress& bd_addr, return false; } bool bluetooth::shim::L2CA_FlowControl(uint16_t cid, bool data_enabled) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SendTestSFrame(uint16_t cid, uint8_t sup_type, uint8_t back_track) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetChnlDataRate(uint16_t cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetFlushTimeout(const RawAddress& bd_addr, uint16_t flush_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading @@ -297,11 +306,9 @@ bool bluetooth::shim::L2CA_GetBDAddrbyHandle(uint16_t handle, return false; } uint8_t bluetooth::shim::L2CA_GetChnlFcrMode(uint16_t lcid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Fixed Channel APIs */ bool bluetooth::shim::L2CA_RegisterFixedChannel(uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); Loading Loading @@ -334,13 +341,9 @@ bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t fixed_cid, return false; } bool bluetooth::shim::L2CA_SetFixedChannelTout(const RawAddress& rem_bda, uint16_t fixed_cid, uint16_t idle_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } /** * Channel Configuration API */ bool bluetooth::shim::L2CA_GetCurrentConfig( uint16_t lcid, tL2CAP_CFG_INFO** pp_our_cfg, tL2CAP_CH_CFG_BITS* p_our_cfg_bits, tL2CAP_CFG_INFO** pp_peer_cfg, Loading @@ -356,25 +359,59 @@ bool bluetooth::shim::L2CA_GetConnectionConfig(uint16_t lcid, uint16_t* mtu, return false; } bool bluetooth::shim::L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda) { /** * Channel hygiene APIs */ bool bluetooth::shim::L2CA_GetIdentifiers(uint16_t lcid, uint16_t* rcid, uint16_t* handle) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { bool bluetooth::shim::L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout, bool is_global) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_FlowControl(uint16_t cid, bool data_enabled) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SendTestSFrame(uint16_t cid, uint8_t sup_type, uint8_t back_track) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } bool bluetooth::shim::L2CA_SetChnlDataRate(uint16_t cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_GetChnlFcrMode(uint16_t lcid) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { bool bluetooth::shim::L2CA_SetFixedChannelTout(const RawAddress& rem_bda, uint16_t fixed_cid, uint16_t idle_tout) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } uint8_t bluetooth::shim::L2CA_DataWriteEx(uint16_t cid, BT_HDR* p_data, uint16_t flags) { bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; } Loading @@ -384,3 +421,12 @@ uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid, LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return 0; } /** * Misc APIs */ bool bluetooth::shim::L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__); return false; }
system/main/shim/l2cap.cc +96 −0 Original line number Diff line number Diff line Loading @@ -13,8 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "bt_shim_l2cap" #include "main/shim/l2cap.h" #include "main/shim/entry.h" #include "main/shim/shim.h" #include "osi/include/allocator.h" #include "osi/include/log.h" constexpr size_t kBtHdrSize = sizeof(BT_HDR); bool bluetooth::shim::PsmData::IsPsmAllocated(uint16_t psm) const { return psm_to_callback_map.find(psm) != psm_to_callback_map.end(); Loading Loading @@ -115,3 +122,92 @@ uint16_t bluetooth::shim::L2cap::GetNextDynamicClassicPsm() { } return classic_dynamic_psm_; } void bluetooth::shim::L2cap::Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info, bool enable_snoop) { LOG_DEBUG(LOG_TAG, "Registering service psm:%hd", psm); std::chrono::system_clock::time_point two_seconds = std::chrono::system_clock::now() + std::chrono::seconds(2); std::promise<void> register_completed; auto completed = register_completed.get_future(); bluetooth::shim::GetL2cap()->RegisterService(psm, enable_snoop, std::move(register_completed)); completed.wait(); if (std::future_status::ready != completed.wait_until(two_seconds)) { LOG_WARN(LOG_TAG, "Timed out registering service to psm:%hd", psm); } } uint16_t bluetooth::shim::L2cap::Connect(uint16_t psm, const RawAddress& raw_address) { LOG_DEBUG(LOG_TAG, "Requesting connection to psm:%hd address:%s", psm, raw_address.ToString().c_str()); std::chrono::system_clock::time_point two_seconds = std::chrono::system_clock::now() + std::chrono::seconds(2); std::promise<uint16_t> connect_completed; auto completed = connect_completed.get_future(); bluetooth::shim::GetL2cap()->Connect(psm, raw_address.ToString(), std::move(connect_completed)); if (std::future_status::ready == completed.wait_until(two_seconds)) { return completed.get(); } LOG_WARN(LOG_TAG, "Timed out connecting to psm:%hd address:%s", psm, raw_address.ToString().c_str()); return 0; } bool bluetooth::shim::L2cap::IsCongested(uint16_t cid) const { LOG_WARN(LOG_TAG, "UNIMPLEMENTED checking congestion on a channel"); return false; } bool bluetooth::shim::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->Write(cid, data, len); } bool bluetooth::shim::L2cap::WriteFlushable(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->WriteFlushable(cid, data, len); } bool bluetooth::shim::L2cap::WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr) { const uint8_t* data = bt_hdr->data + bt_hdr->offset; size_t len = bt_hdr->len; return bluetooth::shim::GetL2cap()->WriteNonFlushable(cid, data, len); } bool bluetooth::shim::L2cap::SetCallbacks(uint16_t cid, const tL2CAP_APPL_INFO* callbacks) { LOG_ASSERT(cid_to_callback_map_.find(cid) != cid_to_callback_map_.end()) << "Registering multiple channel callbacks cid:" << cid; cid_to_callback_map_[cid] = callbacks; bluetooth::shim::GetL2cap()->SetOnReadDataReady( cid, [this](uint16_t cid, std::vector<const uint8_t> data) { LOG_INFO(LOG_TAG, "Got data on cid:%hd len:%zd", cid, data.size()); BT_HDR* bt_hdr = static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize)); std::copy(data.begin(), data.end(), bt_hdr->data); bt_hdr->len = data.size(); cid_to_callback_map_[cid]->pL2CA_DataInd_Cb(cid, bt_hdr); }); bluetooth::shim::GetL2cap()->SetOnClose(cid, [this, &cid](int error_code) { LOG_DEBUG(LOG_TAG, "Channel closed cid:%hd", cid); cid_to_callback_map_[cid]->pL2CA_DisconnectInd_Cb(cid, true); }); return true; } void bluetooth::shim::L2cap::ClearCallbacks(uint16_t cid) { LOG_ASSERT(cid_to_callback_map_.find(cid) == cid_to_callback_map_.end()) << "Clearing callbacks that do not exist cid:" << cid; cid_to_callback_map_.erase(cid); }
system/main/shim/l2cap.h +12 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,17 @@ class L2cap { uint16_t ConvertClientToRealPsm(uint16_t psm); void RemoveClientPsm(uint16_t client_psm); void Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info, bool enable_snoop); uint16_t Connect(uint16_t psm, const RawAddress& raw_address); bool Write(uint16_t cid, BT_HDR* bt_hdr); bool WriteFlushable(uint16_t cid, BT_HDR* bt_hdr); bool WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr); bool IsCongested(uint16_t cid) const; bool SetCallbacks(uint16_t cid, const tL2CAP_APPL_INFO* client_callbacks); void ClearCallbacks(uint16_t cid); private: uint16_t GetNextVirtualPsm(uint16_t real_psm); Loading @@ -71,6 +82,7 @@ class L2cap { uint16_t classic_virtual_psm_; std::unordered_map<uint16_t, uint16_t> client_psm_to_real_psm_map_; std::unordered_map<uint16_t, const tL2CAP_APPL_INFO*> cid_to_callback_map_; }; } // namespace shim Loading