首先我们都知道蓝牙第一步是上电,但是android4.4蓝牙上电部分的代码实际已经和android4.3不一样了。
android4.3蓝牙os是走system/bluetooth,但是android4.4走的是hardware/libhardware和external/bluetooth/,具体请看下面:
Bluetooth.h(hardware/libhardware/include/hardware/)----这是结构体,主要是看enable函数。
- typedef struct {
- /** set to sizeof(bt_interface_t) */
- size_t size;
- /**
- * Opens the interface and provides the callback routines
- * to the implemenation of this interface.
- */
- int (*init)(bt_callbacks_t* callbacks );
- /** Enable Bluetooth. */
- int (*<span style="color:#ff0000;">enable</span>)(void);
- /** Disable Bluetooth. */
- int (*disable)(void);
- /** Closes the interface. */
- void (*cleanup)(void);
- /** Get all Bluetooth Adapter properties at init */
- int (*get_adapter_properties)(void);
- /** Get Bluetooth Adapter property of 'type' */
- int (*get_adapter_property)(bt_property_type_t type);
- /** Set Bluetooth Adapter property of 'type' */
- /* Based on the type, val shall be one of
- * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc
- */
- int (*set_adapter_property)(const bt_property_t *property);
- /** Get all Remote Device properties */
- int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);
- /** Get Remote Device property of 'type' */
- int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,
- bt_property_type_t type);
- /** Set Remote Device property of 'type' */
- int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,
- const bt_property_t *property);
- /** Get Remote Device's service record for the given UUID */
- int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,
- bt_uuid_t *uuid);
- /** Start SDP to get remote services */
- int (*get_remote_services)(bt_bdaddr_t *remote_addr);
- /** Start Discovery */
- int (*start_discovery)(void);
- /** Cancel Discovery */
- int (*cancel_discovery)(void);
- /** Create Bluetooth Bonding */
- int (*create_bond)(const bt_bdaddr_t *bd_addr);
- /** Remove Bond */
- int (*remove_bond)(const bt_bdaddr_t *bd_addr);
- /** Cancel Bond */
- int (*cancel_bond)(const bt_bdaddr_t *bd_addr);
- /** BT Legacy PinKey Reply */
- /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */
- int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,
- uint8_t pin_len, bt_pin_code_t *pin_code);
- /** BT SSP Reply - Just Works, Numeric Comparison and Passkey
- * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON &
- * BT_SSP_VARIANT_CONSENT
- * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey
- * shall be zero */
- int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
- uint8_t accept, uint32_t passkey);
- /** Get Bluetooth profile interface */
- const void* (*get_profile_interface) (const char *profile_id);
- /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */
- /* Configure DUT Mode - Use this mode to enter/exit DUT mode */
- int (*dut_mode_configure)(uint8_t enable);
- /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */
- int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);
- /** BLE Test Mode APIs */
- /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */
- int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);
- /* enable or disable bluetooth HCI snoop log */
- int (*config_hci_snoop_log)(uint8_t enable);
- } bt_interface_t;
Bluetooth.c (external\bluetooth\bluedroid\btif\src)
- const bt_interface_t* bluetooth__get_bluetooth_interface ()
- {
- /* fixme -- add property to disable bt interface ? */
- return &bluetoothInterface;
- }
- static const bt_interface_t bluetoothInterface = {
- sizeof(bluetoothInterface),
- init,
- enable,
- disable,
- cleanup,
- get_adapter_properties,
- get_adapter_property,
- set_adapter_property,
- get_remote_device_properties,
- get_remote_device_property,
- set_remote_device_property,
- get_remote_service_record,
- get_remote_services,
- start_discovery,
- cancel_discovery,
- create_bond,
- remove_bond,
- cancel_bond,
- pin_reply,
- ssp_reply,
- get_profile_interface,
- dut_mode_configure,
- dut_mode_send,
- #if BLE_INCLUDED == TRUE
- le_test_mode,
- #else
- NULL,
- #endif
- config_hci_snoop_log
- };
- static int enable( void )
- {
- ALOGI("enable");
- /* sanity check */
- if (interface_ready() == FALSE)
- return BT_STATUS_NOT_READY;
- return btif_enable_bluetooth();
- }
Btif_core.c (\external\bluetooth\bluedroid\btif\src)
- bt_status_t btif_enable_bluetooth(void)
- {
- BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");
- if (btif_core_state != BTIF_CORE_STATE_DISABLED)
- {
- ALOGD("not disabled\n");
- return BT_STATUS_DONE;
- }
- btif_core_state = BTIF_CORE_STATE_ENABLING;
- /* Create the GKI tasks and run them */
- bte_main_enable();
- return BT_STATUS_SUCCESS;
- }
- void bte_main_enable()
- {
- APPL_TRACE_DEBUG1("%s", __FUNCTION__);
- /* Initialize BTE control block */
- BTE_Init();
- lpm_enabled = FALSE;
- bte_hci_enable();
- GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
- (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
- sizeof(bte_btu_stack));
- GKI_run(0);
- }
- static void bte_hci_enable(void)
- {
- APPL_TRACE_DEBUG1("%s", __FUNCTION__);
- preload_start_wait_timer();
- if (bt_hc_if)
- {
- int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
- APPL_TRACE_EVENT1("libbt-hci init returns %d", result);
- assert(result == BT_HC_STATUS_SUCCESS);
- if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)
- bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);
- #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
- APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__);
- /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag
- is defined and set to TRUE to avoid below mentioned issue.
- Wingray kernel driver maintains a combined counter to keep track of
- BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
- in OFF state causes this counter to be incorrectly decremented and results in undesired
- behavior of the chip.
- This is only a workaround and when the issue is fixed in the kernel this work around
- should be removed. */
- #else
- /* toggle chip power to ensure we will reset chip in case
- a previous stack shutdown wasn't completed gracefully */
- bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
- #endif
- bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
- bt_hc_if->preload(NULL);
- }
- }
- static bt_hc_interface_t *bt_hc_if=NULL;
通过函数对照你会找到Bt_hci_bdroid.c (\android4.4\external\bluetooth\bluedroid\hci\src),这里才是set_power的实现。
- const bt_hc_interface_t *bt_hc_get_interface(void)
- {
- return &bluetoothHCLibInterface;
- }
- static const bt_hc_interface_t bluetoothHCLibInterface = {
- sizeof(bt_hc_interface_t),
- init,
- set_power,
- lpm,
- preload,
- postload,
- transmit_buf,
- set_rxflow,
- logging,
- cleanup
- };
- /** Chip power control */
- static void set_power(bt_hc_chip_power_state_t state)
- {
- int pwr_state;
- BTHCDBG("set_power %d", state);
- /* Calling vendor-specific part */
- pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;
- if (bt_vnd_if)
- bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);
- else
- ALOGE("vendor lib is missing!");
- }
bt_vendor_interface_t的结构体是在Bt_vendor_lib.h (\external\bluetooth\bluedroid\hci\include) 大家可以自己去查一下,我这里也不贴了。
这个时候我们要去找op函数的实现在Bt_vendor_brcm.c (\android4.4\hardware\broadcom\libbt\src)
- // Entry point of DLib
- const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
- sizeof(bt_vendor_interface_t),
- init,
- op,
- cleanup
- };
- static int op(bt_vendor_opcode_t opcode, void *param)
- {
- int retval = 0;
- BTVNDDBG("op for %d", opcode);
- switch(opcode)
- {
- 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;
- case BT_VND_OP_FW_CFG:
- {
- hw_config_start();
- }
- break;
- case BT_VND_OP_SCO_CFG:
- {
- #if (SCO_CFG_INCLUDED == TRUE)
- hw_sco_config();
- #else
- retval = -1;
- #endif
- }
- break;
- case BT_VND_OP_USERIAL_OPEN:
- {
- int (*fd_array)[] = (int (*)[]) param;
- int fd, idx;
- fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
- if (fd != -1)
- {
- for (idx=0; idx < CH_MAX; idx++)
- (*fd_array)[idx] = fd;
- retval = 1;
- }
- /* retval contains numbers of open fd of HCI channels */
- }
- break;
- case BT_VND_OP_USERIAL_CLOSE:
- {
- userial_vendor_close();
- }
- break;
- case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
- {
- uint32_t *timeout_ms = (uint32_t *) param;
- *timeout_ms = hw_lpm_get_idle_timeout();
- }
- break;
- case BT_VND_OP_LPM_SET_MODE:
- {
- uint8_t *mode = (uint8_t *) param;
- retval = hw_lpm_enable(*mode);
- }
- break;
- case BT_VND_OP_LPM_WAKE_SET_STATE:
- {
- uint8_t *state = (uint8_t *) param;
- uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
- TRUE : FALSE;
- hw_lpm_set_wake_state(wake_assert);
- }
- break;
- case BT_VND_OP_EPILOG:
- {
- #if (HW_END_WITH_HCI_RESET == FALSE)
- if (bt_vendor_cbacks)
- {
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
- }
- #else
- hw_epilog_process();
- #endif
- }
- break;
- }
- return retval;
- }
- 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;
接下来已经到Upio.c (android4.4\hardware\broadcom\libbt\src)
忽然发现,这个文件结构有点像android4.3以前的bluetooth.c,找到实现代码:
- static int init_rfkill()
- {
- char path[64];
- char buf[16];
- int fd, sz, id;
- if (is_rfkill_disabled())
- return -1;
- for (id = 0; ; id++)
- {
- snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- {
- ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \
- path, strerror(errno), errno);
- return -1;
- }
- sz = read(fd, &buf, sizeof(buf));
- close(fd);
- if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)
- {
- rfkill_id = id;
- break;
- }
- }
- asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
- return 0;
- }
- int upio_set_bluetooth_power(int on)
- {
- int sz;
- int fd = -1;
- int ret = -1;
- char buffer = '0';
- switch(on)
- {
- case UPIO_BT_POWER_OFF:
- buffer = '0';
- break;
- case UPIO_BT_POWER_ON:
- buffer = '1';
- break;
- }
- if (is_emulator_context())
- {
- /* if new value is same as current, return -1 */
- if (bt_emul_enable == on)
- return ret;
- UPIODBG("set_bluetooth_power [emul] %d", on);
- bt_emul_enable = on;
- return 0;
- }
- /* check if we have rfkill interface */
- if (is_rfkill_disabled())
- return 0;
- if (rfkill_id == -1)
- {
- if (init_rfkill())
- return ret;
- }
- fd = open(rfkill_state_path, O_WRONLY);
- if (fd < 0)
- {
- ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",
- rfkill_state_path, strerror(errno), errno);
- return ret;
- }
- sz = write(fd, &buffer, 1);
- if (sz < 0) {
- ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",
- rfkill_state_path, strerror(errno),errno);
- }
- else
- ret = 0;
- if (fd >= 0)
- close(fd);
- return ret;
- }
好的,我们终于找到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函数。
- typedef struct {
- /** set to sizeof(bt_interface_t) */
- size_t size;
- /**
- * Opens the interface and provides the callback routines
- * to the implemenation of this interface.
- */
- int (*init)(bt_callbacks_t* callbacks );
- /** Enable Bluetooth. */
- int (*<span style="color:#ff0000;">enable</span>)(void);
- /** Disable Bluetooth. */
- int (*disable)(void);
- /** Closes the interface. */
- void (*cleanup)(void);
- /** Get all Bluetooth Adapter properties at init */
- int (*get_adapter_properties)(void);
- /** Get Bluetooth Adapter property of 'type' */
- int (*get_adapter_property)(bt_property_type_t type);
- /** Set Bluetooth Adapter property of 'type' */
- /* Based on the type, val shall be one of
- * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc
- */
- int (*set_adapter_property)(const bt_property_t *property);
- /** Get all Remote Device properties */
- int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);
- /** Get Remote Device property of 'type' */
- int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,
- bt_property_type_t type);
- /** Set Remote Device property of 'type' */
- int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,
- const bt_property_t *property);
- /** Get Remote Device's service record for the given UUID */
- int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,
- bt_uuid_t *uuid);
- /** Start SDP to get remote services */
- int (*get_remote_services)(bt_bdaddr_t *remote_addr);
- /** Start Discovery */
- int (*start_discovery)(void);
- /** Cancel Discovery */
- int (*cancel_discovery)(void);
- /** Create Bluetooth Bonding */
- int (*create_bond)(const bt_bdaddr_t *bd_addr);
- /** Remove Bond */
- int (*remove_bond)(const bt_bdaddr_t *bd_addr);
- /** Cancel Bond */
- int (*cancel_bond)(const bt_bdaddr_t *bd_addr);
- /** BT Legacy PinKey Reply */
- /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */
- int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,
- uint8_t pin_len, bt_pin_code_t *pin_code);
- /** BT SSP Reply - Just Works, Numeric Comparison and Passkey
- * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON &
- * BT_SSP_VARIANT_CONSENT
- * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey
- * shall be zero */
- int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
- uint8_t accept, uint32_t passkey);
- /** Get Bluetooth profile interface */
- const void* (*get_profile_interface) (const char *profile_id);
- /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */
- /* Configure DUT Mode - Use this mode to enter/exit DUT mode */
- int (*dut_mode_configure)(uint8_t enable);
- /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */
- int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);
- /** BLE Test Mode APIs */
- /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */
- int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);
- /* enable or disable bluetooth HCI snoop log */
- int (*config_hci_snoop_log)(uint8_t enable);
- } bt_interface_t;
Bluetooth.c (external\bluetooth\bluedroid\btif\src)
- const bt_interface_t* bluetooth__get_bluetooth_interface ()
- {
- /* fixme -- add property to disable bt interface ? */
- return &bluetoothInterface;
- }
- static const bt_interface_t bluetoothInterface = {
- sizeof(bluetoothInterface),
- init,
- enable,
- disable,
- cleanup,
- get_adapter_properties,
- get_adapter_property,
- set_adapter_property,
- get_remote_device_properties,
- get_remote_device_property,
- set_remote_device_property,
- get_remote_service_record,
- get_remote_services,
- start_discovery,
- cancel_discovery,
- create_bond,
- remove_bond,
- cancel_bond,
- pin_reply,
- ssp_reply,
- get_profile_interface,
- dut_mode_configure,
- dut_mode_send,
- #if BLE_INCLUDED == TRUE
- le_test_mode,
- #else
- NULL,
- #endif
- config_hci_snoop_log
- };
- static int enable( void )
- {
- ALOGI("enable");
- /* sanity check */
- if (interface_ready() == FALSE)
- return BT_STATUS_NOT_READY;
- return btif_enable_bluetooth();
- }
Btif_core.c (\external\bluetooth\bluedroid\btif\src)
- bt_status_t btif_enable_bluetooth(void)
- {
- BTIF_TRACE_DEBUG0("BTIF ENABLE BLUETOOTH");
- if (btif_core_state != BTIF_CORE_STATE_DISABLED)
- {
- ALOGD("not disabled\n");
- return BT_STATUS_DONE;
- }
- btif_core_state = BTIF_CORE_STATE_ENABLING;
- /* Create the GKI tasks and run them */
- bte_main_enable();
- return BT_STATUS_SUCCESS;
- }
- void bte_main_enable()
- {
- APPL_TRACE_DEBUG1("%s", __FUNCTION__);
- /* Initialize BTE control block */
- BTE_Init();
- lpm_enabled = FALSE;
- bte_hci_enable();
- GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
- (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
- sizeof(bte_btu_stack));
- GKI_run(0);
- }
- static void bte_hci_enable(void)
- {
- APPL_TRACE_DEBUG1("%s", __FUNCTION__);
- preload_start_wait_timer();
- if (bt_hc_if)
- {
- int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
- APPL_TRACE_EVENT1("libbt-hci init returns %d", result);
- assert(result == BT_HC_STATUS_SUCCESS);
- if (hci_logging_enabled == TRUE || hci_logging_config == TRUE)
- bt_hc_if->logging(BT_HC_LOGGING_ON, hci_logfile);
- #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE)
- APPL_TRACE_DEBUG1("%s Not Turninig Off the BT before Turninig ON", __FUNCTION__);
- /* Do not power off the chip before powering on if BT_CLEAN_TURN_ON_DISABLED flag
- is defined and set to TRUE to avoid below mentioned issue.
- Wingray kernel driver maintains a combined counter to keep track of
- BT-Wifi state. Invoking set_power(BT_HC_CHIP_PWR_OFF) when the BT is already
- in OFF state causes this counter to be incorrectly decremented and results in undesired
- behavior of the chip.
- This is only a workaround and when the issue is fixed in the kernel this work around
- should be removed. */
- #else
- /* toggle chip power to ensure we will reset chip in case
- a previous stack shutdown wasn't completed gracefully */
- bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
- #endif
- bt_hc_if->set_power(BT_HC_CHIP_PWR_ON);
- bt_hc_if->preload(NULL);
- }
- }
- static bt_hc_interface_t *bt_hc_if=NULL;
通过函数对照你会找到Bt_hci_bdroid.c (\android4.4\external\bluetooth\bluedroid\hci\src),这里才是set_power的实现。
- const bt_hc_interface_t *bt_hc_get_interface(void)
- {
- return &bluetoothHCLibInterface;
- }
- static const bt_hc_interface_t bluetoothHCLibInterface = {
- sizeof(bt_hc_interface_t),
- init,
- set_power,
- lpm,
- preload,
- postload,
- transmit_buf,
- set_rxflow,
- logging,
- cleanup
- };
- /** Chip power control */
- static void set_power(bt_hc_chip_power_state_t state)
- {
- int pwr_state;
- BTHCDBG("set_power %d", state);
- /* Calling vendor-specific part */
- pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF;
- if (bt_vnd_if)
- bt_vnd_if->op(BT_VND_OP_POWER_CTRL, &pwr_state);
- else
- ALOGE("vendor lib is missing!");
- }
bt_vendor_interface_t的结构体是在Bt_vendor_lib.h (\external\bluetooth\bluedroid\hci\include) 大家可以自己去查一下,我这里也不贴了。
这个时候我们要去找op函数的实现在Bt_vendor_brcm.c (\android4.4\hardware\broadcom\libbt\src)
- // Entry point of DLib
- const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
- sizeof(bt_vendor_interface_t),
- init,
- op,
- cleanup
- };
- static int op(bt_vendor_opcode_t opcode, void *param)
- {
- int retval = 0;
- BTVNDDBG("op for %d", opcode);
- switch(opcode)
- {
- 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;
- case BT_VND_OP_FW_CFG:
- {
- hw_config_start();
- }
- break;
- case BT_VND_OP_SCO_CFG:
- {
- #if (SCO_CFG_INCLUDED == TRUE)
- hw_sco_config();
- #else
- retval = -1;
- #endif
- }
- break;
- case BT_VND_OP_USERIAL_OPEN:
- {
- int (*fd_array)[] = (int (*)[]) param;
- int fd, idx;
- fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
- if (fd != -1)
- {
- for (idx=0; idx < CH_MAX; idx++)
- (*fd_array)[idx] = fd;
- retval = 1;
- }
- /* retval contains numbers of open fd of HCI channels */
- }
- break;
- case BT_VND_OP_USERIAL_CLOSE:
- {
- userial_vendor_close();
- }
- break;
- case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
- {
- uint32_t *timeout_ms = (uint32_t *) param;
- *timeout_ms = hw_lpm_get_idle_timeout();
- }
- break;
- case BT_VND_OP_LPM_SET_MODE:
- {
- uint8_t *mode = (uint8_t *) param;
- retval = hw_lpm_enable(*mode);
- }
- break;
- case BT_VND_OP_LPM_WAKE_SET_STATE:
- {
- uint8_t *state = (uint8_t *) param;
- uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
- TRUE : FALSE;
- hw_lpm_set_wake_state(wake_assert);
- }
- break;
- case BT_VND_OP_EPILOG:
- {
- #if (HW_END_WITH_HCI_RESET == FALSE)
- if (bt_vendor_cbacks)
- {
- bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
- }
- #else
- hw_epilog_process();
- #endif
- }
- break;
- }
- return retval;
- }
- 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;
接下来已经到Upio.c (android4.4\hardware\broadcom\libbt\src)
忽然发现,这个文件结构有点像android4.3以前的bluetooth.c,找到实现代码:
- static int init_rfkill()
- {
- char path[64];
- char buf[16];
- int fd, sz, id;
- if (is_rfkill_disabled())
- return -1;
- for (id = 0; ; id++)
- {
- snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- {
- ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \
- path, strerror(errno), errno);
- return -1;
- }
- sz = read(fd, &buf, sizeof(buf));
- close(fd);
- if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)
- {
- rfkill_id = id;
- break;
- }
- }
- asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
- return 0;
- }
- int upio_set_bluetooth_power(int on)
- {
- int sz;
- int fd = -1;
- int ret = -1;
- char buffer = '0';
- switch(on)
- {
- case UPIO_BT_POWER_OFF:
- buffer = '0';
- break;
- case UPIO_BT_POWER_ON:
- buffer = '1';
- break;
- }
- if (is_emulator_context())
- {
- /* if new value is same as current, return -1 */
- if (bt_emul_enable == on)
- return ret;
- UPIODBG("set_bluetooth_power [emul] %d", on);
- bt_emul_enable = on;
- return 0;
- }
- /* check if we have rfkill interface */
- if (is_rfkill_disabled())
- return 0;
- if (rfkill_id == -1)
- {
- if (init_rfkill())
- return ret;
- }
- fd = open(rfkill_state_path, O_WRONLY);
- if (fd < 0)
- {
- ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",
- rfkill_state_path, strerror(errno), errno);
- return ret;
- }
- sz = write(fd, &buffer, 1);
- if (sz < 0) {
- ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",
- rfkill_state_path, strerror(errno),errno);
- }
- else
- ret = 0;
- if (fd >= 0)
- close(fd);
- return ret;
- }
好的,我们终于找到rfkill的路径了,剩下的就是调用kernel bluetooth的sys设备符了。