• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the implementation file for the MCAP Control Channel Action
22  *  Functions.
23  *
24  ******************************************************************************/
25 #include <string.h>
26 #include "bt_target.h"
27 #include "bt_utils.h"
28 #include "gki.h"
29 #include "btm_api.h"
30 #include "mca_api.h"
31 #include "mca_defs.h"
32 #include "mca_int.h"
33 
34 
35 #include  "btu.h"
36 /*****************************************************************************
37 ** constants
38 *****************************************************************************/
39 /*******************************************************************************
40 **
41 ** Function         mca_ccb_rsp_tout
42 **
43 ** Description      This function processes the response timeout.
44 **
45 ** Returns          void.
46 **
47 *******************************************************************************/
mca_ccb_rsp_tout(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)48 void mca_ccb_rsp_tout(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
49 {
50    tMCA_CTRL   evt_data;
51    UNUSED(p_data);
52 
53    mca_ccb_report_event(p_ccb, MCA_RSP_TOUT_IND_EVT, &evt_data);
54 }
55 
56 /*******************************************************************************
57 **
58 ** Function         mca_ccb_report_event
59 **
60 ** Description      This function reports the given event.
61 **
62 ** Returns          void.
63 **
64 *******************************************************************************/
mca_ccb_report_event(tMCA_CCB * p_ccb,UINT8 event,tMCA_CTRL * p_data)65 void mca_ccb_report_event(tMCA_CCB *p_ccb, UINT8 event, tMCA_CTRL *p_data)
66 {
67     if (p_ccb && p_ccb->p_rcb && p_ccb->p_rcb->p_cback)
68         (*p_ccb->p_rcb->p_cback)(mca_rcb_to_handle(p_ccb->p_rcb), mca_ccb_to_hdl(p_ccb), event, p_data);
69 }
70 
71 /*******************************************************************************
72 **
73 ** Function         mca_ccb_free_msg
74 **
75 ** Description      This function frees the received message.
76 **
77 ** Returns          void.
78 **
79 *******************************************************************************/
mca_ccb_free_msg(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)80 void mca_ccb_free_msg(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
81 {
82     UNUSED(p_ccb);
83 
84     GKI_freebuf (p_data);
85 }
86 
87 /*******************************************************************************
88 **
89 ** Function         mca_ccb_snd_req
90 **
91 ** Description      This function builds a request and sends it to the peer.
92 **
93 ** Returns          void.
94 **
95 *******************************************************************************/
mca_ccb_snd_req(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)96 void mca_ccb_snd_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
97 {
98     tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
99     BT_HDR  *p_pkt;
100     UINT8   *p, *p_start;
101     BOOLEAN is_abort = FALSE;
102     tMCA_DCB *p_dcb;
103 
104     MCA_TRACE_DEBUG ("mca_ccb_snd_req cong=%d req=%d", p_ccb->cong, p_msg->op_code);
105     /* check for abort request */
106     if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (p_msg->op_code == MCA_OP_MDL_ABORT_REQ))
107     {
108         p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
109         /* the Abort API does not have the associated mdl_id.
110          * Get the mdl_id in dcb to compose the request */
111         p_msg->mdl_id = p_dcb->mdl_id;
112         mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
113         mca_free_buf ((void **)&p_ccb->p_tx_req);
114         p_ccb->status = MCA_CCB_STAT_NORM;
115         is_abort = TRUE;
116     }
117 
118     /* no pending outgoing messages or it's an abort request for a pending data channel */
119     if ((!p_ccb->p_tx_req) || is_abort)
120     {
121         p_ccb->p_tx_req = p_msg;
122         if (!p_ccb->cong)
123         {
124             p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
125             if (p_pkt)
126             {
127                 p_pkt->offset = L2CAP_MIN_OFFSET;
128                 p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
129                 *p++ = p_msg->op_code;
130                 UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
131                 if (p_msg->op_code == MCA_OP_MDL_CREATE_REQ)
132                 {
133                     *p++ = p_msg->mdep_id;
134                     *p++ = p_msg->param;
135                 }
136                 p_msg->hdr.layer_specific = TRUE;   /* mark this message as sent */
137                 p_pkt->len = p - p_start;
138                 L2CA_DataWrite (p_ccb->lcid, p_pkt);
139                 p_ccb->timer_entry.param = (TIMER_PARAM_TYPE) p_ccb;
140                 btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_MCA_CCB_RSP, p_ccb->p_rcb->reg.rsp_tout);
141             }
142         }
143         /* else the L2CAP channel is congested. keep the message to be sent later */
144     }
145     else
146     {
147         MCA_TRACE_WARNING ("dropping api req");
148         GKI_freebuf (p_data);
149     }
150 }
151 
152 /*******************************************************************************
153 **
154 ** Function         mca_ccb_snd_rsp
155 **
156 ** Description      This function builds a response and sends it to
157 **                  the peer.
158 **
159 ** Returns          void.
160 **
161 *******************************************************************************/
mca_ccb_snd_rsp(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)162 void mca_ccb_snd_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
163 {
164     tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
165     BT_HDR  *p_pkt;
166     UINT8   *p, *p_start;
167     BOOLEAN chk_mdl = FALSE;
168     tMCA_DCB    *p_dcb;
169 
170     MCA_TRACE_DEBUG ("mca_ccb_snd_rsp cong=%d req=%d", p_ccb->cong, p_msg->op_code);
171     /* assume that API functions verified the parameters */
172     p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
173     if (p_pkt)
174     {
175         p_pkt->offset = L2CAP_MIN_OFFSET;
176         p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
177         *p++ = p_msg->op_code;
178         *p++ = p_msg->rsp_code;
179         UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
180         if (p_msg->op_code == MCA_OP_MDL_CREATE_RSP)
181         {
182             *p++ = p_msg->param;
183             chk_mdl = TRUE;
184         }
185         else if (p_msg->op_code == MCA_OP_MDL_RECONNECT_RSP)
186                 chk_mdl = TRUE;
187 
188         if (chk_mdl && p_msg->rsp_code == MCA_RSP_SUCCESS)
189         {
190             p_dcb = mca_dcb_by_hdl(p_msg->dcb_idx);
191             BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
192                 p_ccb->p_rcb->reg.data_psm, BTM_SEC_PROTO_MCA, p_msg->dcb_idx);
193             p_ccb->status = MCA_CCB_STAT_PENDING;
194             /* set p_tx_req to block API_REQ/API_RSP before DL is up */
195             mca_free_buf ((void **)&p_ccb->p_tx_req);
196             p_ccb->p_tx_req = p_ccb->p_rx_msg;
197             p_ccb->p_rx_msg = NULL;
198             p_ccb->p_tx_req->dcb_idx = p_msg->dcb_idx;
199         }
200         mca_free_buf ((void **)&p_ccb->p_rx_msg);
201         p_pkt->len = p - p_start;
202         L2CA_DataWrite (p_ccb->lcid, p_pkt);
203     }
204 
205 }
206 
207 /*******************************************************************************
208 **
209 ** Function         mca_ccb_do_disconn
210 **
211 ** Description      This function closes a control channel.
212 **
213 ** Returns          void.
214 **
215 *******************************************************************************/
mca_ccb_do_disconn(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)216 void mca_ccb_do_disconn (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
217 {
218     UNUSED(p_data);
219 
220     mca_dcb_close_by_mdl_id (p_ccb, MCA_ALL_MDL_ID);
221     L2CA_DisconnectReq(p_ccb->lcid);
222 }
223 
224 /*******************************************************************************
225 **
226 ** Function         mca_ccb_cong
227 **
228 ** Description      This function sets the congestion state for the CCB.
229 **
230 ** Returns          void.
231 **
232 *******************************************************************************/
mca_ccb_cong(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)233 void mca_ccb_cong(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
234 {
235     MCA_TRACE_DEBUG ("mca_ccb_cong cong=%d/%d", p_ccb->cong, p_data->llcong);
236     p_ccb->cong = p_data->llcong;
237     if (!p_ccb->cong)
238     {
239         /* if there's a held packet, send it now */
240         if (p_ccb->p_tx_req && !p_ccb->p_tx_req->hdr.layer_specific)
241         {
242             p_data = (tMCA_CCB_EVT *)p_ccb->p_tx_req;
243             p_ccb->p_tx_req = NULL;
244             mca_ccb_snd_req (p_ccb, p_data);
245         }
246     }
247 }
248 
249 /*******************************************************************************
250 **
251 ** Function         mca_ccb_hdl_req
252 **
253 ** Description      This function is called when a MCAP request is received from
254 **                  the peer. It calls the application callback function to
255 **                  report the event.
256 **
257 ** Returns          void.
258 **
259 *******************************************************************************/
mca_ccb_hdl_req(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)260 void mca_ccb_hdl_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
261 {
262     BT_HDR  *p_pkt = &p_data->hdr;
263     BT_HDR  *p_buf;
264     UINT8   *p, *p_start;
265     tMCA_DCB    *p_dcb;
266     tMCA_CTRL       evt_data;
267     tMCA_CCB_MSG    *p_rx_msg = NULL;
268     UINT8           reject_code = MCA_RSP_NO_RESOURCE;
269     BOOLEAN         send_rsp = FALSE;
270     BOOLEAN         check_req = FALSE;
271     UINT8           reject_opcode;
272 
273     MCA_TRACE_DEBUG ("mca_ccb_hdl_req status:%d", p_ccb->status);
274     p_rx_msg = (tMCA_CCB_MSG *)p_pkt;
275     p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
276     evt_data.hdr.op_code = *p++;
277     BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
278     reject_opcode = evt_data.hdr.op_code+1;
279 
280     MCA_TRACE_DEBUG ("received mdl id: %d ", evt_data.hdr.mdl_id);
281     if (p_ccb->status == MCA_CCB_STAT_PENDING)
282     {
283         MCA_TRACE_DEBUG ("received req inpending state");
284         /* allow abort in pending state */
285         if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (evt_data.hdr.op_code == MCA_OP_MDL_ABORT_REQ))
286         {
287             reject_code = MCA_RSP_SUCCESS;
288             send_rsp = TRUE;
289             /* clear the pending status */
290             p_ccb->status = MCA_CCB_STAT_NORM;
291             if (p_ccb->p_tx_req && ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx))!= NULL))
292             {
293                 mca_dcb_dealloc (p_dcb, NULL);
294                 mca_free_buf ((void **)&p_ccb->p_tx_req);
295             }
296         }
297         else
298             reject_code = MCA_RSP_BAD_OP;
299     }
300     else if (p_ccb->p_rx_msg)
301     {
302         MCA_TRACE_DEBUG ("still handling prev req");
303         /* still holding previous message, reject this new one ?? */
304 
305     }
306     else if (p_ccb->p_tx_req)
307     {
308         MCA_TRACE_DEBUG ("still waiting for a response ctrl_vpsm:0x%x", p_ccb->ctrl_vpsm);
309         /* sent a request; waiting for response */
310         if (p_ccb->ctrl_vpsm == 0)
311         {
312             MCA_TRACE_DEBUG ("local is ACP. accept the cmd from INT");
313             /* local is acceptor, need to handle the request */
314             check_req = TRUE;
315             reject_code = MCA_RSP_SUCCESS;
316             /* drop the previous request */
317             if ((p_ccb->p_tx_req->op_code == MCA_OP_MDL_CREATE_REQ) &&
318                 ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) != NULL))
319             {
320                 mca_dcb_dealloc(p_dcb, NULL);
321             }
322             mca_free_buf ((void **)&p_ccb->p_tx_req);
323             mca_stop_timer(p_ccb);
324         }
325         else
326         {
327             /*  local is initiator, ignore the req */
328             GKI_freebuf (p_pkt);
329             return;
330         }
331     }
332     else if (p_pkt->layer_specific != MCA_RSP_SUCCESS)
333     {
334 
335         reject_code = (UINT8)p_pkt->layer_specific;
336         if (((evt_data.hdr.op_code >= MCA_NUM_STANDARD_OPCODE) &&
337             (evt_data.hdr.op_code < MCA_FIRST_SYNC_OP)) ||
338             (evt_data.hdr.op_code > MCA_LAST_SYNC_OP))
339         {
340             /* invalid op code */
341             reject_opcode = MCA_OP_ERROR_RSP;
342             evt_data.hdr.mdl_id = 0;
343         }
344     }
345     else
346     {
347         check_req = TRUE;
348         reject_code = MCA_RSP_SUCCESS;
349     }
350 
351     if (check_req)
352     {
353         if (reject_code == MCA_RSP_SUCCESS)
354         {
355             reject_code = MCA_RSP_BAD_MDL;
356             if (MCA_IS_VALID_MDL_ID(evt_data.hdr.mdl_id) ||
357                 ((evt_data.hdr.mdl_id == MCA_ALL_MDL_ID) && (evt_data.hdr.op_code == MCA_OP_MDL_DELETE_REQ)))
358             {
359                 reject_code = MCA_RSP_SUCCESS;
360                 /* mdl_id is valid according to the spec */
361                 switch (evt_data.hdr.op_code)
362                 {
363                 case MCA_OP_MDL_CREATE_REQ:
364                     evt_data.create_ind.dep_id = *p++;
365                     evt_data.create_ind.cfg = *p++;
366                     p_rx_msg->mdep_id = evt_data.create_ind.dep_id;
367                     if (!mca_is_valid_dep_id(p_ccb->p_rcb, p_rx_msg->mdep_id))
368                     {
369                         MCA_TRACE_ERROR ("not a valid local mdep id");
370                         reject_code = MCA_RSP_BAD_MDEP;
371                     }
372                     else if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
373                     {
374                         MCA_TRACE_DEBUG ("the mdl_id is currently used in the CL(create)");
375                         mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
376                     }
377                     else
378                     {
379                         /* check if this dep still have MDL available */
380                         if (mca_dep_free_mdl(p_ccb, evt_data.create_ind.dep_id) == 0)
381                         {
382                             MCA_TRACE_ERROR ("the mdep is currently using max_mdl");
383                             reject_code = MCA_RSP_MDEP_BUSY;
384                         }
385                     }
386                     break;
387 
388                 case MCA_OP_MDL_RECONNECT_REQ:
389                     if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
390                     {
391                         MCA_TRACE_ERROR ("the mdl_id is currently used in the CL(reconn)");
392                         reject_code = MCA_RSP_MDL_BUSY;
393                     }
394                     break;
395 
396                 case MCA_OP_MDL_ABORT_REQ:
397                     reject_code = MCA_RSP_BAD_OP;
398                     break;
399 
400                 case MCA_OP_MDL_DELETE_REQ:
401                     /* delete the associated mdl */
402                     mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
403                     send_rsp = TRUE;
404                     break;
405                 }
406             }
407         }
408     }
409 
410     if (((reject_code != MCA_RSP_SUCCESS) && (evt_data.hdr.op_code != MCA_OP_SYNC_INFO_IND))
411         || send_rsp)
412     {
413         p_buf = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
414         if (p_buf)
415         {
416             p_buf->offset = L2CAP_MIN_OFFSET;
417             p = p_start = (UINT8*)(p_buf + 1) + L2CAP_MIN_OFFSET;
418             *p++ = reject_opcode;
419             *p++ = reject_code;
420             UINT16_TO_BE_STREAM (p, evt_data.hdr.mdl_id);
421             /*
422             if (((*p_start) == MCA_OP_MDL_CREATE_RSP) && (reject_code == MCA_RSP_SUCCESS))
423             {
424                 *p++ = evt_data.create_ind.cfg;
425             }
426             */
427 
428             p_buf->len = p - p_start;
429             L2CA_DataWrite (p_ccb->lcid, p_buf);
430         }
431     }
432 
433     if (reject_code == MCA_RSP_SUCCESS)
434     {
435         /* use the received GKI buffer to store information to double check response API */
436         p_rx_msg->op_code = evt_data.hdr.op_code;
437         p_rx_msg->mdl_id = evt_data.hdr.mdl_id;
438         p_ccb->p_rx_msg = p_rx_msg;
439         if (send_rsp)
440         {
441             GKI_freebuf (p_pkt);
442             p_ccb->p_rx_msg = NULL;
443         }
444         mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
445     }
446     else
447         GKI_freebuf (p_pkt);
448 }
449 
450 /*******************************************************************************
451 **
452 ** Function         mca_ccb_hdl_rsp
453 **
454 ** Description      This function is called when a MCAP response is received from
455 **                  the peer.  It calls the application callback function with
456 **                  the results.
457 **
458 ** Returns          void.
459 **
460 *******************************************************************************/
mca_ccb_hdl_rsp(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)461 void mca_ccb_hdl_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
462 {
463     BT_HDR  *p_pkt = &p_data->hdr;
464     UINT8   *p;
465     tMCA_CTRL   evt_data;
466     BOOLEAN     chk_mdl = FALSE;
467     tMCA_DCB    *p_dcb;
468     tMCA_RESULT result = MCA_BAD_HANDLE;
469     tMCA_TC_TBL *p_tbl;
470 
471     if (p_ccb->p_tx_req)
472     {
473         /* verify that the received response matches the sent request */
474         p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
475         evt_data.hdr.op_code = *p++;
476         if ((evt_data.hdr.op_code == 0) ||
477             ((p_ccb->p_tx_req->op_code + 1) == evt_data.hdr.op_code))
478         {
479             evt_data.rsp.rsp_code = *p++;
480             mca_stop_timer(p_ccb);
481             BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
482             if (evt_data.hdr.op_code == MCA_OP_MDL_CREATE_RSP)
483             {
484                 evt_data.create_cfm.cfg = *p++;
485                 chk_mdl = TRUE;
486             }
487             else if (evt_data.hdr.op_code == MCA_OP_MDL_RECONNECT_RSP)
488                     chk_mdl = TRUE;
489 
490             if (chk_mdl)
491             {
492                 p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
493                 if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
494                 {
495                     if (evt_data.hdr.mdl_id != p_dcb->mdl_id)
496                     {
497                         MCA_TRACE_ERROR ("peer's mdl_id=%d != our mdl_id=%d", evt_data.hdr.mdl_id, p_dcb->mdl_id);
498                         /* change the response code to be an error */
499                         if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
500                         {
501                             evt_data.rsp.rsp_code = MCA_RSP_BAD_MDL;
502                             /* send Abort */
503                             p_ccb->status = MCA_CCB_STAT_PENDING;
504                             MCA_Abort(mca_ccb_to_hdl(p_ccb));
505                         }
506                     }
507                     else if (p_dcb->p_chnl_cfg)
508                     {
509                         /* the data channel configuration is known. Proceed with data channel initiation */
510                         BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
511                             p_ccb->data_vpsm, BTM_SEC_PROTO_MCA, p_ccb->p_tx_req->dcb_idx);
512                         p_dcb->lcid = mca_l2c_open_req(p_ccb->peer_addr, p_ccb->data_vpsm, p_dcb->p_chnl_cfg);
513                         if (p_dcb->lcid)
514                         {
515                             p_tbl = mca_tc_tbl_dalloc(p_dcb);
516                             if (p_tbl)
517                             {
518                                 p_tbl->state = MCA_TC_ST_CONN;
519                                 p_ccb->status = MCA_CCB_STAT_PENDING;
520                                 result = MCA_SUCCESS;
521                             }
522                         }
523                     }
524                     else
525                     {
526                         /* mark this MCL as pending and wait for MCA_DataChnlCfg */
527                         p_ccb->status = MCA_CCB_STAT_PENDING;
528                         result = MCA_SUCCESS;
529                     }
530                 }
531 
532                 if (result != MCA_SUCCESS && p_dcb)
533                 {
534                     mca_dcb_dealloc(p_dcb, NULL);
535                 }
536             } /* end of chk_mdl */
537 
538             if (p_ccb->status != MCA_CCB_STAT_PENDING)
539                 mca_free_buf ((void **)&p_ccb->p_tx_req);
540             mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
541         }
542         /* else a bad response is received */
543     }
544     else
545     {
546         /* not expecting any response. drop it */
547         MCA_TRACE_WARNING ("dropping received rsp (not expecting a response)");
548     }
549     GKI_freebuf (p_data);
550 }
551 
552 /*******************************************************************************
553 **
554 ** Function         mca_ccb_ll_open
555 **
556 ** Description      This function is called to report MCA_CONNECT_IND_EVT event.
557 **                  It also clears the congestion flag (ccb.cong).
558 **
559 ** Returns          void.
560 **
561 *******************************************************************************/
mca_ccb_ll_open(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)562 void mca_ccb_ll_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
563 {
564     tMCA_CTRL    evt_data;
565     p_ccb->cong  = FALSE;
566     evt_data.connect_ind.mtu = p_data->open.peer_mtu;
567     memcpy (evt_data.connect_ind.bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
568     mca_ccb_report_event (p_ccb, MCA_CONNECT_IND_EVT, &evt_data);
569 }
570 
571 /*******************************************************************************
572 **
573 ** Function         mca_ccb_dl_open
574 **
575 ** Description      This function is called when data channel is open.
576 **                  It clears p_tx_req to allow other message exchage on this CL.
577 **
578 ** Returns          void.
579 **
580 *******************************************************************************/
mca_ccb_dl_open(tMCA_CCB * p_ccb,tMCA_CCB_EVT * p_data)581 void mca_ccb_dl_open (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
582 {
583     UNUSED(p_data);
584 
585     mca_free_buf ((void **)&p_ccb->p_tx_req);
586     mca_free_buf ((void **)&p_ccb->p_rx_msg);
587     p_ccb->status = MCA_CCB_STAT_NORM;
588 }
589 
590