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