蓝牙之五-bludroid协议栈和厂商代码的交互

协议栈和厂商代码交互

完整的蓝牙调用图

蓝牙之五-bludroid协议栈和厂商代码的交互_第1张图片
协议栈所在的目录是/system/bt;厂商代码所在的目录是hardware/broadcom/libbt。
这两个不同的目录反应的是协议栈和厂商固件的交互流程,它们通过hci层进行交互,在bluez时代hci层是在linux kernel实现的,bluedroid时代放在了android层实现。两者交互的主要目录是system/bt/hci。


static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so";
​static const char *VENDOR_LIBRARY_SYMBOL_NAME = "BLUETOOTH_VENDOR_LIB_INTERFACE";

 46 static bool vendor_open(
 47     const uint8_t *local_bdaddr,
 48     const hci_t *hci_interface) {
 49   assert(lib_handle == NULL);
 50   hci = hci_interface;
 51 
 52   lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
 53   if (!lib_handle) {
 54     LOG_ERROR("%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
 55     goto error;
 56   }
 57 
 58   lib_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
 59   if (!lib_interface) {
 60     LOG_ERROR("%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
 61     goto error;
 62   }
 63 
 64   LOG_INFO("alloc value %p", lib_callbacks.alloc);
 65 
 66   int status = lib_interface->init(&lib_callbacks, (unsigned char *)local_bdaddr);
 67   if (status) {
 68     LOG_ERROR("%s unable to initialize vendor library: %d", __func__, status);
 69     goto error;
 70   }
 71 
 72   return true;
 73 
 74 error:;
 75   lib_interface = NULL;
 76   if (lib_handle)
 77     dlclose(lib_handle);
 78   lib_handle = NULL;
 79   return false;
 80 }

libbt-vendor是hardware/broadcom/libbt目录下编译出来的。
这里写图片描述
58行在这个库里查找BLUETOOTH_VENDOR_LIB_INTERFACE interface也即BLUETOOTH_VENDOR_LIB_INTERFACE。这个符号定义于hardware/broadcom/libbt/src/bt_vendor_brcm.c
蓝牙之五-bludroid协议栈和厂商代码的交互_第2张图片
init初始化蓝牙使用的串口设备号,
upio_init是io控制初始化,
vnd_load_conf加载蓝牙配置文件(/etc/bluetooth/bt_vendor.conf),

 ​ bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;

将传递进来的函数指针集赋给bt_vendor_cbacks,该集合具有的方法如下。lib_callbacks定义了若干回调函数。

 ​static const bt_vendor_callbacks_t lib_callbacks = {
  sizeof(lib_callbacks),
  firmware_config_cb,
  sco_config_cb,
  low_power_mode_cb,
  sco_audiostate_cb,
  buffer_alloc_cb,
  buffer_free_cb,
  transmit_cb,
  epilog_cb
};
 ​memcpy(vnd_local_bd_addr, local_bdaddr, 6);

将本地的6字节蓝牙设备地址赋值到vnd_local_bd_addr里。init,op以及cleanup函数如下。


 92 static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
 93 {
...
115     userial_vendor_init();
116     upio_init();
117 
118     vnd_load_conf(VENDOR_LIB_CONF_FILE);
119 
120     /* store reference to user callbacks */
121     bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
122 
123     /* This is handed over from the stack */
124     memcpy(vnd_local_bd_addr, local_bdaddr, 6);
125 
126     return 0;
127 }
131 static int op(bt_vendor_opcode_t opcode, void *param)
132 {
133     int retval = 0;
134 
135     BTVNDDBG("op for %d", opcode);
136 
137     switch(opcode)
138     {
139         case BT_VND_OP_POWER_CTRL:
140             {
141                 int *state = (int *) param;
142                 if (*state == BT_VND_PWR_OFF)
143                     upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
144                 else if (*state == BT_VND_PWR_ON)
145                     upio_set_bluetooth_power(UPIO_BT_POWER_ON);
146             }
147             break;
148 
149         case BT_VND_OP_FW_CFG:
150             {
151                 hw_config_start();
152             }
153             break;
154 
155         case BT_VND_OP_SCO_CFG:
156             {
157 #if (SCO_CFG_INCLUDED == TRUE)
158                 hw_sco_config();
159 #else
160                 retval = -1;
161 #endif
162             }
163             break;
164 
165         case BT_VND_OP_USERIAL_OPEN:
166             {
167                 int (*fd_array)[] = (int (*)[]) param;
168                 int fd, idx;
169                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
170                 if (fd != -1)
171                 {
172                     for (idx=0; idx < CH_MAX; idx++)
173                         (*fd_array)[idx] = fd;
174 
175                     retval = 1;
176                 }
177                 /* retval contains numbers of open fd of HCI channels */
178             }
179             break;
180 
181         case BT_VND_OP_USERIAL_CLOSE:
182             {
183                 userial_vendor_close();
184             }
185             break;
186 
187         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
188             {
189                 uint32_t *timeout_ms = (uint32_t *) param;
190                 *timeout_ms = hw_lpm_get_idle_timeout();
191             }
192             break;
193 
194         case BT_VND_OP_LPM_SET_MODE:
195             {
196                 uint8_t *mode = (uint8_t *) param;
197                 retval = hw_lpm_enable(*mode);
198             }
199             break;
200 
201         case BT_VND_OP_LPM_WAKE_SET_STATE:
202             {
203                 uint8_t *state = (uint8_t *) param;
204                 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
205                                         TRUE : FALSE;
206 
207                 hw_lpm_set_wake_state(wake_assert);
208             }
209             break;
210 
211          case BT_VND_OP_SET_AUDIO_STATE:
212             {
213                 retval = hw_set_audio_state((bt_vendor_op_audio_state_t *)param);
214             }
215             break;
216 
217         case BT_VND_OP_EPILOG:
218             {
219 #if (HW_END_WITH_HCI_RESET == FALSE)
220                 if (bt_vendor_cbacks)
221                 {
222                     bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
223                 }
224 #else
225                 hw_epilog_process();
226 #endif
227             }
228             break;
229     }
230 
231     return retval;
232 }
233 
234 /** Closes the interface */
235 static void cleanup( void )
236 {
237     BTVNDDBG("cleanup");
238 
239     upio_cleanup();
240 
241     bt_vendor_cbacks = NULL;
242 }


​245 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
246     sizeof(bt_vendor_interface_t),
247     init,
248     op,
249     cleanup
250 };

op函数定义了博通给的若干命令和命令参数接口,如:

 ​        case BT_VND_OP_POWER_CTRL:
            {
                int *state = (int *) param;
                if (*state == BT_VND_PWR_OFF)
                    upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
                else if (*state == BT_VND_PWR_ON)
                    upio_set_bluetooth_power(UPIO_BT_POWER_ON);
            }
            break;

该命令是蓝牙模块电源控制命令,根据参数值决定IO管脚是上拉还是下拉来管理设备上下电。底层实现是读写rfkill目录。操作码的op函数的使用方法和init类似,在同一个文件目录。如:

 ​
static int send_command(vendor_opcode_t opcode, void *param) {
  assert(lib_interface != NULL);
  return lib_interface->op(opcode, param);
}

接下来协议栈向上层

vendor_open是如何被调用的?又是谁调用的?

 <​system/bt/hci/src/vendor.c>
static const vendor_t interface = {
  vendor_open,
  vendor_close,
  send_command,
  send_async_command,
  set_callback,
};

const vendor_t *vendor_get_interface() {
  buffer_allocator = buffer_allocator_get_interface();
  return &interface;
}

vendor_open做为了interface的函数指针集,而调用vendor_get_interface就会返回该interface。查了下协议栈下调用该接口的源码,调用的地方如下:

< system/bt/>
hci/src/hci_hal_h4.c:255:  vendor = vendor_get_interface();
hci/src/hci_layer.c:782:  vendor = vendor_get_interface();
hci/src/low_power_manager.c:236:  vendor = vendor_get_interface();
hci/src/hci_hal_mct.c:202:  vendor = vendor_get_interface();

实际上vendor_open会被hci_hal_h4.c和hci_layer.c调用。

 
​254 const hci_hal_t *hci_hal_h4_get_interface() {
255   vendor = vendor_get_interface();
256   return &interface;
257 }

const hci_hal_t *hci_hal_get_interface() {
#if HCI_USE_MCT
  return hci_hal_mct_get_interface();
#else
  return hci_hal_h4_get_interface();
#endif
}



const hci_t *hci_layer_get_interface() {
  buffer_allocator = buffer_allocator_get_interface();
  hal = hci_hal_get_interface();
  btsnoop = btsnoop_get_interface();
  hci_inject = hci_inject_get_interface();
  packet_fragmenter = packet_fragmenter_get_interface();
  vendor = vendor_get_interface();
  low_power_manager = low_power_manager_get_interface();

  init_layer_interface();
  return &interface;
}

hci_hal_get_interface();
vendor = vendor_get_interface();
上述函数被system/bt/main/bte_main.c调用。

 ​void bte_main_boot_entry(void)
{
    module_init(get_module(GKI_MODULE));
    module_init(get_module(COUNTER_MODULE));

    hci = hci_layer_get_interface();
    if (!hci)
      LOG_ERROR("%s could not get hci layer interface.", __func__);

    btu_hci_msg_queue = fixed_queue_new(SIZE_MAX);
    if (btu_hci_msg_queue == NULL) {
      LOG_ERROR("%s unable to allocate hci message queue.", __func__);
      return;
    }

    data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);
    hci->set_data_queue(btu_hci_msg_queue);

#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
    bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
#endif
    module_init(get_module(STACK_CONFIG_MODULE));
}

这一过程如下。
蓝牙之五-bludroid协议栈和厂商代码的交互_第3张图片
附,协议栈几个目录作用:
Bluetooth Embedded System(BTE),它实现了BT的核心功能。
Bluetooth Application Layer (BTA),用于和android framework层交互。
BTI F: Bluetooth Interface
BTU : Bluetooth Upper Layer
BTM: Bluetooth Manager
BT 系统服务通过JNI与BT stack交互,并且通过Binder IPC通信与应用交互。这个系统服务同时也提供给RD获取不同的BT profiles。
GKI以库libbt-brcm_gki.so(Static Lib?)的形式提供给BlueDroid使用,该层是一个适配层,适配了OS相关的进程、内存相关的管理,还可以用于线程间传递消息主要通过变量gki_cb实现对进程的统一管理。

你可能感兴趣的:(蓝牙,android,蓝牙,bluedroid,栈)