# Porting a new Bluetooth stack into PebbleOS ## Build notes Unlike many other things in the build, a platform textually selects a Bluetooth controller using the `waf` environment variable, `conf.env.bt_controller`. This ends up pulling in a whole sublibrary (essentially), in `src/bluetooth-fw`. This is somewhat cleaner than the rest of the driver stack, but it is a change from what you might expect from the respect of PebbleOS! ## API surface A Bluetooth driver exports 70-ish APIs, and has a handful of callbacks that it needs to trigger at appropriate times. I group these below in terms of API families that one should implement, roughly in order of how critical it is to implement them to get anything at all working. ### Power and identity * bt_driver_init * bt_driver_start * bt_driver_stop * bt_driver_power_down_controller_on_boot * bt_driver_id_set_local_device_name * bt_driver_id_copy_local_identity_address * bt_driver_id_copy_chip_info_string * bt_driver_id_generate_private_resolvable_address * bt_driver_supports_bt_classic * bt_driver_set_local_address * bt_driver_comm_schedule_send_next_job -- you probably just want to have these run on KernelMain, unless you have your own thread that sends should happen from. copy from qemu * bt_driver_comm_is_current_task_send_next_task ### Advertising * bt_driver_adv_reconnect_get_job_terms * bt_driver_advert_advertising_disable * bt_driver_advert_client_get_tx_power * bt_driver_advert_set_advertising_data * bt_driver_advert_advertising_enable ### GAP * bt_driver_gap_le_disconnect * bt_driver_gap_le_device_name_request * bt_driver_gap_le_device_name_request_all * bt_driver_le_connection_parameter_update * bt_driver_handle_le_connection_handle_update_address_and_irk * bt_driver_handle_peer_version_info_event * bt_driver_handle_le_connection_complete_event * bt_driver_handle_le_disconnection_complete_event * bt_driver_handle_le_encryption_change_event * bt_driver_handle_le_conn_params_update_event ### Pairing and pairing service Bond database in-memory is managed by the controller. Bond database in flash is managed by the OS. * bt_driver_cb_pairing_confirm_handle_request -- a GAP LE connection wants to bond, post message to UI to say so * bt_driver_pairing_confirm -- UI agrees to do it * bt_driver_cb_pairing_confirm_handle_completed -- bond is complete, from BLE controller * bt_driver_handle_host_added_bonding -- OS has booted, add bond from in-flash database to in-controller database (make sure to kill these in bt_driver_stop when reinitting) * bt_driver_handle_host_removed_bonding -- user requested bond remove from UI * bt_driver_cb_handle_create_bonding -- controller has exchanged keys and would like OS to store a bond in flash ### Pebble Pairing Service Pebble Pairing Service is an internal GATT service managed not by the OS but by the controller (done in firmware on Dialog, obviously done as a Bluetopia client on TI). Implicit in this API is an init that actually sets up the Pebble Pairing Service, called within BLE stack! See at least one implementation: https://github.com/pebble-dev/RebbleOS/blob/master/hw/drivers/nrf52_bluetooth/nrf52_bluetooth_ppogatt.c#L352-L417 * bt_driver_pebble_pairing_service_handle_status_change * bt_driver_cb_pebble_pairing_service_handle_connection_parameter_write * bt_driver_cb_pebble_pairing_service_handle_ios_app_termination_detected ### GATT server / client shim * bt_driver_gatt_respond_read_subscription * bt_driver_gatt_send_changed_indication * bt_driver_gatt_start_discovery_range * bt_driver_gatt_stop_discovery * bt_driver_gatt_handle_discovery_abandoned * bt_driver_cb_gatt_client_discovery_handle_indication * bt_driver_cb_gatt_client_discovery_complete * bt_driver_cb_gatt_client_operations_handle_response * bt_driver_cb_gatt_service_changed_server_confirmation * bt_driver_cb_gatt_service_changed_server_subscribe * bt_driver_cb_gatt_service_changed_server_read_subscription * bt_driver_cb_gatt_client_discovery_handle_service_changed * bt_driver_gatt_write_without_response * bt_driver_gatt_write * bt_driver_gatt_read * bt_driver_cb_gatt_handle_connect * bt_driver_cb_gatt_handle_disconnect * bt_driver_cb_gatt_handle_mtu_update * bt_driver_cb_gatt_handle_notification * bt_driver_cb_gatt_handle_indication * bt_driver_cb_gatt_handle_buffer_empty ### Heart rate monitor The controller implements the GATT functionality for the heart rate monitor, rather than the OS. Not implemented on TI. * bt_driver_is_hrm_service_supported * bt_driver_cb_hrm_service_update_subscription * bt_driver_hrm_service_handle_measurement ### Scanning Scanning was only used by APIs that never became public. * bt_driver_start_le_scan * bt_driver_stop_le_scan * bt_driver_cb_le_scan_handle_report ### Bluetooth Classic These apply only to Bluetooth Classic and are no-ops on BLE. * bt_driver_classic_disconnect * bt_driver_classic_is_connected * bt_driver_classic_copy_connected_address * bt_driver_classic_copy_connected_device_name * bt_driver_classic_update_connectability * bt_driver_reconnect_pause * bt_driver_reconnect_resume * bt_driver_reconnect_try_now * bt_driver_reconnect_reset_interval * bt_driver_reconnect_notify_platform_bitfield * bt_driver_le_pairability_set_enabled -- not implemented even on Dialog * bt_driver_classic_pairability_set_enabled * sys_app_comm_get_sniff_interval ### Analytics * bt_driver_analytics_get_connection_quality * bt_driver_analytics_collect_ble_parameters * bt_driver_analytics_external_collect_chip_specific_parameters * bt_driver_analytics_external_collect_bt_chip_heartbeat * bt_driver_analytics_get_conn_event_stats * bluetooth_analytics_handle_ble_pairing_request (callback) ### Factory test mode / debugging. Implemented both by classic and BLE. Used for factory test. Probably needs to exist for production test in the future, but * bt_driver_test_selftest -- implemented * bt_driver_test_mfi_chip_selftest -- not implemented on LE-only * hc_endpoint_logging_set_level -- not implemented on TI * hc_endpoint_logging_get_level -- not implemented on TI * bt_driver_core_dump -- not implemented on TI * bt_driver_test_start * bt_driver_test_enter_hci_passthrough * bt_driver_test_handle_hci_passthrough_character * bt_driver_test_enter_rf_test_mode * bt_driver_test_set_spoof_address * bt_driver_test_stop Some drivers also have: * bt_driver_start_unmodulated_tx * bt_driver_stop_unmodulated_tx