Android 4.2 BT系统之蓝牙关闭过程全跟踪
UserHandle.USER_CURRENT)) {
setAdapterPropertyNative,调用蓝牙HAL接口
sBluetoothInterface->set_adapter_property(&prop);
BT_PROPERTY_ADAPTER_SCAN_MODE设置的处理,先保存discovery
mode为BTA_DM_NON_DISC,表示不可发现,保存connecable
mode为BTA_DM_NON_CONN,表示不可连接。然后,调用external/bluetooth/bluedroid/bta/dm
/bta_dm_api.c :: BTA_DmSetVisibility方法
*p_msg,填入discovery mode, connetiable
mode等参数,然后调用external/bluetooth/bluedroid/bta/sys/bta_sys_main.c
:: bta_sys_sendmsg
/common/gki_buffer.c ::
GKI_send_msg发送一条GKI信息到BTA,GKI_send_msg有三个参数,第一个参数是线程id,也作为task id,
通过bta_sys_init获得,第二个参数是mailbox id,第三个是上一步封装好的p_msg
id对应的任务队列中,调用external/bluetooth/bluedroid/gki/ulinux/gki_ulinux.c
:: GKI_send_event进行发送
event;,
通过pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);通知另外线程。
sizeof(btif_task_stack)); 启动这个任务,第一个参数btif_task是任务处理函数,第二个参数是task id,第三个是对应string表示形式,第四个是任务列表的起始指针,第四个是任务栈最大深度。
(void *)gki_task_entry,
&gki_pthread_info[task_id]); //gki_pthread_info保存了任务信息:task_id,task_entry。
#define TASK_MBOX_1 1
#define TASK_MBOX_2 2
#define TASK_MBOX_3 3
#define NUM_TASK_MBOX 4
#define TASK_MBOX_0_EVT_MASK 0x0001
#define TASK_MBOX_1_EVT_MASK 0x0002
#define TASK_MBOX_2_EVT_MASK 0x0004
#define TASK_MBOX_3_EVT_MASK 0x0008
#ifndef BTU_TASK
#define BTU_TASK 0
#endif
#ifndef BTIF_TASK
#define BTIF_TASK 1
#endif
#ifndef A2DP_MEDIA_TASK
#define A2DP_MEDIA_TASK 2
#endif
/* The number of GKI tasks in the software system. */
#ifndef GKI_MAX_TASKS
#define GKI_MAX_TASKS 3
#endif
sizeof(bte_btu_stack)); //启动BTU任务
&timer_attr,
timer_thread,
NULL); //根据NO_GKI_RUN_RETURN是否执行timer_thread线程,NO_GKI_RUN_RETURN是什么意思?LINUX是否需要定义此宏?
#endif
#endif
{
GKI_send_msg(bta_sys_cb.task_id, p_bta_sys_cfg->mbox, p_msg);
}
这里GKI_send_msg的第一个参数已经确定,第二个参数见BTA相关参数的映射:
#ifndef BTA_MBOX_EVT
#define BTA_MBOX_EVT TASK_MBOX_2_EVT_MASK
#endif
/* GKI task mailbox for BTA. */
#ifndef BTA_MBOX
#define BTA_MBOX TASK_MBOX_2
#endif
/* GKI timer id used for protocol timer for BTA. */
#ifndef BTA_TIMER
#define BTA_TIMER TIMER_1
#endif
const tBTA_SYS_CFG bta_sys_cfg =
{
BTA_MBOX_EVT, /* GKI mailbox event */
BTA_MBOX, /* GKI mailbox id */
BTA_TIMER, /* GKI timer id */
APPL_INITIAL_TRACE_LEVEL /* initial trace level */
};
tBTA_SYS_CFG *p_bta_sys_cfg = (tBTA_SYS_CFG *)&bta_sys_cfg;
{
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL) //取出p_msg
{
bta_sys_event(p_msg); //处理p_msg
}
}
{
{
/* device manager local device API events */
BTA_DM_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_DM),
//注意这里BTA_SYS_EVT_START(BTA_ID_DM)实现#define
BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 <<
(id));因为BTA_ID_DM是1,
BTA_DM_API_SET_NAME_EVT,
BTA_DM_API_SET_VISIBILITY_EVT,
BTA_DM_API_SET_AFH_CHANNELS_EVT,
BTA_API_DM_SIG_STRENGTH_EVT,
BTA_DM_API_VENDOR_SPECIFIC_COMMAND_EVT,
BTA_DM_API_TX_INQPWR_EVT,
BTA_DM_ACL_CHANGE_EVT,
BTA_DM_API_ADD_DEVICE_EVT,
{
BTIF_TRACE_DEBUG0("btif_task: received trigger stack init event");
BTA_EnableBluetooth(bte_dm_evt);
}
{
bta_dm_sm_execute,
{
/* device manager local device API events */
bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */
bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */
bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */
bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */
bta_dm_set_afhchannels, /* 4 BTA_DM_API_SET_AFH_CHANNELS_EVT */
bta_dm_signal_strength, /* 5 BTA_API_DM_SIG_STRENGTH_EVT */
bta_dm_vendor_spec_command,/* 6 BTA_DM_API_VENDOR_SPECIFIC_COMMAND_EVT */
bta_dm_tx_inqpower, /* 7 BTA_DM_API_SIG_STRENGTH_EVT */
bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */
bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */
...
bta_dm_cb.inquiry_scan_window,
bta_dm_cb.inquiry_scan_interval); //调用这个实现设置discovery mode
bta_dm_cb.page_scan_window,
bta_dm_cb.page_scan_interval); //调用这个实现设置can mode
(UINT16)(BTU_TTYPE_BTU_CMD_CMPL + controller_id),
BTU_CMD_CMPL_TIMEOUT); //启动计时器, cmd_cmpltimer与cmd_cmpl_q的关系?
if (controller_id == LOCAL_BR_EDR_CONTROLLER_ID)
{
HCI_CMD_TO_LOWER(p_buf); //发送到底层,是一个宏
}
(sub_event == LOCAL_BLE_CONTROLLER_ID))
bt_hc_if->transmit_buf((TRANSAC)p_msg, \
(char *) (p_msg + 1), \
p_msg->len); //调用transmit_buf接口发送出去。
{
return &bluetoothHCLibInterface; //返回接口列表
bt_hc_if->preload(NULL);
bt_hc_worker_thread, NULL) != 0) //起工作线程
{
utils_enqueue(&tx_q, (void *) transac); //链接到发送队列
bthc_signal_event(HC_EVENT_TX); //广播事件
return BT_HC_STATUS_SUCCESS;
}
p_hci_if->send(sending_msg_que[i]); //调用p_hci_if的send接口发送出去。
type = H4_TYPE_COMMAND; //设定cmd类型
acl_data_size = h4_cb.hc_acl_data_size;
acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE; //设置数据大小
}
BT_HC_TX_SUCCESS); //将发送结果通过回调发回去,注意这里只是成功发送到串口,有没有成功,应该是从内核往上发,由userial_read_thread来完成。
BTHC_USERIAL_READ_MEM_SIZE);
bthc_signal_event(HC_EVENT_RX);
bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
}
{
p_hci_if->rcv(); //调用rcv,也就是hci_h4_func_table的hci_h4_receive_msg回调
}
H4_RX_MSGTYPE_ST,
H4_RX_LEN_ST,
H4_RX_DATA_ST,
H4_RX_IGNORE_ST
} tHCI_H4_RCV_STATE;
通过条件p_cb->rcv_msg_type和acl_rx_frame_end_chk()两个条件,判断当前是否收完一帧数据,如果是,则调用bt_hc_cbacks的data_ind回调把数据上发:
(char *) (p_cb->p_rcv_msg + 1), \
p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE);
{
BT_HDR *p_msg = (BT_HDR *) transac;
GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); //发到btu task中去了,而且mbox为TASK_MBOX_0
return BT_HC_STATUS_SUCCESS;
}
{
int btif_status;
/* pass on to storage for updating local database */
memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
// btif_transfer_context会将一个消息到BTU_BTIF_MBO,也就是TASK_MBOX_1信箱,并且这个消息
return btif_transfer_context(execute_storage_request,
storage_req_id,
(char*)&req,
sizeof(btif_storage_req_t)+property->len,
btif_in_storage_request_copy_cb);
}
{
case BT_EVT_CONTEXT_SWITCH_EVT: //判断消息类型,符合
btif_context_switched(p_msg); //处理消息
break;
{
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); //取出事件处理回调函数,也就是execute_storage_request
}
case BTIF_CORE_STORAGE_ADAPTER_WRITE: //判断事件类型,符合
{
bt_property_t *p_prop = &(p_req->write_req.prop);
status = btif_storage_set_adapter_property(p_prop); //是否会阻塞?
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,
};
{
return &bluetoothInterface;
}
sizeof(bt_interface_t),
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
};
{
return prop2cfg(NULL, property) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
{
btif_config_set_int("Local", "Adapter",
BTIF_STORAGE_KEY_ADAPTER_SCANMODE, *(int*)prop->val);
break;
{
return btif_config_set(section, key, name, (char*)&value, sizeof(value), BTIF_CFG_TYPE_INT); //加上config类型
}
{
set_node(section, key, name, value, (short)bytes, (short)type); //找到一个cfg_node*(配置节点)
}
{
const char* name;
union
{
struct cfg_node_s* child;
char* value;
};
short bytes;
short type;
short used;
short flag;
} cfg_node;
alloc_node(&root, CFG_GROW_SIZE);
dump_node("root", &root);
pth = btsock_thread_create(NULL, cfg_cmd_callback);
ts[h].cmd_callback = cmd_callback; //sock_poll_thread将会调用它来处理写config
{
prepare_poll_fds(h, pfds);
int ret = poll(pfds, ts[h].poll_count, -1); //开始监听
if(ret != 0)
{
int need_process_data_fd = TRUE;
if(pfds[0].revents) //cmd fd always is the first one
{
asrt(pfds[0].fd == ts[h].cmd_fdr);
if(!process_cmd_sock(h)) //先尝试处理cmd命令,即上面提到的CMD_USER_PRIVATE
{
APPL_TRACE_DEBUG1("h:%d, process_cmd_sock return false, exit...", h);
break;
}
if(ret == 1)
need_process_data_fd = FALSE;
else ret--; //exclude the cmd fd
}
if(need_process_data_fd)
process_data_sock(h, pfds, ret); //再处理数据。
}
else {APPL_TRACE_DEBUG1("no data, select ret: %d", ret)};
}
ts[h].thread_id = -1;
{
sock_cmd_t cmd = {-1, 0, 0, 0, 0};
int fd = ts[h].cmd_fdr;
if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
{
APPL_TRACE_ERROR1("recv cmd errno:%d", errno);
return FALSE;
}
switch(cmd.id)
{
case CMD_USER_PRIVATE:
asrt(ts[h].cmd_callback);
if(ts[h].cmd_callback)
ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id); //调用回调处理,即上文的cfg_cmd_callback
break;
return TRUE;
}
{
//BTIF_TRACE_DEBUG2("cmd type:%d, size:%d", type, size);
switch(type)
{
case CFG_CMD_SAVE:
lock_slot(&slot_lock);
save_cfg(); //保存所有的config到配置文件中,从根config node:root开始遍历
unlock_slot(&slot_lock);
break;
}
}
int mode = Utils.byteArrayToInt(val, 0);
mScanMode = mService.convertScanModeFromHal(mode);
intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
debugLog("Scan Mode:" + mScanMode);
if (mBluetoothDisabling) {
mBluetoothDisabling=false;
mService.startBluetoothDisable(); //调用服务的startBluetoothDisable停掉蓝牙设备
}
break;
btif_pan_cleanup();
{
if (pairing_cb.state == BT_BOND_STATE_BONDING)
{
bt_bdaddr_t bd_addr;
bdcpy(bd_addr.address, pairing_cb.bd_addr);
btif_dm_cancel_bond(&bd_addr); 如果正在配对,则取消配对
}
}
{
BT_HDR *p_msg;
if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) //太暴力了,直接从BTA中拿出一条消息,
{
p_msg->event = BTA_DM_API_DISABLE_EVT; //然后改写事件。
bta_sys_sendmsg(p_msg);
}
else
{
return BTA_FAILURE;
}
return BTA_SUCCESS;
}
{
while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
{
bta_sys_event(p_msg);
}
}
{
UINT16 event = p_msg->event & 0x00ff;
APPL_TRACE_EVENT1("bta_dm_sm_execute event:0x%x", event);
/* execute action functions */
if(event < BTA_DM_NUM_ACTIONS)
{
(*bta_dm_action[event])( (tBTA_DM_MSG*) p_msg); //BTA_DM_API_DISABLE_EVT对应的处理函数是bta_dm_disable
}
return TRUE;
}
{
/* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0); //设置L2CAP通道超时时间
/* disable all active subsystems */
bta_sys_disable(BTA_SYS_HW_BLUETOOTH); //停掉BTA DM 子系统
BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0); //这两者上文解析过了
bta_dm_disable_pm();
bta_dm_cb.disabling = TRUE;
bta_dm_search_cancel(NULL); //停止搜寻设备
if(BTM_GetNumAclLinks()==0)
{
#if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
/* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
* BTA_DISABLE_DELAY milliseconds
*/
APPL_TRACE_WARNING2("%s BTA_DISABLE_DELAY set to %d ms",
__FUNCTION__, BTA_DISABLE_DELAY);
bta_sys_stop_timer(&bta_dm_cb.disable_timer);
bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_conn_down_timer_cback;
bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, BTA_DISABLE_DELAY);
#else
bta_dm_disable_conn_down_timer_cback(NULL);
#endif
}
else
{
bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000); //终止所有定时器的操作。
}
bta_sys_cb.reg[bta_id]->disable方法,也就是上文的bta_dm_reg的其中的
bta_dm_sm_disable方法
{
bta_dm_sm_execute,
bta_dm_sm_disable
};
{
bta_sys_deregister( BTA_ID_DM );
}
{
bta_sys_cb.is_reg[id] = FALSE;//只是简单的将is_reg赋值为FALSE
}
{
tBTA_DM_MSG * p_msg;
if(BTM_IsInquiryActive())
{
BTM_CancelInquiry(); //取消搜寻
bta_dm_search_cancel_notify(NULL);
if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL)
{
p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
bta_sys_sendmsg(p_msg); //给btu_task发消息
}
}
/* If no Service Search going on then issue cancel remote name in case it is active */
else if (!bta_dm_search_cb.name_discover_done)
{
BTM_CancelRemoteDeviceName();
}
#if ((BLE_INCLUDED == TRUE) && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
if (bta_dm_search_cb.gatt_disc_active)
{
bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
}
#endif
}
{
lock_slot(&slot_lock);
if(cached_change > 0)
save_cfg(); //保存配置到文件
unlock_slot(&slot_lock);
}
{
const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
int ret = FALSE;
if(access(file_name_old, F_OK) == 0)
unlink(file_name_old); //删除缓存文件
if(access(file_name_new, F_OK) == 0)
unlink(file_name_new);
if(btif_config_save_file(file_name_new)) //保存最新配置到file_name_new,上文讲过了,就是根节点遍历config node数据结构,然后写入xml文件中。
{
cached_change = 0;
chown(file_name_new, -1, AID_NET_BT_STACK);
chmod(file_name_new, 0660);
rename(file_name, file_name_old);
rename(file_name_new, file_name); //更新配置到file_name
ret = TRUE;
}
else BTIF_TRACE_ERROR0("btif_config_save_file failed");
return ret;
}
更多
1
- 9楼 andger032 2013-11-12 09:52发表 [回复]
- 上面:“4、调用hci接口,(替代4.1的hciattach进程?),给bt设备上电。”
我觉得应该不是调用hci接口,bt_hc_if->set_power这类的应该是调用蓝牙芯片厂商自己定义的接口。
- Re: woyaoxiazaibiefanwo 2013-12-28 17:03发表 [回复]
- 回复andger032:9楼理解的是对的bt_hc_if->set_power会进入芯片厂商给的一个.so的库文件,有的人能够拿到,能够跟到。
- 6楼 gordon1986 2013-09-17 09:38发表 [回复]
- 希望继续更新,谢谢
- 1楼 dearpenguin 2013-08-06 16:55发表 [回复]
- 博主,请教下bluedroid的transport layer 只能用H4吗?如果要用BCSP的话应该从何下手呢?多谢分享