# 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_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
