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,21 @@ static void bluetooth_btstack_run_loop_execute(void) {
9991026 // not used
10001027}
10011028
1029+ static void bluetooth_btstack_run_loop_dump_timer (void ) {
1030+ // not used
1031+ }
1032+
1033+ static void bluetooth_btstack_run_loop_dump_timer (void ) {
1034+ // not used
1035+ }
1036+
1037+ static bool do_poll_handler ;
1038+
1039+ void pbdrv_bluetooth_btstack_run_loop_trigger (void ) {
1040+ do_poll_handler = true;
1041+ pbio_os_request_poll ();
1042+ }
1043+
10021044static const btstack_run_loop_t bluetooth_btstack_run_loop = {
10031045 .init = btstack_run_loop_base_init ,
10041046 .add_data_source = btstack_run_loop_base_add_data_source ,
@@ -1011,14 +1053,10 @@ static const btstack_run_loop_t bluetooth_btstack_run_loop = {
10111053 .execute = bluetooth_btstack_run_loop_execute ,
10121054 .dump_timer = btstack_run_loop_base_dump_timer ,
10131055 .get_time_ms = pbdrv_clock_get_ms ,
1056+ .poll_data_sources_from_irq = pbdrv_bluetooth_btstack_run_loop_trigger ,
10141057};
10151058
1016- static bool do_poll_handler ;
10171059
1018- void pbdrv_bluetooth_btstack_run_loop_trigger (void ) {
1019- do_poll_handler = true;
1020- pbio_os_request_poll ();
1021- }
10221060
10231061static pbio_os_process_t pbdrv_bluetooth_hci_process ;
10241062
@@ -1028,9 +1066,71 @@ static pbio_os_process_t pbdrv_bluetooth_hci_process;
10281066 */
10291067static pbio_error_t pbdrv_bluetooth_hci_process_thread (pbio_os_state_t * state , void * context ) {
10301068
1031- if (do_poll_handler ) {
1069+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
1070+ int nfds = btstack_linked_list_count (& data_sources );
1071+ struct pollfd fds [nfds ];
1072+ #endif
1073+
1074+ if (do_poll_handler || PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX ) {
10321075 do_poll_handler = false;
10331076 btstack_run_loop_base_poll_data_sources ();
1077+
1078+ btstack_data_source_t * ds , * next ;
1079+ for (ds = (void * )data_sources ; ds != NULL ; ds = next ) {
1080+ // cache pointer to next data_source to allow data source to remove itself
1081+ next = (void * )ds -> item .next ;
1082+ if (ds -> flags & DATA_SOURCE_CALLBACK_POLL ) {
1083+ ds -> process (ds , DATA_SOURCE_CALLBACK_POLL );
1084+ }
1085+ }
1086+
1087+ btstack_data_source_t * ds , * next ;
1088+ int i ;
1089+ for (i = 0 , ds = (void * )data_sources ; ds != NULL ; ++ i , ds = next ) {
1090+ // cache pointer to next data_source to allow data source to remove itself
1091+ next = (void * )ds -> item .next ;
1092+ if (ds -> flags & DATA_SOURCE_CALLBACK_POLL ) {
1093+ ds -> process (ds , DATA_SOURCE_CALLBACK_POLL );
1094+ }
1095+
1096+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
1097+ // In POSIX mode we must additionally identify data source FDs that
1098+ // are ready for reading or writing.
1099+ struct pollfd * pfd = & fds [i ];
1100+ pfd -> fd = ds -> source .fd ;
1101+ pfd -> events = 0 ;
1102+ if (ds -> flags & DATA_SOURCE_CALLBACK_READ ) {
1103+ pfd -> events |= POLLIN ;
1104+ }
1105+ if (ds -> flags & DATA_SOURCE_CALLBACK_WRITE ) {
1106+ pfd -> events |= POLLOUT ;
1107+ }
1108+ #endif
1109+ }
1110+
1111+ #if PBDRV_CONFIG_BLUETOOTH_BTSTACK_POSIX
1112+ int err = poll (fds , nfds , 0 );
1113+ if (err < 0 ) {
1114+ DEBUG_PRINT ("btstack: poll() returned %d, ignoring\n" , errno );
1115+ } else if (err > 0 ) {
1116+ // Some fd was ready.
1117+ btstack_linked_list_iterator_t it ;
1118+ int i ;
1119+ for (i = 0 , btstack_linked_list_iterator_init (& it , & data_sources );
1120+ btstack_linked_list_iterator_has_next (& it ); ++ i ) {
1121+ btstack_data_source_t * ds = (void * )btstack_linked_list_iterator_next (& it );
1122+ struct pollfd * pfd = & fds [i ];
1123+ if (pfd -> revents & POLLIN ) {
1124+ ds -> process (ds , DATA_SOURCE_CALLBACK_READ );
1125+ } else if (pfd -> revents & POLLOUT ) {
1126+ ds -> process (ds , DATA_SOURCE_CALLBACK_WRITE );
1127+ } else if (pfd -> revents & POLLERR ) {
1128+ DEBUG_PRINT ("btstack: poll() error on fd %d\n" , pfd -> fd );
1129+ }
1130+ }
1131+
1132+ }
1133+ #endif
10341134 }
10351135
10361136 static pbio_os_timer_t btstack_timer = {
@@ -1065,9 +1165,12 @@ void pbdrv_bluetooth_init_hci(void) {
10651165 btstack_run_loop_init (& bluetooth_btstack_run_loop );
10661166
10671167 hci_init (pdata -> transport_instance (), pdata -> transport_config ());
1068- hci_set_chipset (pdata -> chipset_instance ());
1168+ if (pdata -> chipset_instance != NULL ) {
1169+ hci_set_chipset (pdata -> chipset_instance ());
1170+ }
10691171 hci_set_control (pdata -> control_instance ());
10701172
1173+
10711174 // REVISIT: do we need to call btstack_chipset_cc256x_set_power() or btstack_chipset_cc256x_set_power_vector()?
10721175
10731176 hci_event_callback_registration .callback = & packet_handler ;
0 commit comments