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