3030#include "pybricks_service_server.h"
3131#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
3232
33+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
34+
35+ #include <errno.h>
36+ #include <poll.h>
37+
38+ #endif
39+
3340#ifdef PBDRV_CONFIG_BLUETOOTH_BTSTACK_HUB_KIND
3441#define HUB_KIND PBDRV_CONFIG_BLUETOOTH_BTSTACK_HUB_KIND
3542#else
3643#error "PBDRV_CONFIG_BLUETOOTH_BTSTACK_HUB_KIND is required"
3744#endif
3845
46+ #ifndef PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
47+ #define PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX 0
48+ #endif
49+
3950// location of product variant in bootloader flash memory of Technic Large hubs
4051#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_HUB_VARIANT_ADDR
4152#define HUB_VARIANT (*(const uint16_t *)PBDRV_CONFIG_BLUETOOTH_BTSTACK_HUB_VARIANT_ADDR)
@@ -223,23 +234,39 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
223234 pbdrv_bluetooth_peripheral_t * peri = & peripheral_singleton ;
224235 #endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
225236
237+ static pbdrv_bluetooth_btstack_device_discriminator device_info ;
238+
226239 switch (hci_event_packet_get_type (packet )) {
240+ case HCI_EVENT_TRANSPORT_USB_INFO : {
241+ // Store USB vendor and product IDs for later use
242+ device_info .usb_vendor_id = hci_event_transport_usb_info_get_vendor_id (packet );
243+ device_info .usb_product_id = hci_event_transport_usb_info_get_product_id (packet );
244+ break ;
245+ }
227246 case HCI_EVENT_COMMAND_COMPLETE : {
228247 const uint8_t * rp = hci_event_command_complete_get_return_parameters (packet );
229248 switch (hci_event_command_complete_get_command_opcode (packet )) {
230249 case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION : {
231- uint16_t lmp_pal_subversion = pbio_get_uint16_le (& rp [7 ]);
232- pbdrv_bluetooth_btstack_set_chipset (lmp_pal_subversion );
250+ device_info .hci_version = rp [0 ];
251+ device_info .hci_revision = pbio_get_uint16_le (& rp [1 ]);
252+ device_info .lmp_pal_version = rp [3 ];
253+ device_info .manufacturer = pbio_get_uint16_le (& rp [4 ]);
254+ device_info .lmp_pal_subversion = pbio_get_uint16_le (& rp [6 ]);
255+ pbdrv_bluetooth_btstack_set_chipset (& device_info );
233256
234257 #if DEBUG
235258 // Show version in ev3dev format.
259+ uint16_t lmp_pal_subversion = device_info .lmp_pal_subversion ;
236260 uint16_t chip = (lmp_pal_subversion & 0x7C00 ) >> 10 ;
237261 uint16_t min_ver = (lmp_pal_subversion & 0x007F );
238262 uint16_t maj_ver = (lmp_pal_subversion & 0x0380 ) >> 7 ;
239263 if (lmp_pal_subversion & 0x8000 ) {
240264 maj_ver |= 0x0008 ;
241265 }
242266 DEBUG_PRINT ("LMP %04x: TIInit_%d.%d.%d.bts\n" , lmp_pal_subversion , chip , maj_ver , min_ver );
267+ (void )maj_ver ; // In lib/pbio/test, this variable appears unused even though it's not.
268+ (void )min_ver ;
269+ (void )chip ;
243270 #endif
244271 break ;
245272 }
@@ -999,6 +1026,13 @@ static void bluetooth_btstack_run_loop_execute(void) {
9991026 // not used
10001027}
10011028
1029+ static bool do_poll_handler ;
1030+
1031+ void pbdrv_bluetooth_btstack_run_loop_trigger (void ) {
1032+ do_poll_handler = true;
1033+ pbio_os_request_poll ();
1034+ }
1035+
10021036static const btstack_run_loop_t bluetooth_btstack_run_loop = {
10031037 .init = btstack_run_loop_base_init ,
10041038 .add_data_source = btstack_run_loop_base_add_data_source ,
@@ -1011,14 +1045,10 @@ static const btstack_run_loop_t bluetooth_btstack_run_loop = {
10111045 .execute = bluetooth_btstack_run_loop_execute ,
10121046 .dump_timer = btstack_run_loop_base_dump_timer ,
10131047 .get_time_ms = pbdrv_clock_get_ms ,
1048+ .poll_data_sources_from_irq = pbdrv_bluetooth_btstack_run_loop_trigger ,
10141049};
10151050
1016- static bool do_poll_handler ;
10171051
1018- void pbdrv_bluetooth_btstack_run_loop_trigger (void ) {
1019- do_poll_handler = true;
1020- pbio_os_request_poll ();
1021- }
10221052
10231053static pbio_os_process_t pbdrv_bluetooth_hci_process ;
10241054
@@ -1028,9 +1058,57 @@ static pbio_os_process_t pbdrv_bluetooth_hci_process;
10281058 */
10291059static pbio_error_t pbdrv_bluetooth_hci_process_thread (pbio_os_state_t * state , void * context ) {
10301060
1031- if (do_poll_handler ) {
1061+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
1062+ int nfds = btstack_linked_list_count (& btstack_run_loop_base_data_sources );
1063+ struct pollfd fds [nfds ];
1064+ #endif
1065+
1066+ if (do_poll_handler || PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX ) {
10321067 do_poll_handler = false;
10331068 btstack_run_loop_base_poll_data_sources ();
1069+
1070+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
1071+ btstack_linked_list_iterator_t it ;
1072+ int i ;
1073+ for (i = 0 , btstack_linked_list_iterator_init (& it , & btstack_run_loop_base_data_sources );
1074+ btstack_linked_list_iterator_has_next (& it ); ++ i ) {
1075+ // cache pointer to next data_source to allow data source to remove itself
1076+ btstack_data_source_t * ds = (void * )btstack_linked_list_iterator_next (& it );
1077+
1078+ // In POSIX mode we must additionally identify data source FDs that
1079+ // are ready for reading or writing.
1080+ struct pollfd * pfd = & fds [i ];
1081+ pfd -> fd = ds -> source .fd ;
1082+ pfd -> events = 0 ;
1083+ if (ds -> flags & DATA_SOURCE_CALLBACK_READ ) {
1084+ pfd -> events |= POLLIN ;
1085+ }
1086+ if (ds -> flags & DATA_SOURCE_CALLBACK_WRITE ) {
1087+ pfd -> events |= POLLOUT ;
1088+ }
1089+
1090+ }
1091+
1092+ int err = poll (fds , nfds , 0 );
1093+ if (err < 0 ) {
1094+ DEBUG_PRINT ("btstack: poll() returned %d, ignoring\n" , errno );
1095+ } else if (err > 0 ) {
1096+ // Some fd was ready.
1097+ for (i = 0 , btstack_linked_list_iterator_init (& it , & btstack_run_loop_base_data_sources );
1098+ btstack_linked_list_iterator_has_next (& it ); ++ i ) {
1099+ btstack_data_source_t * ds = (void * )btstack_linked_list_iterator_next (& it );
1100+ struct pollfd * pfd = & fds [i ];
1101+ if (pfd -> revents & POLLIN ) {
1102+ ds -> process (ds , DATA_SOURCE_CALLBACK_READ );
1103+ } else if (pfd -> revents & POLLOUT ) {
1104+ ds -> process (ds , DATA_SOURCE_CALLBACK_WRITE );
1105+ } else if (pfd -> revents & POLLERR ) {
1106+ DEBUG_PRINT ("btstack: poll() error on fd %d\n" , pfd -> fd );
1107+ }
1108+ }
1109+
1110+ }
1111+ #endif
10341112 }
10351113
10361114 static pbio_os_timer_t btstack_timer = {
@@ -1065,9 +1143,12 @@ void pbdrv_bluetooth_init_hci(void) {
10651143 btstack_run_loop_init (& bluetooth_btstack_run_loop );
10661144
10671145 hci_init (pdata -> transport_instance (), pdata -> transport_config ());
1068- hci_set_chipset (pdata -> chipset_instance ());
1146+ if (pdata -> chipset_instance != NULL ) {
1147+ hci_set_chipset (pdata -> chipset_instance ());
1148+ }
10691149 hci_set_control (pdata -> control_instance ());
10701150
1151+
10711152 // REVISIT: do we need to call btstack_chipset_cc256x_set_power() or btstack_chipset_cc256x_set_power_vector()?
10721153
10731154 hci_event_callback_registration .callback = & packet_handler ;
0 commit comments