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