https://www.bluetooth.com/
藍牙協議包含BR/EDR、AMP、LE三種技術,比較熱門的BLE(Bluetooth Low Energy)
http://www.wowotech.net/bluetooth/ble_stack_overview.html
device\brand\common\connectivity\product_package\product_package.mk
cfg_folder := vendor/brand/proprietary/hardware/connectivity/combo_tool/cfg_folder
patch_folder := vendor/brand/proprietary/hardware/connectivity/combo_tool/patch_folder
init_folder := device/brand/common/connectivity/init
bondStateChangeCallback(int status, byte[] address, int newState) {
bondStateChangeCallback: Status: 9 Address: D2:60:6C:XX:XX:XX newState: 0
BluetoothDevice.BOND_NONE 0
Status BT_STATUS_AUTH_FAILURE 9
UNBOND_REASON_AUTH_FAILED 1
/**
* A bond attempt failed because pins did not match, or remote device did
* not respond to pin request in time
* @hide
*/
public static final int UNBOND_REASON_AUTH_FAILED = 1;
之後需要在btu初始化的時候,把這個隊列和相關的線程關聯起來,這樣發送完消息後,就可以通知相關的線程去隊列裏面取消息並進行處理
在文件bt/stack/btu/btu_task.c,
void btu_task_start_up(UNUSED_ATTR void *context) {
..................
fixed_queue_register_dequeue(btu_hci_msg_queue, //接收隊列
thread_get_reactor(bt_workqueue_thread),
btu_hci_msg_ready,//接收函數
NULL);
}
發送消息的方式如下:
在文件bt/stack/btu/btu_hcif.c或btu_init.c中,
fixed_queue_enqueue(btu_hci_msg_queue, event);
發送到隊列後,開始使用如下的方法進行處理:
btu_hci_msg_ready
btm_ble_process_adv_pkt_cont
btu_hcif_connection_comp_evt
system\bt\stack\btm\btm_sec.c
btm_sec_connected
btm_sec_dev_rec_cback_event
btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT, FALSE);
bond_state_changed
system\bt\btif\src\btif_core.c
bt_jni_msg_ready
BTIF_CORE_STORAGE_READ_ALL
btif_transfer_context event 8, len 280
static void btif_context_switched(void *p_msg)
{
BTIF_TRACE_VERBOSE("btif_context_switched");
tBTIF_CONTEXT_SWITCH_CBACK *p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
/* each callback knows how to parse the data */
if (p->p_cb)
p->p_cb(p->event, p->p_param);
}
system\bt\btif\src\btif_dm.c
btif_dm_upstreams_evt
CASE_RETURN_STR(BTA_DM_AUTH_CMPL_EVT)
#define BTA_DM_AUTH_CMPL_EVT 3 /* Authentication complete indication. */
btif_dm_upstreams_cback ev: BTA_DM_AUTH_CMPL_EVT
case BTA_DM_AUTH_CMPL_EVT:
btif_dm_auth_cmpl_evt(&p_data->auth_cmpl);
btif_dm_auth_cmpl_evt
BTIF_TRACE_DEBUG(" %s() Authentication fail reason %d",
__FUNCTION__, p_auth_cmpl->fail_reason);
HCI_ERR_PEER_USER
btif_dm_auth_cmpl_evt() Authentication fail reason 19
從底層上報的配對狀態:
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\RemoteDevices.java
aclStateChangeCallback
frameworks\base\core\java\android\bluetooth\BluetoothDevice.java
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\BondStateMachine.java
static final int CREATE_BOND = 1;
static final int CANCEL_BOND = 2;
static final int REMOVE_BOND = 3;
static final int BONDING_STATE_CHANGE = 4;
static final int SSP_REQUEST = 5;
static final int PIN_REQUEST = 6;
static final int BOND_STATE_NONE = 0;
static final int BOND_STATE_BONDING = 1;
static final int BOND_STATE_BONDED = 2;
PendingCommandState
processMessage //BONDING_STATE_CHANGE
bondStateChangeCallback
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\JniCallbacks.java
bondStateChangeCallback
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
static bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
adapter_state_change_callback,
adapter_properties_callback,
remote_device_properties_callback,
device_found_callback,
discovery_state_changed_callback,
pin_request_callback,
ssp_request_callback,
bond_state_changed_callback,
acl_state_changed_callback,
callback_thread_event,
dut_mode_recv_callback,
le_test_mode_recv_callback,
energy_info_recv_callback
};
bond_state_changed_callback
method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
"bondStateChangeCallback", "(I[BI)V");
硬件抽象層:Hardware HAL層
hw_get_module(BT_STACK_MODULE_ID, (hw_module_t const**)&module);
bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
bt_interface_t* sBluetoothInterface = btStack->get_bluetooth_interface();
hardware/libhardware/include/hardware/bluetooth.h:34:#define BT_STACK_MODULE_ID "bluetooth"
hardware/libhardware/include/hardware/bluetooth.h:33:#define BT_HARDWARE_MODULE_ID "bluetooth"
system\bt\main\Android.mk
LOCAL_MODULE := bluetooth.default
system\bt\btif\src\bluetooth.c
EXPORT_SYMBOL struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = BT_HARDWARE_MODULE_ID,
.name = "Bluetooth Stack",
.author = "The Android Open Source Project",
.methods = &bt_stack_module_methods
};
system/bt/btif/src/btif_core.c:505: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
system/bt/btif/src/btif_core.c:750: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb,
system/bt/btif/src/btif_core.c:796: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_core.c:829: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, p_prop);
system/bt/btif/src/btif_core.c:873: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop);
system/bt/btif/src/btif_core.c:883: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 0, NULL);
system/bt/btif/src/btif_core.c:911: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_core.c:931: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb,
system/bt/btif/src/btif_core.c:938: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_core.c:1326: HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);
system/bt/btif/src/btif_core.c:1331: HAL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM);
system/bt/btif/src/btif_core.c:1332: bt_hal_cbacks = NULL;
system/bt/btif/src/bluetooth.c:76:bt_callbacks_t *bt_hal_cbacks = NULL;
system/bt/btif/src/bluetooth.c:118: return bt_hal_cbacks != NULL;
system/bt/btif/src/bluetooth.c:143: bt_hal_cbacks = callbacks;
system/bt/btif/src/btif_dm.c:560: HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
system/bt/btif/src/btif_dm.c:571: HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
system/bt/btif/src/btif_dm.c:688: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:994: HAL_CBACK(bt_hal_cbacks, pin_request_cb,
system/bt/btif/src/btif_dm.c:1075: HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name, cod,
system/bt/btif/src/btif_dm.c:1109: HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name,
system/bt/btif/src/btif_dm.c:1221: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:1353: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:1462: HAL_CBACK(bt_hal_cbacks, device_found_cb,
system/bt/btif/src/btif_dm.c:1480: HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STOPPED);
system/bt/btif/src/btif_dm.c:1501: HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STOPPED);
system/bt/btif/src/btif_dm.c:1582: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:1646: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:1699: HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
system/bt/btif/src/btif_dm.c:1842: HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb,
system/bt/btif/src/btif_dm.c:1848: HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb,
system/bt/btif/src/btif_dm.c:1865: HAL_CBACK(bt_hal_cbacks, acl_state_changed_cb, BT_STATUS_SUCCESS,
system/bt/btif/src/btif_dm.c:1873: HAL_CBACK(bt_hal_cbacks, acl_state_changed_cb, BT_STATUS_SUCCESS,
system/bt/btif/src/btif_dm.c:2032: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
system/bt/btif/src/btif_dm.c:2048: HAL_CBACK(bt_hal_cbacks, energy_info_cb, &energy_info, data);
system/bt/btif/src/btif_dm.c:2084: HAL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STARTED);
system/bt/btif/src/btif_dm.c:2118: HAL_CBACK(bt_hal_cbacks, le_test_mode_cb,
system/bt/btif/src/btif_dm.c:2129: HAL_CBACK(bt_hal_cbacks, le_test_mode_cb,
system/bt/btif/src/btif_dm.c:2783: HAL_CBACK(bt_hal_cbacks, adapter_properties_cb,
system/bt/btif/src/btif_dm.c:3080: HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name,
system/bt/btif/src/btif_dm.c:3321: HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name, cod,
system/bt/btif/src/btif_dm.c:3357: HAL_CBACK(bt_hal_cbacks, pin_request_cb,
system/bt/btif/src/btif_dm.c:3380: HAL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name,
system/bt/btif/src/stack_manager.c:220: HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
system/bt/btif/src/stack_manager.c:224: HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
system/bt/btif/src/btif_dm.c
bond_state_changed
HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
打印log:
system\bt\main\bte_logmsg.c
load_levels_from_config //解析配置文件bt_stack.conf
system\bt\main\stack_config.c
/etc/bluetooth/bt_stack.conf //加載配置文件bt_stack.conf
system\bt\conf\bt_stack.conf
# Trace level configuration
# BT_TRACE_LEVEL_NONE 0 ( No trace messages to be generated )
# BT_TRACE_LEVEL_ERROR 1 ( Error condition trace messages )
# BT_TRACE_LEVEL_WARNING 2 ( Warning condition trace messages )
# BT_TRACE_LEVEL_API 3 ( API traces )
# BT_TRACE_LEVEL_EVENT 4 ( Debug messages for events )
# BT_TRACE_LEVEL_DEBUG 5 ( Full debug messages )
# BT_TRACE_LEVEL_VERBOSE 6 ( Verbose messages ) - Currently supported for TRC_BTAPP only.
TRC_BTIF=2
thermal_repeater
private void onPair(String value) {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN://需要密碼
// 注意這裏是用了轉換的方法,不是直接調用value.getBytes();方法
byte[] pinBytes = BluetoothDevice.convertPinToBytes(value);
if (pinBytes == null) {
return;
}
Log.i("kangwz", "PAIRING_VARIANT_PIN"+pinBytes);
// 直接調用setPin方法,然後就沒有了,等到收到狀態改變的廣播後就進行dismiss,請看54行的mReceiver
mDevice.setPin(pinBytes);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
int passkey = Integer.parseInt(value);
Log.i("kangwz", "PAIRING_VARIANT_PASSKEY"+passkey);//密碼
mDevice.setPasskey(passkey);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT://確認按鈕
Log.i("kangwz", "PAIRING_VARIANT_CONSENT");
mDevice.setPairingConfirmation(true);
break;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
// Do nothing.
break;
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
mDevice.setRemoteOutOfBandData();
break;
default:
Log.e(TAG, "Incorrect pairing type received");
}
}
01-01 00:11:43.505 1534 1534 I kangwz : BUTTON_POSITIVE
01-01 00:11:43.505 1534 1534 I kangwz : PAIRING_VARIANT_CONSENT
cachedDevice.connect(true)//配對
mDevice.setPairingConfirmation(true);//彈窗允許配對
sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION,accept, 0);
/* Security Callback Events */
#define BTA_DM_ENABLE_EVT 0 /* Enable Event */
#define BTA_DM_DISABLE_EVT 1 /* Disable Event */
#define BTA_DM_PIN_REQ_EVT 2 /* PIN request. */
#define BTA_DM_AUTH_CMPL_EVT 3 /* Authentication complete indication. */
#define BTA_DM_AUTHORIZE_EVT 4 /* Authorization request. */
#define BTA_DM_LINK_UP_EVT 5 /* Connection UP event */
#define BTA_DM_LINK_DOWN_EVT 6 /* Connection DOWN event */
#define BTA_DM_SIG_STRENGTH_EVT 7 /* Signal strength for bluetooth connection */
#define BTA_DM_BUSY_LEVEL_EVT 8 /* System busy level */
#define BTA_DM_BOND_CANCEL_CMPL_EVT 9 /* Bond cancel complete indication */
#define BTA_DM_SP_CFM_REQ_EVT 10 /* Simple Pairing User Confirmation request. */
#define BTA_DM_SP_KEY_NOTIF_EVT 11 /* Simple Pairing Passkey Notification */
#define BTA_DM_SP_RMT_OOB_EVT 12 /* Simple Pairing Remote OOB Data request. */
#define BTA_DM_SP_KEYPRESS_EVT 13 /* Key press notification event. */
#define BTA_DM_ROLE_CHG_EVT 14 /* Role Change event. */
#define BTA_DM_BLE_KEY_EVT 15 /* BLE SMP key event for peer device keys */
#define BTA_DM_BLE_SEC_REQ_EVT 16 /* BLE SMP security request */
#define BTA_DM_BLE_PASSKEY_NOTIF_EVT 17 /* SMP passkey notification event */
#define BTA_DM_BLE_PASSKEY_REQ_EVT 18 /* SMP passkey request event */
#define BTA_DM_BLE_OOB_REQ_EVT 19 /* SMP OOB request event */
#define BTA_DM_BLE_LOCAL_IR_EVT 20 /* BLE local IR event */
#define BTA_DM_BLE_LOCAL_ER_EVT 21 /* BLE local ER event */
#define BTA_DM_BLE_NC_REQ_EVT 22 /* SMP Numeric Comparison request event */
#define BTA_DM_SP_RMT_OOB_EXT_EVT 23 /* Simple Pairing Remote OOB Extended Data request. */
#define BTA_DM_BLE_AUTH_CMPL_EVT 24 /* BLE Auth complete */
#define BTA_DM_DEV_UNPAIRED_EVT 25
#define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */
#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */
#define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
/* Pairing State */
enum
{
BTM_PAIR_STATE_IDLE, /* Idle */
BTM_PAIR_STATE_GET_REM_NAME, /* Getting the remote name (to check for SM4) */
BTM_PAIR_STATE_WAIT_PIN_REQ, /* Started authentication, waiting for PIN req (PIN is pre-fetched) */
BTM_PAIR_STATE_WAIT_LOCAL_PIN, /* Waiting for local PIN code */
BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM, /* Waiting user 'yes' to numeric confirmation */
BTM_PAIR_STATE_KEY_ENTRY, /* Key entry state (we are a keyboard) */
BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP, /* Waiting for local response to peer OOB data */
BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS, /* Waiting for local IO capabilities and OOB data */
BTM_PAIR_STATE_INCOMING_SSP, /* Incoming SSP (got peer IO caps when idle) */
BTM_PAIR_STATE_WAIT_AUTH_COMPLETE, /* All done, waiting authentication cpmplete */
BTM_PAIR_STATE_WAIT_DISCONNECT /* Waiting to disconnect the ACL */
};
/*******************************************************************************
**
** Function btm_pair_state_descr
**
** Description Return state description for tracing
**
*******************************************************************************/
#if (BT_USE_TRACES == TRUE)
static char *btm_pair_state_descr (tBTM_PAIRING_STATE state)
{
#if (BT_TRACE_VERBOSE == TRUE)
switch (state)
{
case BTM_PAIR_STATE_IDLE: return("IDLE");
case BTM_PAIR_STATE_GET_REM_NAME: return("GET_REM_NAME");
case BTM_PAIR_STATE_WAIT_PIN_REQ: return("WAIT_PIN_REQ");
case BTM_PAIR_STATE_WAIT_LOCAL_PIN: return("WAIT_LOCAL_PIN");
case BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM: return("WAIT_NUM_CONFIRM");
case BTM_PAIR_STATE_KEY_ENTRY: return("KEY_ENTRY");
case BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP: return("WAIT_LOCAL_OOB_RSP");
case BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS: return("WAIT_LOCAL_IOCAPS");
case BTM_PAIR_STATE_INCOMING_SSP: return("INCOMING_SSP");
case BTM_PAIR_STATE_WAIT_AUTH_COMPLETE: return("WAIT_AUTH_COMPLETE");
case BTM_PAIR_STATE_WAIT_DISCONNECT: return("WAIT_DISCONNECT");
}
return("???");
#else
sprintf(btm_cb.state_temp_buffer,"%hhu",state);
return(btm_cb.state_temp_buffer);
#endif
}
btif_dm_generic_evt//開始配對的callback
btif_dm_cb_create_bond
bond_state_changed
HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);//BluetoothBondStateMachine: bondStateChangeCallback
BTA_DmBondByTransport
fixed_queue_enqueue(btu_bta_msg_queue, p_msg);//入列btu_bta_msg_queue
btu_bta_msg_ready
fixed_queue_dequeue(queue);//出列btu_bta_msg_queue
bta_sys_event(p_msg);
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);//bta_sys_register(BTA_ID_DM, &bta_dm_reg );
//evt_hdlr=bta_dm_sm_execute,disable=bta_dm_sm_disable
bta_dm_sm_execute
bta_dm_bond
BTM_SecBondByTransport
btm_sec_bond_by_transport
/* local is 2.1 and peer is unknown */
if ((p_dev_rec->sm4 & BTM_SM4_CONN_PEND) == 0)
{
/* we are not accepting connection request from peer
* -> RNR (to learn if peer is 2.1)
* RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);//Pairing State:0->1
BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR);
}
01-01 00:35:01.603 1484 1664 I bt_btu_task: btu_hci_msg_ready
01-01 00:35:01.603 1484 1664 I bt_btu_task: btu_hci_msg_process BT_EVT_TO_BTU_HCI_EVT
01-01 00:35:01.603 1484 1664 I bt_hci : btu_hcif_process_event) hci_evt_code=18
01-01 00:35:01.603 1484 1664 D bt_btm : btm_acl_role_changed
01-01 00:35:01.603 1484 1664 D bt_btm : btm_acl_report_role_change
01-01 00:34:46.025 1484 1664 D bt_btm : Random address, treating device as LE only
01-01 00:34:45.197 1484 1664 W bt_btm_ble: btm_ble_process_adv_pkt_cont device is no longer discoverable so discarding advertising packet pkt
01-01 00:34:46.546 1484 1664 D bt_btm : BR/EDR NOT SUPPORT bit set, LE only device
01-01 00:34:46.546 1484 1664 D bt_btm : btm_ble_process_adv_pkt:bda= 43:8c:8:f8:6e:e1
01-01 00:34:46.549 1484 1645 D bt_btif : in, bd addr:43:8c:08:f8:6e:e1, prop type:5, len:4
01-01 00:34:46.549 1484 1645 D bt_btif : btif_in_fetch_bonded_ble_device Found a LE device: 43:8c:08:f8:6e:e1
01-01 00:34:46.549 1484 1645 D bt_btif : Remote device:43:8c:08:f8:6e:e1, no link key or ble key found
01-01 00:34:46.558 1484 1645 I bt_btif : HAL bt_hal_cbacks->device_found_cb
01-01 00:34:49.962 1484 1664 I bt_hci : btu_hcif_process_event) hci_evt_code=7
01-01 00:34:49.962 1484 1664 I bt_btm : BDA d2:60:6c:6c:ff:9e
01-01 00:34:49.962 1484 1664 I bt_btm : Inquire BDA d2:60:6c:6c:ff:9e
01-01 00:34:49.962 1484 1664 I bt_btm : BTM_InqDbRead: bd addr [d2606c6cff9e]
01-01 00:34:49.962 1484 1664 D bt_btm : btm_find_dev_type - device_type = 1 addr_type = 0
01-01 00:34:49.962 1484 1664 I bt_btm : btm_sec_rmt_name_request_complete
01-01 00:34:49.962 1484 1664 D bt_btm : btm_acl_resubmit_page
01-01 00:34:49.962 1484 1664 I bt_btm : btm_sec_rmt_name_request_complete PairState: 1 RemName: LBH19 status: 0 State:0 p_dev_rec: 0xe28d9c00
01-01 00:34:49.963 1484 1664 I bt_btm : setting BTM_SEC_NAME_KNOWN sec_flags:0x88
01-01 00:34:49.963 1484 1664 I bt_btm : btm_sec_rmt_name_request_complete() continue bonding sm4: 0x0011, status:0x0
01-01 00:34:49.963 1484 1664 D bt_btm : btm_sec_rmt_name_request_complete, SM4 Value: 11, Legacy:0,IS SM4:1, Unknown:0
01-01 00:34:49.963 1484 1664 I bt_l2cap: l2c_link_adjust_allocation num_hipri: 0 num_lowpri: 1 low_quota: 7 round_robin_quota: 0 qq: 7
01-01 00:34:49.963 1484 1664 I bt_l2cap: l2c_link_adjust_allocation LCB 0 Priority: 0 XmitQuota: 7
01-01 00:34:49.963 1484 1664 I bt_l2cap: SentNotAcked: 0 RRUnacked: 0
01-01 00:34:49.963 1484 1664 I bt_btm : BTM_InqDbRead: bd addr [d2606c6cff9e]
01-01 00:34:49.963 1484 1664 D bt_btm : btm_find_dev_type - device_type = 1 addr_type = 0
01-01 00:34:49.963 1484 1664 D bt_l2cap: l2cu_create_conn_after_switch :0 num_acl:0 no_hi: 0 is_bonding:1
01-01 00:34:49.964 1484 1664 I bt_btm : BTM_InqDbRead: bd addr [d2606c6cff9e]
01-01 00:34:49.964 1484 1664 D bt_btm : btm_acl_paging discing:0, paging:0 BDA: d2606c6cff9e
01-01 00:34:49.964 1484 1664 D bt_btm : connecting_bda: d2606c6cff9e
01-01 00:34:49.964 1484 1664 I bt_btm : btm_find_or_alloc_dev
01-01 00:34:49.964 1484 1664 E bt_hci : btu_hcif_send_cmd
01-01 00:34:49.964 1484 1664 D bt_btm : btm_acl_update_busy_level
01-01 00:34:49.964 1484 1664 D bt_btm : BTM_BLI_PAGE_EVT
01-01 00:34:49.964 1484 1664 D bt_btm : btm_acl_update_busy_level
01-01 00:34:49.964 1484 1664 D bt_btm : BTM_BLI_PAGE_EVT
01-01 00:34:49.964 1484 1664 D bt_btm : Security Manager: btm_sec_dd_create_conn [d2606c6cff9e]
01-01 00:34:49.964 1484 1664 I bt_btm : btm_sec_change_pairing_state() Old: 1
01-01 00:34:49.964 1484 1664 I bt_btm : btm_sec_change_pairing_state() New: 2 pairing_flags:0x5
#define HCI_RMT_NAME_REQUEST_COMP_EVT 0x07
#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT 0x3D //61
/* ULP HCI Event */
#define HCI_BLE_EVENT 0x3e //62
btm_sec_rmt_name_request_complete
btm_sec_dd_create_conn
l2cu_allocate_lcb
l2cu_create_conn
l2cu_create_conn_after_switch (p_lcb)
btsnd_hcic_create_conn
btm_acl_paging (p, dest);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);//This function is called to send commands to the Host Controller
hci_layer_get_interface()->transmit_command(p_buf,btu_hcif_command_complete_evt,btu_hcif_command_status_evt,vsc_callback);
btm_acl_update_busy_level
case BTM_BLI_PAGE_EVT: //開始連接
BTM_TRACE_DEBUG ("BTM_BLI_PAGE_EVT");
btm_cb.is_paging = TRUE;
evt.busy_level_flags= BTM_BL_PAGING_STARTED;
case BTM_BLI_INQ_EVT: //開始搜索
BTM_TRACE_DEBUG ("BTM_BLI_INQ_EVT");
btm_cb.is_inquiry = TRUE;
evt.busy_level_flags = BTM_BL_INQUIRY_STARTED;
break;
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);//Pairing State:1->2
event_command_ready
waiting_command_t *wait_entry = fixed_queue_dequeue(queue);//出列command_queue
packet_fragmenter->fragment_and_dispatch(wait_entry->command);// 調用packet_fragmenter.c裏面的fragment_and_dispatch方法
transmit_command
enqueue_command(wait_entry);
fixed_queue_enqueue(command_queue, wait_entry);//入列command_queue
system\bt\hci\src\hci_layer.c
transmit_fragment
btsnoop->capture(packet, false);//記錄btsnoop數據
hal->transmit_data(type, packet->data + packet->offset, packet->len);//調用hal接口發送數據
01-01 00:34:56.692 1484 1664 D bt_btm : update RSSI new:-80, old:-84
01-01 00:34:57.667 1484 1664 D bt_btm : connecting_bda: d2606c6cff9e
01-01 00:35:01.603 1484 1664 I bt_hci : btu_hcif_process_event) hci_evt_code=18
01-01 00:35:01.603 1484 1664 D bt_btm : btm_acl_role_changed
01-01 00:35:01.603 1484 1664 D bt_btm : btm_acl_report_role_change
01-01 00:35:17.241 1484 1664 I bt_hci : btu_hcif_process_event) hci_evt_code=3
01-01 00:35:17.241 1484 1664 I bt_hci : btu_hcif_connection_comp_evt) status=19
01-01 00:35:17.242 1484 1664 I bt_btm : Security Manager: btm_sec_connected in state: 2 handle:0 status:19 enc_mode:0 bda:6c6cff9e RName:LBH19
01-01 00:35:17.243 1484 1664 D bt_l2cap: l2cu_update_lcb_4_bonding BDA: d2606c6cff9e is_bonding: 0
#define HCI_CONNECTION_COMP_EVT 0x03
#define HCI_ROLE_CHANGE_EVT 0x12
event_uart_has_bytes// See what data is waiting, and notify the upper layer//callbacks->data_ready(current_data_type);
hal_says_data_ready
data_dispatcher_dispatch
fixed_queue_enqueue(queue, data);
btu_hci_msg_ready
btu_hcif_process_event //#define HCI_ROLE_CHANGE_EVT 0x12
btm_acl_role_changed
btu_hci_msg_ready
btu_hci_msg_process
btu_hcif_process_event
case HCI_CONNECTION_COMP_EVT:
btu_hcif_connection_comp_evt//status=19
btm_sec_connected
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);//status != HCI_SUCCESS //Pairing State:2->0
/* security API events */
bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */
bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */
bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */
success:BTM_PAIR_STATE_IDLE->BTM_PAIR_STATE_GET_REM_NAME->BTM_PAIR_STATE_WAIT_PIN_REQ->BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS->BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM->BTM_PAIR_STATE_WAIT_AUTH_COMPLETE->BTM_PAIR_STATE_IDLE(0->1->2->7->4->9->0)
fail:BTM_PAIR_STATE_IDLE->BTM_PAIR_STATE_GET_REM_NAME->BTM_PAIR_STATE_WAIT_PIN_REQ->BTM_PAIR_STATE_IDLE->BTM_PAIR_STATE_INCOMING_SSP->BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS->BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM(0->1->2->0->8->7->4)
BTIF —> BTA —-> BTM —–> BTU —–> HCI
bluedroid的代碼層級基本是這麼定義,後續可能再從其他角度來看下這個層級結構
從上面看起來,事件是通過HCI–>BTU—>BTM—->BTA—->BTIF一層層往上拋的,剛好與發送掃描命令相反。
一、send event:
system\bt\hci\src\vendor.c
send_command
lib_interface->op((bt_vendor_opcode_t)opcode, param);//libbt-vendor.so
bt_vendor_linux.c
bt_vendor_op
case BT_VND_OP_USERIAL_OPEN //VENDOR_OPEN_USERIAL
bt_vendor_open(param);
fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);//hci層(net/bluetooth/hci_sock.c)
#if HCI_USE_MCT
(system/bt/hci/src/hci_hal_mct.c)
system/bt/hci/src/hci_hal_h4.c
hal_open
int number_of_ports = vendor->send_command(VENDOR_OPEN_USERIAL, &fd_array);//通過vendor接口去打開底層的設備節點,存儲在fd_array中
uart_stream = eager_reader_new(uart_fd, &allocator_malloc, HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX, "hci_single_channel");
eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL);//監聽上傳的數據
event_uart_has_bytes
callbacks->data_ready(current_data_type);
system\bt\hci\src\hci_layer.c
hal_says_data_ready //callbacks->data_ready
transmit_data
OSI_NO_INTR(ret = write(uart_fd, data + transmitted_length, length));
hal層調用的接口很簡單,主要就是往hal_open返回的節點描述符寫數據,這個數據最終會經過內核抵達硬件設備端。
發送數據的流程就結束了。
system\bt\hci\src\hci_layer.c
transmit_fragment
btsnoop->capture(packet, false);//記錄btsnoop數據
hal->transmit_data(type, packet->data + packet->offset, packet->len);//調用hal接口發送數據
system\bt\hci\src\packet_fragmenter.c
fragment_and_dispatch
callbacks->fragmented(packet, true);// 調用hci_layer.c文件中的packet_fragmenter_callbacks 結構體中的transmit_fragment
system/bt/stack/btu/btu_hcif.c
btu_hcif_send_cmd//send commands to the Host Controller //發送命令到藍牙適配器
hci_layer_get_interface()->transmit_command(p_buf, btu_hcif_command_complete_evt, btu_hcif_command_status_evt, vsc_callback);
system\bt\hci\src\hci_layer.c
static fixed_queue_t *command_queue;
static fixed_queue_t *packet_queue;
//建立工作線程和消息隊列以及處理函數
fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL);
fixed_queue_register_dequeue(packet_queue, thread_get_reactor(thread), event_packet_ready, NULL);
event_command_ready
waiting_command_t *wait_entry = fixed_queue_dequeue(queue);//出列command_queue
packet_fragmenter->fragment_and_dispatch(wait_entry->command);// 調用packet_fragmenter.c裏面的fragment_and_dispatch方法
transmit_command
enqueue_command(wait_entry);
fixed_queue_enqueue(command_queue, wait_entry);//入列command_queue
btu_hcif_command_complete_evt
btu_hcif_command_status_evt
fixed_queue_enqueue(btu_hci_msg_queue, event);//入列btu_hci_msg_queue
二、receive event:
btu_task.c
fixed_queue_register_dequeue(btu_bta_msg_queue,
thread_get_reactor(bt_workqueue_thread),
btu_bta_msg_ready,
NULL);
//建立工作線程和消息隊列以及處理函數
btu_task_start_up
fixed_queue_register_dequeue(btu_hci_msg_queue,
thread_get_reactor(bt_workqueue_thread),
btu_hci_msg_ready,
NULL);
//處理函數
btu_hci_msg_ready
BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);//出列btu_hci_msg_queue
BT_EVT_TO_BTU_HCI_EVT
btu_hci_msg_process
三、handle event:
btu_hcif.c
btu_hcif_process_event
HCI_CONNECTION_COMP_EVT//
btu_hcif_connection_comp_evt
btm_sec.c
btm_sec_connected
四、kernel層
數據發送
net\bluetooth\hci_sock.c
hci_sock_init
err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
Android藍牙協議-藍牙配對與連接
藍牙設備在連接前,會先檢查設備是否已經配對過,如果沒有則先配對,配對完成後,再開始連接。
打開藍牙接口:
BluetoothManagerService.handleEnable
handleEnable會檢查是否綁定了IBluetooth Server,如果沒有綁定已經綁定調用IBluetooth.enable方法打開藍牙
AdapterService.AdapterServiceBinder(IBluetooth Server) :createBond
com_android_bluetooth_btservice_AdapterService.cpp
createBondNative
sBluetoothInterface->create_bond((bt_bdaddr_t *)addr, transport);
system/bt/btif/src/bluetooth.c
create_bond
btif_dm_create_bond
btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND,
(char *)&create_bond_cb, sizeof(btif_dm_create_bond_cb_t), NULL);