• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "mcap_test_app.h"
17 #include "mca_defs.h"
18 
19 namespace SYSTEM_BT_TOOLS_MCAP_TOOL {
20 
21 #define CASE_RETURN_STR(const) \
22   case const:                  \
23     return #const;
24 
dump_mcap_events(const uint8_t event)25 static const char* dump_mcap_events(const uint8_t event) {
26   switch (event) {
27     CASE_RETURN_STR(MCA_ERROR_RSP_EVT)
28     CASE_RETURN_STR(MCA_CREATE_IND_EVT)
29     CASE_RETURN_STR(MCA_CREATE_CFM_EVT)
30     CASE_RETURN_STR(MCA_RECONNECT_IND_EVT)
31     CASE_RETURN_STR(MCA_RECONNECT_CFM_EVT)
32     CASE_RETURN_STR(MCA_ABORT_IND_EVT)
33     CASE_RETURN_STR(MCA_ABORT_CFM_EVT)
34     CASE_RETURN_STR(MCA_DELETE_IND_EVT)
35     CASE_RETURN_STR(MCA_DELETE_CFM_EVT)
36     CASE_RETURN_STR(MCA_SYNC_CAP_IND_EVT)
37     CASE_RETURN_STR(MCA_SYNC_CAP_CFM_EVT)
38     CASE_RETURN_STR(MCA_SYNC_SET_IND_EVT)
39     CASE_RETURN_STR(MCA_SYNC_SET_CFM_EVT)
40     CASE_RETURN_STR(MCA_SYNC_INFO_IND_EVT)
41     CASE_RETURN_STR(MCA_CONNECT_IND_EVT)
42     CASE_RETURN_STR(MCA_DISCONNECT_IND_EVT)
43     CASE_RETURN_STR(MCA_OPEN_IND_EVT)
44     CASE_RETURN_STR(MCA_OPEN_CFM_EVT)
45     CASE_RETURN_STR(MCA_CLOSE_IND_EVT)
46     CASE_RETURN_STR(MCA_CLOSE_CFM_EVT)
47     CASE_RETURN_STR(MCA_CONG_CHG_EVT)
48     CASE_RETURN_STR(MCA_RSP_TOUT_IND_EVT)
49     default:
50       return "Unknown event";
51   }
52 }
53 
print_mcap_event(const tMCA_DISCONNECT_IND * mcap_disconnect_ind)54 static void print_mcap_event(const tMCA_DISCONNECT_IND* mcap_disconnect_ind) {
55   printf("%s: peer_bd_addr=%s,l2cap_disconnect_reason=0x%04x\n", __func__,
56          mcap_disconnect_ind->bd_addr.ToString().c_str(),
57          mcap_disconnect_ind->reason);
58 }
59 
print_mcap_event(const tMCA_CONNECT_IND * mcap_connect_ind)60 static void print_mcap_event(const tMCA_CONNECT_IND* mcap_connect_ind) {
61   printf("%s: peer_bd_addr=%s, peer_mtu=%d \n", __func__,
62          mcap_connect_ind->bd_addr.ToString().c_str(), mcap_connect_ind->mtu);
63 }
64 
print_mcap_event(const tMCA_RSP_EVT * mcap_rsp)65 static void print_mcap_event(const tMCA_RSP_EVT* mcap_rsp) {
66   printf("%s: response, mdl_id=%d, op_code=0x%02x, rsp_code=0x%02x\n", __func__,
67          mcap_rsp->mdl_id, mcap_rsp->op_code, mcap_rsp->rsp_code);
68 }
69 
print_mcap_event(const tMCA_EVT_HDR * mcap_evt_hdr)70 static void print_mcap_event(const tMCA_EVT_HDR* mcap_evt_hdr) {
71   printf("%s: event, mdl_id=%d, op_code=0x%02x\n", __func__,
72          mcap_evt_hdr->mdl_id, mcap_evt_hdr->op_code);
73 }
74 
print_mcap_event(const tMCA_CREATE_IND * mcap_create_ind)75 static void print_mcap_event(const tMCA_CREATE_IND* mcap_create_ind) {
76   printf("%s: mdl_id=%d, op_code=0x%02x, dep_id=%d, cfg=0x%02x\n", __func__,
77          mcap_create_ind->mdl_id, mcap_create_ind->op_code,
78          mcap_create_ind->dep_id, mcap_create_ind->cfg);
79 }
80 
print_mcap_event(const tMCA_CREATE_CFM * mcap_create_cfm)81 static void print_mcap_event(const tMCA_CREATE_CFM* mcap_create_cfm) {
82   printf("%s: mdl_id=%d, op_code=0x%02x, rsp_code=%d, cfg=0x%02x\n", __func__,
83          mcap_create_cfm->mdl_id, mcap_create_cfm->op_code,
84          mcap_create_cfm->rsp_code, mcap_create_cfm->cfg);
85 }
86 
print_mcap_event(const tMCA_DL_OPEN * mcap_dl_open)87 static void print_mcap_event(const tMCA_DL_OPEN* mcap_dl_open) {
88   printf("%s: mdl_id=%d, mdl_handle=%d, mtu=%d\n", __func__,
89          mcap_dl_open->mdl_id, mcap_dl_open->mdl, mcap_dl_open->mtu);
90 }
91 
print_mcap_event(const tMCA_DL_CLOSE * mcap_dl_close)92 static void print_mcap_event(const tMCA_DL_CLOSE* mcap_dl_close) {
93   printf("%s: mdl_id=%d, mdl_handle=%d, l2cap_disconnect_reason=0x%04x\n",
94          __func__, mcap_dl_close->mdl_id, mcap_dl_close->mdl,
95          mcap_dl_close->reason);
96 }
97 
print_mcap_event(const tMCA_CONG_CHG * mcap_congestion_change)98 static void print_mcap_event(const tMCA_CONG_CHG* mcap_congestion_change) {
99   printf("%s: mdl_id=%d, mdl_handle=%d, congested=%d\n", __func__,
100          mcap_congestion_change->mdl_id, mcap_congestion_change->mdl,
101          mcap_congestion_change->cong);
102 }
103 
McapTestApp(btmcap_test_interface_t * mcap_test_interface)104 McapTestApp::McapTestApp(btmcap_test_interface_t* mcap_test_interface)
105     : _mcl_list(), _mdep_list() {
106   _mcap_test_interface = mcap_test_interface;
107 }
108 
GetInterface()109 btmcap_test_interface_t* McapTestApp::GetInterface() {
110   return _mcap_test_interface;
111 }
112 
Register(uint16_t ctrl_psm,uint16_t data_psm,uint16_t sec_mask,tMCA_CTRL_CBACK * callback)113 bool McapTestApp::Register(uint16_t ctrl_psm, uint16_t data_psm,
114                            uint16_t sec_mask, tMCA_CTRL_CBACK* callback) {
115   if (!callback) {
116     LOG(ERROR) << "callback is null";
117     return false;
118   }
119   _mca_reg.rsp_tout = 5000;
120   _mca_reg.ctrl_psm = ctrl_psm;
121   _mca_reg.data_psm = data_psm;
122   _mca_reg.sec_mask = sec_mask;
123   _mcap_handle =
124       _mcap_test_interface->register_application(&_mca_reg, callback);
125   return _mcap_handle > 0;
126 }
127 
Deregister()128 void McapTestApp::Deregister() {
129   _mcap_test_interface->deregister_application(_mcap_handle);
130   _mcap_handle = 0;
131 }
132 
Registered()133 bool McapTestApp::Registered() { return _mcap_handle > 0; }
134 
ConnectMcl(const RawAddress & bd_addr,uint16_t ctrl_psm,uint16_t sec_mask)135 bool McapTestApp::ConnectMcl(const RawAddress& bd_addr, uint16_t ctrl_psm,
136                              uint16_t sec_mask) {
137   if (!Registered()) {
138     LOG(ERROR) << "Application not registered";
139     return false;
140   }
141   McapMcl* mcap_mcl = FindMclByPeerAddress(bd_addr);
142   if (!mcap_mcl) {
143     LOG(INFO) << "MCL does not exist, creating new MCL";
144     _mcl_list.push_back(McapMcl(_mcap_test_interface, _mcap_handle, bd_addr));
145     mcap_mcl = &_mcl_list[_mcl_list.size() - 1];
146   }
147   if (mcap_mcl->GetHandle() != 0) {
148     LOG(ERROR) << "MCL is still active, cannot make another connection";
149     return false;
150   }
151   return mcap_mcl->Connect(ctrl_psm, sec_mask);
152 }
153 
CreateMdep(uint8_t type,uint8_t max_mdl,tMCA_DATA_CBACK * data_callback)154 bool McapTestApp::CreateMdep(uint8_t type, uint8_t max_mdl,
155                              tMCA_DATA_CBACK* data_callback) {
156   if (!data_callback) {
157     LOG(ERROR) << "Data callback is null";
158     return false;
159   }
160   _mdep_list.push_back(McapMdep(_mcap_test_interface, _mcap_handle, type,
161                                 max_mdl, data_callback));
162   return _mdep_list[_mdep_list.size() - 1].Create();
163 }
164 
GetHandle()165 uint8_t McapTestApp::GetHandle() { return _mcap_handle; }
166 
FindMclByPeerAddress(const RawAddress & bd_addr)167 McapMcl* McapTestApp::FindMclByPeerAddress(const RawAddress& bd_addr) {
168   for (McapMcl& mcl : _mcl_list) {
169     if (mcl.GetPeerAddress() == bd_addr) {
170       return &mcl;
171     }
172   }
173   return nullptr;
174 }
175 
FindMclByHandle(tMCA_CL mcl_handle)176 McapMcl* McapTestApp::FindMclByHandle(tMCA_CL mcl_handle) {
177   for (McapMcl& mcl : _mcl_list) {
178     if (mcl.GetHandle() == mcl_handle) {
179       return &mcl;
180     }
181   }
182   return nullptr;
183 }
184 
FindMdepByHandle(tMCA_DEP mdep_handle)185 McapMdep* McapTestApp::FindMdepByHandle(tMCA_DEP mdep_handle) {
186   for (McapMdep& mdep : _mdep_list) {
187     if (mdep.GetHandle() == mdep_handle) {
188       return &mdep;
189     }
190   }
191   return nullptr;
192 }
193 
RemoveMclByHandle(tMCA_CL mcl_handle)194 void McapTestApp::RemoveMclByHandle(tMCA_CL mcl_handle) {
195   LOG(INFO) << "Removing MCL handle " << (int)mcl_handle;
196   for (std::vector<McapMcl>::iterator it = _mcl_list.begin();
197        it != _mcl_list.end(); ++it) {
198     if (it->GetHandle() == mcl_handle) {
199       _mcl_list.erase(it);
200       LOG(INFO) << "Removed MCL handle " << (int)mcl_handle;
201       return;
202     }
203   }
204 }
205 
IsRegistered()206 bool McapTestApp::IsRegistered() { return _mcap_handle > 0; }
207 
ControlCallback(tMCA_HANDLE handle,tMCA_CL mcl,uint8_t event,tMCA_CTRL * p_data)208 void McapTestApp::ControlCallback(tMCA_HANDLE handle, tMCA_CL mcl,
209                                   uint8_t event, tMCA_CTRL* p_data) {
210   McapMcl* mcap_mcl = FindMclByHandle(mcl);
211   McapMdl* mcap_mdl = nullptr;
212   printf("%s: mcap_handle=%d, mcl_handle=%d, event=%s (0x%02x)\n", __func__,
213          handle, mcl, dump_mcap_events(event), event);
214   if (_mcap_handle != handle) {
215     LOG(ERROR) << "MCAP handle mismatch, self=" << _mcap_handle
216                << ", other=" << handle;
217     return;
218   }
219   switch (event) {
220     case MCA_ERROR_RSP_EVT:
221       print_mcap_event(&p_data->rsp);
222       break;
223 
224     case MCA_CREATE_CFM_EVT:
225       // Called when MCA_CreateMdl succeeded step 1 when response is received
226       print_mcap_event(&p_data->create_cfm);
227       if (!mcap_mcl) {
228         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
229         break;
230       }
231       if (!mcap_mcl->IsConnected()) {
232         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
233         break;
234       }
235       mcap_mdl = mcap_mcl->FindMdlById(p_data->create_cfm.mdl_id);
236       if (!mcap_mdl) {
237         LOG(ERROR) << "MDL not found for id " << p_data->create_cfm.mdl_id;
238         break;
239       }
240       if (mcap_mdl->GetResponseCode() >= 0) {
241         LOG(ERROR) << "MDL already got response " << mcap_mdl->GetResponseCode()
242                    << " for id " << p_data->create_cfm.mdl_id;
243         break;
244       }
245       mcap_mdl->SetResponseCode(p_data->create_cfm.rsp_code);
246       break;
247 
248     case MCA_CREATE_IND_EVT: {
249       // Should be replied with MCA_CreateMdlRsp
250       print_mcap_event(&p_data->create_ind);
251       if (!mcap_mcl) {
252         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
253         break;
254       }
255       if (!mcap_mcl->IsConnected()) {
256         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
257         break;
258       }
259       McapMdep* mcap_mdep = FindMdepByHandle(p_data->create_ind.dep_id);
260       if (!mcap_mdep) {
261         LOG(ERROR) << "MDEP ID " << (int)p_data->create_ind.dep_id
262                    << " does not exist";
263         _mcap_test_interface->create_mdl_response(
264             mcl, p_data->create_ind.dep_id, p_data->create_ind.mdl_id, 0,
265             MCA_RSP_BAD_MDEP, get_test_channel_config());
266         break;
267       }
268       bool ret = mcap_mcl->CreateMdlResponse(
269           mcap_mdep->GetHandle(), p_data->create_ind.mdl_id,
270           p_data->create_ind.dep_id, p_data->create_ind.cfg);
271       LOG(INFO) << (ret ? "SUCCESS" : "FAIL");
272       if (!ret) {
273         _mcap_test_interface->create_mdl_response(
274             mcl, p_data->create_ind.dep_id, p_data->create_ind.mdl_id, 0,
275             MCA_RSP_NO_RESOURCE, get_test_channel_config());
276       }
277       break;
278     }
279     case MCA_RECONNECT_IND_EVT: {
280       // Called when remote device asks to reconnect
281       // reply with MCA_ReconnectMdlRsp
282       print_mcap_event(&p_data->reconnect_ind);
283       if (!mcap_mcl) {
284         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
285         break;
286       }
287       if (!mcap_mcl->IsConnected()) {
288         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
289         break;
290       }
291       mcap_mdl = mcap_mcl->FindMdlById(p_data->reconnect_ind.mdl_id);
292       if (mcap_mdl && !mcap_mdl->IsConnected()) {
293         LOG(INFO) << "Creating reconnect response for MDL "
294                   << (int)p_data->reconnect_ind.mdl_id;
295         mcap_mdl->ReconnectResponse();
296         break;
297       }
298       LOG_IF(WARNING, mcap_mdl && mcap_mdl->IsConnected())
299           << "MDL ID " << (int)p_data->reconnect_ind.mdl_id
300           << " is already connected";
301       LOG_IF(WARNING, !mcap_mdl) << "No MDL for mdl_id "
302                                  << p_data->reconnect_ind.mdl_id;
303       tMCA_DEP mdep_handle = 0;
304       if (_mdep_list.size() > 0) {
305         mdep_handle = _mdep_list[0].GetHandle();
306       } else {
307         LOG(ERROR) << "Cannot find any available MDEP";
308       }
309       tMCA_RESULT ret = _mcap_test_interface->reconnect_mdl_response(
310           mcl, mdep_handle, p_data->reconnect_ind.mdl_id, MCA_RSP_BAD_MDL,
311           get_test_channel_config());
312       LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << ret;
313       break;
314     }
315     case MCA_RECONNECT_CFM_EVT:
316       // Called when MCA_ReconnectMdl step 1, receives a response
317       print_mcap_event(&p_data->reconnect_cfm);
318       if (!mcap_mcl) {
319         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
320         break;
321       }
322       if (!mcap_mcl->IsConnected()) {
323         LOG(ERROR) << "MCL not connected for mcl_handle " << (int)mcl;
324         break;
325       }
326       mcap_mdl = mcap_mcl->FindMdlById(p_data->reconnect_cfm.mdl_id);
327       if (!mcap_mdl) {
328         LOG(ERROR) << "MDL not found for id " << p_data->reconnect_cfm.mdl_id;
329         break;
330       }
331       if (mcap_mdl->GetResponseCode() >= 0) {
332         LOG(ERROR) << "MDL already got response " << mcap_mdl->GetResponseCode()
333                    << " for id " << p_data->reconnect_cfm.mdl_id;
334         break;
335       }
336       mcap_mdl->SetResponseCode(p_data->reconnect_cfm.rsp_code);
337       break;
338 
339     case MCA_ABORT_IND_EVT:
340       print_mcap_event(&p_data->abort_ind);
341       if (!mcap_mcl) {
342         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
343         break;
344       }
345       if (!mcap_mcl->IsConnected()) {
346         LOG(ERROR) << "MCL not connected for mcl_handle " << (int)mcl;
347         break;
348       }
349       mcap_mdl = mcap_mcl->FindMdlById(p_data->abort_ind.mdl_id);
350       if (!mcap_mdl) {
351         LOG(ERROR) << "MDL not found for id " << (int)p_data->abort_ind.mdl_id;
352         break;
353       }
354       if (mcap_mdl->IsConnected()) {
355         LOG(ERROR) << "MDL is already connected for id "
356                    << (int)p_data->abort_ind.mdl_id;
357       }
358       mcap_mcl->RemoveMdl(p_data->abort_ind.mdl_id);
359       break;
360 
361     case MCA_ABORT_CFM_EVT:
362       // Called when MCA_Abort succeeded
363       print_mcap_event(&p_data->abort_cfm);
364       if (!mcap_mcl) {
365         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
366         break;
367       }
368       if (!mcap_mcl->IsConnected()) {
369         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
370         break;
371       }
372       mcap_mdl = mcap_mcl->FindMdlById(p_data->abort_cfm.mdl_id);
373       if (!mcap_mdl) {
374         LOG(ERROR) << "MDL not found for id " << (int)p_data->abort_cfm.mdl_id;
375         break;
376       }
377       if (mcap_mdl->IsConnected()) {
378         LOG(ERROR) << "MDL is already connected for id "
379                    << (int)p_data->abort_cfm.mdl_id;
380       }
381       mcap_mcl->RemoveMdl(p_data->abort_cfm.mdl_id);
382       break;
383 
384     case MCA_DELETE_IND_EVT:
385       print_mcap_event(&p_data->delete_ind);
386       if (!mcap_mcl) {
387         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
388         break;
389       }
390       if (!mcap_mcl->IsConnected()) {
391         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
392         break;
393       }
394       if (p_data->delete_ind.mdl_id == MCA_ALL_MDL_ID) {
395         mcap_mcl->RemoveAllMdl();
396       } else {
397         mcap_mcl->RemoveMdl(p_data->delete_ind.mdl_id);
398       }
399       break;
400 
401     case MCA_DELETE_CFM_EVT:
402       // Called when MCA_Delete succeeded
403       print_mcap_event(&p_data->delete_cfm);
404       if (!mcap_mcl) {
405         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
406         break;
407       }
408       if (!mcap_mcl->IsConnected()) {
409         LOG(ERROR) << "MCL " << (int)mcl << " not connected";
410         break;
411       }
412       if (p_data->delete_cfm.rsp_code) {
413         LOG(ERROR) << "No success response " << (int)p_data->delete_cfm.rsp_code
414                    << " when deleting MDL_ID "
415                    << (int)p_data->delete_cfm.mdl_id;
416         break;
417       }
418       if (p_data->delete_cfm.mdl_id == MCA_ALL_MDL_ID) {
419         mcap_mcl->RemoveAllMdl();
420       } else {
421         mcap_mcl->RemoveMdl(p_data->delete_cfm.mdl_id);
422       }
423       break;
424 
425     case MCA_CONNECT_IND_EVT: {
426       // Called when MCA_ConnectReq succeeded
427       print_mcap_event(&p_data->connect_ind);
428       LOG(INFO) << "Received MCL handle " << (int)mcl;
429       RawAddress bd_addr = p_data->connect_ind.bd_addr;
430       mcap_mcl = FindMclByPeerAddress(bd_addr);
431       if (!mcap_mcl) {
432         LOG(INFO) << "Creating new MCL for ID " << (int)mcl;
433         _mcl_list.push_back(
434             McapMcl(_mcap_test_interface, _mcap_handle, bd_addr));
435         mcap_mcl = &_mcl_list[_mcl_list.size() - 1];
436       }
437       if (mcap_mcl->IsConnected()) {
438         LOG(ERROR) << "MCL is already connected for handle " << (int)mcl;
439         break;
440       }
441       mcap_mcl->SetHandle(mcl);
442       mcap_mcl->SetMtu(p_data->connect_ind.mtu);
443       break;
444     }
445     case MCA_DISCONNECT_IND_EVT: {
446       // Called when MCA_ConnectReq failed or MCA_DisconnectReq succeeded
447       print_mcap_event(&p_data->disconnect_ind);
448       RawAddress bd_addr = p_data->disconnect_ind.bd_addr;
449       mcap_mcl = FindMclByPeerAddress(bd_addr);
450       if (!mcap_mcl) {
451         LOG(ERROR) << "No MCL for BD addr " << bd_addr;
452         break;
453       }
454       if (!mcap_mcl->IsConnected()) {
455         LOG(WARNING) << "MCL for " << bd_addr << " is already disconnected";
456       }
457       mcap_mcl->SetHandle(0);
458       mcap_mcl->SetMtu(0);
459       mcap_mcl->ResetAllMdl();
460       break;
461     }
462     case MCA_OPEN_IND_EVT:
463     // Called when MCA_CreateMdlRsp succeeded step 2, data channel is open
464     // Called when MCA_ReconnectMdlRsp succeeded step 2, data channel is open
465     case MCA_OPEN_CFM_EVT:
466       // Called when MCA_CreateMdl succeeded step 2, data channel is open
467       // Called when MCA_ReconnectMdl succeeded step 2, data channel is open
468       // Called when MCA_DataChnlCfg succeeded
469       print_mcap_event(&p_data->open_ind);
470       if (!mcap_mcl) {
471         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
472         break;
473       }
474       if (!mcap_mcl->IsConnected()) {
475         LOG(ERROR) << "MCL not connected for mcl_handle " << (int)mcl;
476         break;
477       }
478       mcap_mdl = mcap_mcl->FindMdlById(p_data->open_ind.mdl_id);
479       if (mcap_mdl) {
480         if (mcap_mdl->IsConnected()) {
481           LOG(ERROR) << "MDL is already connected for mcl_handle "
482                      << (int)p_data->open_ind.mdl_id;
483           break;
484         }
485         mcap_mdl->SetMtu(p_data->open_ind.mtu);
486         mcap_mdl->SetHandle(p_data->open_ind.mdl);
487       } else {
488         LOG(ERROR) << "No MDL for mdl_id " << (int)p_data->reconnect_ind.mdl_id;
489       }
490       break;
491 
492     case MCA_CLOSE_IND_EVT:
493     case MCA_CLOSE_CFM_EVT:
494       // Called when MCA_CloseReq is successful
495       print_mcap_event(&p_data->close_cfm);
496       if (!mcap_mcl) {
497         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
498         break;
499       }
500       if (!mcap_mcl->IsConnected()) {
501         LOG(ERROR) << "MCL not connected for mcl_handle " << (int)mcl;
502         break;
503       }
504       mcap_mdl = mcap_mcl->FindMdlById(p_data->close_cfm.mdl_id);
505       if (mcap_mdl) {
506         mcap_mdl->SetMtu(0);
507         mcap_mdl->SetHandle(0);
508       } else {
509         LOG(WARNING) << "No MDL for mdl_id " << (int)p_data->close_cfm.mdl_id;
510       }
511       break;
512 
513     case MCA_CONG_CHG_EVT:
514       print_mcap_event(&p_data->cong_chg);
515       if (!mcap_mcl) {
516         LOG(ERROR) << "No MCL for mcl_handle " << (int)mcl;
517         break;
518       }
519       if (!mcap_mcl->IsConnected()) {
520         LOG(ERROR) << "MCL not connected for mcl_handle " << (int)mcl;
521         break;
522       }
523       break;
524 
525     case MCA_RSP_TOUT_IND_EVT:
526     case MCA_SYNC_CAP_IND_EVT:
527     case MCA_SYNC_CAP_CFM_EVT:
528     case MCA_SYNC_SET_IND_EVT:
529     case MCA_SYNC_SET_CFM_EVT:
530     case MCA_SYNC_INFO_IND_EVT:
531       print_mcap_event(&p_data->hdr);
532       break;
533   }
534 }
535 
536 }  // namespace SYSTEM_BT_TOOLS_MCAP_TOOL
537