Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ddfcbc7 authored by Chris Manton's avatar Chris Manton Committed by Gerrit Code Review
Browse files

Merge "Legacy portion of l2cap shim layer"

parents dfe199a2 8b78b0cf
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -9,8 +9,10 @@ filegroup {
        "bte_logmsg.cc",
        "bte_main.cc",
        "shim/controller.cc",
        "shim/hci_layer.cc",
        "shim/entry.cc",
        "shim/hci_layer.cc",
        "shim/l2c_api.cc",
        "shim/l2cap.cc",
        "shim/shim.cc",
        "stack_config.cc",
    ]
+386 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "bt_shim_l2cap"

#include "main/shim/l2c_api.h"
#include "main/shim/l2cap.h"
#include "main/shim/shim.h"
#include "osi/include/log.h"

static bluetooth::shim::L2cap shim_l2cap;

uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm,
                                        tL2CAP_APPL_INFO* p_cb_info,
                                        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)) {
    LOG_ERROR(LOG_TAG, "%s Invalid classic callbacks psm:0x%04x", __func__,
              client_psm);
    return 0;
  }

  /**
   * Check if this is a registration for an outgoing-only connection.
   */
  bool is_outgoing_connection_only = p_cb_info->pL2CA_ConnectInd_Cb == nullptr;
  uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm,
                                                   is_outgoing_connection_only);

  if (shim_l2cap.Classic().IsPsmRegistered(psm)) {
    LOG_ERROR(LOG_TAG,
              "%s Already registered classic client_psm:0x%04x psm:0x%04x",
              __func__, client_psm, psm);
    return 0;
  }
  shim_l2cap.Classic().RegisterPsm(psm, p_cb_info);

  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
  return psm;
}

void bluetooth::shim::L2CA_Deregister(uint16_t client_psm) {
  if (L2C_INVALID_PSM(client_psm)) {
    LOG_ERROR(LOG_TAG, "%s Invalid classic psm:0x%04x", __func__, client_psm);
    return;
  }
  uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm);

  if (!shim_l2cap.Classic().IsPsmRegistered(psm)) {
    LOG_ERROR(
        LOG_TAG,
        "%s Not previously registered classic client_psm:0x%04x psm:0x%04x",
        __func__, client_psm, psm);
    return;
  }
  shim_l2cap.Classic().UnregisterPsm(psm);
  shim_l2cap.RemoveClientPsm(client_psm);
}

uint16_t bluetooth::shim::L2CA_AllocatePSM(void) {
  uint16_t psm = shim_l2cap.GetNextDynamicClassicPsm();
  shim_l2cap.Classic().AllocatePsm(psm);
  return psm;
}

uint16_t bluetooth::shim::L2CA_AllocateLePSM(void) {
  uint16_t psm = shim_l2cap.GetNextDynamicLePsm();
  shim_l2cap.Le().AllocatePsm(psm);
  return psm;
}

void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) {
  if (!shim_l2cap.Le().IsPsmAllocated(psm)) {
    LOG_ERROR(LOG_TAG, "%s Not previously allocated le psm:0x%04x", __func__,
              psm);
    return;
  }
  if (!shim_l2cap.Le().IsPsmRegistered(psm)) {
    LOG_ERROR(LOG_TAG, "%s Must deregister psm before deallocation psm:0x%04x",
              __func__, psm);
    return;
  }
  shim_l2cap.Le().DeallocatePsm(psm);
}

uint16_t bluetooth::shim::L2CA_ErtmConnectReq(uint16_t psm,
                                              const RawAddress& p_bd_addr,
                                              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;
}

uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm,
                                          const RawAddress& p_bd_addr) {
  return bluetooth::shim::L2CA_ErtmConnectReq(psm, p_bd_addr, nullptr);
}

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);
  return 0;
}

void bluetooth::shim::L2CA_DeregisterLECoc(uint16_t psm) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd", __func__, psm);
}

uint16_t bluetooth::shim::L2CA_ConnectLECocReq(uint16_t psm,
                                               const RawAddress& p_bd_addr,
                                               tL2CAP_LE_CFG_INFO* p_cfg) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s psm:%hd addr:%s p_cfg:%p", __func__, psm,
           p_bd_addr.ToString().c_str(), p_cfg);
  return 0;
}

bool bluetooth::shim::L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr,
                                           uint8_t id, uint16_t lcid,
                                           uint16_t result, uint16_t status,
                                           tL2CAP_LE_CFG_INFO* p_cfg) {
  LOG_INFO(LOG_TAG,
           "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd "
           "p_cfg:%p",
           __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status,
           p_cfg);
  return false;
}

bool bluetooth::shim::L2CA_GetPeerLECocConfig(uint16_t lcid,
                                              tL2CAP_LE_CFG_INFO* peer_cfg) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s lcid:%hd peer_cfg:%p", __func__, lcid,
           peer_cfg);
  return false;
}

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;
}

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;
}

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__,
           p_bd_addr.ToString().c_str(), p_callback);
  return false;
}

bool bluetooth::shim::L2CA_Echo(const RawAddress& p_bd_addr, BT_HDR* p_data,
                                tL2CA_ECHO_DATA_CB* p_callback) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s addr:%s p_callback:%p", __func__,
           p_bd_addr.ToString().c_str(), p_callback);
  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;
}

bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr,
                                                  uint16_t timeout,
                                                  tBT_TRANSPORT transport) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  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__);
  return 0;
}

bool bluetooth::shim::L2CA_SetAclPriority(const RawAddress& bd_addr,
                                          uint8_t priority) {
  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;
}

bool bluetooth::shim::L2CA_SetFlushTimeout(const RawAddress& bd_addr,
                                           uint16_t flush_tout) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_GetPeerFeatures(const RawAddress& bd_addr,
                                           uint32_t* p_ext_feat,
                                           uint8_t* p_chnl_mask) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_GetBDAddrbyHandle(uint16_t handle,
                                             RawAddress& bd_addr) {
  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_RegisterFixedChannel(uint16_t fixed_cid,
                                                tL2CAP_FIXED_CHNL_REG* p_freg) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_ConnectFixedChnl(uint16_t fixed_cid,
                                            const RawAddress& rem_bda) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_ConnectFixedChnl(uint16_t fixed_cid,
                                            const RawAddress& rem_bda,
                                            uint8_t initiating_phys) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

uint16_t bluetooth::shim::L2CA_SendFixedChnlData(uint16_t fixed_cid,
                                                 const RawAddress& rem_bda,
                                                 BT_HDR* p_buf) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return 0;
}

bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t fixed_cid,
                                           const RawAddress& rem_bda) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  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;
}

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,
    tL2CAP_CH_CFG_BITS* p_peer_cfg_bits) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_GetConnectionConfig(uint16_t lcid, uint16_t* mtu,
                                               uint16_t* rcid,
                                               uint16_t* handle) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

bool bluetooth::shim::L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb,
                                         const RawAddress& p_bda) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return 0;
}

bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid,
                                               bool is_flushable) {
  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) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return false;
}

uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid,
                                            uint16_t num_to_flush) {
  LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s", __func__);
  return 0;
}
+874 −0

File added.

Preview size limit exceeded, changes collapsed.

+117 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "main/shim/l2cap.h"

bool bluetooth::shim::PsmData::IsPsmAllocated(uint16_t psm) const {
  return psm_to_callback_map.find(psm) != psm_to_callback_map.end();
}

bool bluetooth::shim::PsmData::IsPsmRegistered(uint16_t psm) const {
  return IsPsmAllocated(psm) && psm_to_callback_map.at(psm) != nullptr;
}

void bluetooth::shim::PsmData::AllocatePsm(uint16_t psm) {
  RegisterPsm(psm, nullptr);
}

void bluetooth::shim::PsmData::RegisterPsm(uint16_t psm,
                                           const tL2CAP_APPL_INFO* callbacks) {
  psm_to_callback_map[psm] = callbacks;
}

void bluetooth::shim::PsmData::UnregisterPsm(uint16_t psm) {
  psm_to_callback_map[psm] = nullptr;
}

void bluetooth::shim::PsmData::DeallocatePsm(uint16_t psm) {
  psm_to_callback_map.erase(psm);
}

bluetooth::shim::L2cap::L2cap()
    : classic_dynamic_psm_(kInitialClassicDynamicPsm),
      le_dynamic_psm_(kInitialLeDynamicPsm),
      classic_virtual_psm_(kInitialClassicVirtualPsm) {}

bluetooth::shim::PsmData& bluetooth::shim::L2cap::Le() { return le_; }

bluetooth::shim::PsmData& bluetooth::shim::L2cap::Classic() { return classic_; }

uint16_t bluetooth::shim::L2cap::ConvertClientToRealPsm(
    uint16_t client_psm, bool is_outgoing_only_connection) {
  if (!is_outgoing_only_connection) {
    return client_psm;
  }
  return GetNextVirtualPsm(client_psm);
}

uint16_t bluetooth::shim::L2cap::ConvertClientToRealPsm(uint16_t client_psm) {
  if (client_psm_to_real_psm_map_.find(client_psm) ==
      client_psm_to_real_psm_map_.end()) {
    return client_psm;
  }
  return client_psm_to_real_psm_map_.at(client_psm);
}

void bluetooth::shim::L2cap::RemoveClientPsm(uint16_t client_psm) {
  if (client_psm_to_real_psm_map_.find(client_psm) !=
      client_psm_to_real_psm_map_.end()) {
    client_psm_to_real_psm_map_.erase(client_psm);
  }
}

uint16_t bluetooth::shim::L2cap::GetNextVirtualPsm(uint16_t real_psm) {
  if (real_psm < kInitialClassicDynamicPsm) {
    return real_psm;
  }

  while (Classic().IsPsmAllocated(classic_virtual_psm_)) {
    classic_virtual_psm_ += 2;
    if (classic_virtual_psm_ >= kFinalClassicVirtualPsm) {
      classic_virtual_psm_ = kInitialClassicVirtualPsm;
    }
  }
  return classic_virtual_psm_;
}

uint16_t bluetooth::shim::L2cap::GetNextDynamicLePsm() {
  while (Le().IsPsmAllocated(le_dynamic_psm_)) {
    le_dynamic_psm_++;
    if (le_dynamic_psm_ > kFinalLeDynamicPsm) {
      le_dynamic_psm_ = kInitialLeDynamicPsm;
    }
  }
  return le_dynamic_psm_;
}

uint16_t bluetooth::shim::L2cap::GetNextDynamicClassicPsm() {
  while (Classic().IsPsmAllocated(classic_dynamic_psm_)) {
    classic_dynamic_psm_ += 2;
    if (classic_dynamic_psm_ > kFinalClassicDynamicPsm) {
      classic_dynamic_psm_ = kInitialClassicDynamicPsm;
    } else if (classic_dynamic_psm_ & 0x0100) {
      /* the upper byte must be even */
      classic_dynamic_psm_ += 0x0100;
    }

    /* if psm is in range of reserved BRCM Aware features */
    if ((BRCM_RESERVED_PSM_START <= classic_dynamic_psm_) &&
        (classic_dynamic_psm_ <= BRCM_RESERVED_PSM_END)) {
      classic_dynamic_psm_ = BRCM_RESERVED_PSM_END + 2;
    }
  }
  return classic_dynamic_psm_;
}
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>
#include <unordered_map>

#include "stack/include/l2c_api.h"

namespace bluetooth {
namespace shim {

static constexpr uint16_t kInitialClassicDynamicPsm = 0x1001;
static constexpr uint16_t kFinalClassicDynamicPsm = 0xfeff;
static constexpr uint16_t kInitialClassicVirtualPsm = kInitialClassicDynamicPsm;
static constexpr uint16_t kFinalClassicVirtualPsm = 0x8000;
static constexpr uint16_t kInitialLeDynamicPsm = 0x0080;
static constexpr uint16_t kFinalLeDynamicPsm = 0x00ff;

using PsmData = struct {
  bool IsPsmAllocated(uint16_t psm) const;
  bool IsPsmRegistered(uint16_t psm) const;

  void AllocatePsm(uint16_t psm);
  void RegisterPsm(uint16_t psm, const tL2CAP_APPL_INFO* callbacks);

  void UnregisterPsm(uint16_t psm);
  void DeallocatePsm(uint16_t psm);

 private:
  std::unordered_map<uint16_t, const tL2CAP_APPL_INFO*> psm_to_callback_map;
};

class L2cap {
 public:
  L2cap();

  PsmData& Classic();
  PsmData& Le();

  uint16_t GetNextDynamicClassicPsm();
  uint16_t GetNextDynamicLePsm();

  uint16_t ConvertClientToRealPsm(uint16_t psm,
                                  bool is_outgoing_only_connection);
  uint16_t ConvertClientToRealPsm(uint16_t psm);
  void RemoveClientPsm(uint16_t client_psm);

 private:
  uint16_t GetNextVirtualPsm(uint16_t real_psm);

  PsmData classic_;
  PsmData le_;

  uint16_t classic_dynamic_psm_;
  uint16_t le_dynamic_psm_;
  uint16_t classic_virtual_psm_;

  std::unordered_map<uint16_t, uint16_t> client_psm_to_real_psm_map_;
};

}  // namespace shim
}  // namespace bluetooth
Loading