hcid分析实际上就是蓝牙启动流程的分析。
先看用法:hcid [-n] [-d] [-m mtu] [-f config file]
进入main()函数:
1.hcid的一些默认设置,例如安全方式,名字等
init_defaults();
static inline void
init_device_defaults(struct device_opts *device_opts)
{
memset(device_opts, 0, sizeof(*device_opts));
device_opts->scan = SCAN_PAGE;
device_opts->mode = MODE_CONNECTABLE;
device_opts->name = g_strdup("BlueZ");
device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT;
}
2.分析命令行
while ((opt = getopt(argc, argv, "ndsm:xf:")) != EOF)
3.运行于后台,设置权限,并设置信号
if (daemonize && daemon(0, 0))
umask(0077);
4.创建并绑定hci socket
if ((hcid.sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
error("Can't open HCI socket: %s (%d)",
strerror(errno), errno);
exit(1);
}
if (bind(hcid.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
error("Can't bind HCI socket: %s (%d)",
strerror(errno), errno);
exit(1);
}
5.设置过滤
hci_filter_clear(&flt);
hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
hci_filter_set_event(EVT_STACK_INTERNAL, &flt);
if (setsockopt(hcid.sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
error("Can't set filter: %s (%d)",
strerror(errno), errno);
exit(1);
}
6.下载main.conf
config = load_config(CONFIGDIR "/main.conf");
if (read_config(hcid.config_file) < 0)
error("Config load failed");
7.添加IO通道
g_io_add_watch(child_io,
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
child_exit, NULL);
8.初始化适配器
init_adapters();
9.初始化agent
agent_init();
10.初始化dbus
if (hcid_dbus_init() < 0) {
error("Unable to get on D-Bus");
exit(1);
}
11.开始sdp服务
start_sdp_server(mtu, hcid.deviceid, SDP_SERVER_COMPAT);
12.初始化插件
plugin_init(config);
13.初始化安全数据
init_security_data();
14.初始化已连接的设备
init_all_devices(hcid.sock);
15.恢复,清理
hcid_dbus_unregister();
plugin_cleanup();
stop_sdp_server();
free_device_opts();
agent_exit();
hcid_dbus_exit();