1 /******************************************************************************
3 * Copyright (C) 2014 Google, Inc.
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 #define LOG_TAG "bt_vendor"
26 #include "buffer_allocator.h"
27 #include "osi/include/log.h"
28 #include "osi/include/osi.h"
30 #define LAST_VENDOR_OPCODE_VALUE VENDOR_DO_EPILOG
32 static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so";
33 static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE";
35 static const vendor_t interface;
36 static const allocator_t *buffer_allocator;
37 static const hci_t *hci;
38 static vendor_cb callbacks[LAST_VENDOR_OPCODE_VALUE + 1];
40 static void *lib_handle;
41 static bt_vendor_interface_t *lib_interface;
42 static const bt_vendor_callbacks_t lib_callbacks;
44 // Interface functions
46 static bool vendor_open(
47 const uint8_t *local_bdaddr,
48 const hci_t *hci_interface) {
49 assert(lib_handle == NULL);
52 lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
54 LOG_ERROR(LOG_TAG, "%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
58 lib_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
60 LOG_ERROR(LOG_TAG, "%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
64 LOG_INFO(LOG_TAG, "alloc value %p", lib_callbacks.alloc);
66 int status = lib_interface->init(&lib_callbacks, (unsigned char *)local_bdaddr);
68 LOG_ERROR(LOG_TAG, "%s unable to initialize vendor library: %d", __func__, status);
82 static void vendor_close(void) {
84 lib_interface->cleanup();
93 static int send_command(vendor_opcode_t opcode, void *param) {
94 assert(lib_interface != NULL);
95 return lib_interface->op(opcode, param);
98 static int send_async_command(vendor_async_opcode_t opcode, void *param) {
99 assert(lib_interface != NULL);
100 return lib_interface->op(opcode, param);
103 static void set_callback(vendor_async_opcode_t opcode, vendor_cb callback) {
104 callbacks[opcode] = callback;
107 // Internal functions
109 // Called back from vendor library when the firmware configuration
111 static void firmware_config_cb(bt_vendor_op_result_t result) {
112 LOG_INFO(LOG_TAG, "firmware callback");
113 vendor_cb callback = callbacks[VENDOR_CONFIGURE_FIRMWARE];
114 assert(callback != NULL);
115 callback(result == BT_VND_OP_RESULT_SUCCESS);
118 // Called back from vendor library to indicate status of previous
119 // SCO configuration request. This should only happen during the
121 static void sco_config_cb(bt_vendor_op_result_t result) {
122 LOG_INFO(LOG_TAG, "%s", __func__);
123 vendor_cb callback = callbacks[VENDOR_CONFIGURE_SCO];
124 assert(callback != NULL);
125 callback(result == BT_VND_OP_RESULT_SUCCESS);
128 // Called back from vendor library to indicate status of previous
129 // LPM enable/disable request.
130 static void low_power_mode_cb(bt_vendor_op_result_t result) {
131 LOG_INFO(LOG_TAG, "%s", __func__);
132 vendor_cb callback = callbacks[VENDOR_SET_LPM_MODE];
133 assert(callback != NULL);
134 callback(result == BT_VND_OP_RESULT_SUCCESS);
137 /******************************************************************************
139 ** Function sco_audiostate_cb
141 ** Description HOST/CONTROLLER VENDOR LIB CALLBACK API - This function is
142 ** called when the libbt-vendor completed vendor specific codec
147 ******************************************************************************/
148 static void sco_audiostate_cb(bt_vendor_op_result_t result)
150 uint8_t status = (result == BT_VND_OP_RESULT_SUCCESS) ? 0 : 1;
152 LOG_INFO(LOG_TAG, "sco_audiostate_cb(status: %d)",status);
155 // Called by vendor library when it needs an HCI buffer.
156 static void *buffer_alloc_cb(int size) {
157 return buffer_allocator->alloc(size);
160 // Called by vendor library when it needs to free a buffer allocated with
161 // |buffer_alloc_cb|.
162 static void buffer_free_cb(void *buffer) {
163 buffer_allocator->free(buffer);
166 static void transmit_completed_callback(BT_HDR *response, void *context) {
167 // Call back to the vendor library if it provided a callback to call.
169 ((tINT_CMD_CBACK)context)(response);
172 // Called back from vendor library when it wants to send an HCI command.
173 static uint8_t transmit_cb(UNUSED_ATTR uint16_t opcode, void *buffer, tINT_CMD_CBACK callback) {
175 hci->transmit_command((BT_HDR *)buffer, transmit_completed_callback, NULL, callback);
179 // Called back from vendor library when the epilog procedure has
180 // completed. It is safe to call vendor_interface->cleanup() after
181 // this callback has been received.
182 static void epilog_cb(bt_vendor_op_result_t result) {
183 LOG_INFO(LOG_TAG, "%s", __func__);
184 vendor_cb callback = callbacks[VENDOR_DO_EPILOG];
185 assert(callback != NULL);
186 callback(result == BT_VND_OP_RESULT_SUCCESS);
189 static const bt_vendor_callbacks_t lib_callbacks = {
190 sizeof(lib_callbacks),
201 static const vendor_t interface = {
209 const vendor_t *vendor_get_interface() {
210 buffer_allocator = buffer_allocator_get_interface();