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