一. setting中的调用
1. 当在屏幕上点击搜索到的蓝牙设备时,会产生一个onClicked事件
在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java中
会调用pair函数
mCachedDevice
是一个CachedBluetoothDevice
2. 在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java中
在pair时,如果正在搜索,则停止搜索,并调用
CachedBluetoothDevice的createBond, mDevice
是一个 BluetoothDevice在framework层
二. framework层中的调用
在./frameworks/base/core/java/android/bluetooth/BluetoothDevice.java中
调用了sService
的createBond, 其中sService是IBluetooth,要到packages层去了
三.packages中的调用
3.1 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中
的AdapterServiceBinder类中
在AdapterService类中
发送了一个CREATE_BOND的消息
3.2 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java中
在消息处理函数createBond中
看到
createBondNative这个函数,就知道要调用jni了。
四. jni中的调用
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
其中这个sBluetoothInterface
是协议栈的接口
五.协议栈bluedroid中的调用
5.1 在./external/bluetooth/bluedroid/btif/src/bluetooth.c中
5.2 在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
具体的如何调用到了这个回调函数,参见附录1
5.3 在回调函数中进行具体的处理
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
5.3.1 回调的具体处理
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
5.3.2
在./external/bluetooth/bluedroid/bta/dm/bta_dm_api.c中
在./external/bluetooth/bluedroid/bta/sys/bta_sys_main.c中
又到了这个sendmsg,不过这次的跟上一次不一样的地方是参数task_id不是BTIF_TASK, 所以接收者不是btif_task而是btu_task
5.3.3 在./stack/btu/btu_task.c中
在./bta/sys/bta_sys_main.c中
会调用全局函数
bta_sys_cb
.
reg
[
id
]
-
>
evt_hdlr,这个东东是从哪儿来的呢?
5.4 bta_sys_cb . reg [ id ] - > evt_hdlr的由来
在bta/sys/bta_sys_main.c中
在bta/dm/bta_dm_api.c中
通过bta_sys_register (BTA_ID_DM, &bta_dm_reg )注册的,
所以这儿的 bta_sys_cb . reg [ id ] - > evt_hdlr调用的就是bta_dm_sm_execute
5.5 bta_dm_sm_execute
在bta/dm/bta_dm_main.c中
bta_dm_action是一个函数指针的数组,此时event=10,在数组中是函数bta_dm_bond
5.6
在./bta/dm/bta_dm_act.c中
5.6.1 在./stack/btm/btm_sec.c中
在stack/l2cap/l2c_utils.c中
在
附一: 协议栈中消息的传递
在 btif_dm_create_bond 中调用了函数btif_transfer_context来发送CREATE_BOND命令
btif_transfer_context ( btif_dm_generic_evt , BTIF_DM_CB_CREATE_BOND ,
( char * ) bd_addr , sizeof ( bt_bdaddr_t ) , NULL ) ;
其中btif_dm_generic_evt 是回调函数,
BTIF_DM_CB_CREATE_BOND 是命令
( char * ) bd_addr 是参数
1.1 stack中消息的发送与处理过程
在./external/bluetooth/bluedroid/btif/src/btif_core.c中
1.2 进入core
在 ./external/bluetooth/bluedroid/btif/src/btif_core.c中
1.3 组成命令,并发送//这个event就是发送的命令
在./external/bluetooth/bluedroid/gki/common/gki_buffer.c中
1.4 具体的发送过程
这儿说是发送,并不是发送msg,而是向接收者发送了一个信号。
在./external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c中
1.5 接收者
因为GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);发送的task是BTIF_TASK
所以在./external/bluetooth/bluedroid/btif/src/btif_core.c中
1.6 最后调用回调函数
在./external/bluetooth/bluedroid/btif/src/btif_core.c中
1.7 在回调函数中进行具体的处理
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
1.8
根据task_id来区分是发送给btif_task还是btu_task
2.5 总结一下
附三:
在stack/hcic/hcicmds.c中
在stack/btu/btu_hcif.c中
#define HCI_CMD_TO_LOWER(p) bte_main_hci_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);
在main/bte_main.c 中
在hci/src/bt_hci_bdroid.c中
发送了一个
HC_EVENT_TX
信号
那么是谁来接收这个HC_EVENT_TX命令呢?
在hci/src/bt_hci_bdroid.c中
其中p_hci_if的初始化是在hci/src/bt_hci_bdroid.c中
在hci/src/userial.c中
在hci/src/userial.c中,初始化了userial_cb . fd
1. 当在屏幕上点击搜索到的蓝牙设备时,会产生一个onClicked事件
在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java中
- void onClicked() {
- int bondState = mCachedDevice.getBondState();
-
- if (mCachedDevice.isConnected()) {
- askDisconnect();
- } else if (bondState == BluetoothDevice.BOND_BONDED) {
- mCachedDevice.connect(true);
- } else if (bondState == BluetoothDevice.BOND_NONE) {
- pair();
- }
- }
- private void pair() {
- if (!mCachedDevice.startPairing()) {
- Utils.showError(getContext(), mCachedDevice.getName(),
- R.string.bluetooth_pairing_error_message);
- }
- }
2. 在./device/softwinner/common/packages/TvdSettings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java中
- boolean startPairing() {
- if (mLocalAdapter.isDiscovering()) {
- mLocalAdapter.cancelDiscovery();
- }
- if (!mDevice.createBond()) {
- return false;
- }
- mConnectAfterPairing = true; // auto-connect after pairing
- return true;
- }
二. framework层中的调用
在./frameworks/base/core/java/android/bluetooth/BluetoothDevice.java中
- public boolean createBond() {
- if (sService == null) {
- return false;
- }
- try {
- return sService.createBond(this);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
三.packages中的调用
3.1 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java中
的AdapterServiceBinder类中
- public boolean createBond(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
- return false;
- }
-
- AdapterService service = getService();
- if (service == null) return false;
- return service.createBond(device);
- }
- boolean createBond(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
- DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
- if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
- return false;
- }
- Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
- msg.obj = device;
- mBondStateMachine.sendMessage(msg);
- return true;
- }
3.2 在./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java中
- public boolean processMessage(Message msg) {
- switch(msg.what) {
- case CREATE_BOND:
- createBond(dev, true);
- break;
- }
- }
- private boolean createBond(BluetoothDevice dev, boolean transition) {
- if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
- byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
- if (!mAdapterService.createBondNative(addr)) {
- sendIntent(dev, BluetoothDevice.BOND_NONE,
- BluetoothDevice.UNBOND_REASON_REMOVED);
- return false;
- } else if (transition) {
- transitionTo(mPendingCommandState);
- }
- return true;
- }
- return false;
- }
四. jni中的调用
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
- static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
- jbyte *addr;
- jboolean result = JNI_FALSE;
-
- if (!sBluetoothInterface) return result;
-
- addr = env->GetByteArrayElements(address, NULL);
- int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);
- env->ReleaseByteArrayElements(address, addr, NULL);
- result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
- return result;
- }
五.协议栈bluedroid中的调用
5.1 在./external/bluetooth/bluedroid/btif/src/bluetooth.c中
- static int create_bond(const bt_bdaddr_t *bd_addr)
- {
- /* sanity check */
- if (interface_ready() == FALSE)
- return BT_STATUS_NOT_READY;
- return btif_dm_create_bond(bd_addr);
- }
- bt_status_t btif_dm_create_bond(const bt_bdaddr_t *bd_addr)
- {
- bdstr_t bdstr;
- if (pairing_cb.state != BT_BOND_STATE_NONE)
- return BT_STATUS_BUSY;
- btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND,
- (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
-
- return BT_STATUS_SUCCESS;
- }
5.3 在回调函数中进行具体的处理
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
- static void btif_dm_generic_evt(UINT16 event, char* p_param)
- {
- switch(event) //这个event就是发送的命令
- {
- case BTIF_DM_CB_CREATE_BOND:
- {
- btif_dm_cb_create_bond((bt_bdaddr_t *)p_param);
- }
- break;
- }
- }
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
- static void btif_dm_cb_create_bond(bt_bdaddr_t *bd_addr)
- {
- //状态由BT_BOND_STATE_NONE--> BT_BOND_STATE_BONDING,并通知上层
- //这儿具体如何调用上层的过程,参见附录2
- bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
- if (check_cod(bd_addr, COD_HID_POINTING)){
- int status;
- status = btif_hh_connect(bd_addr);
- if(status != BT_STATUS_SUCCESS)
- bond_state_changed(status, bd_addr, BT_BOND_STATE_NONE);
- }
- else
- {
- BTA_DmBond ((UINT8 *)bd_addr->address);
- }
- pairing_cb.is_local_initiated = TRUE;
- }
在./external/bluetooth/bluedroid/bta/dm/bta_dm_api.c中
- void BTA_DmBond(BD_ADDR bd_addr)
- {
- tBTA_DM_API_BOND *p_msg;
-
- if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL)
- {
- p_msg->hdr.event = BTA_DM_API_BOND_EVT;
- bdcpy(p_msg->bd_addr, bd_addr);
- bta_sys_sendmsg(p_msg);
- }
- }
- void bta_sys_sendmsg(void *p_msg)
- {
- GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
- }
5.3.3 在./stack/btu/btu_task.c中
- BTU_API UINT32 btu_task (UINT32 param)
- {
- if (event & TASK_MBOX_2_EVT_MASK)
- {
- while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
- {
- bta_sys_event(p_msg);
- }
- }
- }
- BTA_API void bta_sys_event(BT_HDR *p_msg)
- {
- UINT8 id;
- BOOLEAN freebuf = TRUE;
- id = (UINT8) (p_msg->event >> 8);
- freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
- }
5.4 bta_sys_cb . reg [ id ] - > evt_hdlr的由来
在bta/sys/bta_sys_main.c中
- void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
- {
- bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
- bta_sys_cb.is_reg[id] = TRUE;
- }
- static const tBTA_SYS_REG bta_dm_reg =
- {
- bta_dm_sm_execute,
- bta_dm_sm_disable
- };
所以这儿的 bta_sys_cb . reg [ id ] - > evt_hdlr调用的就是bta_dm_sm_execute
5.5 bta_dm_sm_execute
在bta/dm/bta_dm_main.c中
- BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)
- {
- UINT16 event = p_msg->event & 0x00ff;
- if(event < BTA_DM_NUM_ACTIONS)
- {
- (*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg);
- }
-
- return TRUE;
- }
5.6
在./bta/dm/bta_dm_act.c中
- void bta_dm_bond (tBTA_DM_MSG *p_data)
- {
- tBTM_STATUS status;
- tBTA_DM_SEC sec_event;
- char *p_name;
-
- status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
- if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
- {
- p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
- if (!p_name)
- p_name = "";
-
- memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
- bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
- memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
- sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
- sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
- if (status == BTM_SUCCESS)
- sec_event.auth_cmpl.success = TRUE;
-
- bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
- }
-
- }
5.6.1 在./stack/btm/btm_sec.c中
- tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
- {
- p_dev_rec = btm_find_or_alloc_dev (bd_addr); //第一次配对时alloc一个device
- status = btm_sec_dd_create_conn(p_dev_rec); //进入下一步
- return status;
- }
在stack/l2cap/l2c_utils.c中
在
附一: 协议栈中消息的传递
在 btif_dm_create_bond 中调用了函数btif_transfer_context来发送CREATE_BOND命令
btif_transfer_context ( btif_dm_generic_evt , BTIF_DM_CB_CREATE_BOND ,
( char * ) bd_addr , sizeof ( bt_bdaddr_t ) , NULL ) ;
其中btif_dm_generic_evt 是回调函数,
BTIF_DM_CB_CREATE_BOND 是命令
( char * ) bd_addr 是参数
1.1 stack中消息的发送与处理过程
在./external/bluetooth/bluedroid/btif/src/btif_core.c中
- bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback)
- {
- tBTIF_CONTEXT_SWITCH_CBACK *p_msg;
- //第1步获取msg的buffer
- if ((p_msg = (tBTIF_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)
- {
- //第2步组成一个msg
- p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT;
- p_msg->p_cb = p_cback;
- p_msg->event = event;
- if (p_copy_cback)
- {
- p_copy_cback(event, p_msg->p_param, p_params);
- }
- else if (p_params)
- {
- memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */
- }
- /第3步,最后一步发送
- btif_sendmsg(p_msg);
- return BT_STATUS_SUCCESS;
- }
- else
- {
- return BT_STATUS_NOMEM;
- }
- }
在 ./external/bluetooth/bluedroid/btif/src/btif_core.c中
- void btif_sendmsg(void *p_msg)
- {
- GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
- }
在./external/bluetooth/bluedroid/gki/common/gki_buffer.c中
- void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
- {
- BUFFER_HDR_T *p_hdr;
- tGKI_COM_CB *p_cb = &gki_cb.com;
-
- p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
- GKI_disable();
- if (p_cb->OSTaskQFirst[task_id][mbox])
- p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
- else
- p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
-
- p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
- p_hdr->p_next = NULL;
- p_hdr->status = BUF_STATUS_QUEUED;
- p_hdr->task_id = task_id;
- GKI_enable();
- GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
- return;
- }
这儿说是发送,并不是发送msg,而是向接收者发送了一个信号。
在./external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c中
- UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
- {
- if (task_id < GKI_MAX_TASKS)
- {
- pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
- gki_cb.com.OSWaitEvt[task_id] |= event;
- pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
- pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
- return ( GKI_SUCCESS );
- }
- return (GKI_FAILURE);
- }
因为GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);发送的task是BTIF_TASK
所以在./external/bluetooth/bluedroid/btif/src/btif_core.c中
- static void btif_task(UINT32 params)
- {
- UINT16 event;
- BT_HDR *p_msg;
- btif_associate_evt();
- for(;;)
- {
- //上面的pthread_cond_signal,把下面的wait打断
- event = GKI_wait(0xFFFF, 0);
-
- if(event & TASK_MBOX_1_EVT_MASK)
- {//这个event就是发送的命令
- while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)
- {
- switch (p_msg->event)
- {
- case BT_EVT_CONTEXT_SWITCH_EVT: //执行到这儿
- btif_context_switched(p_msg);
- break;
- default:
- break;
- }
- GKI_freebuf(p_msg);
- }
- }
- }
-
- btif_disassociate_evt();
- }
在./external/bluetooth/bluedroid/btif/src/btif_core.c中
- static void btif_context_switched(void *p_msg)
- {
- tBTIF_CONTEXT_SWITCH_CBACK *p;
-
- BTIF_TRACE_VERBOSE0("btif_context_switched");
-
- p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
- //调用回调函数
- if (p->p_cb)
- p->p_cb(p->event, p->p_param);
- }
在./external/bluetooth/bluedroid/btif/src/btif_dm.c中
- static void btif_dm_generic_evt(UINT16 event, char* p_param)
- {
- switch(event) //这个event就是发送的命令
- {
- case BTIF_DM_CB_CREATE_BOND:
- {
- btif_dm_cb_create_bond((bt_bdaddr_t *)p_param);
- }
- break;
- }
- }
根据task_id来区分是发送给btif_task还是btu_task
2.5 总结一下
附三:
在stack/hcic/hcicmds.c中
- BOOLEAN btsnd_hcic_delete_stored_key (BD_ADDR bd_addr, BOOLEAN delete_all_flag)
- {
- BT_HDR *p;
- UINT8 *pp;
-
- p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_DELETE_STORED_KEY); //获取buffer
- pp = (UINT8 *)(p + 1);
-
- p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_DELETE_STORED_KEY;
- p->offset = 0;
-
- UINT16_TO_STREAM (pp, HCI_DELETE_STORED_LINK_KEY);
- UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_DELETE_STORED_KEY);
-
- BDADDR_TO_STREAM (pp, bd_addr);
- UINT8_TO_STREAM (pp, delete_all_flag);
-
- btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
- return (TRUE);
- }
在stack/btu/btu_hcif.c中
- void btu_hcif_send_cmd (UINT8 controller_id, BT_HDR *p_buf)
- {
- if (controller_id == LOCAL_BR_EDR_CONTROLLER_ID)
- HCI_CMD_TO_LOWER(p_buf);
- }
在main/bte_main.c 中
- void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
- {
- UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
- p_msg->event = event;
- if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || (sub_event == LOCAL_BLE_CONTROLLER_ID))
- {
- if (bt_hc_if)
- {
- bt_hc_if->transmit_buf((TRANSAC)p_msg, (char *) (p_msg + 1), p_msg->len);
- }
- else
- GKI_freebuf(p_msg);
- }
- }
在hci/src/bt_hci_bdroid.c中
- static int transmit_buf(TRANSAC transac, char *p_buf, int len)
- {
- utils_enqueue(&tx_q, (void *) transac);
- bthc_signal_event(HC_EVENT_TX);
- return BT_HC_STATUS_SUCCESS;
- }
那么是谁来接收这个HC_EVENT_TX命令呢?
在hci/src/bt_hci_bdroid.c中
- static void *bt_hc_worker_thread(void *arg)
- {
- if (events & HC_EVENT_TX)
- {
- tx_cmd_pkts_pending = FALSE;
- HC_BT_HDR * sending_msg_que[64];
- int sending_msg_count = 0;
- utils_lock();
- p_next_msg = tx_q.p_first;
- while (p_next_msg && sending_msg_count < (int)sizeof(sending_msg_que)/sizeof(sending_msg_que[0]))
- {
- if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
- {
- if ((tx_cmd_pkts_pending == TRUE) || (num_hci_cmd_pkts <= 0))
- {
- tx_cmd_pkts_pending = TRUE;
- p_next_msg = utils_getnext(p_next_msg);
- continue;
- }
- }
-
- p_msg = p_next_msg;
- p_next_msg = utils_getnext(p_msg);
- utils_remove_from_queue_unlocked(&tx_q, p_msg);
- sending_msg_que[sending_msg_count++] = p_msg;
- }
- utils_unlock();
- int i;
- for(i = 0; i < sending_msg_count; i++)
- p_hci_if->send(sending_msg_que[i]);
- if (tx_cmd_pkts_pending == TRUE)
- BTHCDBG("Used up Tx Cmd credits");
- }
- }
其中p_hci_if的初始化是在hci/src/bt_hci_bdroid.c中
- static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
- {
-
- #ifdef HCI_USE_MCT //MCT: Multi-Channels Transport
- extern tHCI_IF hci_mct_func_table;
- p_hci_if = &hci_mct_func_table;
- #elif defined HCI_USE_RTK_H5
- extern tHCI_IF hci_h5_func_table;
- p_hci_if = &hci_h5_func_table;
- #else
- extern tHCI_IF hci_h4_func_table;
- p_hci_if = &hci_h4_func_table; //这儿是用的这个
- #endif
-
- p_hci_if->init();
- }
在hci/src/userial.c中
- uint16_t userial_write(uint16_t msg_id, uint8_t *p_data, uint16_t len)
- {
- int ret, total = 0;
-
- while(len != 0)
- {
- ret = write(userial_cb.fd, p_data+total, len);
- total += ret;
- len -= ret;
- }
-
- return ((uint16_t)total);
- }
在hci/src/userial.c中,初始化了userial_cb . fd
- uint8_t userial_open(uint8_t port)
- {
- bt_vnd_if->op(BT_VND_OP_USERIAL_OPEN, &fd_array); //向libbt_verder.so发消息
- userial_cb.fd = fd_array[0];
- }
- root@android:/ # ls /dev/ttyS2 -l
- crw-rw---- bluetooth net_bt_stack 250, 2 2014-08-19 15:30 ttyS2