blob: 0c5ed41ecdd76b100c1adeaa2b835de7536734c7 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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>
Chris Manton83e2c342014-09-29 21:37:44 -070030#include "bt_types.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080031#include "bt_target.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080032#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080033#include "avdt_api.h"
34#include "avdtc_api.h"
35#include "avdt_int.h"
Pavlin Radoslavov258c2532015-09-27 20:59:05 -070036#include "bt_common.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080037#include "btu.h"
38
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -080039extern fixed_queue_t *btu_general_alarm_queue;
40
The Android Open Source Project5738f832012-12-12 16:00:35 -080041/*****************************************************************************
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 */
Marie Janssend19e0782016-07-15 12:48:27 -070057typedef void (*tAVDT_MSG_BLD)(uint8_t **p, tAVDT_MSG *p_msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -080058
59/* type for message parsing functions */
Marie Janssend19e0782016-07-15 12:48:27 -070060typedef uint8_t (*tAVDT_MSG_PRS)(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
The Android Open Source Project5738f832012-12-12 16:00:35 -080061
62
63/*****************************************************************************
64** local function declarations
65*****************************************************************************/
66
Marie Janssend19e0782016-07-15 12:48:27 -070067static void avdt_msg_bld_none(uint8_t **p, tAVDT_MSG *p_msg);
68static void avdt_msg_bld_single(uint8_t **p, tAVDT_MSG *p_msg);
69static void avdt_msg_bld_setconfig_cmd(uint8_t **p, tAVDT_MSG *p_msg);
70static void avdt_msg_bld_reconfig_cmd(uint8_t **p, tAVDT_MSG *p_msg);
71static void avdt_msg_bld_multi(uint8_t **p, tAVDT_MSG *p_msg);
72static void avdt_msg_bld_security_cmd(uint8_t **p, tAVDT_MSG *p_msg);
73static void avdt_msg_bld_discover_rsp(uint8_t **p, tAVDT_MSG *p_msg);
74static void avdt_msg_bld_svccap(uint8_t **p, tAVDT_MSG *p_msg);
75static void avdt_msg_bld_security_rsp(uint8_t **p, tAVDT_MSG *p_msg);
76static void avdt_msg_bld_all_svccap(uint8_t **p, tAVDT_MSG *p_msg);
77static void avdt_msg_bld_delay_rpt(uint8_t **p, tAVDT_MSG *p_msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -080078
Marie Janssend19e0782016-07-15 12:48:27 -070079static uint8_t avdt_msg_prs_none(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
80static uint8_t avdt_msg_prs_single(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
81static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
82static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG *p_msg, uint8_t *p, 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, uint16_t len);
85static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
86static uint8_t avdt_msg_prs_svccap(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
87static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
88static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
89static uint8_t avdt_msg_prs_delay_rpt (tAVDT_MSG *p_msg, uint8_t *p, uint16_t len);
The Android Open Source Project5738f832012-12-12 16:00:35 -080090
91/*****************************************************************************
92** constants
93*****************************************************************************/
94
95/* table of information element minimum lengths used for parsing */
Marie Janssend19e0782016-07-15 12:48:27 -070096const uint8_t avdt_msg_ie_len_min[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -080097 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700109const uint8_t avdt_msg_ie_len_max[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800110 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700122const uint8_t avdt_msg_ie_err[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800123 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700135static const uint8_t avdt_msg_pkt_type_len[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800136 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 */
143const 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 */
160const 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 */
177const 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 */
194const 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700211const uint8_t avdt_msg_cmd_2_evt[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800212 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700228const uint8_t avdt_msg_rsp_2_evt[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800229 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 */
Marie Janssend19e0782016-07-15 12:48:27 -0700245const uint8_t avdt_msg_rej_2_evt[] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800246 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*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700272static void avdt_msg_bld_cfg(uint8_t **p, tAVDT_CFG *p_cfg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800273{
Marie Janssend19e0782016-07-15 12:48:27 -0700274 uint8_t len;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800275
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
Marie Janssend19e0782016-07-15 12:48:27 -0700285#if (AVDT_REPORTING == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800286 /* 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
The Android Open Source Project5738f832012-12-12 16:00:35 -0800318 /* delay report */
319 if (p_cfg->psc_mask & AVDT_PSC_DELAY_RPT)
320 {
321 *(*p)++ = AVDT_CAT_DELAY_RPT;
322 *(*p)++ = 0; /* length */
323 }
324}
325
326/*******************************************************************************
327**
328** Function avdt_msg_bld_none
329**
330** Description This message building function builds an empty message.
331**
332**
333** Returns void.
334**
335*******************************************************************************/
Myles Watsond35a6482016-10-27 08:52:16 -0700336static void avdt_msg_bld_none(UNUSED_ATTR uint8_t **p,
337 UNUSED_ATTR tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800338{
339 return;
340}
341
342/*******************************************************************************
343**
344** Function avdt_msg_bld_single
345**
346** Description This message building function builds a message containing
347** a single SEID.
348**
349**
350** Returns void.
351**
352*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700353static void avdt_msg_bld_single(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800354{
355 AVDT_MSG_BLD_SEID(*p, p_msg->single.seid);
356}
357
358/*******************************************************************************
359**
360** Function avdt_msg_bld_setconfig_cmd
361**
362** Description This message building function builds a set configuration
363** command message.
364**
365**
366** Returns void.
367**
368*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700369static void avdt_msg_bld_setconfig_cmd(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800370{
371 AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.hdr.seid);
372 AVDT_MSG_BLD_SEID(*p, p_msg->config_cmd.int_seid);
373 avdt_msg_bld_cfg(p, p_msg->config_cmd.p_cfg);
374}
375
376/*******************************************************************************
377**
378** Function avdt_msg_bld_reconfig_cmd
379**
380** Description This message building function builds a reconfiguration
381** command message.
382**
383**
384** Returns void.
385**
386*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700387static void avdt_msg_bld_reconfig_cmd(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800388{
389 AVDT_MSG_BLD_SEID(*p, p_msg->reconfig_cmd.hdr.seid);
390
391 /* force psc mask zero to build only codec and security */
392 p_msg->reconfig_cmd.p_cfg->psc_mask = 0;
393 avdt_msg_bld_cfg(p, p_msg->reconfig_cmd.p_cfg);
394}
395
396/*******************************************************************************
397**
398** Function avdt_msg_bld_multi
399**
400** Description This message building function builds a message containing
401** multiple SEID's.
402**
403**
404** Returns void.
405**
406*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700407static void avdt_msg_bld_multi(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800408{
409 int i;
410
411 for (i = 0; i < p_msg->multi.num_seps; i++)
412 {
413 AVDT_MSG_BLD_SEID(*p, p_msg->multi.seid_list[i]);
414 }
415}
416
417/*******************************************************************************
418**
419** Function avdt_msg_bld_security_cmd
420**
421** Description This message building function builds a security
422** command message.
423**
424** Returns void.
425**
426*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700427static void avdt_msg_bld_security_cmd(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800428{
429 AVDT_MSG_BLD_SEID(*p, p_msg->security_cmd.hdr.seid);
430 memcpy(*p, p_msg->security_cmd.p_data, p_msg->security_cmd.len);
431 *p += p_msg->security_cmd.len;
432}
433
434/*******************************************************************************
435**
436** Function avdt_msg_bld_delay_rpt
437**
438** Description This message building function builds a delay report
439** command message.
440**
441** Returns void.
442**
443*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700444static void avdt_msg_bld_delay_rpt(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800445{
446 AVDT_MSG_BLD_SEID(*p, p_msg->delay_rpt_cmd.hdr.seid);
447 UINT16_TO_BE_STREAM(*p, p_msg->delay_rpt_cmd.delay);
448}
449
450/*******************************************************************************
451**
452** Function avdt_msg_bld_discover_rsp
453**
454** Description This message building function builds a discover
455** response message.
456**
457**
458** Returns void.
459**
460*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700461static void avdt_msg_bld_discover_rsp(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800462{
463 int i;
464
465 for (i = 0; i < p_msg->discover_rsp.num_seps; i++)
466 {
467 /* build discover rsp info */
468 AVDT_MSG_BLD_DISC(*p, p_msg->discover_rsp.p_sep_info[i].seid,
469 p_msg->discover_rsp.p_sep_info[i].in_use,
470 p_msg->discover_rsp.p_sep_info[i].media_type,
471 p_msg->discover_rsp.p_sep_info[i].tsep);
472 }
473}
474
475/*******************************************************************************
476**
477** Function avdt_msg_bld_svccap
478**
479** Description This message building function builds a message containing
480** service capabilities parameters.
481**
482**
483** Returns void.
484**
485*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700486static void avdt_msg_bld_svccap(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800487{
488 tAVDT_CFG cfg;
489
490 /* make sure the delay report category is not reported */
491 memcpy (&cfg, p_msg->svccap.p_cfg, sizeof(tAVDT_CFG));
492 cfg.psc_mask &= ~AVDT_PSC_DELAY_RPT;
493 avdt_msg_bld_cfg(p, &cfg);
494}
495
496/*******************************************************************************
497**
498** Function avdt_msg_bld_all_svccap
499**
500** Description This message building function builds a message containing
501** service capabilities parameters.
502**
503**
504** Returns void.
505**
506*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700507static void avdt_msg_bld_all_svccap(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800508{
509 avdt_msg_bld_cfg(p, p_msg->svccap.p_cfg);
510}
511
512/*******************************************************************************
513**
514** Function avdt_msg_bld_security_rsp
515**
516** Description This message building function builds a security
517** response message.
518**
519**
520** Returns void.
521**
522*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700523static void avdt_msg_bld_security_rsp(uint8_t **p, tAVDT_MSG *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800524{
525 memcpy(*p, p_msg->security_rsp.p_data, p_msg->security_rsp.len);
526 *p += p_msg->security_rsp.len;
527}
528
529/*******************************************************************************
530**
531** Function avdt_msg_prs_cfg
532**
533** Description This message parsing function parses the configuration
534** parameters field of a message.
535**
536**
537** Returns Error code or zero if no error, and element that failed
538** in p_elem.
539**
540*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700541static uint8_t avdt_msg_prs_cfg(tAVDT_CFG *p_cfg, uint8_t *p, uint16_t len, uint8_t* p_elem, uint8_t sig_id)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800542{
Marie Janssend19e0782016-07-15 12:48:27 -0700543 uint8_t *p_end;
544 uint8_t elem = 0;
545 uint8_t elem_len;
546 uint8_t tmp;
547 uint8_t err = 0;
548 uint8_t protect_offset = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800549
550 if (!p_cfg)
551 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700552 AVDT_TRACE_ERROR ("not expecting this cfg");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800553 return AVDT_ERR_BAD_STATE;
554 }
555
556 p_cfg->psc_mask = 0;
557 p_cfg->num_codec = 0;
558 p_cfg->num_protect = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800559
560 /* while there is still data to parse */
561 p_end = p + len;
562 while ((p < p_end) && (err == 0))
563 {
564 /* verify overall length */
565 if ((p_end - p) < AVDT_LEN_CFG_MIN)
566 {
567 err = AVDT_ERR_PAYLOAD;
568 break;
569 }
570
571 /* get and verify info elem id, length */
572 elem = *p++;
573 elem_len = *p++;
574
575 if ((elem == 0) || (elem > AVDT_CAT_MAX_CUR))
576 {
577 /* this may not be really bad.
578 * It may be a service category that is too new for us.
579 * allow these to be parsed without reporting an error.
580 * If this is a "capability" (as in GetCapRsp & GetConfigRsp), this is filtered out.
581 * If this is a Configuration (as in SetConfigCmd & ReconfigCmd),
582 * this will be marked as an error in the caller of this function */
583 if ((sig_id == AVDT_SIG_SETCONFIG) || (sig_id == AVDT_SIG_RECONFIG))
584 {
585 /* Cannot accept unknown category. */
586 err = AVDT_ERR_CATEGORY;
587 break;
588 }
589 else /* GETCAP or GET_ALLCAP */
590 {
591 /* Skip unknown categories. */
592 p += elem_len;
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700593 AVDT_TRACE_DEBUG("skipping unknown service category=%d len: %d", elem, elem_len);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800594 continue;
595 }
596 }
597
598 if ((elem_len > avdt_msg_ie_len_max[elem]) ||
599 (elem_len < avdt_msg_ie_len_min[elem]))
600 {
601 err = avdt_msg_ie_err[elem];
602 break;
603 }
604
605 /* add element to psc mask, but mask out codec or protect */
606 p_cfg->psc_mask |= (1 << elem);
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700607 AVDT_TRACE_DEBUG("elem=%d elem_len: %d psc_mask=0x%x", elem, elem_len, p_cfg->psc_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800608
609 /* parse individual information elements with additional parameters */
610 switch (elem)
611 {
612 case AVDT_CAT_RECOV:
613 p_cfg->recov_type = *p++;
614 p_cfg->recov_mrws = *p++;
615 p_cfg->recov_mnmp = *p++;
616 if (p_cfg->recov_type != AVDT_RECOV_RFC2733)
617 {
618 err = AVDT_ERR_RECOV_TYPE;
619 }
620 else if ((p_cfg->recov_mrws < AVDT_RECOV_MRWS_MIN) ||
621 (p_cfg->recov_mrws > AVDT_RECOV_MRWS_MAX) ||
622 (p_cfg->recov_mnmp < AVDT_RECOV_MNMP_MIN) ||
623 (p_cfg->recov_mnmp > AVDT_RECOV_MNMP_MAX))
624 {
625 err = AVDT_ERR_RECOV_FMT;
626 }
627 break;
628
629 case AVDT_CAT_PROTECT:
630 p_cfg->psc_mask &= ~AVDT_PSC_PROTECT;
631 if ((elem_len + protect_offset) < AVDT_PROTECT_SIZE)
632 {
633 p_cfg->num_protect++;
634 p_cfg->protect_info[protect_offset] = elem_len;
635 protect_offset++;
636 memcpy(&p_cfg->protect_info[protect_offset], p, elem_len);
637 protect_offset += elem_len;
638 }
639 p += elem_len;
640 break;
641
642 case AVDT_CAT_HDRCMP:
643 p_cfg->hdrcmp_mask = *p++;
644 break;
645
The Android Open Source Project5738f832012-12-12 16:00:35 -0800646 case AVDT_CAT_CODEC:
647 p_cfg->psc_mask &= ~AVDT_PSC_CODEC;
648 tmp = elem_len;
649 if (elem_len >= AVDT_CODEC_SIZE)
650 {
651 tmp = AVDT_CODEC_SIZE - 1;
652 }
653 p_cfg->num_codec++;
654 p_cfg->codec_info[0] = elem_len;
655 memcpy(&p_cfg->codec_info[1], p, tmp);
656 p += elem_len;
657 break;
658
659 case AVDT_CAT_DELAY_RPT:
660 break;
661
662 default:
663 p += elem_len;
664 break;
665 } /* switch */
666 } /* while ! err, !end*/
667 *p_elem = elem;
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700668 AVDT_TRACE_DEBUG("err=0x%x, elem:0x%x psc_mask=0x%x", err, elem, p_cfg->psc_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800669
670 return err;
671}
672
673/*******************************************************************************
674**
675** Function avdt_msg_prs_none
676**
677** Description This message parsing function parses a message with no parameters.
678
679**
680**
681** Returns Error code or zero if no error.
682**
683*******************************************************************************/
Myles Watsond35a6482016-10-27 08:52:16 -0700684static uint8_t avdt_msg_prs_none(UNUSED_ATTR tAVDT_MSG *p_msg, UNUSED_ATTR uint8_t *p,
685 UNUSED_ATTR uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800686{
The Android Open Source Project5738f832012-12-12 16:00:35 -0800687 return 0;
688}
689
690/*******************************************************************************
691**
692** Function avdt_msg_prs_single
693**
694** Description This message parsing function parses a message with a
695** single SEID.
696**
697**
698** Returns Error code or zero if no error.
699**
700*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700701static uint8_t avdt_msg_prs_single(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800702{
Marie Janssend19e0782016-07-15 12:48:27 -0700703 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800704
705 /* verify len */
706 if (len != AVDT_LEN_SINGLE)
707 {
708 err = AVDT_ERR_LENGTH;
709 }
710 else
711 {
712 AVDT_MSG_PRS_SEID(p, p_msg->single.seid);
713
714 if (avdt_scb_by_hdl(p_msg->single.seid) == NULL)
715 {
716 err = AVDT_ERR_SEID;
717 }
718 }
719 return err;
720}
721
722/*******************************************************************************
723**
724** Function avdt_msg_prs_setconfig_cmd
725**
726** Description This message parsing function parses a set configuration
727** command message.
728**
729**
730** Returns Error code or zero if no error.
731**
732*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700733static uint8_t avdt_msg_prs_setconfig_cmd(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800734{
Marie Janssend19e0782016-07-15 12:48:27 -0700735 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800736
737 p_msg->hdr.err_param = 0;
738
739 /* verify len */
740 if (len < AVDT_LEN_SETCONFIG_MIN)
741 {
742 err = AVDT_ERR_LENGTH;
743 }
744 else
745 {
746 /* get seids */
747 AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.hdr.seid);
748 if (avdt_scb_by_hdl(p_msg->config_cmd.hdr.seid) == NULL)
749 {
750 err = AVDT_ERR_SEID;
751 }
752
753 AVDT_MSG_PRS_SEID(p, p_msg->config_cmd.int_seid);
754 if ((p_msg->config_cmd.int_seid < AVDT_SEID_MIN) ||
755 (p_msg->config_cmd.int_seid > AVDT_SEID_MAX))
756 {
757 err = AVDT_ERR_SEID;
758 }
759 }
760
761 if (!err)
762 {
763 /* parse configuration parameters */
764 len -= 2;
765 err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_SETCONFIG);
766
767 if (!err)
768 {
769 /* verify protocol service capabilities are supported */
770 if (((p_msg->config_cmd.p_cfg->psc_mask & (~AVDT_PSC)) != 0) ||
771 (p_msg->config_cmd.p_cfg->num_codec == 0))
772 {
773 err = AVDT_ERR_INVALID_CAP;
774 }
775 }
776 }
777
778 return err;
779}
780
781/*******************************************************************************
782**
783** Function avdt_msg_prs_reconfig_cmd
784**
785** Description This message parsing function parses a reconfiguration
786** command message.
787**
788**
789** Returns Error code or zero if no error.
790**
791*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700792static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800793{
Marie Janssend19e0782016-07-15 12:48:27 -0700794 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800795
796 p_msg->hdr.err_param = 0;
797
798 /* verify len */
799 if (len < AVDT_LEN_RECONFIG_MIN)
800 {
801 err = AVDT_ERR_LENGTH;
802 }
803 else
804 {
805 /* get seid */
806 AVDT_MSG_PRS_SEID(p, p_msg->reconfig_cmd.hdr.seid);
807 if (avdt_scb_by_hdl(p_msg->reconfig_cmd.hdr.seid) == NULL)
808 {
809 err = AVDT_ERR_SEID;
810 }
811 else
812 {
813 /* parse config parameters */
814 len--;
815 err = avdt_msg_prs_cfg(p_msg->config_cmd.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_RECONFIG);
816
817 /* verify no protocol service capabilities in parameters */
818 if (!err)
819 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700820 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);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800821 if ((p_msg->config_cmd.p_cfg->psc_mask != 0) ||
822 (p_msg->config_cmd.p_cfg->num_codec == 0 && p_msg->config_cmd.p_cfg->num_protect == 0))
823 {
824 err = AVDT_ERR_INVALID_CAP;
825 }
826 }
827 }
828 }
829 return err;
830}
831
832/*******************************************************************************
833**
834** Function avdt_msg_prs_multi
835**
836** Description This message parsing function parses a message containing
837** multiple SEID's.
838**
839**
840** Returns Error code or zero if no error.
841**
842*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700843static uint8_t avdt_msg_prs_multi(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800844{
845 int i;
Marie Janssend19e0782016-07-15 12:48:27 -0700846 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800847
848 p_msg->hdr.err_param = 0;
849
850 /* verify len */
851 if (len < AVDT_LEN_MULTI_MIN || (len > AVDT_NUM_SEPS))
852 {
853 err = AVDT_ERR_LENGTH;
854 }
855 else
856 {
857 /* get and verify all seps */
858 for (i = 0; i < len; i++)
859 {
860 AVDT_MSG_PRS_SEID(p, p_msg->multi.seid_list[i]);
861 if (avdt_scb_by_hdl(p_msg->multi.seid_list[i]) == NULL)
862 {
863 err = AVDT_ERR_SEID;
864 p_msg->hdr.err_param = p_msg->multi.seid_list[i];
865 break;
866 }
867 }
Marie Janssend19e0782016-07-15 12:48:27 -0700868 p_msg->multi.num_seps = (uint8_t)i;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800869 }
870
871 return err;
872}
873
874/*******************************************************************************
875**
876** Function avdt_msg_prs_security_cmd
877**
878** Description This message parsing function parses a security
879** command message.
880**
881**
882** Returns Error code or zero if no error.
883**
884*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700885static uint8_t avdt_msg_prs_security_cmd(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800886{
Marie Janssend19e0782016-07-15 12:48:27 -0700887 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800888
889 /* verify len */
890 if (len < AVDT_LEN_SECURITY_MIN)
891 {
892 err = AVDT_ERR_LENGTH;
893 }
894 else
895 {
896 /* get seid */
897 AVDT_MSG_PRS_SEID(p, p_msg->security_cmd.hdr.seid);
898 if (avdt_scb_by_hdl(p_msg->security_cmd.hdr.seid) == NULL)
899 {
900 err = AVDT_ERR_SEID;
901 }
902 else
903 {
904 p_msg->security_cmd.p_data = p;
905 p_msg->security_cmd.len = len - 1;
906 }
907 }
908 return err;
909}
910
911/*******************************************************************************
912**
913** Function avdt_msg_prs_discover_rsp
914**
915** Description This message parsing function parses a discover
916** response message.
917**
918**
919** Returns Error code or zero if no error.
920**
921*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700922static uint8_t avdt_msg_prs_discover_rsp(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800923{
924 int i;
Marie Janssend19e0782016-07-15 12:48:27 -0700925 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800926
927 /* determine number of seps; seps in msg is len/2, but set to minimum
928 ** of seps app has supplied memory for and seps in msg
929 */
930 if (p_msg->discover_rsp.num_seps > (len / 2))
931 {
932 p_msg->discover_rsp.num_seps = (len / 2);
933 }
934
935 /* parse out sep info */
936 for (i = 0; i < p_msg->discover_rsp.num_seps; i++)
937 {
938 /* parse discover rsp info */
939 AVDT_MSG_PRS_DISC(p, p_msg->discover_rsp.p_sep_info[i].seid,
940 p_msg->discover_rsp.p_sep_info[i].in_use,
941 p_msg->discover_rsp.p_sep_info[i].media_type,
942 p_msg->discover_rsp.p_sep_info[i].tsep);
943
944 /* verify that seid is valid */
945 if ((p_msg->discover_rsp.p_sep_info[i].seid < AVDT_SEID_MIN) ||
946 (p_msg->discover_rsp.p_sep_info[i].seid > AVDT_SEID_MAX))
947 {
948 err = AVDT_ERR_SEID;
949 break;
950 }
951 }
952
953 return err;
954}
955
956/*******************************************************************************
957**
958** Function avdt_msg_prs_svccap
959**
960** Description This message parsing function parses a message containing
961** service capabilities parameters.
962**
963**
964** Returns Error code or zero if no error.
965**
966*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700967static uint8_t avdt_msg_prs_svccap(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800968{
969 /* parse parameters */
Marie Janssend19e0782016-07-15 12:48:27 -0700970 uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_GETCAP);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800971 if (p_msg->svccap.p_cfg)
972 {
973 p_msg->svccap.p_cfg->psc_mask &= AVDT_LEG_PSC;
974 }
975
976 return (err);
977}
978
979/*******************************************************************************
980**
981** Function avdt_msg_prs_all_svccap
982**
983** Description This message parsing function parses a message containing
984** service capabilities parameters.
985**
986**
987** Returns Error code or zero if no error.
988**
989*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700990static uint8_t avdt_msg_prs_all_svccap(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800991{
Marie Janssend19e0782016-07-15 12:48:27 -0700992 uint8_t err = avdt_msg_prs_cfg(p_msg->svccap.p_cfg, p, len, &p_msg->hdr.err_param, AVDT_SIG_GET_ALLCAP);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800993 if (p_msg->svccap.p_cfg)
994 {
995 p_msg->svccap.p_cfg->psc_mask &= AVDT_MSG_PSC_MASK;
996 }
997 return (err);
998}
999
1000/*******************************************************************************
1001**
1002** Function avdt_msg_prs_security_rsp
1003**
1004** Description This message parsing function parsing a security
1005** response message.
1006**
1007**
1008** Returns Error code or zero if no error.
1009**
1010*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001011static uint8_t avdt_msg_prs_security_rsp(tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001012{
1013 p_msg->security_rsp.p_data = p;
1014 p_msg->security_rsp.len = len;
1015
1016 return 0;
1017}
1018
1019/*******************************************************************************
1020**
1021** Function avdt_msg_prs_rej
1022**
1023** Description
1024**
1025**
1026** Returns Error code or zero if no error.
1027**
1028*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001029static uint8_t avdt_msg_prs_rej(tAVDT_MSG *p_msg, uint8_t *p, uint8_t sig)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001030{
1031 if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG))
1032 {
1033 p_msg->hdr.err_param = *p++;
1034 p_msg->hdr.err_code = *p;
1035 }
1036 else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND))
1037 {
1038 AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
1039 p_msg->hdr.err_code = *p;
1040 }
1041 else
1042 {
1043 p_msg->hdr.err_code = *p;
1044 }
1045
1046 return 0;
1047}
1048
1049/*******************************************************************************
1050**
1051** Function avdt_msg_prs_delay_rpt
1052**
1053** Description This message parsing function parses a security
1054** command message.
1055**
1056**
1057** Returns Error code or zero if no error.
1058**
1059*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001060static uint8_t avdt_msg_prs_delay_rpt (tAVDT_MSG *p_msg, uint8_t *p, uint16_t len)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001061{
Marie Janssend19e0782016-07-15 12:48:27 -07001062 uint8_t err = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001063
1064 /* verify len */
1065 if (len != AVDT_LEN_DELAY_RPT)
1066 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001067 AVDT_TRACE_WARNING("avdt_msg_prs_delay_rpt expected len: %u got: %u", AVDT_LEN_DELAY_RPT, len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001068 err = AVDT_ERR_LENGTH;
1069 }
1070 else
1071 {
1072 /* get seid */
1073 AVDT_MSG_PRS_SEID (p, p_msg->delay_rpt_cmd.hdr.seid);
1074
1075 if (avdt_scb_by_hdl(p_msg->delay_rpt_cmd.hdr.seid) == NULL)
1076 {
1077 err = AVDT_ERR_SEID;
1078 }
1079 else
1080 {
1081 BE_STREAM_TO_UINT16 (p_msg->delay_rpt_cmd.delay, p);
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001082 AVDT_TRACE_DEBUG("avdt_msg_prs_delay_rpt delay: %u", p_msg->delay_rpt_cmd.delay);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001083 }
1084 }
1085 return err;
1086}
1087
1088
1089/*******************************************************************************
1090**
1091** Function avdt_msg_send
1092**
1093** Description Send, and if necessary fragment the next message.
1094**
1095**
Marie Janssend19e0782016-07-15 12:48:27 -07001096** Returns Congested state; true if CCB congested, false if not.
The Android Open Source Project5738f832012-12-12 16:00:35 -08001097**
1098*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001099bool avdt_msg_send(tAVDT_CCB *p_ccb, BT_HDR *p_msg)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001100{
Marie Janssend19e0782016-07-15 12:48:27 -07001101 uint16_t curr_msg_len;
1102 uint8_t pkt_type;
1103 uint8_t hdr_len;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001104 tAVDT_TC_TBL *p_tbl;
1105 BT_HDR *p_buf;
Marie Janssend19e0782016-07-15 12:48:27 -07001106 uint8_t *p;
1107 uint8_t label;
1108 uint8_t msg;
1109 uint8_t sig;
1110 uint8_t nosp = 0; /* number of subsequent packets */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001111
1112 /* look up transport channel table entry to get peer mtu */
1113 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_SIG, p_ccb, NULL);
1114
1115 /* set the current message if there is a message passed in */
1116 if (p_msg != NULL)
1117 {
1118 p_ccb->p_curr_msg = p_msg;
1119 }
1120
1121 /* store copy of curr_msg->len */
1122 curr_msg_len = p_ccb->p_curr_msg->len;
1123
1124 /* while not congested and we haven't sent it all */
1125 while ((!p_ccb->cong) && (p_ccb->p_curr_msg != NULL))
1126 {
1127 /* check what kind of message we've got here; we are using the offset
1128 ** to indicate that a message is being fragmented
1129 */
1130
1131 /* if message isn't being fragmented and it fits in mtu */
1132 if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
1133 (p_ccb->p_curr_msg->len <= p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE))
1134 {
1135 pkt_type = AVDT_PKT_TYPE_SINGLE;
1136 hdr_len = AVDT_LEN_TYPE_SINGLE;
1137 p_buf = p_ccb->p_curr_msg;
1138 }
1139 /* if message isn't being fragmented and it doesn't fit in mtu */
1140 else if ((p_ccb->p_curr_msg->offset == AVDT_MSG_OFFSET) &&
1141 (p_ccb->p_curr_msg->len > p_tbl->peer_mtu - AVDT_LEN_TYPE_SINGLE))
1142 {
1143 pkt_type = AVDT_PKT_TYPE_START;
1144 hdr_len = AVDT_LEN_TYPE_START;
1145 nosp = (p_ccb->p_curr_msg->len + AVDT_LEN_TYPE_START - p_tbl->peer_mtu) /
1146 (p_tbl->peer_mtu - 1) + 2;
1147
1148 /* get a new buffer for fragment we are sending */
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001149 p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001150
1151 /* copy portion of data from current message to new buffer */
1152 p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1153 p_buf->len = p_tbl->peer_mtu - hdr_len;
Marie Janssend19e0782016-07-15 12:48:27 -07001154 memcpy((uint8_t *)(p_buf + 1) + p_buf->offset,
1155 (uint8_t *)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset, p_buf->len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001156 }
1157 /* if message is being fragmented and remaining bytes don't fit in mtu */
1158 else if ((p_ccb->p_curr_msg->offset > AVDT_MSG_OFFSET) &&
1159 (p_ccb->p_curr_msg->len > (p_tbl->peer_mtu - AVDT_LEN_TYPE_CONT)))
1160 {
1161 pkt_type = AVDT_PKT_TYPE_CONT;
1162 hdr_len = AVDT_LEN_TYPE_CONT;
1163
1164 /* get a new buffer for fragment we are sending */
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001165 p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001166
1167 /* copy portion of data from current message to new buffer */
1168 p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
1169 p_buf->len = p_tbl->peer_mtu - hdr_len;
Marie Janssend19e0782016-07-15 12:48:27 -07001170 memcpy((uint8_t *)(p_buf + 1) + p_buf->offset,
1171 (uint8_t *)(p_ccb->p_curr_msg + 1) + p_ccb->p_curr_msg->offset, p_buf->len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001172 }
1173 /* if message is being fragmented and remaining bytes do fit in mtu */
1174 else
1175 {
1176 pkt_type = AVDT_PKT_TYPE_END;
1177 hdr_len = AVDT_LEN_TYPE_END;
1178 p_buf = p_ccb->p_curr_msg;
1179 }
1180
1181 /* label, sig id, msg type are in hdr of p_curr_msg */
1182 label = AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_msg->layer_specific);
1183 msg = AVDT_LAYERSPEC_MSG(p_ccb->p_curr_msg->layer_specific);
Marie Janssend19e0782016-07-15 12:48:27 -07001184 sig = (uint8_t) p_ccb->p_curr_msg->event;
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001185 AVDT_TRACE_DEBUG("avdt_msg_send label:%d, msg:%d, sig:%d", label, msg, sig);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001186
1187 /* keep track of how much of msg we've sent */
1188 curr_msg_len -= p_buf->len;
1189 if (curr_msg_len == 0)
1190 {
1191 /* entire message sent; mark as finished */
1192 p_ccb->p_curr_msg = NULL;
1193
1194 /* start timer here for commands */
1195 if (msg == AVDT_MSG_TYPE_CMD)
1196 {
1197 /* if retransmit timeout set to zero, sig doesn't use retransmit */
1198 if ((sig == AVDT_SIG_DISCOVER) || (sig == AVDT_SIG_GETCAP) ||
1199 (sig == AVDT_SIG_SECURITY) || (avdt_cb.rcb.ret_tout == 0))
1200 {
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -08001201 alarm_cancel(p_ccb->idle_ccb_timer);
1202 alarm_cancel(p_ccb->ret_ccb_timer);
1203 period_ms_t interval_ms = avdt_cb.rcb.sig_tout * 1000;
1204 alarm_set_on_queue(p_ccb->rsp_ccb_timer, interval_ms,
1205 avdt_ccb_rsp_ccb_timer_timeout, p_ccb,
1206 btu_general_alarm_queue);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001207 }
1208 else if (sig != AVDT_SIG_DELAY_RPT)
1209 {
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -08001210 alarm_cancel(p_ccb->idle_ccb_timer);
1211 alarm_cancel(p_ccb->rsp_ccb_timer);
1212 period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
1213 alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
1214 avdt_ccb_ret_ccb_timer_timeout, p_ccb,
1215 btu_general_alarm_queue);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001216 }
1217 }
1218 }
1219 else
1220 {
1221 /* message being fragmented and not completely sent */
1222 p_ccb->p_curr_msg->len -= p_buf->len;
1223 p_ccb->p_curr_msg->offset += p_buf->len;
1224 }
1225
1226 /* set up to build header */
1227 p_buf->len += hdr_len;
1228 p_buf->offset -= hdr_len;
Marie Janssend19e0782016-07-15 12:48:27 -07001229 p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001230
1231 /* build header */
1232 AVDT_MSG_BLD_HDR(p, label, pkt_type, msg);
1233 if (pkt_type == AVDT_PKT_TYPE_START)
1234 {
1235 AVDT_MSG_BLD_NOSP(p, nosp);
1236 }
1237 if ((pkt_type == AVDT_PKT_TYPE_START) || (pkt_type == AVDT_PKT_TYPE_SINGLE))
1238 {
1239 AVDT_MSG_BLD_SIG(p, sig);
1240 }
1241
1242 /* send msg buffer down */
1243 avdt_ad_write_req(AVDT_CHAN_SIG, p_ccb, NULL, p_buf);
1244 }
1245 return (p_ccb->cong);
1246}
1247
1248/*******************************************************************************
1249**
1250** Function avdt_msg_asmbl
1251**
1252** Description Reassemble incoming message.
1253**
1254**
1255** Returns Pointer to reassembled message; NULL if no message
1256** available.
1257**
1258*******************************************************************************/
1259BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
1260{
Marie Janssend19e0782016-07-15 12:48:27 -07001261 uint8_t *p;
1262 uint8_t pkt_type;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001263 BT_HDR *p_ret;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001264
1265 /* parse the message header */
Marie Janssend19e0782016-07-15 12:48:27 -07001266 p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001267 AVDT_MSG_PRS_PKT_TYPE(p, pkt_type);
1268
1269 /* quick sanity check on length */
1270 if (p_buf->len < avdt_msg_pkt_type_len[pkt_type])
1271 {
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001272 osi_free(p_buf);
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001273 AVDT_TRACE_WARNING("Bad length during reassembly");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001274 p_ret = NULL;
1275 }
1276 /* single packet */
1277 else if (pkt_type == AVDT_PKT_TYPE_SINGLE)
1278 {
1279 /* if reassembly in progress drop message and process new single */
1280 if (p_ccb->p_rx_msg != NULL)
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001281 AVDT_TRACE_WARNING("Got single during reassembly");
Pavlin Radoslavov20524d32016-02-02 18:12:08 -08001282
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001283 osi_free_and_reset((void **)&p_ccb->p_rx_msg);
Pavlin Radoslavov20524d32016-02-02 18:12:08 -08001284
The Android Open Source Project5738f832012-12-12 16:00:35 -08001285 p_ret = p_buf;
1286 }
1287 /* start packet */
1288 else if (pkt_type == AVDT_PKT_TYPE_START)
1289 {
1290 /* if reassembly in progress drop message and process new single */
1291 if (p_ccb->p_rx_msg != NULL)
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001292 AVDT_TRACE_WARNING("Got start during reassembly");
Pavlin Radoslavov20524d32016-02-02 18:12:08 -08001293
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001294 osi_free_and_reset((void **)&p_ccb->p_rx_msg);
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001295
1296 /*
1297 * Allocate bigger buffer for reassembly. As lower layers are
1298 * not aware of possible packet size after reassembly, they
1299 * would have allocated smaller buffer.
1300 */
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001301 p_ccb->p_rx_msg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001302 memcpy(p_ccb->p_rx_msg, p_buf,
1303 sizeof(BT_HDR) + p_buf->offset + p_buf->len);
1304
1305 /* Free original buffer */
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001306 osi_free(p_buf);
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001307
1308 /* update p to point to new buffer */
Marie Janssend19e0782016-07-15 12:48:27 -07001309 p = (uint8_t *)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001310
1311 /* copy first header byte over nosp */
1312 *(p + 1) = *p;
1313
1314 /* set offset to point to where to copy next */
1315 p_ccb->p_rx_msg->offset += p_ccb->p_rx_msg->len;
1316
1317 /* adjust length for packet header */
1318 p_ccb->p_rx_msg->len -= 1;
1319
1320 p_ret = NULL;
1321 }
1322 /* continue or end */
1323 else
1324 {
1325 /* if no reassembly in progress drop message */
1326 if (p_ccb->p_rx_msg == NULL)
1327 {
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001328 osi_free(p_buf);
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001329 AVDT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001330 p_ret = NULL;
1331 }
1332 else
1333 {
1334 /* get size of buffer holding assembled message */
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001335 /*
1336 * NOTE: The buffer is allocated above at the beginning of the
1337 * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
1338 */
Marie Janssend19e0782016-07-15 12:48:27 -07001339 uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001340
1341 /* adjust offset and len of fragment for header byte */
1342 p_buf->offset += AVDT_LEN_TYPE_CONT;
1343 p_buf->len -= AVDT_LEN_TYPE_CONT;
1344
1345 /* verify length */
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001346 if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) {
The Android Open Source Project5738f832012-12-12 16:00:35 -08001347 /* won't fit; free everything */
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001348 AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001349 osi_free_and_reset((void **)&p_ccb->p_rx_msg);
1350 osi_free(p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001351 p_ret = NULL;
Pavlin Radoslavov0a20dd42016-02-04 18:20:06 -08001352 } else {
The Android Open Source Project5738f832012-12-12 16:00:35 -08001353 /* copy contents of p_buf to p_rx_msg */
Marie Janssend19e0782016-07-15 12:48:27 -07001354 memcpy((uint8_t *)(p_ccb->p_rx_msg + 1) + p_ccb->p_rx_msg->offset,
1355 (uint8_t *)(p_buf + 1) + p_buf->offset, p_buf->len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001356
1357 if (pkt_type == AVDT_PKT_TYPE_END)
1358 {
1359 p_ccb->p_rx_msg->offset -= p_ccb->p_rx_msg->len;
1360 p_ccb->p_rx_msg->len += p_buf->len;
1361 p_ret = p_ccb->p_rx_msg;
1362 p_ccb->p_rx_msg = NULL;
1363 }
1364 else
1365 {
1366 p_ccb->p_rx_msg->offset += p_buf->len;
1367 p_ccb->p_rx_msg->len += p_buf->len;
1368 p_ret = NULL;
1369 }
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001370 osi_free(p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001371 }
1372 }
1373 }
1374 return p_ret;
1375}
1376
1377/*******************************************************************************
1378**
1379** Function avdt_msg_send_cmd
1380**
1381** Description This function is called to send a command message. The
1382** sig_id parameter indicates the message type, p_params
1383** points to the message parameters, if any. It gets a buffer
1384** from the AVDTP command pool, executes the message building
1385** function for this message type. It then queues the message
1386** in the command queue for this CCB.
1387**
1388**
1389** Returns Nothing.
1390**
1391*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001392void avdt_msg_send_cmd(tAVDT_CCB *p_ccb, void *p_scb, uint8_t sig_id, tAVDT_MSG *p_params)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001393{
Marie Janssend19e0782016-07-15 12:48:27 -07001394 uint8_t *p;
1395 uint8_t *p_start;
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001396 BT_HDR *p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001397
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07001398 /* set up buf pointer and offset */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001399 p_buf->offset = AVDT_MSG_OFFSET;
Marie Janssend19e0782016-07-15 12:48:27 -07001400 p_start = p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001401
1402 /* execute parameter building function to build message */
1403 (*avdt_msg_bld_cmd[sig_id - 1])(&p, p_params);
1404
1405 /* set len */
Marie Janssend19e0782016-07-15 12:48:27 -07001406 p_buf->len = (uint16_t) (p - p_start);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001407
1408 /* now store scb hdls, if any, in buf */
1409 if (p_scb != NULL)
1410 {
Marie Janssend19e0782016-07-15 12:48:27 -07001411 p = (uint8_t *)(p_buf + 1);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001412
1413 /* for start and suspend, p_scb points to array of handles */
1414 if ((sig_id == AVDT_SIG_START) || (sig_id == AVDT_SIG_SUSPEND))
1415 {
Marie Janssend19e0782016-07-15 12:48:27 -07001416 memcpy(p, (uint8_t *) p_scb, p_buf->len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001417 }
1418 /* for all others, p_scb points to scb as usual */
1419 else
1420 {
1421 *p = avdt_scb_to_hdl((tAVDT_SCB *) p_scb);
1422 }
1423 }
1424
1425 /* stash sig, label, and message type in buf */
1426 p_buf->event = sig_id;
1427 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_CMD, p_ccb->label);
1428
1429 /* increment label */
1430 p_ccb->label = (p_ccb->label + 1) % 16;
1431
1432 /* queue message and trigger ccb to send it */
Pavlin Radoslavov1a3844f2015-09-25 11:21:15 -07001433 fixed_queue_enqueue(p_ccb->cmd_q, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001434 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1435}
1436
1437
1438/*******************************************************************************
1439**
1440** Function avdt_msg_send_rsp
1441**
1442** Description This function is called to send a response message. The
1443** sig_id parameter indicates the message type, p_params
1444** points to the message parameters, if any. It gets a buffer
1445** from the AVDTP command pool, executes the message building
1446** function for this message type. It then queues the message
1447** in the response queue for this CCB.
1448**
1449**
1450** Returns Nothing.
1451**
1452*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001453void avdt_msg_send_rsp(tAVDT_CCB *p_ccb, uint8_t sig_id, tAVDT_MSG *p_params)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001454{
Marie Janssend19e0782016-07-15 12:48:27 -07001455 uint8_t *p;
1456 uint8_t *p_start;
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001457 BT_HDR *p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001458
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07001459 /* set up buf pointer and offset */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001460 p_buf->offset = AVDT_MSG_OFFSET;
Marie Janssend19e0782016-07-15 12:48:27 -07001461 p_start = p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001462
1463 /* execute parameter building function to build message */
1464 (*avdt_msg_bld_rsp[sig_id - 1])(&p, p_params);
1465
1466 /* set length */
Marie Janssend19e0782016-07-15 12:48:27 -07001467 p_buf->len = (uint16_t) (p - p_start);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001468
1469 /* stash sig, label, and message type in buf */
1470 p_buf->event = sig_id;
1471 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_RSP, p_params->hdr.label);
1472
1473 /* queue message and trigger ccb to send it */
Pavlin Radoslavov1a3844f2015-09-25 11:21:15 -07001474 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001475 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1476}
1477
1478
1479/*******************************************************************************
1480**
1481** Function avdt_msg_send_rej
1482**
1483** Description This function is called to send a reject message. The
1484** sig_id parameter indicates the message type. It gets
1485** a buffer from the AVDTP command pool and builds the
1486** message based on the message type and the error code.
1487** It then queues the message in the response queue for
1488** this CCB.
1489**
1490**
1491** Returns Nothing.
1492**
1493*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001494void avdt_msg_send_rej(tAVDT_CCB *p_ccb, uint8_t sig_id, tAVDT_MSG *p_params)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001495{
Marie Janssend19e0782016-07-15 12:48:27 -07001496 uint8_t *p;
1497 uint8_t *p_start;
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001498 BT_HDR *p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001499
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07001500 /* set up buf pointer and offset */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001501 p_buf->offset = AVDT_MSG_OFFSET;
Marie Janssend19e0782016-07-15 12:48:27 -07001502 p_start = p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001503
1504 /* if sig id included, build into message */
1505 if (sig_id != AVDT_SIG_NONE)
1506 {
1507 /* if this sig has a parameter, add the parameter */
1508 if ((sig_id == AVDT_SIG_SETCONFIG) ||
1509 (sig_id == AVDT_SIG_RECONFIG))
1510 {
1511 AVDT_MSG_BLD_PARAM(p, p_params->hdr.err_param);
1512 }
1513 else if ((sig_id == AVDT_SIG_START) ||
1514 (sig_id == AVDT_SIG_SUSPEND))
1515 {
1516 AVDT_MSG_BLD_SEID(p, p_params->hdr.err_param);
1517 }
1518
1519 /* add the error code */
1520 AVDT_MSG_BLD_ERR(p, p_params->hdr.err_code);
1521 }
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001522 AVDT_TRACE_DEBUG("avdt_msg_send_rej");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001523
1524 /* calculate length */
Marie Janssend19e0782016-07-15 12:48:27 -07001525 p_buf->len = (uint16_t) (p - p_start);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001526
1527 /* stash sig, label, and message type in buf */
1528 p_buf->event = sig_id;
1529 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_REJ, p_params->hdr.label);
1530
1531 /* queue message and trigger ccb to send it */
Pavlin Radoslavov1a3844f2015-09-25 11:21:15 -07001532 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001533 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1534}
1535
1536/*******************************************************************************
1537**
1538** Function avdt_msg_send_grej
1539**
1540** Description This function is called to send a general reject message. The
1541** sig_id parameter indicates the message type. It gets
1542** a buffer from the AVDTP command pool and builds the
1543** message based on the message type and the error code.
1544** It then queues the message in the response queue for
1545** this CCB.
1546**
1547**
1548** Returns Nothing.
1549**
1550*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -07001551void avdt_msg_send_grej(tAVDT_CCB *p_ccb, uint8_t sig_id, tAVDT_MSG *p_params)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001552{
Marie Janssend19e0782016-07-15 12:48:27 -07001553 uint8_t *p;
1554 uint8_t *p_start;
Pavlin Radoslavov717a4a92016-02-06 08:36:06 -08001555 BT_HDR *p_buf = (BT_HDR *)osi_malloc(AVDT_CMD_BUF_SIZE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001556
Pavlin Radoslavov258c2532015-09-27 20:59:05 -07001557 /* set up buf pointer and offset */
The Android Open Source Project5738f832012-12-12 16:00:35 -08001558 p_buf->offset = AVDT_MSG_OFFSET;
Marie Janssend19e0782016-07-15 12:48:27 -07001559 p_start = p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001560
1561 /* calculate length */
Marie Janssend19e0782016-07-15 12:48:27 -07001562 p_buf->len = (uint16_t) (p - p_start);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001563
1564 /* stash sig, label, and message type in buf */
JivakDhadseb8b761e2015-08-07 18:58:38 +05301565 p_buf->event = sig_id;
1566 AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ, p_params->hdr.label);
1567 AVDT_TRACE_DEBUG(__func__);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001568
1569 /* queue message and trigger ccb to send it */
Pavlin Radoslavov1a3844f2015-09-25 11:21:15 -07001570 fixed_queue_enqueue(p_ccb->rsp_q, p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001571 avdt_ccb_event(p_ccb, AVDT_CCB_SENDMSG_EVT, NULL);
1572}
1573
1574/*******************************************************************************
1575**
1576** Function avdt_msg_ind
1577**
1578** Description This function is called by the adaption layer when an
1579** incoming message is received on the signaling channel.
1580** It parses the message and sends an event to the appropriate
1581** SCB or CCB for the message.
1582**
1583**
1584** Returns Nothing.
1585**
1586*******************************************************************************/
1587void avdt_msg_ind(tAVDT_CCB *p_ccb, BT_HDR *p_buf)
1588{
1589 tAVDT_SCB *p_scb;
Marie Janssend19e0782016-07-15 12:48:27 -07001590 uint8_t *p;
1591 bool ok = true;
1592 bool handle_rsp = false;
1593 bool gen_rej = false;
1594 uint8_t label;
1595 uint8_t pkt_type;
1596 uint8_t msg_type;
1597 uint8_t sig = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001598 tAVDT_MSG msg;
1599 tAVDT_CFG cfg;
Marie Janssend19e0782016-07-15 12:48:27 -07001600 uint8_t err;
1601 uint8_t evt = 0;
1602 uint8_t scb_hdl;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001603
1604 /* reassemble message; if no message available (we received a fragment) return */
1605 if ((p_buf = avdt_msg_asmbl(p_ccb, p_buf)) == NULL)
1606 {
1607 return;
1608 }
1609
Marie Janssend19e0782016-07-15 12:48:27 -07001610 p = (uint8_t *)(p_buf + 1) + p_buf->offset;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001611
1612 /* parse the message header */
1613 AVDT_MSG_PRS_HDR(p, label, pkt_type, msg_type);
1614
Sharvil Nanavatif1c764f2015-02-23 17:31:48 -08001615 UNUSED(pkt_type);
1616
Anubhav Guptaf799a862014-11-12 19:55:00 +05301617 AVDT_TRACE_DEBUG("msg_type=%d, sig=%d", msg_type, sig);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001618 /* set up label and ccb_idx in message hdr */
1619 msg.hdr.label = label;
1620 msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
1621
1622 /* verify msg type */
1623 if (msg_type == AVDT_MSG_TYPE_GRJ)
1624 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001625 AVDT_TRACE_WARNING("Dropping msg msg_type=%d", msg_type);
Marie Janssend19e0782016-07-15 12:48:27 -07001626 ok = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001627 }
1628 /* check for general reject */
1629 else if ((msg_type == AVDT_MSG_TYPE_REJ) && (p_buf->len == AVDT_LEN_GEN_REJ))
1630 {
Marie Janssend19e0782016-07-15 12:48:27 -07001631 gen_rej = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001632 if (p_ccb->p_curr_cmd != NULL)
1633 {
Marie Janssend19e0782016-07-15 12:48:27 -07001634 msg.hdr.sig_id = sig = (uint8_t) p_ccb->p_curr_cmd->event;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001635 evt = avdt_msg_rej_2_evt[sig - 1];
1636 msg.hdr.err_code = AVDT_ERR_NSC;
1637 msg.hdr.err_param = 0;
1638 }
1639 }
1640 else /* not a general reject */
1641 {
1642 /* get and verify signal */
1643 AVDT_MSG_PRS_SIG(p, sig);
1644 msg.hdr.sig_id = sig;
1645 if ((sig == 0) || (sig > AVDT_SIG_MAX))
1646 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001647 AVDT_TRACE_WARNING("Dropping msg sig=%d msg_type:%d", sig, msg_type);
Marie Janssend19e0782016-07-15 12:48:27 -07001648 ok = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001649
1650 /* send a general reject */
1651 if (msg_type == AVDT_MSG_TYPE_CMD)
1652 {
1653 avdt_msg_send_grej(p_ccb, sig, &msg);
1654 }
1655 }
1656 }
1657
1658 if (ok && !gen_rej)
1659 {
1660 /* skip over header (msg length already verified during reassembly) */
1661 p_buf->len -= AVDT_LEN_TYPE_SINGLE;
1662
1663 /* set up to parse message */
1664 if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_DISCOVER))
1665 {
1666 /* parse discover rsp message to struct supplied by app */
1667 msg.discover_rsp.p_sep_info = (tAVDT_SEP_INFO *) p_ccb->p_proc_data;
1668 msg.discover_rsp.num_seps = p_ccb->proc_param;
1669 }
1670 else if ((msg_type == AVDT_MSG_TYPE_RSP) &&
1671 ((sig == AVDT_SIG_GETCAP) || (sig == AVDT_SIG_GET_ALLCAP)))
1672 {
1673 /* parse discover rsp message to struct supplied by app */
1674 msg.svccap.p_cfg = (tAVDT_CFG *) p_ccb->p_proc_data;
1675 }
1676 else if ((msg_type == AVDT_MSG_TYPE_RSP) && (sig == AVDT_SIG_GETCONFIG))
1677 {
1678 /* parse get config rsp message to struct allocated locally */
1679 msg.svccap.p_cfg = &cfg;
1680 }
1681 else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_SETCONFIG))
1682 {
1683 /* parse config cmd message to struct allocated locally */
1684 msg.config_cmd.p_cfg = &cfg;
1685 }
1686 else if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig == AVDT_SIG_RECONFIG))
1687 {
1688 /* parse reconfig cmd message to struct allocated locally */
1689 msg.reconfig_cmd.p_cfg = &cfg;
1690 }
1691
1692 /* parse message; while we're at it map message sig to event */
1693 if (msg_type == AVDT_MSG_TYPE_CMD)
1694 {
1695 msg.hdr.err_code = err = (*avdt_msg_prs_cmd[sig - 1])(&msg, p, p_buf->len);
1696 evt = avdt_msg_cmd_2_evt[sig - 1];
1697 }
1698 else if (msg_type == AVDT_MSG_TYPE_RSP)
1699 {
1700 msg.hdr.err_code = err = (*avdt_msg_prs_rsp[sig - 1])(&msg, p, p_buf->len);
1701 evt = avdt_msg_rsp_2_evt[sig - 1];
1702 }
1703 else /* msg_type == AVDT_MSG_TYPE_REJ */
1704 {
1705 err = avdt_msg_prs_rej(&msg, p, sig);
1706 evt = avdt_msg_rej_2_evt[sig - 1];
1707 }
1708
1709 /* if parsing failed */
1710 if (err != 0)
1711 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001712 AVDT_TRACE_WARNING("Parsing failed sig=%d err=0x%x", sig, err);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001713
1714 /* if its a rsp or rej, drop it; if its a cmd, send a rej;
1715 ** note special case for abort; never send abort reject
1716 */
Marie Janssend19e0782016-07-15 12:48:27 -07001717 ok = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001718 if ((msg_type == AVDT_MSG_TYPE_CMD) && (sig != AVDT_SIG_ABORT))
1719 {
1720 avdt_msg_send_rej(p_ccb, sig, &msg);
1721 }
1722 }
1723 }
1724
1725 /* if its a rsp or rej, check sent cmd to see if we're waiting for
1726 ** the rsp or rej. If we didn't send a cmd for it, drop it. If
1727 ** it does match a cmd, stop timer for the cmd.
1728 */
1729 if (ok)
1730 {
1731 if ((msg_type == AVDT_MSG_TYPE_RSP) || (msg_type == AVDT_MSG_TYPE_REJ))
1732 {
1733 if ((p_ccb->p_curr_cmd != NULL) &&
1734 (p_ccb->p_curr_cmd->event == sig) &&
1735 (AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_cmd->layer_specific) == label))
1736 {
1737 /* stop timer */
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -08001738 alarm_cancel(p_ccb->idle_ccb_timer);
1739 alarm_cancel(p_ccb->ret_ccb_timer);
1740 alarm_cancel(p_ccb->rsp_ccb_timer);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001741
1742 /* clear retransmission count */
1743 p_ccb->ret_count = 0;
1744
1745 /* later in this function handle ccb event */
Marie Janssend19e0782016-07-15 12:48:27 -07001746 handle_rsp = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001747 }
1748 else
1749 {
Marie Janssend19e0782016-07-15 12:48:27 -07001750 ok = false;
Sharvil Nanavati158084e2014-05-04 09:53:44 -07001751 AVDT_TRACE_WARNING("Cmd not found for rsp sig=%d label=%d", sig, label);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001752 }
1753 }
1754 }
1755
1756 if (ok)
1757 {
1758 /* if it's a ccb event send to ccb */
1759 if (evt & AVDT_CCB_MKR)
1760 {
Marie Janssend19e0782016-07-15 12:48:27 -07001761 avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001762 }
1763 /* if it's a scb event */
1764 else
1765 {
1766 /* Scb events always have a single seid. For cmd, get seid from
1767 ** message. For rej and rsp, get seid from p_curr_cmd.
1768 */
1769 if (msg_type == AVDT_MSG_TYPE_CMD)
1770 {
1771 scb_hdl = msg.single.seid;
1772 }
1773 else
1774 {
Marie Janssend19e0782016-07-15 12:48:27 -07001775 scb_hdl = *((uint8_t *)(p_ccb->p_curr_cmd + 1));
The Android Open Source Project5738f832012-12-12 16:00:35 -08001776 }
1777
1778 /* Map seid to the scb and send it the event. For cmd, seid has
1779 ** already been verified by parsing function.
1780 */
1781 if (evt && (p_scb = avdt_scb_by_hdl(scb_hdl)) != NULL)
1782 {
1783 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
1784 }
1785 }
1786 }
1787
1788 /* free message buffer */
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001789 osi_free(p_buf);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001790
1791 /* if its a rsp or rej, send event to ccb to free associated
1792 ** cmd msg buffer and handle cmd queue
1793 */
1794 if (handle_rsp)
1795 {
1796 avdt_ccb_event(p_ccb, AVDT_CCB_RCVRSP_EVT, NULL);
1797 }
1798}