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