Android 4.4 蓝牙解析(一)

首先我们都知道蓝牙第一步是上电,但是android4.4蓝牙上电部分的代码实际已经和android4.3不一样了。

android4.3蓝牙os是走system/bluetooth,但是android4.4走的是hardware/libhardware和external/bluetooth/,具体请看下面:

Bluetooth.h(hardware/libhardware/include/hardware/)----这是结构体,主要是看enable函数。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct {  
  2.     /** set to sizeof(bt_interface_t) */  
  3.     size_t size;  
  4.     /** 
  5.      * Opens the interface and provides the callback routines 
  6.      * to the implemenation of this interface. 
  7.      */  
  8.     int (*init)(bt_callbacks_t* callbacks );  
  9.   
  10.     /** Enable Bluetooth. */  
  11.     int (*<span style="color:#ff0000;">enable</span>)(void);  
  12.   
  13.     /** Disable Bluetooth. */  
  14.     int (*disable)(void);  
  15.   
  16.     /** Closes the interface. */  
  17.     void (*cleanup)(void);  
  18.   
  19.     /** Get all Bluetooth Adapter properties at init */  
  20.     int (*get_adapter_properties)(void);  
  21.   
  22.     /** Get Bluetooth Adapter property of 'type' */  
  23.     int (*get_adapter_property)(bt_property_type_t type);  
  24.   
  25.     /** Set Bluetooth Adapter property of 'type' */  
  26.     /* Based on the type, val shall be one of 
  27.      * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc 
  28.      */  
  29.     int (*set_adapter_property)(const bt_property_t *property);  
  30.   
  31.     /** Get all Remote Device properties */  
  32.     int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);  
  33.   
  34.     /** Get Remote Device property of 'type' */  
  35.     int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,  
  36.                                       bt_property_type_t type);  
  37.   
  38.     /** Set Remote Device property of 'type' */  
  39.     int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,  
  40.                                       const bt_property_t *property);  
  41.   
  42.     /** Get Remote Device's service record  for the given UUID */  
  43.     int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,  
  44.                                      bt_uuid_t *uuid);  
  45.   
  46.     /** Start SDP to get remote services */  
  47.     int (*get_remote_services)(bt_bdaddr_t *remote_addr);  
  48.   
  49.     /** Start Discovery */  
  50.     int (*start_discovery)(void);  
  51.   
  52.     /** Cancel Discovery */  
  53.     int (*cancel_discovery)(void);  
  54.   
  55.     /** Create Bluetooth Bonding */  
  56.     int (*create_bond)(const bt_bdaddr_t *bd_addr);  
  57.   
  58.     /** Remove Bond */  
  59.     int (*remove_bond)(const bt_bdaddr_t *bd_addr);  
  60.   
  61.     /** Cancel Bond */  
  62.     int (*cancel_bond)(const bt_bdaddr_t *bd_addr);  
  63.   
  64.     /** BT Legacy PinKey Reply */  
  65.     /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */  
  66.     int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,  
  67.                      uint8_t pin_len, bt_pin_code_t *pin_code);  
  68.   
  69.     /** BT SSP Reply - Just Works, Numeric Comparison and Passkey 
  70.      * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON & 
  71.      * BT_SSP_VARIANT_CONSENT 
  72.      * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey 
  73.      * shall be zero */  
  74.     int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,  
  75.                      uint8_t accept, uint32_t passkey);  
  76.   
  77.     /** Get Bluetooth profile interface */  
  78.     const void* (*get_profile_interface) (const char *profile_id);  
  79.   
  80.     /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */  
  81.     /* Configure DUT Mode - Use this mode to enter/exit DUT mode */  
  82.     int (*dut_mode_configure)(uint8_t enable);  
  83.   
  84.     /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */  
  85.     int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  86.     /** BLE Test Mode APIs */  
  87.     /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */  
  88.     int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  89.   
  90.     /* enable or disable bluetooth HCI snoop log */  
  91.     int (*config_hci_snoop_log)(uint8_t enable);  
  92. } bt_interface_t;  
有结构体就会要找结构体对照的函数实现:

Bluetooth.c (external\bluetooth\bluedroid\btif\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. const bt_interface_t* bluetooth__get_bluetooth_interface ()  
  2. {  
  3.     /* fixme -- add property to disable bt interface ? */  
  4.   
  5.     return &bluetoothInterface;  
  6. }  


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static const bt_interface_t bluetoothInterface = {  
  2.     sizeof(bluetoothInterface),  
  3.     init,  
  4.     enable,  
  5.     disable,  
  6.     cleanup,  
  7.     get_adapter_properties,  
  8.     get_adapter_property,  
  9.     set_adapter_property,  
  10.     get_remote_device_properties,  
  11.     get_remote_device_property,  
  12.     set_remote_device_property,  
  13.     get_remote_service_record,  
  14.     get_remote_services,  
  15.     start_discovery,  
  16.     cancel_discovery,  
  17.     create_bond,  
  18.     remove_bond,  
  19.     cancel_bond,  
  20.     pin_reply,  
  21.     ssp_reply,  
  22.     get_profile_interface,  
  23.     dut_mode_configure,  
  24.     dut_mode_send,  
  25. #if BLE_INCLUDED == TRUE  
  26.     le_test_mode,  
  27. #else  
  28.     NULL,  
  29. #endif  
  30.     config_hci_snoop_log  
  31. };  
找到enable函数了,那就要看看他的实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int enable( void )  
  2. {  
  3.     ALOGI("enable");  
  4.   
  5.     /* sanity check */  
  6.     if (interface_ready() == FALSE)  
  7.         return BT_STATUS_NOT_READY;  
  8.   
  9.     return btif_enable_bluetooth();  
  10. }  
接下来就是按照函数实现一步一步走了,但是btif_enable_bluetooth()是有声明函数的,一定要注意,在btif_api.h,这里就不贴代码了。继续:

Btif_core.c (\external\bluetooth\bluedroid\btif\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. bt_status_t btif_enable_bluetooth(void)  
  2. {  
  3.     BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");  
  4.   
  5.   
  6.     if (btif_core_state != BTIF_CORE_STATE_DISABLED)  
  7.     {  
  8.         ALOGD("not disabled\n");  
  9.         return BT_STATUS_DONE;  
  10.     }  
  11.   
  12.   
  13.     btif_core_state = BTIF_CORE_STATE_ENABLING;  
  14.   
  15.   
  16.     /* Create the GKI tasks and run them */  
  17.     bte_main_enable();  
  18.   
  19.   
  20.     return BT_STATUS_SUCCESS;  
  21. }  
接下来我们要去找bte_main_enable函数的实现了:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void bte_main_enable()  
  2. {  
  3.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  4.   
  5.     /* Initialize BTE control block */  
  6.     BTE_Init();  
  7.   
  8.     lpm_enabled = FALSE;  
  9.   
  10.     bte_hci_enable();  
  11.   
  12.     GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,  
  13.                     (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),  
  14.                     sizeof(bte_btu_stack));  
  15.   
  16.     GKI_run(0);  
  17. }  
接下来是bte_hci_enable,当然有一些函数你可以看看,BTE_Init()和GKI-
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void bte_hci_enable(void)  
  2. {  
  3.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  4.   
  5.     preload_start_wait_timer();  
  6.   
  7.     if (bt_hc_if)  
  8.     {  
  9.         int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);  
  10.         APPL_TRACE_EVENT1("libbt-hci init returns %d", result);  
  11.   
  12.         assert(result == BT_HC_STATUS_SUCCESS);  
  13.   
  14.         if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)  
  15.             bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);  
  16.   
  17. #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)  
  18.         APPL_TRACE_DEBUG1("%s  Not Turninig Off the BT before Turninig ON", __FUNCTION__);  
  19.   
  20.         /* Do not power off the chip before powering on  if BT_CLEAN_TURN_ON_DISABLED flag 
  21.          is defined and set to TRUE to avoid below mentioned issue. 
  22.  
  23.          Wingray kernel driver maintains a combined  counter to keep track of 
  24.          BT-Wifi state. Invoking  set_power(BT_HC_CHIP_PWR_OFF) when the BT is already 
  25.          in OFF state causes this counter to be incorrectly decremented and results in undesired 
  26.          behavior of the chip. 
  27.  
  28.          This is only a workaround and when the issue is fixed in the kernel this work around 
  29.          should be removed. */  
  30. #else  
  31.         /* toggle chip power to ensure we will reset chip in case 
  32.            a previous stack shutdown wasn't completed gracefully */  
  33.         bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);  
  34. #endif  
  35.         bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);  
  36.   
  37.         bt_hc_if->preload(NULL);  
  38.     }  
  39. }  
这个地方就要特别小心了,因为你会发现这里不是现实
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static bt_hc_interface_t *bt_hc_if=NULL;  
具体的对照关系要去bt_hci_lib.h文件里去查bt_hc_interface_t结构体的内容,这里也不贴了。

通过函数对照你会找到Bt_hci_bdroid.c (\android4.4\external\bluetooth\bluedroid\hci\src),这里才是set_power的实现。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. const bt_hc_interface_t *bt_hc_get_interface(void)  
  2. {  
  3.     return &bluetoothHCLibInterface;  
  4. }  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static const bt_hc_interface_t bluetoothHCLibInterface = {  
  2.     sizeof(bt_hc_interface_t),  
  3.     init,  
  4.     set_power,  
  5.     lpm,  
  6.     preload,  
  7.     postload,  
  8.     transmit_buf,  
  9.     set_rxflow,  
  10.     logging,  
  11.     cleanup  
  12. };  
这时候就可以去找set_power的实现了:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** Chip power control */  
  2. static void set_power(bt_hc_chip_power_state_t state)  
  3. {  
  4.     int pwr_state;  
  5.   
  6.     BTHCDBG("set_power %d", state);  
  7.   
  8.     /* Calling vendor-specific part */  
  9.     pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;  
  10.   
  11.     if (bt_vnd_if)  
  12.         bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);  
  13.     else  
  14.         ALOGE("vendor lib is missing!");  
  15. }  
这时候又要进行函数对照了,extern bt_vendor_interface_t *bt_vnd_if; 但是一定要细心奥:
bt_vendor_interface_t的结构体是在Bt_vendor_lib.h (\external\bluetooth\bluedroid\hci\include) 大家可以自己去查一下,我这里也不贴了。

这个时候我们要去找op函数的实现在Bt_vendor_brcm.c (\android4.4\hardware\broadcom\libbt\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Entry point of DLib  
  2. const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {  
  3.     sizeof(bt_vendor_interface_t),  
  4.     init,  
  5.     op,  
  6.     cleanup  
  7. };  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int op(bt_vendor_opcode_t opcode, void *param)  
  2. {  
  3.     int retval = 0;  
  4.   
  5.     BTVNDDBG("op for %d", opcode);  
  6.   
  7.     switch(opcode)  
  8.     {  
  9.         case BT_VND_OP_POWER_CTRL:  
  10.             {  
  11.                 int *state = (int *) param;  
  12.                 if (*state == BT_VND_PWR_OFF)  
  13.                     upio_set_bluetooth_power(UPIO_BT_POWER_OFF);  
  14.                 else if (*state == BT_VND_PWR_ON)  
  15.                     upio_set_bluetooth_power(UPIO_BT_POWER_ON);  
  16.             }  
  17.             break;  
  18.   
  19.         case BT_VND_OP_FW_CFG:  
  20.             {  
  21.                 hw_config_start();  
  22.             }  
  23.             break;  
  24.   
  25.         case BT_VND_OP_SCO_CFG:  
  26.             {  
  27. #if (SCO_CFG_INCLUDED == TRUE)  
  28.                 hw_sco_config();  
  29. #else  
  30.                 retval = -1;  
  31. #endif  
  32.             }  
  33.             break;  
  34.   
  35.         case BT_VND_OP_USERIAL_OPEN:  
  36.             {  
  37.                 int (*fd_array)[] = (int (*)[]) param;  
  38.                 int fd, idx;  
  39.                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);  
  40.                 if (fd != -1)  
  41.                 {  
  42.                     for (idx=0; idx < CH_MAX; idx++)  
  43.                         (*fd_array)[idx] = fd;  
  44.   
  45.                     retval = 1;  
  46.                 }  
  47.                 /* retval contains numbers of open fd of HCI channels */  
  48.             }  
  49.             break;  
  50.   
  51.         case BT_VND_OP_USERIAL_CLOSE:  
  52.             {  
  53.                 userial_vendor_close();  
  54.             }  
  55.             break;  
  56.   
  57.         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:  
  58.             {  
  59.                 uint32_t *timeout_ms = (uint32_t *) param;  
  60.                 *timeout_ms = hw_lpm_get_idle_timeout();  
  61.             }  
  62.             break;  
  63.   
  64.         case BT_VND_OP_LPM_SET_MODE:  
  65.             {  
  66.                 uint8_t *mode = (uint8_t *) param;  
  67.                 retval = hw_lpm_enable(*mode);  
  68.             }  
  69.             break;  
  70.   
  71.         case BT_VND_OP_LPM_WAKE_SET_STATE:  
  72.             {  
  73.                 uint8_t *state = (uint8_t *) param;  
  74.                 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \  
  75.                                         TRUE : FALSE;  
  76.   
  77.                 hw_lpm_set_wake_state(wake_assert);  
  78.             }  
  79.             break;  
  80.   
  81.         case BT_VND_OP_EPILOG:  
  82.             {  
  83. #if (HW_END_WITH_HCI_RESET == FALSE)  
  84.                 if (bt_vendor_cbacks)  
  85.                 {  
  86.                     bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);  
  87.                 }  
  88. #else  
  89.                 hw_epilog_process();  
  90. #endif  
  91.             }  
  92.             break;  
  93.     }  
  94.   
  95.     return retval;  
  96. }  
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.   
刚才传递的参数是BT_VND_OP_POWER_CTRL

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. case BT_VND_OP_POWER_CTRL:  
  2.     {  
  3.         int *state = (int *) param;  
  4.         if (*state == BT_VND_PWR_OFF)  
  5.             upio_set_bluetooth_power(UPIO_BT_POWER_OFF);  
  6.         else if (*state == BT_VND_PWR_ON)  
  7.             upio_set_bluetooth_power(UPIO_BT_POWER_ON);  
  8.     }  
  9.     break;  
实际我们走的是upio_set_bluetooth_power(UPIO_BT_POWER_ON);所以:

接下来已经到Upio.c (android4.4\hardware\broadcom\libbt\src)

忽然发现,这个文件结构有点像android4.3以前的bluetooth.c,找到实现代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int init_rfkill()  
  2. {  
  3.     char path[64];  
  4.     char buf[16];  
  5.     int fd, sz, id;  
  6.   
  7.     if (is_rfkill_disabled())  
  8.         return -1;  
  9.   
  10.     for (id = 0; ; id++)  
  11.     {  
  12.         snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);  
  13.         fd = open(path, O_RDONLY);  
  14.         if (fd < 0)  
  15.         {  
  16.             ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \  
  17.                  path, strerror(errno), errno);  
  18.             return -1;  
  19.         }  
  20.   
  21.         sz = read(fd, &buf, sizeof(buf));  
  22.         close(fd);  
  23.   
  24.         if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)  
  25.         {  
  26.             rfkill_id = id;  
  27.             break;  
  28.         }  
  29.     }  
  30.   
  31.     asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);  
  32.     return 0;  
  33. }  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int upio_set_bluetooth_power(int on)  
  2. {  
  3.     int sz;  
  4.     int fd = -1;  
  5.     int ret = -1;  
  6.     char buffer = '0';  
  7.   
  8.     switch(on)  
  9.     {  
  10.         case UPIO_BT_POWER_OFF:  
  11.             buffer = '0';  
  12.             break;  
  13.   
  14.         case UPIO_BT_POWER_ON:  
  15.             buffer = '1';  
  16.             break;  
  17.     }  
  18.   
  19.     if (is_emulator_context())  
  20.     {  
  21.         /* if new value is same as current, return -1 */  
  22.         if (bt_emul_enable == on)  
  23.             return ret;  
  24.   
  25.         UPIODBG("set_bluetooth_power [emul] %d", on);  
  26.   
  27.         bt_emul_enable = on;  
  28.         return 0;  
  29.     }  
  30.   
  31.     /* check if we have rfkill interface */  
  32.     if (is_rfkill_disabled())  
  33.         return 0;  
  34.   
  35.     if (rfkill_id == -1)  
  36.     {  
  37.         if (init_rfkill())  
  38.             return ret;  
  39.     }  
  40.   
  41.     fd = open(rfkill_state_path, O_WRONLY);  
  42.   
  43.     if (fd < 0)  
  44.     {  
  45.         ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",  
  46.             rfkill_state_path, strerror(errno), errno);  
  47.         return ret;  
  48.     }  
  49.   
  50.     sz = write(fd, &buffer, 1);  
  51.   
  52.     if (sz < 0) {  
  53.         ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",  
  54.             rfkill_state_path, strerror(errno),errno);  
  55.     }  
  56.     else  
  57.         ret = 0;  
  58.   
  59.     if (fd >= 0)  
  60.         close(fd);  
  61.   
  62.     return ret;  
  63. }  

好的,我们终于找到rfkill的路径了,剩下的就是调用kernel bluetooth的sys设备符了。

首先我们都知道蓝牙第一步是上电,但是android4.4蓝牙上电部分的代码实际已经和android4.3不一样了。

android4.3蓝牙os是走system/bluetooth,但是android4.4走的是hardware/libhardware和external/bluetooth/,具体请看下面:

Bluetooth.h(hardware/libhardware/include/hardware/)----这是结构体,主要是看enable函数。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct {  
  2.     /** set to sizeof(bt_interface_t) */  
  3.     size_t size;  
  4.     /** 
  5.      * Opens the interface and provides the callback routines 
  6.      * to the implemenation of this interface. 
  7.      */  
  8.     int (*init)(bt_callbacks_t* callbacks );  
  9.   
  10.     /** Enable Bluetooth. */  
  11.     int (*<span style="color:#ff0000;">enable</span>)(void);  
  12.   
  13.     /** Disable Bluetooth. */  
  14.     int (*disable)(void);  
  15.   
  16.     /** Closes the interface. */  
  17.     void (*cleanup)(void);  
  18.   
  19.     /** Get all Bluetooth Adapter properties at init */  
  20.     int (*get_adapter_properties)(void);  
  21.   
  22.     /** Get Bluetooth Adapter property of 'type' */  
  23.     int (*get_adapter_property)(bt_property_type_t type);  
  24.   
  25.     /** Set Bluetooth Adapter property of 'type' */  
  26.     /* Based on the type, val shall be one of 
  27.      * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc 
  28.      */  
  29.     int (*set_adapter_property)(const bt_property_t *property);  
  30.   
  31.     /** Get all Remote Device properties */  
  32.     int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);  
  33.   
  34.     /** Get Remote Device property of 'type' */  
  35.     int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,  
  36.                                       bt_property_type_t type);  
  37.   
  38.     /** Set Remote Device property of 'type' */  
  39.     int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,  
  40.                                       const bt_property_t *property);  
  41.   
  42.     /** Get Remote Device's service record  for the given UUID */  
  43.     int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,  
  44.                                      bt_uuid_t *uuid);  
  45.   
  46.     /** Start SDP to get remote services */  
  47.     int (*get_remote_services)(bt_bdaddr_t *remote_addr);  
  48.   
  49.     /** Start Discovery */  
  50.     int (*start_discovery)(void);  
  51.   
  52.     /** Cancel Discovery */  
  53.     int (*cancel_discovery)(void);  
  54.   
  55.     /** Create Bluetooth Bonding */  
  56.     int (*create_bond)(const bt_bdaddr_t *bd_addr);  
  57.   
  58.     /** Remove Bond */  
  59.     int (*remove_bond)(const bt_bdaddr_t *bd_addr);  
  60.   
  61.     /** Cancel Bond */  
  62.     int (*cancel_bond)(const bt_bdaddr_t *bd_addr);  
  63.   
  64.     /** BT Legacy PinKey Reply */  
  65.     /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */  
  66.     int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,  
  67.                      uint8_t pin_len, bt_pin_code_t *pin_code);  
  68.   
  69.     /** BT SSP Reply - Just Works, Numeric Comparison and Passkey 
  70.      * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON & 
  71.      * BT_SSP_VARIANT_CONSENT 
  72.      * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey 
  73.      * shall be zero */  
  74.     int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,  
  75.                      uint8_t accept, uint32_t passkey);  
  76.   
  77.     /** Get Bluetooth profile interface */  
  78.     const void* (*get_profile_interface) (const char *profile_id);  
  79.   
  80.     /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */  
  81.     /* Configure DUT Mode - Use this mode to enter/exit DUT mode */  
  82.     int (*dut_mode_configure)(uint8_t enable);  
  83.   
  84.     /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */  
  85.     int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  86.     /** BLE Test Mode APIs */  
  87.     /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */  
  88.     int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  89.   
  90.     /* enable or disable bluetooth HCI snoop log */  
  91.     int (*config_hci_snoop_log)(uint8_t enable);  
  92. } bt_interface_t;  
有结构体就会要找结构体对照的函数实现:

Bluetooth.c (external\bluetooth\bluedroid\btif\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. const bt_interface_t* bluetooth__get_bluetooth_interface ()  
  2. {  
  3.     /* fixme -- add property to disable bt interface ? */  
  4.   
  5.     return &bluetoothInterface;  
  6. }  


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static const bt_interface_t bluetoothInterface = {  
  2.     sizeof(bluetoothInterface),  
  3.     init,  
  4.     enable,  
  5.     disable,  
  6.     cleanup,  
  7.     get_adapter_properties,  
  8.     get_adapter_property,  
  9.     set_adapter_property,  
  10.     get_remote_device_properties,  
  11.     get_remote_device_property,  
  12.     set_remote_device_property,  
  13.     get_remote_service_record,  
  14.     get_remote_services,  
  15.     start_discovery,  
  16.     cancel_discovery,  
  17.     create_bond,  
  18.     remove_bond,  
  19.     cancel_bond,  
  20.     pin_reply,  
  21.     ssp_reply,  
  22.     get_profile_interface,  
  23.     dut_mode_configure,  
  24.     dut_mode_send,  
  25. #if BLE_INCLUDED == TRUE  
  26.     le_test_mode,  
  27. #else  
  28.     NULL,  
  29. #endif  
  30.     config_hci_snoop_log  
  31. };  
找到enable函数了,那就要看看他的实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int enable( void )  
  2. {  
  3.     ALOGI("enable");  
  4.   
  5.     /* sanity check */  
  6.     if (interface_ready() == FALSE)  
  7.         return BT_STATUS_NOT_READY;  
  8.   
  9.     return btif_enable_bluetooth();  
  10. }  
接下来就是按照函数实现一步一步走了,但是btif_enable_bluetooth()是有声明函数的,一定要注意,在btif_api.h,这里就不贴代码了。继续:

Btif_core.c (\external\bluetooth\bluedroid\btif\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. bt_status_t btif_enable_bluetooth(void)  
  2. {  
  3.     BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");  
  4.   
  5.   
  6.     if (btif_core_state != BTIF_CORE_STATE_DISABLED)  
  7.     {  
  8.         ALOGD("not disabled\n");  
  9.         return BT_STATUS_DONE;  
  10.     }  
  11.   
  12.   
  13.     btif_core_state = BTIF_CORE_STATE_ENABLING;  
  14.   
  15.   
  16.     /* Create the GKI tasks and run them */  
  17.     bte_main_enable();  
  18.   
  19.   
  20.     return BT_STATUS_SUCCESS;  
  21. }  
接下来我们要去找bte_main_enable函数的实现了:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void bte_main_enable()  
  2. {  
  3.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  4.   
  5.     /* Initialize BTE control block */  
  6.     BTE_Init();  
  7.   
  8.     lpm_enabled = FALSE;  
  9.   
  10.     bte_hci_enable();  
  11.   
  12.     GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,  
  13.                     (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),  
  14.                     sizeof(bte_btu_stack));  
  15.   
  16.     GKI_run(0);  
  17. }  
接下来是bte_hci_enable,当然有一些函数你可以看看,BTE_Init()和GKI-
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void bte_hci_enable(void)  
  2. {  
  3.     APPL_TRACE_DEBUG1("%s", __FUNCTION__);  
  4.   
  5.     preload_start_wait_timer();  
  6.   
  7.     if (bt_hc_if)  
  8.     {  
  9.         int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);  
  10.         APPL_TRACE_EVENT1("libbt-hci init returns %d", result);  
  11.   
  12.         assert(result == BT_HC_STATUS_SUCCESS);  
  13.   
  14.         if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)  
  15.             bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);  
  16.   
  17. #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)  
  18.         APPL_TRACE_DEBUG1("%s  Not Turninig Off the BT before Turninig ON", __FUNCTION__);  
  19.   
  20.         /* Do not power off the chip before powering on  if BT_CLEAN_TURN_ON_DISABLED flag 
  21.          is defined and set to TRUE to avoid below mentioned issue. 
  22.  
  23.          Wingray kernel driver maintains a combined  counter to keep track of 
  24.          BT-Wifi state. Invoking  set_power(BT_HC_CHIP_PWR_OFF) when the BT is already 
  25.          in OFF state causes this counter to be incorrectly decremented and results in undesired 
  26.          behavior of the chip. 
  27.  
  28.          This is only a workaround and when the issue is fixed in the kernel this work around 
  29.          should be removed. */  
  30. #else  
  31.         /* toggle chip power to ensure we will reset chip in case 
  32.            a previous stack shutdown wasn't completed gracefully */  
  33.         bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);  
  34. #endif  
  35.         bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);  
  36.   
  37.         bt_hc_if->preload(NULL);  
  38.     }  
  39. }  
这个地方就要特别小心了,因为你会发现这里不是现实
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static bt_hc_interface_t *bt_hc_if=NULL;  
具体的对照关系要去bt_hci_lib.h文件里去查bt_hc_interface_t结构体的内容,这里也不贴了。

通过函数对照你会找到Bt_hci_bdroid.c (\android4.4\external\bluetooth\bluedroid\hci\src),这里才是set_power的实现。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. const bt_hc_interface_t *bt_hc_get_interface(void)  
  2. {  
  3.     return &bluetoothHCLibInterface;  
  4. }  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static const bt_hc_interface_t bluetoothHCLibInterface = {  
  2.     sizeof(bt_hc_interface_t),  
  3.     init,  
  4.     set_power,  
  5.     lpm,  
  6.     preload,  
  7.     postload,  
  8.     transmit_buf,  
  9.     set_rxflow,  
  10.     logging,  
  11.     cleanup  
  12. };  
这时候就可以去找set_power的实现了:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** Chip power control */  
  2. static void set_power(bt_hc_chip_power_state_t state)  
  3. {  
  4.     int pwr_state;  
  5.   
  6.     BTHCDBG("set_power %d", state);  
  7.   
  8.     /* Calling vendor-specific part */  
  9.     pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;  
  10.   
  11.     if (bt_vnd_if)  
  12.         bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);  
  13.     else  
  14.         ALOGE("vendor lib is missing!");  
  15. }  
这时候又要进行函数对照了,extern bt_vendor_interface_t *bt_vnd_if; 但是一定要细心奥:
bt_vendor_interface_t的结构体是在Bt_vendor_lib.h (\external\bluetooth\bluedroid\hci\include) 大家可以自己去查一下,我这里也不贴了。

这个时候我们要去找op函数的实现在Bt_vendor_brcm.c (\android4.4\hardware\broadcom\libbt\src)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Entry point of DLib  
  2. const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {  
  3.     sizeof(bt_vendor_interface_t),  
  4.     init,  
  5.     op,  
  6.     cleanup  
  7. };  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int op(bt_vendor_opcode_t opcode, void *param)  
  2. {  
  3.     int retval = 0;  
  4.   
  5.     BTVNDDBG("op for %d", opcode);  
  6.   
  7.     switch(opcode)  
  8.     {  
  9.         case BT_VND_OP_POWER_CTRL:  
  10.             {  
  11.                 int *state = (int *) param;  
  12.                 if (*state == BT_VND_PWR_OFF)  
  13.                     upio_set_bluetooth_power(UPIO_BT_POWER_OFF);  
  14.                 else if (*state == BT_VND_PWR_ON)  
  15.                     upio_set_bluetooth_power(UPIO_BT_POWER_ON);  
  16.             }  
  17.             break;  
  18.   
  19.         case BT_VND_OP_FW_CFG:  
  20.             {  
  21.                 hw_config_start();  
  22.             }  
  23.             break;  
  24.   
  25.         case BT_VND_OP_SCO_CFG:  
  26.             {  
  27. #if (SCO_CFG_INCLUDED == TRUE)  
  28.                 hw_sco_config();  
  29. #else  
  30.                 retval = -1;  
  31. #endif  
  32.             }  
  33.             break;  
  34.   
  35.         case BT_VND_OP_USERIAL_OPEN:  
  36.             {  
  37.                 int (*fd_array)[] = (int (*)[]) param;  
  38.                 int fd, idx;  
  39.                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);  
  40.                 if (fd != -1)  
  41.                 {  
  42.                     for (idx=0; idx < CH_MAX; idx++)  
  43.                         (*fd_array)[idx] = fd;  
  44.   
  45.                     retval = 1;  
  46.                 }  
  47.                 /* retval contains numbers of open fd of HCI channels */  
  48.             }  
  49.             break;  
  50.   
  51.         case BT_VND_OP_USERIAL_CLOSE:  
  52.             {  
  53.                 userial_vendor_close();  
  54.             }  
  55.             break;  
  56.   
  57.         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:  
  58.             {  
  59.                 uint32_t *timeout_ms = (uint32_t *) param;  
  60.                 *timeout_ms = hw_lpm_get_idle_timeout();  
  61.             }  
  62.             break;  
  63.   
  64.         case BT_VND_OP_LPM_SET_MODE:  
  65.             {  
  66.                 uint8_t *mode = (uint8_t *) param;  
  67.                 retval = hw_lpm_enable(*mode);  
  68.             }  
  69.             break;  
  70.   
  71.         case BT_VND_OP_LPM_WAKE_SET_STATE:  
  72.             {  
  73.                 uint8_t *state = (uint8_t *) param;  
  74.                 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \  
  75.                                         TRUE : FALSE;  
  76.   
  77.                 hw_lpm_set_wake_state(wake_assert);  
  78.             }  
  79.             break;  
  80.   
  81.         case BT_VND_OP_EPILOG:  
  82.             {  
  83. #if (HW_END_WITH_HCI_RESET == FALSE)  
  84.                 if (bt_vendor_cbacks)  
  85.                 {  
  86.                     bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);  
  87.                 }  
  88. #else  
  89.                 hw_epilog_process();  
  90. #endif  
  91.             }  
  92.             break;  
  93.     }  
  94.   
  95.     return retval;  
  96. }  
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.   
刚才传递的参数是BT_VND_OP_POWER_CTRL

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. case BT_VND_OP_POWER_CTRL:  
  2.     {  
  3.         int *state = (int *) param;  
  4.         if (*state == BT_VND_PWR_OFF)  
  5.             upio_set_bluetooth_power(UPIO_BT_POWER_OFF);  
  6.         else if (*state == BT_VND_PWR_ON)  
  7.             upio_set_bluetooth_power(UPIO_BT_POWER_ON);  
  8.     }  
  9.     break;  
实际我们走的是upio_set_bluetooth_power(UPIO_BT_POWER_ON);所以:

接下来已经到Upio.c (android4.4\hardware\broadcom\libbt\src)

忽然发现,这个文件结构有点像android4.3以前的bluetooth.c,找到实现代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static int init_rfkill()  
  2. {  
  3.     char path[64];  
  4.     char buf[16];  
  5.     int fd, sz, id;  
  6.   
  7.     if (is_rfkill_disabled())  
  8.         return -1;  
  9.   
  10.     for (id = 0; ; id++)  
  11.     {  
  12.         snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);  
  13.         fd = open(path, O_RDONLY);  
  14.         if (fd < 0)  
  15.         {  
  16.             ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \  
  17.                  path, strerror(errno), errno);  
  18.             return -1;  
  19.         }  
  20.   
  21.         sz = read(fd, &buf, sizeof(buf));  
  22.         close(fd);  
  23.   
  24.         if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)  
  25.         {  
  26.             rfkill_id = id;  
  27.             break;  
  28.         }  
  29.     }  
  30.   
  31.     asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);  
  32.     return 0;  
  33. }  

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int upio_set_bluetooth_power(int on)  
  2. {  
  3.     int sz;  
  4.     int fd = -1;  
  5.     int ret = -1;  
  6.     char buffer = '0';  
  7.   
  8.     switch(on)  
  9.     {  
  10.         case UPIO_BT_POWER_OFF:  
  11.             buffer = '0';  
  12.             break;  
  13.   
  14.         case UPIO_BT_POWER_ON:  
  15.             buffer = '1';  
  16.             break;  
  17.     }  
  18.   
  19.     if (is_emulator_context())  
  20.     {  
  21.         /* if new value is same as current, return -1 */  
  22.         if (bt_emul_enable == on)  
  23.             return ret;  
  24.   
  25.         UPIODBG("set_bluetooth_power [emul] %d", on);  
  26.   
  27.         bt_emul_enable = on;  
  28.         return 0;  
  29.     }  
  30.   
  31.     /* check if we have rfkill interface */  
  32.     if (is_rfkill_disabled())  
  33.         return 0;  
  34.   
  35.     if (rfkill_id == -1)  
  36.     {  
  37.         if (init_rfkill())  
  38.             return ret;  
  39.     }  
  40.   
  41.     fd = open(rfkill_state_path, O_WRONLY);  
  42.   
  43.     if (fd < 0)  
  44.     {  
  45.         ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",  
  46.             rfkill_state_path, strerror(errno), errno);  
  47.         return ret;  
  48.     }  
  49.   
  50.     sz = write(fd, &buffer, 1);  
  51.   
  52.     if (sz < 0) {  
  53.         ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",  
  54.             rfkill_state_path, strerror(errno),errno);  
  55.     }  
  56.     else  
  57.         ret = 0;  
  58.   
  59.     if (fd >= 0)  
  60.         close(fd);  
  61.   
  62.     return ret;  
  63. }  

好的,我们终于找到rfkill的路径了,剩下的就是调用kernel bluetooth的sys设备符了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值