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