1 /******************************************************************************
2 *
3 * Copyright 2003-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 * Interface to AVRCP optional commands
22 *
23 ******************************************************************************/
24 #include <base/logging.h>
25 #include <string.h>
26
27 #include "avrc_api.h"
28 #include "avrc_int.h"
29 #include "osi/include/allocator.h"
30 #include "stack/include/bt_hdr.h"
31
32 /******************************************************************************
33 *
34 * Function avrc_vendor_msg
35 *
36 * Description Compose a VENDOR DEPENDENT command according to p_msg
37 *
38 * Input Parameters:
39 * p_msg: Pointer to VENDOR DEPENDENT message structure.
40 *
41 * Output Parameters:
42 * None.
43 *
44 * Returns pointer to a valid GKI buffer if successful.
45 * NULL if p_msg is NULL.
46 *
47 *****************************************************************************/
avrc_vendor_msg(tAVRC_MSG_VENDOR * p_msg)48 static BT_HDR* avrc_vendor_msg(tAVRC_MSG_VENDOR* p_msg) {
49 BT_HDR* p_cmd;
50 uint8_t* p_data;
51
52 CHECK(p_msg != NULL);
53
54 CHECK(AVRC_META_CMD_BUF_SIZE > (AVRC_MIN_CMD_LEN + p_msg->vendor_len));
55 p_cmd = (BT_HDR*)osi_calloc(AVRC_META_CMD_BUF_SIZE);
56
57 p_cmd->offset = AVCT_MSG_OFFSET;
58 p_data = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
59 *p_data++ = (p_msg->hdr.ctype & AVRC_CTYPE_MASK);
60 *p_data++ =
61 (p_msg->hdr.subunit_type << AVRC_SUBTYPE_SHIFT) | p_msg->hdr.subunit_id;
62 *p_data++ = AVRC_OP_VENDOR;
63 AVRC_CO_ID_TO_BE_STREAM(p_data, p_msg->company_id);
64 if (p_msg->vendor_len && p_msg->p_vendor_data)
65 memcpy(p_data, p_msg->p_vendor_data, p_msg->vendor_len);
66 p_cmd->len = (uint16_t)(p_data + p_msg->vendor_len - (uint8_t*)(p_cmd + 1) -
67 p_cmd->offset);
68 p_cmd->layer_specific = AVCT_DATA_CTRL;
69
70 return p_cmd;
71 }
72
73 /******************************************************************************
74 *
75 * Function AVRC_UnitCmd
76 *
77 * Description Send a UNIT INFO command to the peer device. This
78 * function can only be called for controller role connections.
79 * Any response message from the peer is passed back through
80 * the tAVRC_MSG_CBACK callback function.
81 *
82 * Input Parameters:
83 * handle: Handle of this connection.
84 *
85 * label: Transaction label.
86 *
87 * Output Parameters:
88 * None.
89 *
90 * Returns AVRC_SUCCESS if successful.
91 * AVRC_BAD_HANDLE if handle is invalid.
92 *
93 *****************************************************************************/
AVRC_UnitCmd(uint8_t handle,uint8_t label)94 uint16_t AVRC_UnitCmd(uint8_t handle, uint8_t label) {
95 BT_HDR* p_cmd = (BT_HDR*)osi_calloc(AVRC_CMD_BUF_SIZE);
96 uint8_t* p_data;
97
98 p_cmd->offset = AVCT_MSG_OFFSET;
99 p_data = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
100 *p_data++ = AVRC_CMD_STATUS;
101 /* unit & id ignore */
102 *p_data++ = (AVRC_SUB_UNIT << AVRC_SUBTYPE_SHIFT) | AVRC_SUBID_IGNORE;
103 *p_data++ = AVRC_OP_UNIT_INFO;
104 memset(p_data, AVRC_CMD_OPRND_PAD, AVRC_UNIT_OPRND_BYTES);
105 p_cmd->len =
106 p_data + AVRC_UNIT_OPRND_BYTES - (uint8_t*)(p_cmd + 1) - p_cmd->offset;
107 p_cmd->layer_specific = AVCT_DATA_CTRL;
108
109 return AVCT_MsgReq(handle, label, AVCT_CMD, p_cmd);
110 }
111
112 /******************************************************************************
113 *
114 * Function AVRC_SubCmd
115 *
116 * Description Send a SUBUNIT INFO command to the peer device. This
117 * function can only be called for controller role connections.
118 * Any response message from the peer is passed back through
119 * the tAVRC_MSG_CBACK callback function.
120 *
121 * Input Parameters:
122 * handle: Handle of this connection.
123 *
124 * label: Transaction label.
125 *
126 * page: Specifies which part of the subunit type table
127 * is requested. For AVRCP it is typically zero.
128 * Value range is 0-7.
129 *
130 * Output Parameters:
131 * None.
132 *
133 * Returns AVRC_SUCCESS if successful.
134 * AVRC_BAD_HANDLE if handle is invalid.
135 *
136 *****************************************************************************/
AVRC_SubCmd(uint8_t handle,uint8_t label,uint8_t page)137 uint16_t AVRC_SubCmd(uint8_t handle, uint8_t label, uint8_t page) {
138 BT_HDR* p_cmd = (BT_HDR*)osi_calloc(AVRC_CMD_BUF_SIZE);
139 uint8_t* p_data;
140
141 p_cmd->offset = AVCT_MSG_OFFSET;
142 p_data = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
143 *p_data++ = AVRC_CMD_STATUS;
144 /* unit & id ignore */
145 *p_data++ = (AVRC_SUB_UNIT << AVRC_SUBTYPE_SHIFT) | AVRC_SUBID_IGNORE;
146 *p_data++ = AVRC_OP_SUB_INFO;
147 *p_data++ =
148 ((page & AVRC_SUB_PAGE_MASK) << AVRC_SUB_PAGE_SHIFT) | AVRC_SUB_EXT_CODE;
149 memset(p_data, AVRC_CMD_OPRND_PAD, AVRC_SUB_OPRND_BYTES);
150 p_cmd->len =
151 p_data + AVRC_SUB_OPRND_BYTES - (uint8_t*)(p_cmd + 1) - p_cmd->offset;
152 p_cmd->layer_specific = AVCT_DATA_CTRL;
153
154 return AVCT_MsgReq(handle, label, AVCT_CMD, p_cmd);
155 }
156
157 /******************************************************************************
158 *
159 * Function AVRC_VendorCmd
160 *
161 * Description Send a VENDOR DEPENDENT command to the peer device. This
162 * function can only be called for controller role connections.
163 * Any response message from the peer is passed back through
164 * the tAVRC_MSG_CBACK callback function.
165 *
166 * Input Parameters:
167 * handle: Handle of this connection.
168 *
169 * label: Transaction label.
170 *
171 * p_msg: Pointer to VENDOR DEPENDENT message structure.
172 *
173 * Output Parameters:
174 * None.
175 *
176 * Returns AVRC_SUCCESS if successful.
177 * AVRC_BAD_HANDLE if handle is invalid.
178 *
179 *****************************************************************************/
AVRC_VendorCmd(uint8_t handle,uint8_t label,tAVRC_MSG_VENDOR * p_msg)180 uint16_t AVRC_VendorCmd(uint8_t handle, uint8_t label,
181 tAVRC_MSG_VENDOR* p_msg) {
182 BT_HDR* p_buf = avrc_vendor_msg(p_msg);
183 if (p_buf)
184 return AVCT_MsgReq(handle, label, AVCT_CMD, p_buf);
185 else
186 return AVCT_NO_RESOURCES;
187 }
188
189 /******************************************************************************
190 *
191 * Function AVRC_VendorRsp
192 *
193 * Description Send a VENDOR DEPENDENT response to the peer device. This
194 * function can only be called for target role connections.
195 * This function must be called when a VENDOR DEPENDENT
196 * command message is received from the peer through the
197 * tAVRC_MSG_CBACK callback function.
198 *
199 * Input Parameters:
200 * handle: Handle of this connection.
201 *
202 * label: Transaction label. Must be the same value as
203 * passed with the command message in the callback
204 * function.
205 *
206 * p_msg: Pointer to VENDOR DEPENDENT message structure.
207 *
208 * Output Parameters:
209 * None.
210 *
211 * Returns AVRC_SUCCESS if successful.
212 * AVRC_BAD_HANDLE if handle is invalid.
213 *
214 *****************************************************************************/
AVRC_VendorRsp(uint8_t handle,uint8_t label,tAVRC_MSG_VENDOR * p_msg)215 uint16_t AVRC_VendorRsp(uint8_t handle, uint8_t label,
216 tAVRC_MSG_VENDOR* p_msg) {
217 BT_HDR* p_buf = avrc_vendor_msg(p_msg);
218 if (p_buf)
219 return AVCT_MsgReq(handle, label, AVCT_RSP, p_buf);
220 else
221 return AVCT_NO_RESOURCES;
222 }
223