通过上一章,我们知道,主机向控制器发送了复位命令,发起第一次传输:
btstack_chipset_intel_download_firmware
...
// get started
state = 0;
state_machine(NULL);
...
随后控制器将返回响应(事件)到主机,此时主函数已有执行:
// go
btstack_run_loop_execute();
the_run_loop->execute(); // --> btstack_run_loop_windows_execute
已经对注册到data_sources链表的struct btstack_data_source类型的成员的句柄进行事件监测,控制器一返回数据,对应struct btstack_data_source结构体类型的成员的process成员将被调用;
添加struct btstack_data_source类型的成员到链表data_sources,在打开usb设备中执行:
usb_open() //hci_transport_h2_winusb.c
...
usb_try_open_device();
...
// setup btstack data soures
usb_data_source_event_in.source.handle = usb_overlapped_event_in.hEvent;
btstack_run_loop_set_data_source_handler(&usb_data_source_event_in, &usb_process_event_in);
btstack_run_loop_add_data_source(&usb_data_source_event_in);
usb_data_source_command_out.source.handle = usb_overlapped_command_out.hEvent;
btstack_run_loop_set_data_source_handler(&usb_data_source_command_out, &usb_process_command_out);
btstack_run_loop_add_data_source(&usb_data_source_command_out);
usb_data_source_acl_in.source.handle = usb_overlapped_acl_in.hEvent;
btstack_run_loop_set_data_source_handler(&usb_data_source_acl_in, &usb_process_acl_in);
btstack_run_loop_add_data_source(&usb_data_source_acl_in);
usb_data_source_acl_out.source.handle = usb_overlapped_acl_out.hEvent;
btstack_run_loop_set_data_source_handler(&usb_data_source_acl_out, &usb_process_acl_out);
btstack_run_loop_add_data_source(&usb_data_source_acl_out);
...
usb_process_event_in定义如下:
static void usb_process_event_in(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
DWORD bytes_read;
BOOL ok = WinUsb_GetOverlappedResult(usb_interface_0_handle, &usb_overlapped_event_in, &bytes_read, FALSE);
if(!ok){
DWORD err = GetLastError();
if (err == ERROR_IO_INCOMPLETE){
// IO_INCOMPLETE -> wait for completed
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
} else {
log_error("usb_process_event_in: error reading");
}
return;
}
// notify uppper
packet_handler(HCI_EVENT_PACKET, hci_event_in_buffer, bytes_read);
// re-submit transfer
usb_submit_event_in_transfer();
}
这里关键是packet_handler的调用,packet_handler是一个局部的函数指针变量,通过usb_register_packet_handler函数设置:
static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = &usb_dummy_handler;
static void usb_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
log_info("registering packet handler");
packet_handler = handler;
}
还记得usb_register_packet_handler哪里被调用了么,没错!就是这里:
btstack_chipset_intel_download_firmware
...
transport->register_packet_handler(&transport_packet_handler);
...
transport_packet_handler定义如下:
static void transport_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
UNUSED(packet_type);
// we also get events with packet_type ACL from the controller
hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size);
switch (hci_event_packet_get_type(packet)){
case HCI_EVENT_COMMAND_COMPLETE:
case HCI_EVENT_VENDOR_SPECIFIC:
state_machine(packet);
break;
default:
break;
}
}
主机发出软复位命令后,控制器响应数据,此时packet的内容(0e 04 01 03 0c 00),并且此时state=1:
static void state_machine(uint8_t * packet){
if (packet){
...
// command complete
if (packet[0] == 0x0e){
waiting_for_command_complete = 0;
}
}
switch (state){
...
case 1:
// check if HCI Reset was supported
if (packet[0] == 0x0e && packet[1] == 0x04 && packet[3] == 0x03 && packet[4] == 0x0c && packet[5] == 0x00){
log_info("HCI Reset was successful, no need for firmware upload / or not an Intel chipset");
(*done)(0);
break;
}
// Read Intel Version
state++;
transport_send_cmd(&hci_intel_read_version);
break;
...
}
}
上面看到,全局函数指针done被运行,done已知被赋值为intel_firmware_done,定义如下:
static void intel_firmware_done(int result){
printf("Done %x\n", result);
// close
transport->close();
//
// init HCI
hci_init(transport, NULL);
#ifdef ENABLE_CLASSIC
hci_set_link_key_db(btstack_link_key_db_fs_instance());
#endif
// inform about BTstack state
hci_event_callback_registration.callback = &packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
// setup app
btstack_main(main_argc, main_argv);
}
这个函数做了如下几件大事:
intel_firmware_done
关闭usb设备,后面重新打开
transport->close();
hci_init(transport, NULL);
创建hci_stack并进行初始化
transport->register_packet_handler(&packet_handler); 重新注册了usb的回调函数
/*
static void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
hci_dump_packet(packet_type, 1, packet, size);
switch (packet_type) {
case HCI_EVENT_PACKET:
event_handler(packet, size);
break;
case HCI_ACL_DATA_PACKET:
acl_handler(packet, size);
break;
#ifdef ENABLE_CLASSIC
case HCI_SCO_DATA_PACKET:
sco_handler(packet, size);
break;
#endif
default:
break;
}
}
*/
这是上层应用的入口,上层应用可以是可client、service、可以是包含电池服务的外围设备或心跳服务的外围设备等等。
btstack_main(main_argc, main_argv);