OSDN Git Service

DO NOT MERGE Fix OOB read in avrc_ctrl_pars_vendor_rsp
[android-x86/system-bt.git] / stack / avrc / avrc_pars_ct.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2006-2013 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 #include <string.h>
19
20 #include "bt_common.h"
21 #include "avrc_api.h"
22 #include "avrc_defs.h"
23 #include "avrc_int.h"
24 #include "bt_utils.h"
25 #include "log/log.h"
26
27 /*****************************************************************************
28 **  Global data
29 *****************************************************************************/
30
31 #if (AVRC_METADATA_INCLUDED == TRUE)
32
33 /*******************************************************************************
34 **
35 ** Function         avrc_pars_vendor_rsp
36 **
37 ** Description      This function parses the vendor specific commands defined by
38 **                  Bluetooth SIG
39 **
40 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
41 **                  Otherwise, the error code defined by AVRCP 1.4
42 **
43 *******************************************************************************/
44 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result)
45 {
46     tAVRC_STS  status = AVRC_STS_NO_ERROR;
47     UINT8   *p;
48     UINT16  len;
49 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
50     UINT8 eventid=0;
51 #endif
52
53     /* Check the vendor data */
54     if (p_msg->vendor_len == 0)
55         return AVRC_STS_NO_ERROR;
56     if (p_msg->p_vendor_data == NULL)
57         return AVRC_STS_INTERNAL_ERR;
58
59     p = p_msg->p_vendor_data;
60     BE_STREAM_TO_UINT8 (p_result->pdu, p);
61     p++; /* skip the reserved/packe_type byte */
62     BE_STREAM_TO_UINT16 (len, p);
63     AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d/0x%x",
64                      __func__, p_msg->hdr.ctype, p_result->pdu, len, len);
65     if (p_msg->hdr.ctype == AVRC_RSP_REJ)
66     {
67         p_result->rsp.status = *p;
68         return p_result->rsp.status;
69     }
70
71     switch (p_result->pdu)
72     {
73     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
74     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
75
76 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
77     case AVRC_PDU_SET_ABSOLUTE_VOLUME:      /* 0x50 */
78         if (len != 1)
79             status = AVRC_STS_INTERNAL_ERR;
80         else
81         {
82             BE_STREAM_TO_UINT8 (p_result->volume.volume, p);
83         }
84         break;
85 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
86
87     case AVRC_PDU_REGISTER_NOTIFICATION:    /* 0x31 */
88 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
89         BE_STREAM_TO_UINT8 (eventid, p);
90         if(AVRC_EVT_VOLUME_CHANGE==eventid
91             && (AVRC_RSP_CHANGED==p_msg->hdr.ctype || AVRC_RSP_INTERIM==p_msg->hdr.ctype
92             || AVRC_RSP_REJ==p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL==p_msg->hdr.ctype))
93         {
94             p_result->reg_notif.status=p_msg->hdr.ctype;
95             p_result->reg_notif.event_id=eventid;
96             BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p);
97         }
98         AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
99                          __func__, eventid, p_result->reg_notif.param.volume);
100 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
101         break;
102     default:
103         status = AVRC_STS_BAD_CMD;
104         break;
105     }
106
107     return status;
108 }
109
110 void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp)
111 {
112     BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream);
113     switch (p_rsp->event_id)
114     {
115         case AVRC_EVT_PLAY_STATUS_CHANGE:
116             BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream);
117             break;
118
119         case AVRC_EVT_TRACK_CHANGE:
120             BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8);
121             break;
122
123         case AVRC_EVT_APP_SETTING_CHANGE:
124             BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
125             if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS) {
126                 android_errorWriteLog(0x534e4554, "73782082");
127                 p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
128             }
129             for (int index = 0; index < p_rsp->param.player_setting.num_attr; index++)
130             {
131                 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index], p_stream);
132                 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_value[index], p_stream);
133             }
134             break;
135
136         case AVRC_EVT_NOW_PLAYING_CHANGE:
137             break;
138
139         case AVRC_EVT_AVAL_PLAYERS_CHANGE:
140             break;
141
142         case AVRC_EVT_ADDR_PLAYER_CHANGE:
143             break;
144
145         case AVRC_EVT_UIDS_CHANGE:
146             break;
147
148         case AVRC_EVT_TRACK_REACHED_END:
149         case AVRC_EVT_TRACK_REACHED_START:
150         case AVRC_EVT_PLAY_POS_CHANGED:
151         case AVRC_EVT_BATTERY_STATUS_CHANGE:
152         case AVRC_EVT_SYSTEM_STATUS_CHANGE:
153         default:
154             break;
155     }
156 }
157
158 #if (AVRC_CTLR_INCLUDED == TRUE)
159 /*******************************************************************************
160 **
161 ** Function         avrc_ctrl_pars_vendor_rsp
162 **
163 ** Description      This function parses the vendor specific commands defined by
164 **                  Bluetooth SIG
165 **
166 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
167 **                  Otherwise, the error code defined by AVRCP 1.4
168 **
169 *******************************************************************************/
170 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(
171     tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result, UINT8* p_buf, UINT16* buf_len)
172 {
173     UINT8   *p = p_msg->p_vendor_data;
174     BE_STREAM_TO_UINT8 (p_result->pdu, p);
175     p++; /* skip the reserved/packe_type byte */
176
177     UINT16  len;
178     BE_STREAM_TO_UINT16 (len, p);
179     AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d",
180                      __func__, p_msg->hdr.ctype, p_result->pdu, len);
181     /* Todo: Issue in handling reject, check */
182     if (p_msg->hdr.ctype == AVRC_RSP_REJ)
183     {
184         p_result->rsp.status = *p;
185         return p_result->rsp.status;
186     }
187
188     /* TODO: Break the big switch into functions. */
189     switch (p_result->pdu)
190     {
191     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
192     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
193
194     case AVRC_PDU_REGISTER_NOTIFICATION:
195         avrc_parse_notification_rsp(p, &p_result->reg_notif);
196         break;
197
198     case AVRC_PDU_GET_CAPABILITIES:
199         if (len == 0)
200         {
201             p_result->get_caps.count = 0;
202             p_result->get_caps.capability_id = 0;
203             break;
204         }
205         BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
206         BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
207         AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ",
208                          __func__, p_result->get_caps.capability_id, p_result->get_caps.count);
209         if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID)
210         {
211             for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_COMP_ID));
212                 xx++)
213             {
214                 BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
215             }
216         }
217         else if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED)
218         {
219             for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_EVT_ID));
220                 xx++)
221             {
222                 BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
223             }
224         }
225         break;
226
227     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
228         if (len == 0)
229         {
230             p_result->list_app_attr.num_attr = 0;
231             break;
232         }
233         BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
234
235         if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
236           android_errorWriteLog(0x534e4554, "63146237");
237           p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
238         }
239
240         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->list_app_attr.num_attr);
241         for(int xx = 0; xx < p_result->list_app_attr.num_attr; xx++)
242         {
243             BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
244         }
245         break;
246
247     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
248         if (len == 0)
249         {
250             p_result->list_app_values.num_val = 0;
251             break;
252         }
253         BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
254         if (p_result->list_app_values.num_val > AVRC_MAX_APP_ATTR_SIZE) {
255             android_errorWriteLog(0x534e4554, "78526423");
256             p_result->list_app_values.num_val = AVRC_MAX_APP_ATTR_SIZE;
257         }
258
259         AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->list_app_values.num_val);
260         for(int xx = 0; xx < p_result->list_app_values.num_val; xx++)
261         {
262             BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
263         }
264         break;
265
266     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
267     {
268         if (len == 0)
269         {
270             p_result->get_cur_app_val.num_val = 0;
271             break;
272         }
273         BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
274         tAVRC_APP_SETTING *app_sett =
275             (tAVRC_APP_SETTING*)osi_malloc(p_result->get_cur_app_val.num_val*sizeof(tAVRC_APP_SETTING));
276         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_cur_app_val.num_val);
277
278
279         if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
280             android_errorWriteLog(0x534e4554, "63146237");
281             p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
282         }
283
284         for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++)
285         {
286             BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
287             BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
288         }
289         p_result->get_cur_app_val.p_vals = app_sett;
290     }
291         break;
292
293     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
294     {
295         UINT8                    num_attrs;
296
297         if (len == 0)
298         {
299             p_result->get_app_attr_txt.num_attr = 0;
300             break;
301         }
302         BE_STREAM_TO_UINT8(num_attrs, p);
303         if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
304           num_attrs = AVRC_MAX_APP_ATTR_SIZE;
305         }
306         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_app_attr_txt.num_attr);
307         p_result->get_app_attr_txt.num_attr = num_attrs;
308         p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)
309             osi_malloc(num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
310         for (int xx = 0; xx < num_attrs; xx++)
311         {
312             BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
313             BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id, p);
314             BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
315             if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0)
316             {
317                 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_attr_txt.p_attrs[xx].str_len);
318                 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_attr_txt.p_attrs[xx].str_len);
319                 p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
320             } else {
321                 p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
322             }
323         }
324     }
325         break;
326
327     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
328     {
329         UINT8                    num_vals;
330
331         if (len == 0)
332         {
333             p_result->get_app_val_txt.num_attr = 0;
334             break;
335         }
336         BE_STREAM_TO_UINT8(num_vals, p);
337         if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
338           num_vals = AVRC_MAX_APP_ATTR_SIZE;
339         }
340         p_result->get_app_val_txt.num_attr = num_vals;
341         AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->get_app_val_txt.num_attr);
342
343         p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT *)
344             osi_malloc(num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
345         for (int i = 0; i < num_vals; i++) {
346             BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
347             BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
348             BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
349             if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
350                 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_val_txt.p_attrs[i].str_len);
351                 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_val_txt.p_attrs[i].str_len);
352                 p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
353             } else {
354                 p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
355             }
356         }
357     }
358         break;
359
360     case AVRC_PDU_SET_PLAYER_APP_VALUE:
361         /* nothing comes as part of this rsp */
362         break;
363
364     case AVRC_PDU_GET_ELEMENT_ATTR:
365     {
366         UINT8               num_attrs;
367
368         if (len <= 0)
369         {
370             p_result->get_elem_attrs.num_attr = 0;
371             break;
372         }
373         BE_STREAM_TO_UINT8(num_attrs, p);
374         p_result->get_elem_attrs.num_attr = num_attrs;
375         if (num_attrs)
376         {
377             tAVRC_ATTR_ENTRY *p_attrs =
378                 (tAVRC_ATTR_ENTRY*)osi_malloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
379             for (int i = 0; i < num_attrs; i++) {
380                 BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
381                 BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
382                 BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
383                 if (p_attrs[i].name.str_len > 0) {
384                     p_attrs[i].name.p_str = (UINT8 *)osi_malloc(p_attrs[i].name.str_len);
385                     BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str, p_attrs[i].name.str_len);
386                 }
387             }
388             p_result->get_elem_attrs.p_attrs = p_attrs;
389         }
390     }
391         break;
392
393     case AVRC_PDU_GET_PLAY_STATUS:
394         if (len == 0)
395         {
396             break;
397         }
398         BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
399         BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
400         BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
401         break;
402
403     default:
404         return AVRC_STS_BAD_CMD;
405     }
406     return AVRC_STS_NO_ERROR;
407 }
408
409 /*******************************************************************************
410 **
411 ** Function         AVRC_Ctrl_ParsResponse
412 **
413 ** Description      This function is a parse response for AVRCP Controller.
414 **
415 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
416 **                  Otherwise, the error code defined by AVRCP 1.4
417 **
418 *******************************************************************************/
419 tAVRC_STS AVRC_Ctrl_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16* buf_len)
420 {
421     tAVRC_STS  status = AVRC_STS_INTERNAL_ERR;
422     if (p_msg && p_result)
423     {
424         switch (p_msg->hdr.opcode)
425         {
426         case AVRC_OP_VENDOR:     /*  0x00    Vendor-dependent commands */
427             status = avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf,buf_len);
428             break;
429
430         default:
431             AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
432             break;
433         }
434         p_result->rsp.opcode = p_msg->hdr.opcode;
435         p_result->rsp.status = status;
436     }
437     return status;
438 }
439 #endif /* (AVRC_CTRL_INCLUDED) == TRUE) */
440 /*******************************************************************************
441 **
442 ** Function         AVRC_ParsResponse
443 **
444 ** Description      This function is a superset of AVRC_ParsMetadata to parse the response.
445 **
446 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
447 **                  Otherwise, the error code defined by AVRCP 1.4
448 **
449 *******************************************************************************/
450 tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16 buf_len)
451 {
452     tAVRC_STS  status = AVRC_STS_INTERNAL_ERR;
453     UINT16  id;
454     UNUSED(p_buf);
455     UNUSED(buf_len);
456
457     if (p_msg && p_result)
458     {
459         switch (p_msg->hdr.opcode)
460         {
461         case AVRC_OP_VENDOR:     /*  0x00    Vendor-dependent commands */
462             status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
463             break;
464
465         case AVRC_OP_PASS_THRU:  /*  0x7C    panel subunit opcode */
466             status = avrc_pars_pass_thru(&p_msg->pass, &id);
467             if (status == AVRC_STS_NO_ERROR)
468             {
469                 p_result->pdu = (UINT8)id;
470             }
471             break;
472
473         default:
474             AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
475             break;
476         }
477         p_result->rsp.opcode = p_msg->hdr.opcode;
478         p_result->rsp.status = status;
479     }
480     return status;
481 }
482 #endif /* (AVRC_METADATA_INCLUDED == TRUE) */