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