Home | History | Annotate | Download | only in avdt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2002-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 functions for parsing and building AVDTP signaling
     22  *  messages.  It also contains functions called by the SCB or CCB state
     23  *  machines for sending command, response, and reject messages.  It also
     24  *  contains a function that processes incoming messages and dispatches them
     25  *  to the appropriate SCB or CCB.
     26  *
     27  ******************************************************************************/
     28 
     29 #include <string.h>
     30 #include "avdt_api.h"
     31 #include "avdt_int.h"
     32 #include "avdtc_api.h"
     33 #include "bt_common.h"
     34 #include "bt_target.h"
     35 #include "bt_types.h"
     36 #include "bt_utils.h"
     37 #include "btu.h"
     38 #include "osi/include/osi.h"
     39 
     40 extern fixed_queue_t* btu_general_alarm_queue;
     41 
     42 /*****************************************************************************
     43  * constants
     44  ****************************************************************************/
     45 
     46 /* mask of all psc values */
     47 #define AVDT_MSG_PSC_MASK                                                   \
     48   (AVDT_PSC_TRANS | AVDT_PSC_REPORT | AVDT_PSC_DELAY_RPT | AVDT_PSC_RECOV | \
     49    AVDT_PSC_HDRCMP | AVDT_PSC_MUX)
     50 #define AVDT_PSC_PROTECT (1 << 4) /* Content Protection */
     51 #define AVDT_PSC_CODEC (1 << 7)   /* codec */
     52 
     53 /*****************************************************************************
     54  * type definitions
     55  ****************************************************************************/
     56 
     57 /* type for message building functions */
     58 typedef void (*tAVDT_MSG_BLD)(uint8_t** p, tAVDT_MSG* p_msg);
     59 
     60 /* type for message parsing functions */
     61 typedef uint8_t (*tAVDT_MSG_PRS)(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
     62 
     63 /*****************************************************************************
     64  * local function declarations
     65  ****************************************************************************/
     66 
     67 static void avdt_msg_bld_none(uint8_t** p, tAVDT_MSG* p_msg);
     68 static void avdt_msg_bld_single(uint8_t** p, tAVDT_MSG* p_msg);
     69 static void avdt_msg_bld_setconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg);
     70 static void avdt_msg_bld_reconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg);
     71 static void avdt_msg_bld_multi(uint8_t** p, tAVDT_MSG* p_msg);
     72 static void avdt_msg_bld_security_cmd(uint8_t** p, tAVDT_MSG* p_msg);
     73 static void avdt_msg_bld_discover_rsp(uint8_t** p, tAVDT_MSG* p_msg);
     74 static void avdt_msg_bld_svccap(uint8_t** p, tAVDT_MSG* p_msg);
     75 static void avdt_msg_bld_security_rsp(uint8_t** p, tAVDT_MSG* p_msg);
     76 static void avdt_msg_bld_all_svccap(uint8_t** p, tAVDT_MSG* p_msg);
     77 static void avdt_msg_bld_delay_rpt(uint8_t** p, tAVDT_MSG* p_msg);
     78 
     79 static uint8_t avdt_msg_prs_none(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
     80 static uint8_t avdt_msg_prs_single(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
     81 static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
     82                                           uint16_t len);
     83 static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
     84                                          uint16_t len);
     85 static uint8_t avdt_msg_prs_multi(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
     86 static uint8_t avdt_msg_prs_security_cmd(tAVDT_MSG* p_msg, uint8_t* p,
     87                                          uint16_t len);
     88 static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG* p_msg, uint8_t* p,
     89                                          uint16_t len);
     90 static uint8_t avdt_msg_prs_svccap(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len);
     91 static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG* p_msg, uint8_t* p,
     92                                        uint16_t len);
     93 static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG* p_msg, uint8_t* p,
     94                                          uint16_t len);
     95 static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p,
     96                                       uint16_t len);
     97 
     98 /*****************************************************************************
     99  * constants
    100  ****************************************************************************/
    101 
    102 /* table of information element minimum lengths used for parsing */
    103 const uint8_t avdt_msg_ie_len_min[] = {
    104     0,                     /* unused */
    105     AVDT_LEN_TRANS_MIN,    /* media transport */
    106     AVDT_LEN_REPORT_MIN,   /* reporting */
    107     AVDT_LEN_RECOV_MIN,    /* recovery */
    108     AVDT_LEN_PROTECT_MIN,  /* content protection */
    109     AVDT_LEN_HDRCMP_MIN,   /* header compression */
    110     AVDT_LEN_MUX_MIN,      /* multiplexing */
    111     AVDT_LEN_CODEC_MIN,    /* codec */
    112     AVDT_LEN_DELAY_RPT_MIN /* delay report */
    113 };
    114 
    115 /* table of information element minimum lengths used for parsing */
    116 const uint8_t avdt_msg_ie_len_max[] = {
    117     0,                     /* unused */
    118     AVDT_LEN_TRANS_MAX,    /* media transport */
    119     AVDT_LEN_REPORT_MAX,   /* reporting */
    120     AVDT_LEN_RECOV_MAX,    /* recovery */
    121     AVDT_LEN_PROTECT_MAX,  /* content protection */
    122     AVDT_LEN_HDRCMP_MAX,   /* header compression */
    123     AVDT_LEN_MUX_MAX,      /* multiplexing */
    124     AVDT_LEN_CODEC_MAX,    /* codec */
    125     AVDT_LEN_DELAY_RPT_MAX /* delay report */
    126 };
    127 
    128 /* table of error codes used when decoding information elements */
    129 const uint8_t avdt_msg_ie_err[] = {
    130     0,                    /* unused */
    131     AVDT_ERR_MEDIA_TRANS, /* media transport */
    132     AVDT_ERR_LENGTH,      /* reporting */
    133     AVDT_ERR_RECOV_FMT,   /* recovery */
    134     AVDT_ERR_CP_FMT,      /* content protection */
    135     AVDT_ERR_ROHC_FMT,    /* header compression */
    136     AVDT_ERR_MUX_FMT,     /* multiplexing */
    137     AVDT_ERR_SERVICE,     /* codec */
    138     AVDT_ERR_SERVICE      /* delay report ?? */
    139 };
    140 
    141 /* table of packet type minimum lengths */
    142 static const uint8_t avdt_msg_pkt_type_len[] = {
    143     AVDT_LEN_TYPE_SINGLE, AVDT_LEN_TYPE_START, AVDT_LEN_TYPE_CONT,
    144     AVDT_LEN_TYPE_END};
    145 
    146 /* function table for building command messages */
    147 const tAVDT_MSG_BLD avdt_msg_bld_cmd[] = {
    148     avdt_msg_bld_none,          /* discover */
    149     avdt_msg_bld_single,        /* get capabilities */
    150     avdt_msg_bld_setconfig_cmd, /* set configuration */
    151     avdt_msg_bld_single,        /* get configuration */
    152     avdt_msg_bld_reconfig_cmd,  /* reconfigure */
    153     avdt_msg_bld_single,        /* open */
    154     avdt_msg_bld_multi,         /* start */
    155     avdt_msg_bld_single,        /* close */
    156     avdt_msg_bld_multi,         /* suspend */
    157     avdt_msg_bld_single,        /* abort */
    158     avdt_msg_bld_security_cmd,  /* security control */
    159     avdt_msg_bld_single,        /* get all capabilities */
    160     avdt_msg_bld_delay_rpt      /* delay report */
    161 };
    162 
    163 /* function table for building response messages */
    164 const tAVDT_MSG_BLD avdt_msg_bld_rsp[] = {
    165     avdt_msg_bld_discover_rsp, /* discover */
    166     avdt_msg_bld_svccap,       /* get capabilities */
    167     avdt_msg_bld_none,         /* set configuration */
    168     avdt_msg_bld_all_svccap,   /* get configuration */
    169     avdt_msg_bld_none,         /* reconfigure */
    170     avdt_msg_bld_none,         /* open */
    171     avdt_msg_bld_none,         /* start */
    172     avdt_msg_bld_none,         /* close */
    173     avdt_msg_bld_none,         /* suspend */
    174     avdt_msg_bld_none,         /* abort */
    175     avdt_msg_bld_security_rsp, /* security control */
    176     avdt_msg_bld_all_svccap,   /* get all capabilities */
    177     avdt_msg_bld_none          /* delay report */
    178 };
    179 
    180 /* function table for parsing command messages */
    181 const tAVDT_MSG_PRS avdt_msg_prs_cmd[] = {
    182     avdt_msg_prs_none,          /* discover */
    183     avdt_msg_prs_single,        /* get capabilities */
    184     avdt_msg_prs_setconfig_cmd, /* set configuration */
    185     avdt_msg_prs_single,        /* get configuration */
    186     avdt_msg_prs_reconfig_cmd,  /* reconfigure */
    187     avdt_msg_prs_single,        /* open */
    188     avdt_msg_prs_multi,         /* start */
    189     avdt_msg_prs_single,        /* close */
    190     avdt_msg_prs_multi,         /* suspend */
    191     avdt_msg_prs_single,        /* abort */
    192     avdt_msg_prs_security_cmd,  /* security control */
    193     avdt_msg_prs_single,        /* get all capabilities */
    194     avdt_msg_prs_delay_rpt      /* delay report */
    195 };
    196 
    197 /* function table for parsing response messages */
    198 const tAVDT_MSG_PRS avdt_msg_prs_rsp[] = {
    199     avdt_msg_prs_discover_rsp, /* discover */
    200     avdt_msg_prs_svccap,       /* get capabilities */
    201     avdt_msg_prs_none,         /* set configuration */
    202     avdt_msg_prs_all_svccap,   /* get configuration */
    203     avdt_msg_prs_none,         /* reconfigure */
    204     avdt_msg_prs_none,         /* open */
    205     avdt_msg_prs_none,         /* start */
    206     avdt_msg_prs_none,         /* close */
    207     avdt_msg_prs_none,         /* suspend */
    208     avdt_msg_prs_none,         /* abort */
    209     avdt_msg_prs_security_rsp, /* security control */
    210     avdt_msg_prs_all_svccap,   /* get all capabilities */
    211     avdt_msg_prs_none          /* delay report */
    212 };
    213 
    214 /* command message-to-event lookup table */
    215 const uint8_t avdt_msg_cmd_2_evt[] = {
    216     AVDT_CCB_MSG_DISCOVER_CMD_EVT + AVDT_CCB_MKR, /* discover */
    217     AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR,   /* get capabilities */
    218     AVDT_SCB_MSG_SETCONFIG_CMD_EVT,               /* set configuration */
    219     AVDT_SCB_MSG_GETCONFIG_CMD_EVT,               /* get configuration */
    220     AVDT_SCB_MSG_RECONFIG_CMD_EVT,                /* reconfigure */
    221     AVDT_SCB_MSG_OPEN_CMD_EVT,                    /* open */
    222     AVDT_CCB_MSG_START_CMD_EVT + AVDT_CCB_MKR,    /* start */
    223     AVDT_SCB_MSG_CLOSE_CMD_EVT,                   /* close */
    224     AVDT_CCB_MSG_SUSPEND_CMD_EVT + AVDT_CCB_MKR,  /* suspend */
    225     AVDT_SCB_MSG_ABORT_CMD_EVT,                   /* abort */
    226     AVDT_SCB_MSG_SECURITY_CMD_EVT,                /* security control */
    227     AVDT_CCB_MSG_GETCAP_CMD_EVT + AVDT_CCB_MKR,   /* get all capabilities */
    228     AVDT_SCB_MSG_DELAY_RPT_CMD_EVT                /* delay report */
    229 };
    230 
    231 /* response message-to-event lookup table */
    232 const uint8_t avdt_msg_rsp_2_evt[] = {
    233     AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR, /* discover */
    234     AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,   /* get capabilities */
    235     AVDT_SCB_MSG_SETCONFIG_RSP_EVT,               /* set configuration */
    236     AVDT_SCB_MSG_GETCONFIG_RSP_EVT,               /* get configuration */
    237     AVDT_SCB_MSG_RECONFIG_RSP_EVT,                /* reconfigure */
    238     AVDT_SCB_MSG_OPEN_RSP_EVT,                    /* open */
    239     AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR,    /* start */
    240     AVDT_SCB_MSG_CLOSE_RSP_EVT,                   /* close */
    241     AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR,  /* suspend */
    242     AVDT_SCB_MSG_ABORT_RSP_EVT,                   /* abort */
    243     AVDT_SCB_MSG_SECURITY_RSP_EVT,                /* security control */
    244     AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,   /* get all capabilities */
    245     AVDT_SCB_MSG_DELAY_RPT_RSP_EVT                /* delay report */
    246 };
    247 
    248 /* reject message-to-event lookup table */
    249 const uint8_t avdt_msg_rej_2_evt[] = {
    250     AVDT_CCB_MSG_DISCOVER_RSP_EVT + AVDT_CCB_MKR, /* discover */
    251     AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,   /* get capabilities */
    252     AVDT_SCB_MSG_SETCONFIG_REJ_EVT,               /* set configuration */
    253     AVDT_SCB_MSG_GETCONFIG_RSP_EVT,               /* get configuration */
    254     AVDT_SCB_MSG_RECONFIG_RSP_EVT,                /* reconfigure */
    255     AVDT_SCB_MSG_OPEN_REJ_EVT,                    /* open */
    256     AVDT_CCB_MSG_START_RSP_EVT + AVDT_CCB_MKR,    /* start */
    257     AVDT_SCB_MSG_CLOSE_RSP_EVT,                   /* close */
    258     AVDT_CCB_MSG_SUSPEND_RSP_EVT + AVDT_CCB_MKR,  /* suspend */
    259     AVDT_SCB_MSG_ABORT_RSP_EVT,                   /* abort */
    260     AVDT_SCB_MSG_SECURITY_RSP_EVT,                /* security control */
    261     AVDT_CCB_MSG_GETCAP_RSP_EVT + AVDT_CCB_MKR,   /* get all capabilities */
    262     0                                             /* delay report */
    263 };
    264 
    265 /*******************************************************************************
    266  *
    267  * Function         avdt_msg_bld_cfg
    268  *
    269  * Description      This function builds the configuration parameters contained
    270  *                  in a command or response message.
    271  *
    272  *
    273  * Returns          void.
    274  *
    275  ******************************************************************************/
    276 static void avdt_msg_bld_cfg(uint8_t** p, tAVDT_CFG* p_cfg) {
    277   uint8_t len;
    278 
    279   /* for now, just build media transport, codec, and content protection, and
    280    * multiplexing */
    281 
    282   /* media transport */
    283   if (p_cfg->psc_mask & AVDT_PSC_TRANS) {
    284     *(*p)++ = AVDT_CAT_TRANS;
    285     *(*p)++ = 0; /* length */
    286   }
    287 
    288 #if (AVDT_REPORTING == TRUE)
    289   /* reporting transport */
    290   if (p_cfg->psc_mask & AVDT_PSC_REPORT) {
    291     *(*p)++ = AVDT_CAT_REPORT;
    292     *(*p)++ = 0; /* length */
    293   }
    294 #endif
    295 
    296   /* codec */
    297   if (p_cfg->num_codec != 0) {
    298     *(*p)++ = AVDT_CAT_CODEC;
    299     len = p_cfg->codec_info[0] + 1;
    300     if (len > AVDT_CODEC_SIZE) len = AVDT_CODEC_SIZE;
    301 
    302     memcpy(*p, p_cfg->codec_info, len);
    303     *p += len;
    304   }
    305 
    306   /* content protection */
    307   if (p_cfg->num_protect != 0) {
    308     *(*p)++ = AVDT_CAT_PROTECT;
    309     len = p_cfg->protect_info[0] + 1;
    310     if (len > AVDT_PROTECT_SIZE) len = AVDT_PROTECT_SIZE;
    311 
    312     memcpy(*p, p_cfg->protect_info, len);
    313     *p += len;
    314   }
    315 
    316   /* delay report */
    317   if (p_cfg->psc_mask & AVDT_PSC_DELAY_RPT) {
    318     *(*p)++ = AVDT_CAT_DELAY_RPT;
    319     *(*p)++ = 0; /* length */
    320   }
    321 }
    322 
    323 /*******************************************************************************
    324  *
    325  * Function         avdt_msg_bld_none
    326  *
    327  * Description      This message building function builds an empty message.
    328  *
    329  *
    330  * Returns          void.
    331  *
    332  ******************************************************************************/
    333 static void avdt_msg_bld_none(UNUSED_ATTR uint8_t** p,
    334                               UNUSED_ATTR tAVDT_MSG* p_msg) {
    335   return;
    336 }
    337 
    338 /*******************************************************************************
    339  *
    340  * Function         avdt_msg_bld_single
    341  *
    342  * Description      This message building function builds a message containing
    343  *                  a single SEID.
    344  *
    345  *
    346  * Returns          void.
    347  *
    348  ******************************************************************************/
    349 static void avdt_msg_bld_single(uint8_t** p, tAVDT_MSG* p_msg) {
    350   AVDT_MSG_BLD_SEID(*p, p_msg->single.seid);
    351 }
    352 
    353 /*******************************************************************************
    354  *
    355  * Function         avdt_msg_bld_setconfig_cmd
    356  *
    357  * Description      This message building function builds a set configuration
    358  *                  command message.
    359  *
    360  *
    361  * Returns          void.
    362  *
    363  ******************************************************************************/
    364 static void avdt_msg_bld_setconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg) {
    365   AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.hdr.seid);
    366   AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.int_seid);
    367   avdt_msg_bld_cfg(p, p_msg->config_cmd.p_cfg);
    368 }
    369 
    370 /*******************************************************************************
    371  *
    372  * Function         avdt_msg_bld_reconfig_cmd
    373  *
    374  * Description      This message building function builds a reconfiguration
    375  *                  command message.
    376  *
    377  *
    378  * Returns          void.
    379  *
    380  ******************************************************************************/
    381 static void avdt_msg_bld_reconfig_cmd(uint8_t** p, tAVDT_MSG* p_msg) {
    382   AVDT_MSG_BLD_SEID(*p, p_msg->reconfig_cmd.hdr.seid);
    383 
    384   /* force psc mask zero to build only codec and security */
    385   p_msg->reconfig_cmd.p_cfg->psc_mask = 0;
    386   avdt_msg_bld_cfg(p, p_msg->reconfig_cmd.p_cfg);
    387 }
    388 
    389 /*******************************************************************************
    390  *
    391  * Function         avdt_msg_bld_multi
    392  *
    393  * Description      This message building function builds a message containing
    394  *                  multiple SEID's.
    395  *
    396  *
    397  * Returns          void.
    398  *
    399  ******************************************************************************/
    400 static void avdt_msg_bld_multi(uint8_t** p, tAVDT_MSG* p_msg) {
    401   int i;
    402 
    403   for (i = 0; i < p_msg->multi.num_seps; i++) {
    404     AVDT_MSG_BLD_SEID(*p, p_msg->multi.seid_list[i]);
    405   }
    406 }
    407 
    408 /*******************************************************************************
    409  *
    410  * Function         avdt_msg_bld_security_cmd
    411  *
    412  * Description      This message building function builds a security
    413  *                  command message.
    414  *
    415  * Returns          void.
    416  *
    417  ******************************************************************************/
    418 static void avdt_msg_bld_security_cmd(uint8_t** p, tAVDT_MSG* p_msg) {
    419   AVDT_MSG_BLD_SEID(*p, p_msg->security_cmd.hdr.seid);
    420   memcpy(*p, p_msg->security_cmd.p_data, p_msg->security_cmd.len);
    421   *p += p_msg->security_cmd.len;
    422 }
    423 
    424 /*******************************************************************************
    425  *
    426  * Function         avdt_msg_bld_delay_rpt
    427  *
    428  * Description      This message building function builds a delay report
    429  *                  command message.
    430  *
    431  * Returns          void.
    432  *
    433  ******************************************************************************/
    434 static void avdt_msg_bld_delay_rpt(uint8_t** p, tAVDT_MSG* p_msg) {
    435   AVDT_MSG_BLD_SEID(*p, p_msg->delay_rpt_cmd.hdr.seid);
    436   UINT16_TO_BE_STREAM(*p, p_msg->delay_rpt_cmd.delay);
    437 }
    438 
    439 /*******************************************************************************
    440  *
    441  * Function         avdt_msg_bld_discover_rsp
    442  *
    443  * Description      This message building function builds a discover
    444  *                  response message.
    445  *
    446  *
    447  * Returns          void.
    448  *
    449  ******************************************************************************/
    450 static void avdt_msg_bld_discover_rsp(uint8_t** p, tAVDT_MSG* p_msg) {
    451   int i;
    452 
    453   for (i = 0; i < p_msg->discover_rsp.num_seps; i++) {
    454     /* build discover rsp info */
    455     AVDT_MSG_BLD_DISC(*p, p_msg->discover_rsp.p_sep_info[i].seid,
    456                       p_msg->discover_rsp.p_sep_info[i].in_use,
    457                       p_msg->discover_rsp.p_sep_info[i].media_type,
    458                       p_msg->discover_rsp.p_sep_info[i].tsep);
    459   }
    460 }
    461 
    462 /*******************************************************************************
    463  *
    464  * Function         avdt_msg_bld_svccap
    465  *
    466  * Description      This message building function builds a message containing
    467  *                  service capabilities parameters.
    468  *
    469  *
    470  * Returns          void.
    471  *
    472  ******************************************************************************/
    473 static void avdt_msg_bld_svccap(uint8_t** p, tAVDT_MSG* p_msg) {
    474   tAVDT_CFG cfg;
    475 
    476   /* make sure the delay report category is not reported */
    477   memcpy(&cfg, p_msg->svccap.p_cfg, sizeof(tAVDT_CFG));
    478   cfg.psc_mask &= ~AVDT_PSC_DELAY_RPT;
    479   avdt_msg_bld_cfg(p, &cfg);
    480 }
    481 
    482 /*******************************************************************************
    483  *
    484  * Function         avdt_msg_bld_all_svccap
    485  *
    486  * Description      This message building function builds a message containing
    487  *                  service capabilities parameters.
    488  *
    489  *
    490  * Returns          void.
    491  *
    492  ******************************************************************************/
    493 static void avdt_msg_bld_all_svccap(uint8_t** p, tAVDT_MSG* p_msg) {
    494   avdt_msg_bld_cfg(p, p_msg->svccap.p_cfg);
    495 }
    496 
    497 /*******************************************************************************
    498  *
    499  * Function         avdt_msg_bld_security_rsp
    500  *
    501  * Description      This message building function builds a security
    502  *                  response message.
    503  *
    504  *
    505  * Returns          void.
    506  *
    507  ******************************************************************************/
    508 static void avdt_msg_bld_security_rsp(uint8_t** p, tAVDT_MSG* p_msg) {
    509   memcpy(*p, p_msg->security_rsp.p_data, p_msg->security_rsp.len);
    510   *p += p_msg->security_rsp.len;
    511 }
    512 
    513 /*******************************************************************************
    514  *
    515  * Function         avdt_msg_prs_cfg
    516  *
    517  * Description      This message parsing function parses the configuration
    518  *                  parameters field of a message.
    519  *
    520  *
    521  * Returns          Error code or zero if no error, and element that failed
    522  *                  in p_elem.
    523  *
    524  ******************************************************************************/
    525 static uint8_t avdt_msg_prs_cfg(tAVDT_CFG* p_cfg, uint8_t* p, uint16_t len,
    526                                 uint8_t* p_elem, uint8_t sig_id) {
    527   uint8_t* p_end;
    528   uint8_t elem = 0;
    529   uint8_t elem_len;
    530   uint8_t tmp;
    531   uint8_t err = 0;
    532   uint8_t protect_offset = 0;
    533 
    534   if (!p_cfg) {
    535     AVDT_TRACE_ERROR("not expecting this cfg");
    536     return AVDT_ERR_BAD_STATE;
    537   }
    538 
    539   p_cfg->psc_mask = 0;
    540   p_cfg->num_codec = 0;
    541   p_cfg->num_protect = 0;
    542 
    543   /* while there is still data to parse */
    544   p_end = p + len;
    545   while ((p < p_end) && (err == 0)) {
    546     /* verify overall length */
    547     if ((p_end - p) < AVDT_LEN_CFG_MIN) {
    548       err = AVDT_ERR_PAYLOAD;
    549       break;
    550     }
    551 
    552     /* get and verify info elem id, length */
    553     elem = *p++;
    554     elem_len = *p++;
    555 
    556     if ((elem == 0) || (elem > AVDT_CAT_MAX_CUR)) {
    557       /* this may not be really bad.
    558        * It may be a service category that is too new for us.
    559        * allow these to be parsed without reporting an error.
    560        * If this is a "capability" (as in GetCapRsp & GetConfigRsp), this is
    561        * filtered out.
    562        * If this is a Configuration (as in SetConfigCmd & ReconfigCmd),
    563        *    this will be marked as an error in the caller of this function */
    564       if ((sig_id == AVDT_SIG_SETCONFIG) || (sig_id == AVDT_SIG_RECONFIG)) {
    565         /* Cannot accept unknown category. */
    566         err = AVDT_ERR_CATEGORY;
    567         break;
    568       } else /* GETCAP or GET_ALLCAP */
    569       {
    570         /* Skip unknown categories. */
    571         p += elem_len;
    572         AVDT_TRACE_DEBUG("skipping unknown service category=%d len: %d", elem,
    573                          elem_len);
    574         continue;
    575       }
    576     }
    577 
    578     if ((elem_len > avdt_msg_ie_len_max[elem]) ||
    579         (elem_len < avdt_msg_ie_len_min[elem])) {
    580       err = avdt_msg_ie_err[elem];
    581       break;
    582     }
    583 
    584     /* add element to psc mask, but mask out codec or protect */
    585     p_cfg->psc_mask |= (1 << elem);
    586     AVDT_TRACE_DEBUG("elem=%d elem_len: %d psc_mask=0x%x", elem, elem_len,
    587                      p_cfg->psc_mask);
    588 
    589     /* parse individual information elements with additional parameters */
    590     switch (elem) {
    591       case AVDT_CAT_RECOV:
    592         p_cfg->recov_type = *p++;
    593         p_cfg->recov_mrws = *p++;
    594         p_cfg->recov_mnmp = *p++;
    595         if (p_cfg->recov_type != AVDT_RECOV_RFC2733) {
    596           err = AVDT_ERR_RECOV_TYPE;
    597         } else if ((p_cfg->recov_mrws < AVDT_RECOV_MRWS_MIN) ||
    598                    (p_cfg->recov_mrws > AVDT_RECOV_MRWS_MAX) ||
    599                    (p_cfg->recov_mnmp < AVDT_RECOV_MNMP_MIN) ||
    600                    (p_cfg->recov_mnmp > AVDT_RECOV_MNMP_MAX)) {
    601           err = AVDT_ERR_RECOV_FMT;
    602         }
    603         break;
    604 
    605       case AVDT_CAT_PROTECT:
    606         p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
    607         if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE) {
    608           p_cfg->num_protect++;
    609           p_cfg->protect_info[protect_offset] = elem_len;
    610           protect_offset++;
    611           memcpy(&p_cfg->protect_info[protect_offset], p, elem_len);
    612           protect_offset += elem_len;
    613         }
    614         p += elem_len;
    615         break;
    616 
    617       case AVDT_CAT_HDRCMP:
    618         p_cfg->hdrcmp_mask = *p++;
    619         break;
    620 
    621       case AVDT_CAT_CODEC:
    622         p_cfg->psc_mask &= ~AVDT_PSC_CODEC;
    623         tmp = elem_len;
    624         if (elem_len >= AVDT_CODEC_SIZE) {
    625           tmp = AVDT_CODEC_SIZE - 1;
    626         }
    627         p_cfg->num_codec++;
    628         p_cfg->codec_info[0] = elem_len;
    629         memcpy(&p_cfg->codec_info[1], p, tmp);
    630         p += elem_len;
    631         break;
    632 
    633       case AVDT_CAT_DELAY_RPT:
    634         break;
    635 
    636       default:
    637         p += elem_len;
    638         break;
    639     } /* switch */
    640   }   /* while ! err, !end*/
    641   *p_elem = elem;
    642   AVDT_TRACE_DEBUG("err=0x%x, elem:0x%x psc_mask=0x%x", err, elem,
    643                    p_cfg->psc_mask);
    644 
    645   return err;
    646 }
    647 
    648 /*******************************************************************************
    649  *
    650  * Function         avdt_msg_prs_none
    651  *
    652  * Description      This message parsing function parses a message with no
    653  *                  parameters.
    654  *
    655  *
    656  * Returns          Error code or zero if no error.
    657  *
    658  ******************************************************************************/
    659 static uint8_t avdt_msg_prs_none(UNUSED_ATTR tAVDT_MSG* p_msg,
    660                                  UNUSED_ATTR uint8_t* p,
    661                                  UNUSED_ATTR uint16_t len) {
    662   return 0;
    663 }
    664 
    665 /*******************************************************************************
    666  *
    667  * Function         avdt_msg_prs_single
    668  *
    669  * Description      This message parsing function parses a message with a
    670  *                  single SEID.
    671  *
    672  *
    673  * Returns          Error code or zero if no error.
    674  *
    675  ******************************************************************************/
    676 static uint8_t avdt_msg_prs_single(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
    677   uint8_t err = 0;
    678 
    679   /* verify len */
    680   if (len != AVDT_LEN_SINGLE) {
    681     err = AVDT_ERR_LENGTH;
    682   } else {
    683     AVDT_MSG_PRS_SEID(p, p_msg->single.seid);
    684 
    685     if (avdt_scb_by_hdl(p_msg->single.seid) == NULL) {
    686       err = AVDT_ERR_SEID;
    687     }
    688   }
    689   return err;
    690 }
    691 
    692 /*******************************************************************************
    693  *
    694  * Function         avdt_msg_prs_setconfig_cmd
    695  *
    696  * Description      This message parsing function parses a set configuration
    697  *                  command message.
    698  *
    699  *
    700  * Returns          Error code or zero if no error.
    701  *
    702  ******************************************************************************/
    703 static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
    704                                           uint16_t len) {
    705   uint8_t err = 0;
    706 
    707   p_msg->hdr.err_param = 0;
    708 
    709   /* verify len */
    710   if (len < AVDT_LEN_SETCONFIG_MIN) {
    711     err = AVDT_ERR_LENGTH;
    712   } else {
    713     /* get seids */
    714     AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.hdr.seid);
    715     if (avdt_scb_by_hdl(p_msg->config_cmd.hdr.seid) == NULL) {
    716       err = AVDT_ERR_SEID;
    717     }
    718 
    719     AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.int_seid);
    720     if ((p_msg->config_cmd.int_seid < AVDT_SEID_MIN) ||
    721         (p_msg->config_cmd.int_seid > AVDT_SEID_MAX)) {
    722       err = AVDT_ERR_SEID;
    723     }
    724   }
    725 
    726   if (!err) {
    727     /* parse configuration parameters */
    728     len -= 2;
    729     err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len,
    730                            &p_msg->hdr.err_param, AVDT_SIG_SETCONFIG);
    731 
    732     if (!err) {
    733       /* verify protocol service capabilities are supported */
    734       if (((p_msg->config_cmd.p_cfg->psc_mask & (~AVDT_PSC)) != 0) ||
    735           (p_msg->config_cmd.p_cfg->num_codec == 0)) {
    736         err = AVDT_ERR_INVALID_CAP;
    737       }
    738     }
    739   }
    740 
    741   return err;
    742 }
    743 
    744 /*******************************************************************************
    745  *
    746  * Function         avdt_msg_prs_reconfig_cmd
    747  *
    748  * Description      This message parsing function parses a reconfiguration
    749  *                  command message.
    750  *
    751  *
    752  * Returns          Error code or zero if no error.
    753  *
    754  ******************************************************************************/
    755 static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p,
    756                                          uint16_t len) {
    757   uint8_t err = 0;
    758 
    759   p_msg->hdr.err_param = 0;
    760 
    761   /* verify len */
    762   if (len < AVDT_LEN_RECONFIG_MIN) {
    763     err = AVDT_ERR_LENGTH;
    764   } else {
    765     /* get seid */
    766     AVDT_MSG_PRS_SEID(p, p_msg->reconfig_cmd.hdr.seid);
    767     if (avdt_scb_by_hdl(p_msg->reconfig_cmd.hdr.seid) == NULL) {
    768       err = AVDT_ERR_SEID;
    769     } else {
    770       /* parse config parameters */
    771       len--;
    772       err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len,
    773                              &p_msg->hdr.err_param, AVDT_SIG_RECONFIG);
    774 
    775       /* verify no protocol service capabilities in parameters */
    776       if (!err) {
    777         AVDT_TRACE_DEBUG("avdt_msg_prs_reconfig_cmd psc_mask=0x%x/0x%x",
    778                          p_msg->config_cmd.p_cfg->psc_mask, AVDT_MSG_PSC_MASK);
    779         if ((p_msg->config_cmd.p_cfg->psc_mask != 0) ||
    780             (p_msg->config_cmd.p_cfg->num_codec == 0 &&
    781              p_msg->config_cmd.p_cfg->num_protect == 0)) {
    782           err = AVDT_ERR_INVALID_CAP;
    783         }
    784       }
    785     }
    786   }
    787   return err;
    788 }
    789 
    790 /*******************************************************************************
    791  *
    792  * Function         avdt_msg_prs_multi
    793  *
    794  * Description      This message parsing function parses a message containing
    795  *                  multiple SEID's.
    796  *
    797  *
    798  * Returns          Error code or zero if no error.
    799  *
    800  ******************************************************************************/
    801 static uint8_t avdt_msg_prs_multi(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
    802   int i;
    803   uint8_t err = 0;
    804 
    805   p_msg->hdr.err_param = 0;
    806 
    807   /* verify len */
    808   if (len < AVDT_LEN_MULTI_MIN || (len > AVDT_NUM_SEPS)) {
    809     err = AVDT_ERR_LENGTH;
    810   } else {
    811     /* get and verify all seps */
    812     for (i = 0; i < len; i++) {
    813       AVDT_MSG_PRS_SEID(p, p_msg->multi.seid_list[i]);
    814       if (avdt_scb_by_hdl(p_msg->multi.seid_list[i]) == NULL) {
    815         err = AVDT_ERR_SEID;
    816         p_msg->hdr.err_param = p_msg->multi.seid_list[i];
    817         break;
    818       }
    819     }
    820     p_msg->multi.num_seps = (uint8_t)i;
    821   }
    822 
    823   return err;
    824 }
    825 
    826 /*******************************************************************************
    827  *
    828  * Function         avdt_msg_prs_security_cmd
    829  *
    830  * Description      This message parsing function parses a security
    831  *                  command message.
    832  *
    833  *
    834  * Returns          Error code or zero if no error.
    835  *
    836  ******************************************************************************/
    837 static uint8_t avdt_msg_prs_security_cmd(tAVDT_MSG* p_msg, uint8_t* p,
    838                                          uint16_t len) {
    839   uint8_t err = 0;
    840 
    841   /* verify len */
    842   if (len < AVDT_LEN_SECURITY_MIN) {
    843     err = AVDT_ERR_LENGTH;
    844   } else {
    845     /* get seid */
    846     AVDT_MSG_PRS_SEID(p, p_msg->security_cmd.hdr.seid);
    847     if (avdt_scb_by_hdl(p_msg->security_cmd.hdr.seid) == NULL) {
    848       err = AVDT_ERR_SEID;
    849     } else {
    850       p_msg->security_cmd.p_data = p;
    851       p_msg->security_cmd.len = len - 1;
    852     }
    853   }
    854   return err;
    855 }
    856 
    857 /*******************************************************************************
    858  *
    859  * Function         avdt_msg_prs_discover_rsp
    860  *
    861  * Description      This message parsing function parses a discover
    862  *                  response message.
    863  *
    864  *
    865  * Returns          Error code or zero if no error.
    866  *
    867  ******************************************************************************/
    868 static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG* p_msg, uint8_t* p,
    869                                          uint16_t len) {
    870   int i;
    871   uint8_t err = 0;
    872 
    873   /* determine number of seps; seps in msg is len/2, but set to minimum
    874   ** of seps app has supplied memory for and seps in msg
    875   */
    876   if (p_msg->discover_rsp.num_seps > (len / 2)) {
    877     p_msg->discover_rsp.num_seps = (len / 2);
    878   }
    879 
    880   /* parse out sep info */
    881   for (i = 0; i < p_msg->discover_rsp.num_seps; i++) {
    882     /* parse discover rsp info */
    883     AVDT_MSG_PRS_DISC(p, p_msg->discover_rsp.p_sep_info[i].seid,
    884                       p_msg->discover_rsp.p_sep_info[i].in_use,
    885                       p_msg->discover_rsp.p_sep_info[i].media_type,
    886                       p_msg->discover_rsp.p_sep_info[i].tsep);
    887 
    888     /* verify that seid is valid */
    889     if ((p_msg->discover_rsp.p_sep_info[i].seid < AVDT_SEID_MIN) ||
    890         (p_msg->discover_rsp.p_sep_info[i].seid > AVDT_SEID_MAX)) {
    891       err = AVDT_ERR_SEID;
    892       break;
    893     }
    894   }
    895 
    896   return err;
    897 }
    898 
    899 /*******************************************************************************
    900  *
    901  * Function         avdt_msg_prs_svccap
    902  *
    903  * Description      This message parsing function parses a message containing
    904  *                  service capabilities parameters.
    905  *
    906  *
    907  * Returns          Error code or zero if no error.
    908  *
    909  ******************************************************************************/
    910 static uint8_t avdt_msg_prs_svccap(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len) {
    911   /* parse parameters */
    912   uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len,
    913                                  &p_msg->hdr.err_param, AVDT_SIG_GETCAP);
    914   if (p_msg->svccap.p_cfg) {
    915     p_msg->svccap.p_cfg->psc_mask &= AVDT_LEG_PSC;
    916   }
    917 
    918   return (err);
    919 }
    920 
    921 /*******************************************************************************
    922  *
    923  * Function         avdt_msg_prs_all_svccap
    924  *
    925  * Description      This message parsing function parses a message containing
    926  *                  service capabilities parameters.
    927  *
    928  *
    929  * Returns          Error code or zero if no error.
    930  *
    931  ******************************************************************************/
    932 static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG* p_msg, uint8_t* p,
    933                                        uint16_t len) {
    934   uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len,
    935                                  &p_msg->hdr.err_param, AVDT_SIG_GET_ALLCAP);
    936   if (p_msg->svccap.p_cfg) {
    937     p_msg->svccap.p_cfg->psc_mask &= AVDT_MSG_PSC_MASK;
    938   }
    939   return (err);
    940 }
    941 
    942 /*******************************************************************************
    943  *
    944  * Function         avdt_msg_prs_security_rsp
    945  *
    946  * Description      This message parsing function parsing a security
    947  *                  response message.
    948  *
    949  *
    950  * Returns          Error code or zero if no error.
    951  *
    952  ******************************************************************************/
    953 static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG* p_msg, uint8_t* p,
    954                                          uint16_t len) {
    955   p_msg->security_rsp.p_data = p;
    956   p_msg->security_rsp.len = len;
    957 
    958   return 0;
    959 }
    960 
    961 /*******************************************************************************
    962  *
    963  * Function         avdt_msg_prs_rej
    964  *
    965  * Description
    966  *
    967  *
    968  * Returns          Error code or zero if no error.
    969  *
    970  ******************************************************************************/
    971 static uint8_t avdt_msg_prs_rej(tAVDT_MSG* p_msg, uint8_t* p, uint8_t sig) {
    972   if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG)) {
    973     p_msg->hdr.err_param = *p++;
    974     p_msg->hdr.err_code = *p;
    975   } else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND)) {
    976     AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
    977     p_msg->hdr.err_code = *p;
    978   } else {
    979     p_msg->hdr.err_code = *p;
    980   }
    981 
    982   return 0;
    983 }
    984 
    985 /*******************************************************************************
    986  *
    987  * Function         avdt_msg_prs_delay_rpt
    988  *
    989  * Description      This message parsing function parses a security
    990  *                  command message.
    991  *
    992  *
    993  * Returns          Error code or zero if no error.
    994  *
    995  ******************************************************************************/
    996 static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p,
    997                                       uint16_t len) {
    998   uint8_t err = 0;
    999 
   1000   /* verify len */
   1001   if (len != AVDT_LEN_DELAY_RPT) {
   1002     AVDT_TRACE_WARNING("avdt_msg_prs_delay_rpt expected len: %u  got: %u",
   1003                        AVDT_LEN_DELAY_RPT, len);
   1004     err = AVDT_ERR_LENGTH;
   1005   } else {
   1006     /* get seid */
   1007     AVDT_MSG_PRS_SEID(p, p_msg->delay_rpt_cmd.hdr.seid);
   1008 
   1009     if (avdt_scb_by_hdl(p_msg->delay_rpt_cmd.hdr.seid) == NULL) {
   1010       err = AVDT_ERR_SEID;
   1011     } else {
   1012       BE_STREAM_TO_UINT16(p_msg->delay_rpt_cmd.delay, p);
   1013       AVDT_TRACE_DEBUG("avdt_msg_prs_delay_rpt delay: %u",
   1014                        p_msg->delay_rpt_cmd.delay);
   1015     }
   1016   }
   1017   return err;
   1018 }
   1019 
   1020 /*******************************************************************************
   1021  *
   1022  * Function         avdt_msg_send
   1023  *
   1024  * Description      Send, and if necessary fragment the next message.
   1025  *
   1026  *
   1027  * Returns          Congested state; true if CCB congested, false if not.
   1028  *
   1029  ******************************************************************************/
   1030 bool avdt_msg_send(tAVDT_CCB* p_ccb, BT_HDR* p_msg) {
   1031   uint16_t curr_msg_len;
   1032   uint8_t pkt_type;
   1033   uint8_t hdr_len;
   1034   tAVDT_TC_TBL* p_tbl;
   1035   BT_HDR* p_buf;
   1036   uint8_t* p;
   1037   uint8_t label;
   1038   uint8_t msg;
   1039   uint8_t sig;
   1040   uint8_t nosp = 0; /* number of subsequent packets */
   1041 
   1042   /* look up transport channel table entry to get peer mtu */
   1043   p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_SIG, p_ccb, NULL);
   1044 
   1045   /* set the current message if there is a message passed in */
   1046   if (p_msg != NULL) {
   1047     p_ccb->p_curr_msg = p_msg;
   1048   }
   1049 
   1050   /* store copy of curr_msg->len */
   1051   curr_msg_len = p_ccb->p_curr_msg->len;
   1052 
   1053   /* while not congested and we haven't sent it all */
   1054   while ((!p_ccb->cong) && (p_ccb->p_curr_msg != NULL)) {
   1055     /* check what kind of message we've got here; we are using the offset
   1056     ** to indicate that a message is being fragmented
   1057     */
   1058 
   1059     /* if message isn't being fragmented and it fits in mtu */
   1060     if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
   1061         (p_ccb->p_curr_msg->len <= p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE)) {
   1062       pkt_type = AVDT_PKT_TYPE_SINGLE;
   1063       hdr_len = AVDT_LEN_TYPE_SINGLE;
   1064       p_buf = p_ccb->p_curr_msg;
   1065     }
   1066     /* if message isn't being fragmented and it doesn't fit in mtu */
   1067     else if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
   1068              (p_ccb->p_curr_msg->len >
   1069               p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE)) {
   1070       pkt_type = AVDT_PKT_TYPE_START;
   1071       hdr_len = AVDT_LEN_TYPE_START;
   1072       nosp = (p_ccb->p_curr_msg->len + AVDT_LEN_TYPE_START - p_tbl->peer_mtu) /
   1073                  (p_tbl->peer_mtu - 1) +
   1074              2;
   1075 
   1076       /* get a new buffer for fragment we are sending */
   1077       p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1078 
   1079       /* copy portion of data from current message to new buffer */
   1080       p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
   1081       p_buf->len = p_tbl->peer_mtu - hdr_len;
   1082       memcpy((uint8_t*)(p_buf + 1) + p_buf->offset,
   1083              (uint8_t*)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset,
   1084              p_buf->len);
   1085     }
   1086     /* if message is being fragmented and remaining bytes don't fit in mtu */
   1087     else if ((p_ccb->p_curr_msg->offset > AVDT_MSG_OFFSET) &&
   1088              (p_ccb->p_curr_msg->len >
   1089               (p_tbl->peer_mtu - AVDT_LEN_TYPE_CONT))) {
   1090       pkt_type = AVDT_PKT_TYPE_CONT;
   1091       hdr_len = AVDT_LEN_TYPE_CONT;
   1092 
   1093       /* get a new buffer for fragment we are sending */
   1094       p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1095 
   1096       /* copy portion of data from current message to new buffer */
   1097       p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
   1098       p_buf->len = p_tbl->peer_mtu - hdr_len;
   1099       memcpy((uint8_t*)(p_buf + 1) + p_buf->offset,
   1100              (uint8_t*)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset,
   1101              p_buf->len);
   1102     }
   1103     /* if message is being fragmented and remaining bytes do fit in mtu */
   1104     else {
   1105       pkt_type = AVDT_PKT_TYPE_END;
   1106       hdr_len = AVDT_LEN_TYPE_END;
   1107       p_buf = p_ccb->p_curr_msg;
   1108     }
   1109 
   1110     /* label, sig id, msg type are in hdr of p_curr_msg */
   1111     label = AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_msg->layer_specific);
   1112     msg = AVDT_LAYERSPEC_MSG(p_ccb->p_curr_msg->layer_specific);
   1113     sig = (uint8_t)p_ccb->p_curr_msg->event;
   1114     AVDT_TRACE_DEBUG("avdt_msg_send label:%d, msg:%d, sig:%d", label, msg, sig);
   1115 
   1116     /* keep track of how much of msg we've sent */
   1117     curr_msg_len -= p_buf->len;
   1118     if (curr_msg_len == 0) {
   1119       /* entire message sent; mark as finished */
   1120       p_ccb->p_curr_msg = NULL;
   1121 
   1122       /* start timer here for commands */
   1123       if (msg == AVDT_MSG_TYPE_CMD) {
   1124         /* if retransmit timeout set to zero, sig doesn't use retransmit */
   1125         if ((sig == AVDT_SIG_DISCOVER) || (sig == AVDT_SIG_GETCAP) ||
   1126             (sig == AVDT_SIG_SECURITY) || (avdt_cb.rcb.ret_tout == 0)) {
   1127           alarm_cancel(p_ccb->idle_ccb_timer);
   1128           alarm_cancel(p_ccb->ret_ccb_timer);
   1129           period_ms_t interval_ms = avdt_cb.rcb.sig_tout * 1000;
   1130           alarm_set_on_queue(p_ccb->rsp_ccb_timer, interval_ms,
   1131                              avdt_ccb_rsp_ccb_timer_timeout, p_ccb,
   1132                              btu_general_alarm_queue);
   1133         } else if (sig != AVDT_SIG_DELAY_RPT) {
   1134           alarm_cancel(p_ccb->idle_ccb_timer);
   1135           alarm_cancel(p_ccb->rsp_ccb_timer);
   1136           period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
   1137           alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
   1138                              avdt_ccb_ret_ccb_timer_timeout, p_ccb,
   1139                              btu_general_alarm_queue);
   1140         }
   1141       }
   1142     } else {
   1143       /* message being fragmented and not completely sent */
   1144       p_ccb->p_curr_msg->len -= p_buf->len;
   1145       p_ccb->p_curr_msg->offset += p_buf->len;
   1146     }
   1147 
   1148     /* set up to build header */
   1149     p_buf->len += hdr_len;
   1150     p_buf->offset -= hdr_len;
   1151     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1152 
   1153     /* build header */
   1154     AVDT_MSG_BLD_HDR(p, label, pkt_type, msg);
   1155     if (pkt_type == AVDT_PKT_TYPE_START) {
   1156       AVDT_MSG_BLD_NOSP(p, nosp);
   1157     }
   1158     if ((pkt_type == AVDT_PKT_TYPE_START) ||
   1159         (pkt_type == AVDT_PKT_TYPE_SINGLE)) {
   1160       AVDT_MSG_BLD_SIG(p, sig);
   1161     }
   1162 
   1163     /* send msg buffer down */
   1164     avdt_ad_write_req(AVDT_CHAN_SIG, p_ccb, NULL, p_buf);
   1165   }
   1166   return (p_ccb->cong);
   1167 }
   1168 
   1169 /*******************************************************************************
   1170  *
   1171  * Function         avdt_msg_asmbl
   1172  *
   1173  * Description      Reassemble incoming message.
   1174  *
   1175  *
   1176  * Returns          Pointer to reassembled message;  NULL if no message
   1177  *                  available.
   1178  *
   1179  ******************************************************************************/
   1180 BT_HDR* avdt_msg_asmbl(tAVDT_CCB* p_ccb, BT_HDR* p_buf) {
   1181   uint8_t* p;
   1182   uint8_t pkt_type;
   1183   BT_HDR* p_ret;
   1184 
   1185   /* parse the message header */
   1186   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1187   AVDT_MSG_PRS_PKT_TYPE(p, pkt_type);
   1188 
   1189   /* quick sanity check on length */
   1190   if (p_buf->len < avdt_msg_pkt_type_len[pkt_type]) {
   1191     osi_free(p_buf);
   1192     AVDT_TRACE_WARNING("Bad length during reassembly");
   1193     p_ret = NULL;
   1194   }
   1195   /* single packet */
   1196   else if (pkt_type == AVDT_PKT_TYPE_SINGLE) {
   1197     /* if reassembly in progress drop message and process new single */
   1198     if (p_ccb->p_rx_msg != NULL)
   1199       AVDT_TRACE_WARNING("Got single during reassembly");
   1200 
   1201     osi_free_and_reset((void**)&p_ccb->p_rx_msg);
   1202 
   1203     p_ret = p_buf;
   1204   }
   1205   /* start packet */
   1206   else if (pkt_type == AVDT_PKT_TYPE_START) {
   1207     /* if reassembly in progress drop message and process new single */
   1208     if (p_ccb->p_rx_msg != NULL)
   1209       AVDT_TRACE_WARNING("Got start during reassembly");
   1210 
   1211     osi_free_and_reset((void**)&p_ccb->p_rx_msg);
   1212 
   1213     /*
   1214      * Allocate bigger buffer for reassembly. As lower layers are
   1215      * not aware of possible packet size after reassembly, they
   1216      * would have allocated smaller buffer.
   1217      */
   1218     p_ccb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
   1219     memcpy(p_ccb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len);
   1220 
   1221     /* Free original buffer */
   1222     osi_free(p_buf);
   1223 
   1224     /* update p to point to new buffer */
   1225     p = (uint8_t*)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset;
   1226 
   1227     /* copy first header byte over nosp */
   1228     *(p + 1) = *p;
   1229 
   1230     /* set offset to point to where to copy next */
   1231     p_ccb->p_rx_msg->offset += p_ccb->p_rx_msg->len;
   1232 
   1233     /* adjust length for packet header */
   1234     p_ccb->p_rx_msg->len -= 1;
   1235 
   1236     p_ret = NULL;
   1237   }
   1238   /* continue or end */
   1239   else {
   1240     /* if no reassembly in progress drop message */
   1241     if (p_ccb->p_rx_msg == NULL) {
   1242       osi_free(p_buf);
   1243       AVDT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
   1244       p_ret = NULL;
   1245     } else {
   1246       /* get size of buffer holding assembled message */
   1247       /*
   1248        * NOTE: The buffer is allocated above at the beginning of the
   1249        * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
   1250        */
   1251       uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
   1252 
   1253       /* adjust offset and len of fragment for header byte */
   1254       p_buf->offset += AVDT_LEN_TYPE_CONT;
   1255       p_buf->len -= AVDT_LEN_TYPE_CONT;
   1256 
   1257       /* verify length */
   1258       if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
   1259         /* won't fit; free everything */
   1260         AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
   1261         osi_free_and_reset((void**)&p_ccb->p_rx_msg);
   1262         osi_free(p_buf);
   1263         p_ret = NULL;
   1264       } else {
   1265         /* copy contents of p_buf to p_rx_msg */
   1266         memcpy((uint8_t*)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset,
   1267                (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
   1268 
   1269         if (pkt_type == AVDT_PKT_TYPE_END) {
   1270           p_ccb->p_rx_msg->offset -= p_ccb->p_rx_msg->len;
   1271           p_ccb->p_rx_msg->len += p_buf->len;
   1272           p_ret = p_ccb->p_rx_msg;
   1273           p_ccb->p_rx_msg = NULL;
   1274         } else {
   1275           p_ccb->p_rx_msg->offset += p_buf->len;
   1276           p_ccb->p_rx_msg->len += p_buf->len;
   1277           p_ret = NULL;
   1278         }
   1279         osi_free(p_buf);
   1280       }
   1281     }
   1282   }
   1283   return p_ret;
   1284 }
   1285 
   1286 /*******************************************************************************
   1287  *
   1288  * Function         avdt_msg_send_cmd
   1289  *
   1290  * Description      This function is called to send a command message.  The
   1291  *                  sig_id parameter indicates the message type, p_params
   1292  *                  points to the message parameters, if any.  It gets a buffer
   1293  *                  from the AVDTP command pool, executes the message building
   1294  *                  function for this message type.  It then queues the message
   1295  *                  in the command queue for this CCB.
   1296  *
   1297  *
   1298  * Returns          Nothing.
   1299  *
   1300  ******************************************************************************/
   1301 void avdt_msg_send_cmd(tAVDT_CCB* p_ccb, void* p_scb, uint8_t sig_id,
   1302                        tAVDT_MSG* p_params) {
   1303   uint8_t* p;
   1304   uint8_t* p_start;
   1305   BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1306 
   1307   /* set up buf pointer and offset */
   1308   p_buf->offset = AVDT_MSG_OFFSET;
   1309   p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1310 
   1311   /* execute parameter building function to build message */
   1312   (*avdt_msg_bld_cmd[sig_id - 1])(&p, p_params);
   1313 
   1314   /* set len */
   1315   p_buf->len = (uint16_t)(p - p_start);
   1316 
   1317   /* now store scb hdls, if any, in buf */
   1318   if (p_scb != NULL) {
   1319     p = (uint8_t*)(p_buf + 1);
   1320 
   1321     /* for start and suspend, p_scb points to array of handles */
   1322     if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND)) {
   1323       memcpy(p, (uint8_t*)p_scb, p_buf->len);
   1324     }
   1325     /* for all others, p_scb points to scb as usual */
   1326     else {
   1327       *p = avdt_scb_to_hdl((tAVDT_SCB*)p_scb);
   1328     }
   1329   }
   1330 
   1331   /* stash sig, label, and message type in buf */
   1332   p_buf->event = sig_id;
   1333   AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_CMD, p_ccb->label);
   1334 
   1335   /* increment label */
   1336   p_ccb->label = (p_ccb->label + 1) % 16;
   1337 
   1338   /* queue message and trigger ccb to send it */
   1339   fixed_queue_enqueue(p_ccb->cmd_q, p_buf);
   1340   avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
   1341 }
   1342 
   1343 /*******************************************************************************
   1344  *
   1345  * Function         avdt_msg_send_rsp
   1346  *
   1347  * Description      This function is called to send a response message.  The
   1348  *                  sig_id parameter indicates the message type, p_params
   1349  *                  points to the message parameters, if any.  It gets a buffer
   1350  *                  from the AVDTP command pool, executes the message building
   1351  *                  function for this message type.  It then queues the message
   1352  *                  in the response queue for this CCB.
   1353  *
   1354  *
   1355  * Returns          Nothing.
   1356  *
   1357  ******************************************************************************/
   1358 void avdt_msg_send_rsp(tAVDT_CCB* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
   1359   uint8_t* p;
   1360   uint8_t* p_start;
   1361   BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1362 
   1363   /* set up buf pointer and offset */
   1364   p_buf->offset = AVDT_MSG_OFFSET;
   1365   p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1366 
   1367   /* execute parameter building function to build message */
   1368   (*avdt_msg_bld_rsp[sig_id - 1])(&p, p_params);
   1369 
   1370   /* set length */
   1371   p_buf->len = (uint16_t)(p - p_start);
   1372 
   1373   /* stash sig, label, and message type in buf */
   1374   p_buf->event = sig_id;
   1375   AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_RSP,
   1376                      p_params->hdr.label);
   1377 
   1378   /* queue message and trigger ccb to send it */
   1379   fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
   1380   avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
   1381 }
   1382 
   1383 /*******************************************************************************
   1384  *
   1385  * Function         avdt_msg_send_rej
   1386  *
   1387  * Description      This function is called to send a reject message.  The
   1388  *                  sig_id parameter indicates the message type.  It gets
   1389  *                  a buffer from the AVDTP command pool and builds the
   1390  *                  message based on the message type and the error code.
   1391  *                  It then queues the message in the response queue for
   1392  *                  this CCB.
   1393  *
   1394  *
   1395  * Returns          Nothing.
   1396  *
   1397  ******************************************************************************/
   1398 void avdt_msg_send_rej(tAVDT_CCB* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
   1399   uint8_t* p;
   1400   uint8_t* p_start;
   1401   BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1402 
   1403   /* set up buf pointer and offset */
   1404   p_buf->offset = AVDT_MSG_OFFSET;
   1405   p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1406 
   1407   /* if sig id included, build into message */
   1408   if (sig_id != AVDT_SIG_NONE) {
   1409     /* if this sig has a parameter, add the parameter */
   1410     if ((sig_id == AVDT_SIG_SETCONFIG) || (sig_id == AVDT_SIG_RECONFIG)) {
   1411       AVDT_MSG_BLD_PARAM(p, p_params->hdr.err_param);
   1412     } else if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND)) {
   1413       AVDT_MSG_BLD_SEID(p, p_params->hdr.err_param);
   1414     }
   1415 
   1416     /* add the error code */
   1417     AVDT_MSG_BLD_ERR(p, p_params->hdr.err_code);
   1418   }
   1419   AVDT_TRACE_DEBUG("avdt_msg_send_rej");
   1420 
   1421   /* calculate length */
   1422   p_buf->len = (uint16_t)(p - p_start);
   1423 
   1424   /* stash sig, label, and message type in buf */
   1425   p_buf->event = sig_id;
   1426   AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_REJ,
   1427                      p_params->hdr.label);
   1428 
   1429   /* queue message and trigger ccb to send it */
   1430   fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
   1431   avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
   1432 }
   1433 
   1434 /*******************************************************************************
   1435  *
   1436  * Function         avdt_msg_send_grej
   1437  *
   1438  * Description      This function is called to send a general reject message.
   1439  *                  The sig_id parameter indicates the message type.  It gets
   1440  *                  a buffer from the AVDTP command pool and builds the
   1441  *                  message based on the message type and the error code.
   1442  *                  It then queues the message in the response queue for
   1443  *                  this CCB.
   1444  *
   1445  *
   1446  * Returns          Nothing.
   1447  *
   1448  ******************************************************************************/
   1449 void avdt_msg_send_grej(tAVDT_CCB* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) {
   1450   uint8_t* p;
   1451   uint8_t* p_start;
   1452   BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVDT_CMD_BUF_SIZE);
   1453 
   1454   /* set up buf pointer and offset */
   1455   p_buf->offset = AVDT_MSG_OFFSET;
   1456   p_start = p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1457 
   1458   /* calculate length */
   1459   p_buf->len = (uint16_t)(p - p_start);
   1460 
   1461   /* stash sig, label, and message type in buf */
   1462   p_buf->event = sig_id;
   1463   AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ,
   1464                      p_params->hdr.label);
   1465   AVDT_TRACE_DEBUG(__func__);
   1466 
   1467   /* queue message and trigger ccb to send it */
   1468   fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
   1469   avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
   1470 }
   1471 
   1472 /*******************************************************************************
   1473  *
   1474  * Function         avdt_msg_ind
   1475  *
   1476  * Description      This function is called by the adaption layer when an
   1477  *                  incoming message is received on the signaling channel.
   1478  *                  It parses the message and sends an event to the appropriate
   1479  *                  SCB or CCB for the message.
   1480  *
   1481  *
   1482  * Returns          Nothing.
   1483  *
   1484  ******************************************************************************/
   1485 void avdt_msg_ind(tAVDT_CCB* p_ccb, BT_HDR* p_buf) {
   1486   tAVDT_SCB* p_scb;
   1487   uint8_t* p;
   1488   bool ok = true;
   1489   bool handle_rsp = false;
   1490   bool gen_rej = false;
   1491   uint8_t label;
   1492   uint8_t pkt_type;
   1493   uint8_t msg_type;
   1494   uint8_t sig = 0;
   1495   tAVDT_MSG msg;
   1496   tAVDT_CFG cfg;
   1497   uint8_t err;
   1498   uint8_t evt = 0;
   1499   uint8_t scb_hdl;
   1500 
   1501   /* reassemble message; if no message available (we received a fragment) return
   1502    */
   1503   p_buf = avdt_msg_asmbl(p_ccb, p_buf);
   1504   if (p_buf == NULL) {
   1505     return;
   1506   }
   1507 
   1508   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   1509 
   1510   /* parse the message header */
   1511   AVDT_MSG_PRS_HDR(p, label, pkt_type, msg_type);
   1512 
   1513   AVDT_TRACE_DEBUG("msg_type=%d, sig=%d", msg_type, sig);
   1514   /* set up label and ccb_idx in message hdr */
   1515   msg.hdr.label = label;
   1516   msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
   1517 
   1518   /* verify msg type */
   1519   if (msg_type == AVDT_MSG_TYPE_GRJ) {
   1520     AVDT_TRACE_WARNING("Dropping msg msg_type=%d", msg_type);
   1521     ok = false;
   1522   }
   1523   /* check for general reject */
   1524   else if ((msg_type == AVDT_MSG_TYPE_REJ) &&
   1525            (p_buf->len == AVDT_LEN_GEN_REJ)) {
   1526     gen_rej = true;
   1527     if (p_ccb->p_curr_cmd != NULL) {
   1528       msg.hdr.sig_id = sig = (uint8_t)p_ccb->p_curr_cmd->event;
   1529       evt = avdt_msg_rej_2_evt[sig - 1];
   1530       msg.hdr.err_code = AVDT_ERR_NSC;
   1531       msg.hdr.err_param = 0;
   1532     }
   1533   } else /* not a general reject */
   1534   {
   1535     /* get and verify signal */
   1536     AVDT_MSG_PRS_SIG(p, sig);
   1537     msg.hdr.sig_id = sig;
   1538     if ((sig == 0) || (sig > AVDT_SIG_MAX)) {
   1539       AVDT_TRACE_WARNING("Dropping msg sig=%d msg_type:%d", sig, msg_type);
   1540       ok = false;
   1541 
   1542       /* send a general reject */
   1543       if (msg_type == AVDT_MSG_TYPE_CMD) {
   1544         avdt_msg_send_grej(p_ccb, sig, &msg);
   1545       }
   1546     }
   1547   }
   1548 
   1549   if (ok && !gen_rej) {
   1550     /* skip over header (msg length already verified during reassembly) */
   1551     p_buf->len -= AVDT_LEN_TYPE_SINGLE;
   1552 
   1553     /* set up to parse message */
   1554     if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_DISCOVER)) {
   1555       /* parse discover rsp message to struct supplied by app */
   1556       msg.discover_rsp.p_sep_info = (tAVDT_SEP_INFO*)p_ccb->p_proc_data;
   1557       msg.discover_rsp.num_seps = p_ccb->proc_param;
   1558     } else if ((msg_type == AVDT_MSG_TYPE_RSP) &&
   1559                ((sig == AVDT_SIG_GETCAP) || (sig == AVDT_SIG_GET_ALLCAP))) {
   1560       /* parse discover rsp message to struct supplied by app */
   1561       msg.svccap.p_cfg = (tAVDT_CFG*)p_ccb->p_proc_data;
   1562     } else if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_GETCONFIG)) {
   1563       /* parse get config rsp message to struct allocated locally */
   1564       msg.svccap.p_cfg = &cfg;
   1565     } else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_SETCONFIG)) {
   1566       /* parse config cmd message to struct allocated locally */
   1567       msg.config_cmd.p_cfg = &cfg;
   1568     } else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_RECONFIG)) {
   1569       /* parse reconfig cmd message to struct allocated locally */
   1570       msg.reconfig_cmd.p_cfg = &cfg;
   1571     }
   1572 
   1573     /* parse message; while we're at it map message sig to event */
   1574     if (msg_type == AVDT_MSG_TYPE_CMD) {
   1575       msg.hdr.err_code = err =
   1576           (*avdt_msg_prs_cmd[sig - 1])(&msg, p, p_buf->len);
   1577       evt = avdt_msg_cmd_2_evt[sig - 1];
   1578     } else if (msg_type == AVDT_MSG_TYPE_RSP) {
   1579       msg.hdr.err_code = err =
   1580           (*avdt_msg_prs_rsp[sig - 1])(&msg, p, p_buf->len);
   1581       evt = avdt_msg_rsp_2_evt[sig - 1];
   1582     } else /* msg_type == AVDT_MSG_TYPE_REJ */
   1583     {
   1584       err = avdt_msg_prs_rej(&msg, p, sig);
   1585       evt = avdt_msg_rej_2_evt[sig - 1];
   1586     }
   1587 
   1588     /* if parsing failed */
   1589     if (err != 0) {
   1590       AVDT_TRACE_WARNING("Parsing failed sig=%d err=0x%x", sig, err);
   1591 
   1592       /* if its a rsp or rej, drop it; if its a cmd, send a rej;
   1593       ** note special case for abort; never send abort reject
   1594       */
   1595       ok = false;
   1596       if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig != AVDT_SIG_ABORT)) {
   1597         avdt_msg_send_rej(p_ccb, sig, &msg);
   1598       }
   1599     }
   1600   }
   1601 
   1602   /* if its a rsp or rej, check sent cmd to see if we're waiting for
   1603   ** the rsp or rej.  If we didn't send a cmd for it, drop it.  If
   1604   ** it does match a cmd, stop timer for the cmd.
   1605   */
   1606   if (ok) {
   1607     if ((msg_type == AVDT_MSG_TYPE_RSP) || (msg_type == AVDT_MSG_TYPE_REJ)) {
   1608       if ((p_ccb->p_curr_cmd != NULL) && (p_ccb->p_curr_cmd->event == sig) &&
   1609           (AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_cmd->layer_specific) == label)) {
   1610         /* stop timer */
   1611         alarm_cancel(p_ccb->idle_ccb_timer);
   1612         alarm_cancel(p_ccb->ret_ccb_timer);
   1613         alarm_cancel(p_ccb->rsp_ccb_timer);
   1614 
   1615         /* clear retransmission count */
   1616         p_ccb->ret_count = 0;
   1617 
   1618         /* later in this function handle ccb event */
   1619         handle_rsp = true;
   1620       } else {
   1621         ok = false;
   1622         AVDT_TRACE_WARNING("Cmd not found for rsp sig=%d label=%d", sig, label);
   1623       }
   1624     }
   1625   }
   1626 
   1627   if (ok) {
   1628     /* if it's a ccb event send to ccb */
   1629     if (evt & AVDT_CCB_MKR) {
   1630       avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR),
   1631                      (tAVDT_CCB_EVT*)&msg);
   1632     }
   1633     /* if it's a scb event */
   1634     else {
   1635       /* Scb events always have a single seid.  For cmd, get seid from
   1636       ** message.  For rej and rsp, get seid from p_curr_cmd.
   1637       */
   1638       if (msg_type == AVDT_MSG_TYPE_CMD) {
   1639         scb_hdl = msg.single.seid;
   1640       } else {
   1641         scb_hdl = *((uint8_t*)(p_ccb->p_curr_cmd + 1));
   1642       }
   1643 
   1644       /* Map seid to the scb and send it the event.  For cmd, seid has
   1645       ** already been verified by parsing function.
   1646       */
   1647       if (evt) {
   1648         p_scb = avdt_scb_by_hdl(scb_hdl);
   1649         if (p_scb != NULL) {
   1650           avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT*)&msg);
   1651         }
   1652       }
   1653     }
   1654   }
   1655 
   1656   /* free message buffer */
   1657   osi_free(p_buf);
   1658 
   1659   /* if its a rsp or rej, send event to ccb to free associated
   1660   ** cmd msg buffer and handle cmd queue
   1661   */
   1662   if (handle_rsp) {
   1663     avdt_ccb_event(p_ccb, AVDT_CCB_RCVRSP_EVT, NULL);
   1664   }
   1665 }
   1666