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