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