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