• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 Google, Inc.
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 #define LOG_TAG "bt_vendor"
20 
21 #include <assert.h>
22 #include <dlfcn.h>
23 #include <utils/Log.h>
24 
25 #include "bt_hci_bdroid.h"
26 #include "bt_vendor_lib.h"
27 #include "hci.h"
28 #include "osi.h"
29 
30 // TODO: eliminate these three.
31 extern tHCI_IF *p_hci_if;
32 extern bool fwcfg_acked;
33 void lpm_vnd_cback(uint8_t vnd_result);
34 
35 static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so";
36 static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE";
37 
38 static void *lib_handle;
39 static bt_vendor_interface_t *vendor_interface;
40 
41 static void firmware_config_cb(bt_vendor_op_result_t result);
42 static void sco_config_cb(bt_vendor_op_result_t result);
43 static void low_power_mode_cb(bt_vendor_op_result_t result);
44 static void sco_audiostate_cb(bt_vendor_op_result_t result);
45 static void *buffer_alloc(int size);
46 static void buffer_free(void *buffer);
47 static uint8_t transmit_cb(uint16_t opcode, void *buffer, tINT_CMD_CBACK callback);
48 static void epilog_cb(bt_vendor_op_result_t result);
49 
50 static const bt_vendor_callbacks_t vendor_callbacks = {
51   sizeof(vendor_callbacks),
52   firmware_config_cb,
53   sco_config_cb,
54   low_power_mode_cb,
55   sco_audiostate_cb,
56   buffer_alloc,
57   buffer_free,
58   transmit_cb,
59   epilog_cb
60 };
61 
vendor_open(const uint8_t * local_bdaddr)62 bool vendor_open(const uint8_t *local_bdaddr) {
63   assert(lib_handle == NULL);
64 
65   lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
66   if (!lib_handle) {
67     ALOGE("%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
68     goto error;
69   }
70 
71   vendor_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
72   if (!vendor_interface) {
73     ALOGE("%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
74     goto error;
75   }
76 
77   int status = vendor_interface->init(&vendor_callbacks, (unsigned char *)local_bdaddr);
78   if (status) {
79     ALOGE("%s unable to initialize vendor library: %d", __func__, status);
80     goto error;
81   }
82 
83   return true;
84 
85 error:;
86   vendor_interface = NULL;
87   if (lib_handle)
88     dlclose(lib_handle);
89   lib_handle = NULL;
90   return false;
91 }
92 
vendor_close(void)93 void vendor_close(void) {
94   if (vendor_interface)
95     vendor_interface->cleanup();
96 
97   if (lib_handle)
98     dlclose(lib_handle);
99 
100   vendor_interface = NULL;
101   lib_handle = NULL;
102 }
103 
vendor_send_command(bt_vendor_opcode_t opcode,void * param)104 int vendor_send_command(bt_vendor_opcode_t opcode, void *param) {
105   assert(vendor_interface != NULL);
106 
107   return vendor_interface->op(opcode, param);
108 }
109 
110 // Called back from vendor library when the firmware configuration
111 // completes.
firmware_config_cb(bt_vendor_op_result_t result)112 static void firmware_config_cb(bt_vendor_op_result_t result) {
113   assert(bt_hc_cbacks != NULL);
114 
115   fwcfg_acked = true;
116 
117   bt_hc_postload_result_t status = (result == BT_VND_OP_RESULT_SUCCESS)
118       ? BT_HC_PRELOAD_SUCCESS
119       : BT_HC_PRELOAD_FAIL;
120   bt_hc_cbacks->preload_cb(NULL, status);
121 }
122 
123 // Called back from vendor library to indicate status of previous
124 // SCO configuration request. This should only happen during the
125 // postload process.
sco_config_cb(UNUSED_ATTR bt_vendor_op_result_t result)126 static void sco_config_cb(UNUSED_ATTR bt_vendor_op_result_t result) {
127   assert(p_hci_if != NULL);
128 
129   // Continue the rest of the postload process.
130   p_hci_if->get_acl_max_len();
131 }
132 
133 // Called back from vendor library to indicate status of previous
134 // LPM enable/disable request.
low_power_mode_cb(bt_vendor_op_result_t result)135 static void low_power_mode_cb(bt_vendor_op_result_t result) {
136   lpm_vnd_cback(result != BT_VND_OP_RESULT_SUCCESS);
137 }
138 
139 /******************************************************************************
140 **
141 ** Function         sco_audiostate_cb
142 **
143 ** Description      HOST/CONTROLLER VENDOR LIB CALLBACK API - This function is
144 **                  called when the libbt-vendor completed vendor specific codec
145 **                  setup request
146 **
147 ** Returns          None
148 **
149 ******************************************************************************/
sco_audiostate_cb(bt_vendor_op_result_t result)150 static void sco_audiostate_cb(bt_vendor_op_result_t result)
151 {
152     uint8_t status = (result == BT_VND_OP_RESULT_SUCCESS) ? 0 : 1;
153 
154     ALOGI("sco_audiostate_cb(status: %d)",status);
155 }
156 
157 // Called by vendor library when it needs an HCI buffer.
buffer_alloc(int size)158 static void *buffer_alloc(int size) {
159   assert(bt_hc_cbacks != NULL);
160   return bt_hc_cbacks->alloc(size);
161 }
162 
163 // Called by vendor library when it needs to free a buffer allocated with
164 // |buffer_alloc|.
buffer_free(void * buffer)165 static void buffer_free(void *buffer) {
166   assert(bt_hc_cbacks != NULL);
167   bt_hc_cbacks->dealloc(buffer);
168 }
169 
170 // Called back from vendor library when it wants to send an HCI command.
transmit_cb(uint16_t opcode,void * buffer,tINT_CMD_CBACK callback)171 static uint8_t transmit_cb(uint16_t opcode, void *buffer, tINT_CMD_CBACK callback) {
172   assert(p_hci_if != NULL);
173   return p_hci_if->send_int_cmd(opcode, (HC_BT_HDR *)buffer, callback);
174 }
175 
176 // Called back from vendor library when the epilog procedure has
177 // completed. It is safe to call vendor_interface->cleanup() after
178 // this callback has been received.
epilog_cb(UNUSED_ATTR bt_vendor_op_result_t result)179 static void epilog_cb(UNUSED_ATTR bt_vendor_op_result_t result) {
180 }
181