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