Home | History | Annotate | Download | only in mcap_tool
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include <cstring>
     17 
     18 #include <base/logging.h>
     19 
     20 #include "mca_api.h"
     21 #include "mca_defs.h"
     22 #include "mcap_test_mcl.h"
     23 
     24 namespace SYSTEM_BT_TOOLS_MCAP_TOOL {
     25 
     26 McapMcl::McapMcl(btmcap_test_interface_t* mcap_test_interface,
     27                  tMCA_HANDLE mcap_handle, const RawAddress& peer_bd_addr)
     28     : _mdl_list() {
     29   _mcap_handle = mcap_handle;
     30   _mcap_test_interface = mcap_test_interface;
     31   memcpy(_peer_bd_addr.address, peer_bd_addr.address,
     32          sizeof(_peer_bd_addr.address));
     33 }
     34 
     35 bool McapMcl::Connect(uint16_t ctrl_psm, uint16_t sec_mask) {
     36   tMCA_RESULT ret = _mcap_test_interface->connect_mcl(
     37       _mcap_handle, _peer_bd_addr, ctrl_psm, sec_mask);
     38   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
     39   return ret == MCA_SUCCESS;
     40 }
     41 
     42 bool McapMcl::Disconnect() {
     43   if (!IsConnected()) {
     44     LOG(ERROR) << "MCL is not connected";
     45     return false;
     46   }
     47   tMCA_RESULT ret = _mcap_test_interface->disconnect_mcl(_mcl_handle);
     48   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
     49   return ret == MCA_SUCCESS;
     50 }
     51 
     52 McapMdl* McapMcl::AllocateMdl(tMCA_DEP mdep_handle, uint16_t mdl_id,
     53                               uint8_t dep_id, uint8_t cfg) {
     54   if (!IsConnected()) {
     55     LOG(ERROR) << "MCL is not connected";
     56     return nullptr;
     57   }
     58   if (FindMdlById(mdl_id) != nullptr) {
     59     LOG(ERROR) << "mdl_id=" << mdl_id << "already exists";
     60     return nullptr;
     61   }
     62   if (!HasAvailableMdl()) {
     63     LOG(ERROR) << "No more avaible MDL, currently " << _mdl_list.size();
     64     return nullptr;
     65   }
     66   _mdl_list.push_back(McapMdl(_mcap_test_interface, _mcl_handle, mdep_handle,
     67                               mdl_id, dep_id, cfg));
     68   return &_mdl_list[_mdl_list.size() - 1];
     69 }
     70 
     71 bool McapMcl::CreateMdl(tMCA_DEP mdep_handle, uint16_t data_psm,
     72                         uint16_t mdl_id, uint8_t peer_dep_id, uint8_t cfg,
     73                         bool should_connect) {
     74   if (!IsConnected()) {
     75     LOG(ERROR) << "MCL is not connected";
     76     return false;
     77   }
     78   McapMdl* mcap_mdl = FindMdlById(mdl_id);
     79   if (!mcap_mdl) {
     80     LOG(INFO) << "mdl_id=" << mdl_id << "does not exists, creating new one";
     81     mcap_mdl = AllocateMdl(mdep_handle, mdl_id, peer_dep_id, cfg);
     82     if (!mcap_mdl) {
     83       return false;
     84     }
     85   }
     86   if (mcap_mdl->IsConnected()) {
     87     LOG(ERROR) << "mdl_id=" << mdl_id << "is already connected with handle "
     88                << (int)mcap_mdl->GetHandle();
     89     return false;
     90   }
     91   return mcap_mdl->Create(data_psm, should_connect);
     92 }
     93 
     94 bool McapMcl::DataChannelConfig() {
     95   tMCA_RESULT ret = _mcap_test_interface->data_channel_config(
     96       _mcl_handle, get_test_channel_config());
     97   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
     98   return ret == MCA_SUCCESS;
     99 }
    100 
    101 bool McapMcl::CreateMdlResponse(tMCA_DEP mdep_handle, uint16_t mdl_id,
    102                                 uint8_t my_dep_id, uint8_t cfg) {
    103   if (!IsConnected()) {
    104     LOG(ERROR) << "MCL is not connected";
    105     return false;
    106   }
    107   McapMdl* mcap_mdl = FindMdlById(mdl_id);
    108   if (!mcap_mdl) {
    109     LOG(INFO) << "mdl_id=" << mdl_id << " does not exists, creating new one";
    110     mcap_mdl = AllocateMdl(mdep_handle, mdl_id, my_dep_id, cfg);
    111     if (!mcap_mdl) {
    112       LOG(ERROR) << "MDL cannot be created";
    113       return false;
    114     }
    115   }
    116   if (mcap_mdl->IsConnected()) {
    117     LOG(INFO) << "mdl_id=" << mdl_id << " is already connected with handle "
    118               << (int)mcap_mdl->GetHandle() << ", updating context";
    119     mcap_mdl->UpdateContext(mdep_handle, my_dep_id, cfg);
    120   }
    121   return mcap_mdl->CreateResponse();
    122 }
    123 
    124 bool McapMcl::AbortMdl() {
    125   tMCA_RESULT ret = _mcap_test_interface->abort_mdl(_mcl_handle);
    126   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
    127   return ret == MCA_SUCCESS;
    128 }
    129 
    130 bool McapMcl::DeleteMdl(uint16_t mdl_id) {
    131   tMCA_RESULT ret = _mcap_test_interface->delete_mdl(_mcl_handle, mdl_id);
    132   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
    133   return ret == MCA_SUCCESS;
    134 }
    135 
    136 RawAddress& McapMcl::GetPeerAddress() { return _peer_bd_addr; }
    137 
    138 void McapMcl::SetHandle(tMCA_CL handle) { _mcl_handle = handle; }
    139 
    140 tMCA_CL McapMcl::GetHandle() const { return _mcl_handle; }
    141 
    142 void McapMcl::SetMtu(uint16_t mtu) { _control_mtu = mtu; }
    143 
    144 uint16_t McapMcl::GetMtu() { return _control_mtu; }
    145 
    146 McapMdl* McapMcl::FindMdlById(uint16_t mdl_id) {
    147   for (McapMdl& mdl : _mdl_list) {
    148     if (mdl.GetId() == mdl_id) {
    149       return &mdl;
    150     }
    151   }
    152   return nullptr;
    153 }
    154 
    155 McapMdl* McapMcl::FindMdlByHandle(tMCA_DL mdl_handle) {
    156   for (McapMdl& mdl : _mdl_list) {
    157     if (mdl.GetHandle() == mdl_handle) {
    158       return &mdl;
    159     }
    160   }
    161   return nullptr;
    162 }
    163 
    164 void McapMcl::RemoveAllMdl() { _mdl_list.clear(); }
    165 
    166 void McapMcl::RemoveMdl(uint16_t mdl_id) {
    167   LOG(INFO) << "Removing MDL id " << (int)mdl_id;
    168   for (std::vector<McapMdl>::iterator it = _mdl_list.begin();
    169        it != _mdl_list.end(); ++it) {
    170     if (it->GetId() == mdl_id) {
    171       _mdl_list.erase(it);
    172       LOG(INFO) << "Removed MDL id " << (int)mdl_id;
    173       return;
    174     }
    175   }
    176 }
    177 
    178 void McapMcl::ResetAllMdl() {
    179   for (McapMdl& mcap_mdl : _mdl_list) {
    180     mcap_mdl.SetHandle(0);
    181     mcap_mdl.SetMtu(0);
    182     mcap_mdl.SetResponseCode(-1);
    183   }
    184 }
    185 
    186 void McapMcl::ResetMdl(uint16_t mdl_id) {
    187   LOG(INFO) << "Closing MDL id " << (int)mdl_id;
    188   McapMdl* mcap_mdl = FindMdlById(mdl_id);
    189   if (!mcap_mdl) {
    190     LOG(ERROR) << "Cannot find MDL for id " << (int)mdl_id;
    191     return;
    192   }
    193   if (mcap_mdl->IsConnected()) {
    194     LOG(ERROR) << "MDL " << (int)mdl_id << " is still connected";
    195     return;
    196   }
    197   mcap_mdl->SetHandle(0);
    198   mcap_mdl->SetMtu(0);
    199   mcap_mdl->SetResponseCode(-1);
    200 }
    201 
    202 bool McapMcl::IsConnected() { return _mcl_handle > 0; }
    203 
    204 int McapMcl::ConnectedMdlCount() {
    205   int count = 0;
    206   for (McapMdl& mcap_mdl : _mdl_list) {
    207     if (mcap_mdl.IsConnected()) {
    208       count++;
    209     }
    210   }
    211   return count;
    212 }
    213 
    214 bool McapMcl::HasAvailableMdl() { return ConnectedMdlCount() < MCA_NUM_MDLS; }
    215 
    216 }  // namespace SYSTEM_BT_TOOLS_MCAP_TOOL
    217