Home | History | Annotate | Download | only in avdt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2006-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 module contains the action functions associated with the channel
     22  *  control block state machine.
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "bt_types.h"
     28 #include "bt_target.h"
     29 #include "bt_utils.h"
     30 #include "avdt_api.h"
     31 #include "avdtc_api.h"
     32 #include "avdt_int.h"
     33 #include "bt_common.h"
     34 #include "btu.h"
     35 #include "btm_api.h"
     36 
     37 extern fixed_queue_t *btu_general_alarm_queue;
     38 
     39 /*******************************************************************************
     40 **
     41 ** Function         avdt_ccb_clear_ccb
     42 **
     43 ** Description      This function clears out certain buffers, queues, and
     44 **                  other data elements of a ccb.
     45 **
     46 **
     47 ** Returns          void.
     48 **
     49 *******************************************************************************/
     50 static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb)
     51 {
     52     BT_HDR          *p_buf;
     53 
     54     /* clear certain ccb variables */
     55     p_ccb->cong = FALSE;
     56     p_ccb->ret_count = 0;
     57 
     58     /* free message being fragmented */
     59     osi_free_and_reset((void **)&p_ccb->p_curr_msg);
     60 
     61     /* free message being reassembled */
     62     osi_free_and_reset((void **)&p_ccb->p_rx_msg);
     63 
     64     /* clear out response queue */
     65     while ((p_buf = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL)
     66         osi_free(p_buf);
     67 }
     68 
     69 /*******************************************************************************
     70 **
     71 ** Function         avdt_ccb_chan_open
     72 **
     73 ** Description      This function calls avdt_ad_open_req() to
     74 **                  initiate a signaling channel connection.
     75 **
     76 **
     77 ** Returns          void.
     78 **
     79 *******************************************************************************/
     80 void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
     81 {
     82     UNUSED(p_data);
     83 
     84     BTM_SetOutService(p_ccb->peer_addr, BTM_SEC_SERVICE_AVDTP, AVDT_CHAN_SIG);
     85     avdt_ad_open_req(AVDT_CHAN_SIG, p_ccb, NULL, AVDT_INT);
     86 }
     87 
     88 /*******************************************************************************
     89 **
     90 ** Function         avdt_ccb_chan_close
     91 **
     92 ** Description      This function calls avdt_ad_close_req() to close a
     93 **                  signaling channel connection.
     94 **
     95 **
     96 ** Returns          void.
     97 **
     98 *******************************************************************************/
     99 void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    100 {
    101     UNUSED(p_data);
    102 
    103     /* close the transport channel used by this CCB */
    104     avdt_ad_close_req(AVDT_CHAN_SIG, p_ccb, NULL);
    105 }
    106 
    107 /*******************************************************************************
    108 **
    109 ** Function         avdt_ccb_chk_close
    110 **
    111 ** Description      This function checks for active streams on this CCB.
    112 **                  If there are none, it starts an idle timer.
    113 **
    114 **
    115 ** Returns          void.
    116 **
    117 *******************************************************************************/
    118 void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    119 {
    120     int         i;
    121     tAVDT_SCB   *p_scb = &avdt_cb.scb[0];
    122     UNUSED(p_data);
    123 
    124     /* see if there are any active scbs associated with this ccb */
    125     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
    126     {
    127         if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
    128         {
    129             break;
    130         }
    131     }
    132 
    133     /* if no active scbs start idle timer */
    134     if (i == AVDT_NUM_SEPS)
    135     {
    136         alarm_cancel(p_ccb->ret_ccb_timer);
    137         alarm_cancel(p_ccb->rsp_ccb_timer);
    138         period_ms_t interval_ms = avdt_cb.rcb.idle_tout * 1000;
    139         alarm_set_on_queue(p_ccb->idle_ccb_timer, interval_ms,
    140                            avdt_ccb_idle_ccb_timer_timeout, p_ccb,
    141                            btu_general_alarm_queue);
    142     }
    143 }
    144 
    145 /*******************************************************************************
    146 **
    147 ** Function         avdt_ccb_hdl_discover_cmd
    148 **
    149 ** Description      This function is called when a discover command is
    150 **                  received from the peer.  It gathers up the stream
    151 **                  information for all allocated streams and initiates
    152 **                  sending of a discover response.
    153 **
    154 **
    155 ** Returns          void.
    156 **
    157 *******************************************************************************/
    158 void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    159 {
    160     tAVDT_SEP_INFO      sep_info[AVDT_NUM_SEPS];
    161     tAVDT_SCB           *p_scb = &avdt_cb.scb[0];
    162     int                 i;
    163 
    164     p_data->msg.discover_rsp.p_sep_info = sep_info;
    165     p_data->msg.discover_rsp.num_seps = 0;
    166 
    167     /* for all allocated scbs */
    168     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
    169     {
    170         if (p_scb->allocated)
    171         {
    172             /* copy sep info */
    173             sep_info[p_data->msg.discover_rsp.num_seps].in_use = p_scb->in_use;
    174             sep_info[p_data->msg.discover_rsp.num_seps].seid = i + 1;
    175             sep_info[p_data->msg.discover_rsp.num_seps].media_type = p_scb->cs.media_type;
    176             sep_info[p_data->msg.discover_rsp.num_seps].tsep = p_scb->cs.tsep;
    177 
    178             p_data->msg.discover_rsp.num_seps++;
    179         }
    180     }
    181 
    182     /* send response */
    183     avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_RSP_EVT, p_data);
    184 }
    185 
    186 /*******************************************************************************
    187 **
    188 ** Function         avdt_ccb_hdl_discover_rsp
    189 **
    190 ** Description      This function is called when a discover response or
    191 **                  reject is received from the peer.  It calls the application
    192 **                  callback function with the results.
    193 **
    194 **
    195 ** Returns          void.
    196 **
    197 *******************************************************************************/
    198 void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    199 {
    200     /* we're done with procedure */
    201     p_ccb->proc_busy = FALSE;
    202 
    203     /* call app callback with results */
    204     (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT,
    205                          (tAVDT_CTRL *)(&p_data->msg.discover_rsp));
    206 }
    207 
    208 /*******************************************************************************
    209 **
    210 ** Function         avdt_ccb_hdl_getcap_cmd
    211 **
    212 ** Description      This function is called when a get capabilities command
    213 **                  is received from the peer.  It retrieves the stream
    214 **                  configuration for the requested stream and initiates
    215 **                  sending of a get capabilities response.
    216 **
    217 **
    218 ** Returns          void.
    219 **
    220 *******************************************************************************/
    221 void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    222 {
    223     tAVDT_SCB       *p_scb;
    224 
    225     /* look up scb for seid sent to us */
    226     p_scb = avdt_scb_by_hdl(p_data->msg.single.seid);
    227 
    228     p_data->msg.svccap.p_cfg = &p_scb->cs.cfg;
    229 
    230     avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_RSP_EVT, p_data);
    231 }
    232 
    233 /*******************************************************************************
    234 **
    235 ** Function         avdt_ccb_hdl_getcap_rsp
    236 **
    237 ** Description      This function is called with a get capabilities response
    238 **                  or reject is received from the peer.  It calls the
    239 **                  application callback function with the results.
    240 **
    241 **
    242 ** Returns          void.
    243 **
    244 *******************************************************************************/
    245 void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    246 {
    247     /* we're done with procedure */
    248     p_ccb->proc_busy = FALSE;
    249 
    250     /* call app callback with results */
    251     (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT,
    252                          (tAVDT_CTRL *)(&p_data->msg.svccap));
    253 }
    254 
    255 /*******************************************************************************
    256 **
    257 ** Function         avdt_ccb_hdl_start_cmd
    258 **
    259 ** Description      This function is called when a start command is received
    260 **                  from the peer.  It verifies that all requested streams
    261 **                  are in the proper state.  If so, it initiates sending of
    262 **                  a start response.  Otherwise it sends a start reject.
    263 **
    264 **
    265 ** Returns          void.
    266 **
    267 *******************************************************************************/
    268 void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    269 {
    270     UINT8   err_code = 0;
    271 
    272     /* verify all streams in the right state */
    273     UINT8 seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_START, p_data->msg.multi.seid_list,
    274                                  p_data->msg.multi.num_seps, &err_code);
    275     if (seid == 0 && err_code == 0)
    276     {
    277         /* we're ok, send response */
    278         avdt_ccb_event(p_ccb, AVDT_CCB_API_START_RSP_EVT, p_data);
    279     } else {
    280         /* not ok, send reject */
    281         p_data->msg.hdr.err_code = err_code;
    282         p_data->msg.hdr.err_param = seid;
    283         avdt_msg_send_rej(p_ccb, AVDT_SIG_START, &p_data->msg);
    284     }
    285 }
    286 
    287 /*******************************************************************************
    288 **
    289 ** Function         avdt_ccb_hdl_start_rsp
    290 **
    291 ** Description      This function is called when a start response or reject
    292 **                  is received from the peer.  Using the SEIDs stored in the
    293 **                  current command message, it sends a start response or start
    294 **                  reject event to each SCB associated with the command.
    295 **
    296 **
    297 ** Returns          void.
    298 **
    299 *******************************************************************************/
    300 void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    301 {
    302     UINT8       event;
    303     int         i;
    304     UINT8       *p;
    305     tAVDT_SCB   *p_scb;
    306 
    307     /* determine rsp or rej event */
    308     event = (p_data->msg.hdr.err_code == 0) ?
    309             AVDT_SCB_MSG_START_RSP_EVT : AVDT_SCB_MSG_START_REJ_EVT;
    310 
    311     /* get to where seid's are stashed in current cmd */
    312     p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
    313 
    314     /* little trick here; length of current command equals number of streams */
    315     for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
    316     {
    317         if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
    318         {
    319             avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
    320         }
    321     }
    322 }
    323 
    324 /*******************************************************************************
    325 **
    326 ** Function         avdt_ccb_hdl_suspend_cmd
    327 **
    328 ** Description      This function is called when a suspend command is received
    329 **                  from the peer.  It verifies that all requested streams are
    330 **                  in the proper state.  If so, it initiates sending of a
    331 **                  suspend response.  Otherwise it sends a suspend reject.
    332 
    333 **
    334 **
    335 ** Returns          void.
    336 **
    337 *******************************************************************************/
    338 void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    339 {
    340     UINT8   seid;
    341     UINT8   err_code = 0;
    342 
    343     /* verify all streams in the right state */
    344     if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_SUSPEND, p_data->msg.multi.seid_list,
    345                                 p_data->msg.multi.num_seps, &err_code)) == 0 &&
    346                                 err_code == 0)
    347     {
    348         /* we're ok, send response */
    349         avdt_ccb_event(p_ccb, AVDT_CCB_API_SUSPEND_RSP_EVT, p_data);
    350     }
    351     else
    352     {
    353         /* not ok, send reject */
    354         p_data->msg.hdr.err_code = err_code;
    355         p_data->msg.hdr.err_param = seid;
    356         avdt_msg_send_rej(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
    357     }
    358 }
    359 
    360 /*******************************************************************************
    361 **
    362 ** Function         avdt_ccb_hdl_suspend_rsp
    363 **
    364 ** Description      This function is called when a suspend response or reject
    365 **                  is received from the peer.  Using the SEIDs stored in the
    366 **                  current command message, it sends a suspend response or
    367 **                  suspend reject event to each SCB associated with the command.
    368 **
    369 **
    370 **
    371 ** Returns          void.
    372 **
    373 *******************************************************************************/
    374 void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    375 {
    376     UINT8       event;
    377     int         i;
    378     UINT8       *p;
    379     tAVDT_SCB   *p_scb;
    380 
    381     /* determine rsp or rej event */
    382     event = (p_data->msg.hdr.err_code == 0) ?
    383             AVDT_SCB_MSG_SUSPEND_RSP_EVT : AVDT_SCB_MSG_SUSPEND_REJ_EVT;
    384 
    385     /* get to where seid's are stashed in current cmd */
    386     p = (UINT8 *)(p_ccb->p_curr_cmd + 1);
    387 
    388     /* little trick here; length of current command equals number of streams */
    389     for (i = 0; i < p_ccb->p_curr_cmd->len; i++)
    390     {
    391         if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL)
    392         {
    393             avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg);
    394         }
    395     }
    396 }
    397 
    398 /*******************************************************************************
    399 **
    400 ** Function         avdt_ccb_snd_discover_cmd
    401 **
    402 ** Description      This function is called to send a discover command to the
    403 **                  peer.  It copies variables needed for the procedure from
    404 **                  the event to the CCB.  It marks the CCB as busy and then
    405 **                  sends a discover command.
    406 **
    407 **
    408 ** Returns          void.
    409 **
    410 *******************************************************************************/
    411 void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    412 {
    413     /* store info in ccb struct */
    414     p_ccb->p_proc_data = p_data->discover.p_sep_info;
    415     p_ccb->proc_cback = p_data->discover.p_cback;
    416     p_ccb->proc_param = p_data->discover.num_seps;
    417 
    418     /* we're busy */
    419     p_ccb->proc_busy = TRUE;
    420 
    421     /* build and queue discover req */
    422     avdt_msg_send_cmd(p_ccb, NULL, AVDT_SIG_DISCOVER, NULL);
    423 }
    424 
    425 /*******************************************************************************
    426 **
    427 ** Function         avdt_ccb_snd_discover_rsp
    428 **
    429 ** Description      This function is called to send a discover response to
    430 **                  the peer.  It takes the stream information passed in the
    431 **                  event and sends a discover response.
    432 **
    433 **
    434 ** Returns          void.
    435 **
    436 *******************************************************************************/
    437 void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    438 {
    439     /* send response */
    440     avdt_msg_send_rsp(p_ccb, AVDT_SIG_DISCOVER, &p_data->msg);
    441 }
    442 
    443 /*******************************************************************************
    444 **
    445 ** Function         avdt_ccb_snd_getcap_cmd
    446 **
    447 ** Description      This function is called to send a get capabilities command
    448 **                  to the peer.  It copies variables needed for the procedure
    449 **                  from the event to the CCB.  It marks the CCB as busy and
    450 **                  then sends a get capabilities command.
    451 **
    452 **
    453 ** Returns          void.
    454 **
    455 *******************************************************************************/
    456 void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    457 {
    458     UINT8 sig_id = AVDT_SIG_GETCAP;
    459 
    460     /* store info in ccb struct */
    461     p_ccb->p_proc_data = p_data->getcap.p_cfg;
    462     p_ccb->proc_cback = p_data->getcap.p_cback;
    463 
    464     /* we're busy */
    465     p_ccb->proc_busy = TRUE;
    466 
    467     /* build and queue discover req */
    468     if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
    469         sig_id = AVDT_SIG_GET_ALLCAP;
    470 
    471     avdt_msg_send_cmd(p_ccb, NULL, sig_id, (tAVDT_MSG *) &p_data->getcap.single);
    472 }
    473 
    474 /*******************************************************************************
    475 **
    476 ** Function         avdt_ccb_snd_getcap_rsp
    477 **
    478 ** Description      This function is called to send a get capabilities response
    479 **                  to the peer.  It takes the stream information passed in the
    480 **                  event and sends a get capabilities response.
    481 **
    482 **
    483 ** Returns          void.
    484 **
    485 *******************************************************************************/
    486 void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    487 {
    488     UINT8 sig_id = AVDT_SIG_GETCAP;
    489 
    490     if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP)
    491         sig_id = AVDT_SIG_GET_ALLCAP;
    492 
    493     /* send response */
    494     avdt_msg_send_rsp(p_ccb, sig_id, &p_data->msg);
    495 }
    496 
    497 /*******************************************************************************
    498 **
    499 ** Function         avdt_ccb_snd_start_cmd
    500 **
    501 ** Description      This function is called to send a start command to the
    502 **                  peer.  It verifies that all requested streams are in the
    503 **                  proper state.  If so, it sends a start command.  Otherwise
    504 **                  send ourselves back a start reject.
    505 **
    506 **
    507 ** Returns          void.
    508 **
    509 *******************************************************************************/
    510 void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    511 {
    512     int             i;
    513     tAVDT_SCB       *p_scb;
    514     tAVDT_MSG       avdt_msg;
    515     UINT8           seid_list[AVDT_NUM_SEPS];
    516 
    517     /* make copy of our seid list */
    518     memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
    519 
    520     /* verify all streams in the right state */
    521     if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list,
    522                                          p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
    523     {
    524         /* set peer seid list in messsage */
    525         avdt_scb_peer_seid_list(&p_data->msg.multi);
    526 
    527         /* send command */
    528         avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_START, &p_data->msg);
    529     }
    530     else
    531     {
    532         /* failed; send ourselves a reject for each stream */
    533         for (i = 0; i < p_data->msg.multi.num_seps; i++)
    534         {
    535             if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
    536             {
    537                 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
    538             }
    539         }
    540     }
    541 }
    542 
    543 /*******************************************************************************
    544 **
    545 ** Function         avdt_ccb_snd_start_rsp
    546 **
    547 ** Description      This function is called to send a start response to the
    548 **                  peer.  It takes the stream information passed in the event
    549 **                  and sends a start response.  Then it sends a start event
    550 **                  to the SCB for each stream.
    551 **
    552 **
    553 ** Returns          void.
    554 **
    555 *******************************************************************************/
    556 void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    557 {
    558     tAVDT_SCB *p_scb;
    559     int i;
    560 
    561     /* send response message */
    562     avdt_msg_send_rsp(p_ccb, AVDT_SIG_START, &p_data->msg);
    563 
    564     /* send start event to each scb */
    565     for (i = 0; i < p_data->msg.multi.num_seps; i++)
    566     {
    567         if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
    568         {
    569             avdt_scb_event(p_scb, AVDT_SCB_MSG_START_CMD_EVT, NULL);
    570         }
    571     }
    572 }
    573 
    574 /*******************************************************************************
    575 **
    576 ** Function         avdt_ccb_snd_suspend_cmd
    577 **
    578 ** Description      This function is called to send a suspend command to the
    579 **                  peer.  It verifies that all requested streams are in the
    580 **                  proper state.  If so, it sends a suspend command.
    581 **                  Otherwise it calls the callback function for each requested
    582 **                  stream and sends a suspend confirmation with failure.
    583 **
    584 **
    585 ** Returns          void.
    586 **
    587 *******************************************************************************/
    588 void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    589 {
    590     int             i;
    591     tAVDT_SCB       *p_scb;
    592     tAVDT_MSG       avdt_msg;
    593     UINT8           seid_list[AVDT_NUM_SEPS];
    594 
    595     /* make copy of our seid list */
    596     memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps);
    597 
    598     /* verify all streams in the right state */
    599     if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_STREAMING, p_data->msg.multi.seid_list,
    600                                          p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0)
    601     {
    602         /* set peer seid list in messsage */
    603         avdt_scb_peer_seid_list(&p_data->msg.multi);
    604 
    605         /* send command */
    606         avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_SUSPEND, &p_data->msg);
    607     }
    608     else
    609     {
    610         /* failed; send ourselves a reject for each stream */
    611         for (i = 0; i < p_data->msg.multi.num_seps; i++)
    612         {
    613             if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL)
    614             {
    615                 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr);
    616             }
    617         }
    618     }
    619 }
    620 
    621 /*******************************************************************************
    622 **
    623 ** Function         avdt_ccb_snd_suspend_rsp
    624 **
    625 ** Description      This function is called to send a suspend response to the
    626 **                  peer.  It takes the stream information passed in the event
    627 **                  and sends a suspend response.  Then it sends a suspend event
    628 **                  to the SCB for each stream.
    629 **
    630 **
    631 ** Returns          void.
    632 **
    633 *******************************************************************************/
    634 void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    635 {
    636     tAVDT_SCB *p_scb;
    637     int i;
    638 
    639     /* send response message */
    640     avdt_msg_send_rsp(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg);
    641 
    642     /* send start event to each scb */
    643     for (i = 0; i < p_data->msg.multi.num_seps; i++)
    644     {
    645         if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL)
    646         {
    647             avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_CMD_EVT, NULL);
    648         }
    649     }
    650 }
    651 
    652 /*******************************************************************************
    653 **
    654 ** Function         avdt_ccb_clear_cmds
    655 **
    656 ** Description      This function is called when the signaling channel is
    657 **                  closed to clean up any pending commands.  For each pending
    658 **                  command in the command queue, it frees the command and
    659 **                  calls the application callback function indicating failure.
    660 **                  Certain CCB variables are also initialized.
    661 **
    662 **
    663 ** Returns          void.
    664 **
    665 *******************************************************************************/
    666 void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    667 {
    668     int             i;
    669     tAVDT_SCB       *p_scb = &avdt_cb.scb[0];
    670     UINT8           err_code = AVDT_ERR_CONNECT;
    671     UNUSED(p_data);
    672 
    673     /* clear the ccb */
    674     avdt_ccb_clear_ccb(p_ccb);
    675 
    676     /* clear out command queue; this is a little tricky here; we need
    677     ** to handle the case where there is a command on deck in p_curr_cmd,
    678     ** plus we need to clear out the queue
    679     */
    680     do
    681     {
    682         /* we know p_curr_cmd = NULL after this */
    683         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
    684 
    685         /* set up next message */
    686         p_ccb->p_curr_cmd = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q);
    687 
    688     } while (p_ccb->p_curr_cmd != NULL);
    689 
    690     /* send a CC_CLOSE_EVT any active scbs associated with this ccb */
    691     for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++)
    692     {
    693         if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb))
    694         {
    695             avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL);
    696         }
    697     }
    698 }
    699 
    700 /*******************************************************************************
    701 **
    702 ** Function         avdt_ccb_cmd_fail
    703 **
    704 ** Description      This function is called when there is a response timeout.
    705 **                  The currently pending command is freed and we fake a
    706 **                  reject message back to ourselves.
    707 **
    708 **
    709 ** Returns          void.
    710 **
    711 *******************************************************************************/
    712 void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    713 {
    714     tAVDT_MSG       msg;
    715     UINT8           evt;
    716     tAVDT_SCB       *p_scb;
    717 
    718     if (p_ccb->p_curr_cmd != NULL)
    719     {
    720         /* set up data */
    721         msg.hdr.err_code = p_data->err_code;
    722         msg.hdr.err_param = 0;
    723         msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
    724 
    725         /* pretend that we received a rej message */
    726         evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1];
    727 
    728         if (evt & AVDT_CCB_MKR)
    729         {
    730             avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
    731         }
    732         else
    733         {
    734             /* we get the scb out of the current cmd */
    735             p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1)));
    736             if (p_scb != NULL)
    737             {
    738                 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
    739             }
    740         }
    741 
    742         osi_free_and_reset((void **)&p_ccb->p_curr_cmd);
    743     }
    744 }
    745 
    746 /*******************************************************************************
    747 **
    748 ** Function         avdt_ccb_free_cmd
    749 **
    750 ** Description      This function is called when a response is received for a
    751 **                  currently pending command.  The command is freed.
    752 **
    753 **
    754 ** Returns          void.
    755 **
    756 *******************************************************************************/
    757 void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    758 {
    759     UNUSED(p_data);
    760     osi_free_and_reset((void **)&p_ccb->p_curr_cmd);
    761 }
    762 
    763 /*******************************************************************************
    764 **
    765 ** Function         avdt_ccb_cong_state
    766 **
    767 ** Description      This function is called to set the congestion state for
    768 **                  the CCB.
    769 **
    770 **
    771 ** Returns          void.
    772 **
    773 *******************************************************************************/
    774 void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    775 {
    776     p_ccb->cong = p_data->llcong;
    777 }
    778 
    779 /*******************************************************************************
    780 **
    781 ** Function         avdt_ccb_ret_cmd
    782 **
    783 ** Description      This function is called to retransmit the currently
    784 **                  pending command.  The retransmission count is incremented.
    785 **                  If the count reaches the maximum number of retransmissions,
    786 **                  the event is treated as a response timeout.
    787 **
    788 **
    789 ** Returns          void.
    790 **
    791 *******************************************************************************/
    792 void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    793 {
    794     UINT8   err_code = AVDT_ERR_TIMEOUT;
    795 
    796     p_ccb->ret_count++;
    797     if (p_ccb->ret_count == AVDT_RET_MAX)
    798     {
    799         /* command failed */
    800         p_ccb->ret_count = 0;
    801         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
    802 
    803         /* go to next queued command */
    804         avdt_ccb_snd_cmd(p_ccb, p_data);
    805     }
    806     else
    807     {
    808         /* if command pending and we're not congested and not sending a fragment */
    809         if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL))
    810         {
    811             /* make copy of message in p_curr_cmd and send it */
    812             BT_HDR *p_msg = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
    813             memcpy(p_msg, p_ccb->p_curr_cmd,
    814                    (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len));
    815             avdt_msg_send(p_ccb, p_msg);
    816         }
    817 
    818         /* restart ret timer */
    819         alarm_cancel(p_ccb->idle_ccb_timer);
    820         alarm_cancel(p_ccb->rsp_ccb_timer);
    821         period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
    822         alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
    823                            avdt_ccb_ret_ccb_timer_timeout, p_ccb,
    824                            btu_general_alarm_queue);
    825     }
    826 }
    827 
    828 /*******************************************************************************
    829 **
    830 ** Function         avdt_ccb_snd_cmd
    831 **
    832 ** Description      This function is called the send the next command,
    833 **                  if any, in the command queue.
    834 **
    835 **
    836 ** Returns          void.
    837 **
    838 *******************************************************************************/
    839 void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    840 {
    841     BT_HDR  *p_msg;
    842     UNUSED(p_data);
    843 
    844     /* do we have commands to send?  send next command;  make sure we're clear;
    845     ** not congested, not sending fragment, not waiting for response
    846     */
    847     if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL))
    848     {
    849         if ((p_msg = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q)) != NULL)
    850         {
    851             /* make a copy of buffer in p_curr_cmd */
    852             p_ccb->p_curr_cmd = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
    853             memcpy(p_ccb->p_curr_cmd, p_msg,
    854                    (sizeof(BT_HDR) + p_msg->offset + p_msg->len));
    855             avdt_msg_send(p_ccb, p_msg);
    856         }
    857     }
    858 }
    859 
    860 /*******************************************************************************
    861 **
    862 ** Function         avdt_ccb_snd_msg
    863 **
    864 ** Description
    865 **
    866 **
    867 ** Returns          void.
    868 **
    869 *******************************************************************************/
    870 void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    871 {
    872     BT_HDR      *p_msg;
    873     UNUSED(p_data);
    874 
    875     /* if not congested */
    876     if (!p_ccb->cong)
    877     {
    878         /* are we sending a fragmented message? continue sending fragment */
    879         if (p_ccb->p_curr_msg != NULL)
    880         {
    881             avdt_msg_send(p_ccb, NULL);
    882         }
    883         /* do we have responses to send?  send them */
    884         else if (!fixed_queue_is_empty(p_ccb->rsp_q))
    885         {
    886             while ((p_msg = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL)
    887             {
    888                 if (avdt_msg_send(p_ccb, p_msg) == TRUE)
    889                 {
    890                     /* break out if congested */
    891                     break;
    892                 }
    893             }
    894         }
    895 
    896         /* do we have commands to send?  send next command */
    897         avdt_ccb_snd_cmd(p_ccb, NULL);
    898     }
    899 }
    900 
    901 /*******************************************************************************
    902 **
    903 ** Function         avdt_ccb_set_reconn
    904 **
    905 ** Description      This function is called to enable a reconnect attempt when
    906 **                  a channel transitions from closing to idle state.  It sets
    907 **                  the reconn variable to TRUE.
    908 **
    909 **
    910 ** Returns          void.
    911 **
    912 *******************************************************************************/
    913 void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    914 {
    915     UNUSED(p_data);
    916 
    917     p_ccb->reconn = TRUE;
    918 }
    919 
    920 /*******************************************************************************
    921 **
    922 ** Function         avdt_ccb_clr_reconn
    923 **
    924 ** Description      This function is called to clear the reconn variable.
    925 **
    926 **
    927 ** Returns          void.
    928 **
    929 *******************************************************************************/
    930 void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    931 {
    932     UNUSED(p_data);
    933 
    934     p_ccb->reconn = FALSE;
    935 }
    936 
    937 /*******************************************************************************
    938 **
    939 ** Function         avdt_ccb_chk_reconn
    940 **
    941 ** Description      This function is called to check if a reconnect attempt
    942 **                  is enabled.  If enabled, it sends an AVDT_CCB_UL_OPEN_EVT
    943 **                  to the CCB.  If disabled, the CCB is deallocated.
    944 **
    945 **
    946 ** Returns          void.
    947 **
    948 *******************************************************************************/
    949 void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    950 {
    951     UINT8   err_code = AVDT_ERR_CONNECT;
    952     UNUSED(p_data);
    953 
    954     if (p_ccb->reconn)
    955     {
    956         p_ccb->reconn = FALSE;
    957 
    958         /* clear out ccb */
    959         avdt_ccb_clear_ccb(p_ccb);
    960 
    961         /* clear out current command, if any */
    962         avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);
    963 
    964         /* reopen the signaling channel */
    965         avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL);
    966     }
    967     else
    968     {
    969         avdt_ccb_ll_closed(p_ccb, NULL);
    970     }
    971 }
    972 
    973 /*******************************************************************************
    974 **
    975 ** Function         avdt_ccb_chk_timer
    976 **
    977 ** Description      This function stops the CCB timer if the idle timer is
    978 **                  running.
    979 **
    980 **
    981 ** Returns          void.
    982 **
    983 *******************************************************************************/
    984 void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
    985 {
    986     UNUSED(p_data);
    987 
    988     alarm_cancel(p_ccb->idle_ccb_timer);
    989 }
    990 
    991 /*******************************************************************************
    992 **
    993 ** Function         avdt_ccb_set_conn
    994 **
    995 ** Description      Set CCB variables associated with AVDT_ConnectReq().
    996 **
    997 **
    998 ** Returns          void.
    999 **
   1000 *******************************************************************************/
   1001 void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
   1002 {
   1003     /* save callback */
   1004     p_ccb->p_conn_cback = p_data->connect.p_cback;
   1005 
   1006     /* set security level */
   1007     BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask,
   1008                          AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
   1009 }
   1010 
   1011 /*******************************************************************************
   1012 **
   1013 ** Function         avdt_ccb_set_disconn
   1014 **
   1015 ** Description      Set CCB variables associated with AVDT_DisconnectReq().
   1016 **
   1017 **
   1018 ** Returns          void.
   1019 **
   1020 *******************************************************************************/
   1021 void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
   1022 {
   1023     /*
   1024     AVDT_TRACE_EVENT("avdt_ccb_set_disconn:conn:x%x, api:x%x",
   1025         p_ccb->p_conn_cback, p_data->disconnect.p_cback);
   1026         */
   1027     /* save callback */
   1028     if (p_data->disconnect.p_cback)
   1029         p_ccb->p_conn_cback = p_data->disconnect.p_cback;
   1030 }
   1031 
   1032 /*******************************************************************************
   1033 **
   1034 ** Function         avdt_ccb_do_disconn
   1035 **
   1036 ** Description      Do action associated with AVDT_DisconnectReq().
   1037 **
   1038 **
   1039 ** Returns          void.
   1040 **
   1041 *******************************************************************************/
   1042 void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
   1043 {
   1044     UNUSED(p_data);
   1045 
   1046     /* clear any pending commands */
   1047     avdt_ccb_clear_cmds(p_ccb, NULL);
   1048 
   1049     /* close channel */
   1050     avdt_ccb_chan_close(p_ccb, NULL);
   1051 }
   1052 
   1053 /*******************************************************************************
   1054 **
   1055 ** Function         avdt_ccb_ll_closed
   1056 **
   1057 ** Description      Clear commands from and deallocate CCB.
   1058 **
   1059 **
   1060 ** Returns          void.
   1061 **
   1062 *******************************************************************************/
   1063 void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
   1064 {
   1065     tAVDT_CTRL_CBACK    *p_cback;
   1066     BD_ADDR             bd_addr;
   1067     tAVDT_CTRL          avdt_ctrl;
   1068     UNUSED(p_data);
   1069 
   1070     /* clear any pending commands */
   1071     avdt_ccb_clear_cmds(p_ccb, NULL);
   1072 
   1073     /* save callback pointer, bd addr */
   1074     p_cback = p_ccb->p_conn_cback;
   1075     if (!p_cback)
   1076         p_cback = avdt_cb.p_conn_cback;
   1077     memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
   1078 
   1079     /* dealloc ccb */
   1080     avdt_ccb_dealloc(p_ccb, NULL);
   1081 
   1082     /* call callback */
   1083     if (p_cback)
   1084     {
   1085         avdt_ctrl.hdr.err_code = 0;
   1086         (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
   1087     }
   1088 }
   1089 
   1090 /*******************************************************************************
   1091 **
   1092 ** Function         avdt_ccb_ll_opened
   1093 **
   1094 ** Description      Call callback on open.
   1095 **
   1096 **
   1097 ** Returns          void.
   1098 **
   1099 *******************************************************************************/
   1100 void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
   1101 {
   1102     tAVDT_CTRL          avdt_ctrl;
   1103 
   1104     p_ccb->ll_opened = TRUE;
   1105 
   1106     if (!p_ccb->p_conn_cback)
   1107         p_ccb->p_conn_cback = avdt_cb.p_conn_cback;
   1108 
   1109     /* call callback */
   1110     if (p_ccb->p_conn_cback)
   1111     {
   1112         avdt_ctrl.hdr.err_code = 0;
   1113         avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param;
   1114         (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT, &avdt_ctrl);
   1115     }
   1116 }
   1117