Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

View file

@ -0,0 +1,21 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
typedef struct GAPLEAdvertisingJobTerm GAPLEAdvertisingJobTerm;
const GAPLEAdvertisingJobTerm *bt_driver_adv_reconnect_get_job_terms(size_t *num_terms_out);

View file

@ -0,0 +1,48 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "util/attributes.h"
#include <bluetooth/bluetooth_types.h>
#include <bluetooth/conn_event_stats.h>
#define NUM_LE_CHANNELS 37
typedef struct PACKED LEChannelMap {
uint8_t byte0;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
uint8_t byte4;
} LEChannelMap;
bool bt_driver_analytics_get_connection_quality(const BTDeviceInternal *address,
uint8_t *link_quality_out, int8_t *rssi_out);
bool bt_driver_analytics_collect_ble_parameters(const BTDeviceInternal *addr,
LEChannelMap *le_chan_map_res);
void bt_driver_analytics_external_collect_chip_specific_parameters(void);
void bt_driver_analytics_external_collect_bt_chip_heartbeat(void);
//! Returns true iff there are connection event stats to report
bool bt_driver_analytics_get_conn_event_stats(SlaveConnEventStats *stats);

View file

@ -0,0 +1,281 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "util/uuid.h"
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
//! Bluetooth error codes.
typedef enum {
//! The operation was successful.
BTErrnoOK = 0,
//! Connection established succesfully.
BTErrnoConnected = BTErrnoOK,
//! One or more parameters were invalid.
BTErrnoInvalidParameter = 1,
//! The connection was terminated because it timed out. Examples of cause for
//! a connection timeout are: devices going out of range of each other or
//! lost packets due to RF interference.
BTErrnoConnectionTimeout = 2,
//! The connection was terminated by the remote device.
BTErrnoRemotelyTerminated = 3,
//! The connection was terminated by the system.
BTErrnoLocallyTerminatedBySystem = 4,
//! The connection was terminated by the application.
BTErrnoLocallyTerminatedByApp = 5,
//! The system did not have enough resources for the operation.
BTErrnoNotEnoughResources = 6,
//! The remote device does not support pairing.
BTErrnoPairingNotSupported = 7,
//! The pairing failed because the user did not confirm.
BTErrnoPairingConfirmationFailed = 8,
//! The pairing failed because it timed out.
BTErrnoPairingTimeOut = 9,
//! The pairing failed because Out-of-Band data was not available.
BTErrnoPairingOOBNotAvailable = 10,
//! The requested operation cannot be performed in the current state.
BTErrnoInvalidState = 11,
//! GATT Service Discovery timed out
BTErrnoServiceDiscoveryTimeout = 12,
//! GATT Service Discovery failed due to disconnection
BTErrnoServiceDiscoveryDisconnected = 13,
//! GATT Service Discovery was restarted because the remote device indicated that it changed
//! its GATT database. Prior BLEService, BLECharacteristic and BLEDescriptor handles must be
//! invalidated when receiving this status code. The system will automatically start the
//! service discovery process again, therefore apps do not need to call
//! ble_client_discover_services_and_characteristics() again.
BTErrnoServiceDiscoveryDatabaseChanged = 14,
//! Errors after this value are internal Bluetooth stack errors that could not
//! be mapped onto more meaningful errors by the system.
BTErrnoInternalErrorBegin = 9000,
//! Errors after this fvalue are HCI errors that could not be mapped into more
//! meaningful errors by the system.
BTErrnoHCIErrorBegin = 10000,
//! Other, uncategorized error.
//! @internal This is also the highest allowed value (14 bits all set).
//! See PebbleBLEGATTClientEvent for why.
BTErrnoOther = 0x3fff,
} BTErrno;
//! Error values that can be returned by the server in response to read, write
//! and subscribe operations. These error values correspond to the (G)ATT error
//! codes as specified in the Bluetooth 4.0 Specification, Volume 3, Part F,
//! 3.4.1.1, Table 3.3.
typedef enum {
BLEGATTErrorSuccess = 0x00,
BLEGATTErrorInvalidHandle = 0x01,
BLEGATTErrorReadNotPermitted = 0x02,
BLEGATTErrorWriteNotPermitted = 0x03,
BLEGATTErrorInvalidPDU = 0x04,
BLEGATTErrorInsufficientAuthentication = 0x05,
BLEGATTErrorRequestNotSupported = 0x06,
BLEGATTErrorInvalidOffset = 0x07,
BLEGATTErrorInsufficientAuthorization = 0x08,
BLEGATTErrorPrepareQueueFull = 0x09,
BLEGATTErrorAttributeNotFound = 0x0A,
BLEGATTErrorAttributeNotLong = 0x0B,
BLEGATTErrorInsufficientEncrpytionKeySize = 0x0C,
BLEGATTErrorInvalidAttributeValueLength = 0x0D,
BLEGATTErrorUnlikelyError = 0x0E,
BLEGATTErrorInsufficientEncryption = 0x0F,
BLEGATTErrorUnsupportedGroupType = 0x10,
BLEGATTErrorInsufficientResources = 0x11,
BLEGATTErrorApplicationSpecificErrorStart = 0x80,
BLEGATTErrorApplicationSpecificErrorEnd = 0xFC,
BLEGATTErrorCCCDImproperlyConfigured = 0xFD,
BLEGATTErrorProcedureAlreadyInProgress = 0xFE,
BLEGATTErrorOutOfRange = 0xFF,
BLEGATTErrorRequestTimeOut = 0x100,
BLEGATTErrorRequestPrepareWriteDataMismatch = 0x101,
BLEGATTErrorLocalInsufficientResources = 0x102,
} BLEGATTError;
//! @internal Macro to map Bluetopia errors to BTErrno
#define BTErrnoWithBluetopiaError(e) ((int) BTErrnoInternalErrorBegin - e)
//! @internal Macro to map HCI errors to BTErrno
#define BTErrnoWithHCIError(e) ((int) BTErrnoHCIErrorBegin + e)
//! Property bits of a characteristic
//! See the Bluetooth 4.0 Specification, Volume 3, Part G,
//! 3.3.1.1 "Characteristic Properties" for more details.
//! @see ble_characteristic_get_properties
typedef enum {
BLEAttributePropertyNone = 0,
BLEAttributePropertyBroadcast = (1 << 0),
BLEAttributePropertyRead = (1 << 1),
BLEAttributePropertyWriteWithoutResponse = (1 << 2),
BLEAttributePropertyWrite = (1 << 3),
BLEAttributePropertyNotify = (1 << 4),
BLEAttributePropertyIndicate = (1 << 5),
BLEAttributePropertyAuthenticatedSignedWrites = (1 << 6),
BLEAttributePropertyExtendedProperties = (1 << 7),
// Properties for Characteristics & Descriptors that
// are hosted by the local server:
BLEAttributePropertyReadingRequiresEncryption = (1 << 8),
BLEAttributePropertyWritingRequiresEncryption = (1 << 9),
} BLEAttributeProperty;
//! Opaque reference to a service object.
typedef uintptr_t BLEService;
//! Opaque reference to a characteristic object.
typedef uintptr_t BLECharacteristic;
//! Opaque reference to a descriptor object.
typedef uintptr_t BLEDescriptor;
_Static_assert(sizeof(BLEDescriptor) == sizeof(uintptr_t), "BLEDescriptor is invalid size");
_Static_assert(sizeof(BLECharacteristic) == sizeof(uintptr_t), "BLECharacteristic is invalid size");
#define BLE_SERVICE_INVALID ((BLEService) 0)
#define BLE_CHARACTERISTIC_INVALID ((BLECharacteristic) 0)
#define BLE_DESCRIPTOR_INVALID ((BLEDescriptor) 0)
//! Identifier for a device bonding.
//! They stay the same across reboots, so they can be persisted by apps.
typedef uint8_t BTBondingID;
#define BT_BONDING_ID_INVALID ((BTBondingID) ~0)
typedef struct __attribute__((__packed__)) BTDeviceAddress {
uint8_t octets[6];
} BTDeviceAddress;
//! Size of a BTDeviceAddress struct
#define BT_DEVICE_ADDRESS_SIZE (sizeof(BTDeviceAddress))
//! Print format for printing BTDeviceAddress structs
//! @see BT_DEVICE_ADDRESS_XPLODE
#define BT_DEVICE_ADDRESS_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
#define BT_DEVICE_ADDRESS_FMT_BUFFER_SIZE (18)
#define BD_ADDR_FMT "0x%02X%02X%02X%02X%02X%02X"
#define BT_ADDR_FMT_BUFFER_SIZE_BYTES (15)
#define BT_DEVICE_NAME_BUFFER_SIZE (20)
//! Macro decompose a BTDeviceAddress struct into its parts, so it can be used
//! with the BT_DEVICE_ADDRESS_FMT format macro
#define BT_DEVICE_ADDRESS_XPLODE(a) \
(a).octets[5], (a).octets[4], (a).octets[3], \
(a).octets[2], (a).octets[1], (a).octets[0]
#define BT_DEVICE_ADDRESS_XPLODE_PTR(a) \
(a)->octets[5], (a)->octets[4], (a)->octets[3], \
(a)->octets[2], (a)->octets[1], (a)->octets[0]
//! Data structure that represents a remote Bluetooth device.
//! The fields of the structure are opaque. Its contents should not be changed
//! or relied upon by the application.
typedef struct BTDevice {
union {
uint32_t opaque[2];
uint64_t opaque_64;
};
} BTDevice;
//! @internal The internal layout of the opaque BTDevice. This should not be
//! exported. It can also never be changed in size. It has to be exactly as
//! large as the BTDevice struct.
typedef struct __attribute__((__packed__)) BTDeviceInternal {
union {
struct __attribute__((__packed__)) {
BTDeviceAddress address;
bool is_classic:1;
bool is_random_address:1;
//! !!! WARNING: If you're adding more flags here, you need to update
//! the bt_device_bits field in PebbleBLEGATTClientEvent and PebbleBLEConnectionEvent !!!
uint16_t zero:14;
};
BTDevice opaque;
};
} BTDeviceInternal;
#define BT_DEVICE_INVALID ((const BTDevice) {})
#define BT_DEVICE_INTERNAL_INVALID ((const BTDeviceInternal) {})
_Static_assert(sizeof(BTDeviceInternal) == sizeof(BTDevice),
"BTDeviceInternal should be equal in size to BTDevice");
//! Opaque data structure representing an advertisment report and optional
//! scan response. Use the ble_ad... functions to query its contents.
struct BLEAdData;
//! @internal
//! The maximum size in bytes of an advertising report.
#define GAP_LE_AD_REPORT_DATA_MAX_LENGTH (31)
//! Flags used in an LE Advertising packet. Listed in
//! Supplement to Bluetooth Core Specification | CSSv6, Part A, 1.3.1
#define GAP_LE_AD_FLAGS_LIM_DISCOVERABLE_MASK (1 << 0)
#define GAP_LE_AD_FLAGS_GEN_DISCOVERABLE_MASK (1 << 1)
#define GAP_LE_AD_FLAGS_BR_EDR_NOT_SUPPORTED_MASK (1 << 2)
#define GAP_LE_AD_FLAGS_LE_BR_EDR_SIMULT_CONTROLLER_MASK (1 << 3)
#define GAP_LE_AD_FLAGS_LE_BR_EDR_SIMULT_HOST_MASK (1 << 4)
#define LL_CONN_INTV_MIN_SLOTS (6) // 1.25ms / slot
#define LL_CONN_INTV_MAX_SLOTS (3200) // 1.25ms / slot
#define LL_SUPERVISION_TIMEOUT_MIN_MS (100)
//! Advertisment and scan response data
//! @internal Exported as forward struct
typedef struct BLEAdData {
//! Lengths of the raw advertisment data
uint8_t ad_data_length;
//! Lengths of the raw scan response data
uint8_t scan_resp_data_length;
//! The raw advertisement data, concatenated with the raw scan response data.
uint8_t data[0];
} BLEAdData;
//! Macro that does the same as bt_uuid_expand_32bit / bt_uuid_expand_16bit, but at compile-time
#define BT_UUID_EXPAND(u) \
(0xff & ((uint32_t) u) >> 24), \
(0xff & ((uint32_t) u) >> 16), \
(0xff & ((uint32_t) u) >> 8), \
(0xff & ((uint32_t) u) >> 0), \
0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0x80, \
0x5F, 0x9B, 0x34, 0xFB

View file

@ -0,0 +1,54 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "util/attributes.h"
#include <bluetooth/sm_types.h>
//! Packed, because this is serialized for the host-controller protocol.
typedef struct PACKED BleBonding {
SMPairingInfo pairing_info;
//! True if the remote device is capable of talking PPoGATT.
bool is_gateway:1;
//! True if the local device address should be pinned.
bool should_pin_address:1;
//! @note bt_persistent_storage_... uses only 5 bits to store this!
//! @see BleBondingFlag
uint8_t flags:5;
uint8_t rsvd:1;
//! Valid iff should_pin_address is true
BTDeviceAddress pinned_address;
} BleBonding;
//! Called by the FW after starting the Bluetooth stack to register existing bondings.
//! @note When the Bluetooth is torn down, there won't be any "remove" calls. If needed, the BT
//! driver lib should clean up itself in bt_driver_stop().
void bt_driver_handle_host_added_bonding(const BleBonding *bonding);
//! Called by the FW when a bonding is removed (i.e. user "Forgot" a bonding from Settings).
void bt_driver_handle_host_removed_bonding(const BleBonding *bonding);
//! Called by the BT driver after succesfully pairing a new device.
//! @param addr The address that is used to refer to the connection. This is used to associate
//! the bonding with the GAPLEConnection.
extern void bt_driver_cb_handle_create_bonding(const BleBonding *bonding,
const BTDeviceAddress *addr);

View file

@ -0,0 +1,41 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <bluetooth/bluetooth_types.h>
bool bt_driver_advert_advertising_enable(uint32_t min_interval_ms, uint32_t max_interval_ms,
bool enable_scan_resp);
void bt_driver_advert_advertising_disable(void);
bool bt_driver_advert_client_get_tx_power(int8_t *tx_power);
void bt_driver_advert_set_advertising_data(const BLEAdData *ad_data);
// FIXME: These are ugly. They are used because of the workarounds with the TI chips.
bool bt_driver_advert_is_connectable(void);
bool bt_driver_advert_client_has_cycled(void);
void bt_driver_advert_client_set_cycled(bool has_cycled);
bool bt_driver_advert_should_not_cycle(void);

View file

@ -0,0 +1,31 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
typedef struct CommSession CommSession;
//! Figures out the optimal thread to execute `bt_driver_run_send_next_job` on
//! and schedules a job to do so
bool bt_driver_comm_schedule_send_next_job(CommSession *session);
//! @return The PebbleTask that is used with bt_driver_comm_schedule_send_next_job() to perform
//! the sending of pending data.
bool bt_driver_comm_is_current_task_send_next_task(void);
extern void bt_driver_run_send_next_job(CommSession *session, bool is_callback);

View file

@ -0,0 +1,67 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <bluetooth/bluetooth_types.h>
#include <bluetooth/hci_types.h>
#include <stdbool.h>
void bt_driver_test_start(void);
void bt_driver_test_enter_hci_passthrough(void);
void bt_driver_test_handle_hci_passthrough_character(char c, bool *should_context_switch);
bool bt_driver_test_enter_rf_test_mode(void);
void bt_driver_test_set_spoof_address(const BTDeviceAddress *addr);
void bt_driver_test_stop(void);
bool bt_driver_test_selftest(void);
bool bt_driver_test_mfi_chip_selftest(void);
void bt_driver_le_transmitter_test(
uint8_t tx_channel, uint8_t tx_packet_length, uint8_t packet_payload);
void bt_driver_le_test_end(void);
void bt_driver_le_receiver_test(uint8_t rx_channel);
typedef void (*BTDriverResponseCallback)(HciStatusCode status, const uint8_t *payload);
void bt_driver_register_response_callback(BTDriverResponseCallback callback);
void bt_driver_start_unmodulated_tx(uint8_t tx_channel);
void bt_driver_stop_unmodulated_tx(void);
typedef enum BtlePaConfig {
BtlePaConfig_Disable,
BtlePaConfig_Enable,
BtlePaConfig_Bypass,
BtlePaConfigCount
} BtlePaConfig;
void bt_driver_le_test_pa(BtlePaConfig option);
typedef enum BtleCoreDump {
BtleCoreDump_UserRequest,
BtleCoreDump_ForceHardFault,
BtleCoreDump_Watchdog,
BtleCoreDumpCount
} BtleCoreDump;
void bt_driver_core_dump(BtleCoreDump type);
void bt_driver_send_sleep_test_cmd(bool force_ble_sleep);

View file

@ -0,0 +1,30 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <bluetooth/bluetooth_types.h>
#include <stdbool.h>
//! @param address Pass NULL to disconnect the "active" remote.
void bt_driver_classic_disconnect(const BTDeviceAddress* address);
bool bt_driver_classic_is_connected(void);
bool bt_driver_classic_copy_connected_address(BTDeviceAddress* address);
bool bt_driver_classic_copy_connected_device_name(char name[BT_DEVICE_NAME_BUFFER_SIZE]);

View file

@ -0,0 +1,29 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
typedef struct SlaveConnEventStats {
uint32_t num_conn_events; // BLE Connection Events that have elapsed
uint32_t num_conn_events_skipped; // The number of events the controller never tried to listen for
uint32_t num_sync_errors; // Events where slave did not see a packet from Master
uint32_t num_type_errors;
uint32_t num_len_errors;
uint32_t num_crc_errors; // Events that ended due to a packet CRC error
uint32_t num_mic_errors; // Events that ended due to a packet MIC error
} SlaveConnEventStats;

View file

@ -0,0 +1,21 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
void bt_driver_classic_update_connectability(void);

View file

@ -0,0 +1,39 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include "util/attributes.h"
// The reason the headers that define these lengths aren't included is because this header
// is included by the various number of bt_driver implementations. They don't know what "mfg"
// is, etc.
// NOTE: These sizes are asserted in a .c file to be in sync with the FW
#define MODEL_NUMBER_LEN (10) // MFG_HW_VERSION_SIZE + 1
#define MANUFACTURER_LEN (18) // sizeof("Pebble Technology")
#define SERIAL_NUMBER_LEN (13) // MFG_SERIAL_NUMBER_SIZE + 1
#define FW_REVISION_LEN (32) // FW_METADATA_VERSION_TAG_BYTES)
#define SW_REVISION_LEN (6) // Fmt: xx.xx\0
typedef struct PACKED DisInfo {
char model_number[MODEL_NUMBER_LEN];
char manufacturer[MANUFACTURER_LEN];
char serial_number[SERIAL_NUMBER_LEN];
char fw_revision[FW_REVISION_LEN];
char sw_revision[SW_REVISION_LEN];
} DisInfo;

View file

@ -0,0 +1,21 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
bool bt_driver_supports_bt_classic(void);

View file

@ -0,0 +1,29 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "comm/ble/gap_le_advert.h"
//! @note The client should hold the `bt_lock` when calling these functions.
//! Also note that these functions are a workaround and should ideally not be used.
//! They are kept around to assist with a bug in the TI Bluetooth chips.
extern GAPLEAdvertisingJobRef gap_le_advert_get_current_job(void);
extern GAPLEAdvertisingJobRef gap_le_advert_get_jobs(void);
extern GAPLEAdvertisingJobTag gap_le_advert_get_job_tag(GAPLEAdvertisingJobRef job);

View file

@ -0,0 +1,124 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <inttypes.h>
#include <bluetooth/bluetooth_types.h>
#include <bluetooth/sm_types.h>
#include "util/attributes.h"
#include "bluetooth/hci_types.h"
#include "util/attributes.h"
typedef enum BleAddressType {
BleAddressType_Public,
BleAddressType_Random
} BleAddressType;
#ifndef __clang__
_Static_assert(sizeof(BleAddressType) == 1, "BleAddressType is not 1 byte in size");
#endif
// All values in ms
// Used for ConnectionCompleteEvents
typedef struct PACKED BleConnectionParams {
uint16_t conn_interval_1_25ms;
uint16_t slave_latency_events;
uint16_t supervision_timeout_10ms;
} BleConnectionParams;
// Matches data from "LL_VERSION_IND" - v4.2 2.4.2.13
typedef struct PACKED BleRemoteVersionInfo {
uint8_t version_number;
uint16_t company_identifier;
uint16_t subversion_number;
} BleRemoteVersionInfo;
typedef struct PACKED BleRemoteVersionInfoReceivedEvent {
BTDeviceInternal peer_address;
BleRemoteVersionInfo remote_version_info;
} BleRemoteVersionInfoReceivedEvent;
// Structs providing data from various Ble Events. I attempted to comment below
// what section of the BT Core Spec more info about the event can be found
// "LE Connection Complete Event" - v4.2 7.7.65.1
typedef struct PACKED BleConnectionCompleteEvent {
BleConnectionParams conn_params;
BTDeviceInternal peer_address;
HciStatusCode status;
bool is_master;
bool is_resolved;
SMIdentityResolvingKey irk;
uint16_t handle;
} BleConnectionCompleteEvent;
// "Disconnection Complete Event" - v4.2 7.7.5
typedef struct PACKED BleDisconnectionCompleteEvent {
BTDeviceInternal peer_address;
HciStatusCode status;
HciDisconnectReason reason;
uint16_t handle;
} BleDisconnectionCompleteEvent;
// "LE Connection Update Complete Event" - v4.2 7.7.65.3
typedef struct PACKED BleConnectionUpdateCompleteEvent {
BleConnectionParams conn_params;
//! Using BTDeviceAddress instead of BTDeviceInternal, because Bluetopia's event doesn't contain
//! the address type.
BTDeviceAddress dev_address;
HciStatusCode status;
} BleConnectionUpdateCompleteEvent; // 7.7.65.3
// Note: This will likely change to work with Dialog
// "Encryption Change Event" - v4.2 7.7.8
typedef struct PACKED BleEncryptionChange {
//! Using BTDeviceAddress instead of BTDeviceInternal, because Bluetopia's event doesn't contain
//! the address type.
BTDeviceAddress dev_address;
HciStatusCode status;
bool encryption_enabled;
} BleEncryptionChange;
typedef struct PACKED BleAddressAndIRKChange {
//! Current (or old in case is_address_updated == true) device address info.
BTDeviceInternal device;
//! True if the "new_device" field is valid and underlying stack started using a different address
//! to refer to the connection.
bool is_address_updated;
BTDeviceInternal new_device;
//! True if the "irk" field is valid
bool is_resolved;
SMIdentityResolvingKey irk;
} BleAddressAndIRKChange;
//! Bluetooth LE GAP Connection Driver APIs
int bt_driver_gap_le_disconnect(const BTDeviceInternal *peer_address);
// Callbacks invoked by the bt_driver regarding different BLE Events. It is expected that consumers
// of this module provide an implementation for these callbacks
extern void bt_driver_handle_le_connection_complete_event(const BleConnectionCompleteEvent *event);
extern void bt_driver_handle_le_disconnection_complete_event(
const BleDisconnectionCompleteEvent *event);
extern void bt_driver_handle_le_encryption_change_event(const BleEncryptionChange *event);
extern void bt_driver_handle_le_conn_params_update_event(
const BleConnectionUpdateCompleteEvent *event);
extern void bt_driver_handle_le_connection_handle_update_address_and_irk(
const BleAddressAndIRKChange *e);
extern void bt_driver_handle_peer_version_info_event(const BleRemoteVersionInfoReceivedEvent *e);

View file

@ -0,0 +1,27 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "comm/ble/gap_le_connection.h"
//! Bluetooth LE GAP Device name APIs
void bt_driver_gap_le_device_name_request_all(void);
void bt_driver_gap_le_device_name_request(const BTDeviceInternal *address);
//! The caller is expected to have implemented:
//! ctx will be kernel_free()'d
void bt_driver_store_device_name_kernelbg_cb(void *ctx);

View file

@ -0,0 +1,30 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <inttypes.h>
#include "comm/ble/gap_le_scan.h"
//! Returns true on success, false on failure
bool bt_driver_start_le_scan(bool active_scan, bool use_white_list_filter, bool filter_dups,
uint16_t scan_interval_ms, uint16_t scan_window_ms);
//! Returns true on success, false on failure
bool bt_driver_stop_le_scan(void);
extern void bt_driver_cb_le_scan_handle_report(const GAPLERawAdReport *data, int length);

View file

@ -0,0 +1,164 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <inttypes.h>
#include <bluetooth/bluetooth_types.h>
#include <bluetooth/gatt_discovery.h>
#include <bluetooth/hci_types.h>
#include "comm/ble/gap_le_connection.h"
#include "comm/ble/gatt_client_accessors.h"
#include "util/attributes.h"
// -- Gatt Device/Server Events
#define GATT_SERVICE_UUID ((uint16_t) 0x1801)
#define GATT_SERVICE_CHANGED_CHARACTERISTIC_UUID ((uint16_t) 0x2A05)
#define GATT_CCCD_UUID ((uint16_t) 0x2902)
//! Using BTDeviceAddress instead of BTDeviceInternal, with all these events, because Bluetopia's
//! events doesn't contain the address type.
typedef struct GattDeviceConnectionEvent {
BTDeviceAddress dev_address;
uint32_t connection_id;
uint16_t mtu;
} GattDeviceConnectionEvent;
typedef struct GattDeviceDisconnectionEvent {
BTDeviceAddress dev_address;
} GattDeviceDisconnectionEvent;
typedef struct GattDeviceBufferEmptyEvent {
BTDeviceAddress dev_address;
} GattDeviceBufferEmptyEvent;
typedef struct GattServerNotifIndicEvent {
BTDeviceAddress dev_address;
uint16_t attr_handle;
uint16_t attr_val_len;
uint8_t *attr_val;
void *context;
} GattServerNotifIndicEvent;
typedef struct GattDeviceMtuUpdateEvent {
BTDeviceAddress dev_address;
uint16_t mtu;
} GattDeviceMtuUpdateEvent;
// -- Service Changed Events
typedef struct GattServerChangedConfirmationEvent {
BTDeviceAddress dev_address;
uint32_t connection_id;
uint32_t transaction_id;
HciStatusCode status_code;
} GattServerChangedConfirmationEvent;
typedef struct GattServerReadSubscriptionEvent {
BTDeviceAddress dev_address;
uint32_t connection_id;
uint32_t transaction_id;
} GattServerReadSubscriptionEvent;
typedef struct GattServerSubscribeEvent {
BTDeviceAddress dev_address;
uint32_t connection_id;
bool is_subscribing;
} GattServerSubscribeEvent;
// -- Gatt Client Operations
typedef enum GattClientOpResponseType {
GattClientOpResponseRead,
GattClientOpResponseWrite,
} GattClientOpResponseType;
typedef struct GattClientOpResponseHdr {
GattClientOpResponseType type;
BLEGATTError error_code;
void *context;
} GattClientOpResponseHdr;
typedef struct GattClientOpReadReponse {
GattClientOpResponseHdr hdr;
uint16_t value_length;
uint8_t *value;
} GattClientOpReadReponse;
typedef struct GattClientOpWriteReponse {
GattClientOpResponseHdr hdr;
} GattClientOpWriteReponse;
// -- Gatt Data Structures
void bt_driver_gatt_acknowledge_indication(uint32_t connection_id, uint32_t transaction_id);
// TODO: This will probably need to be changed for the Dialog chip (doesn't have transaction ids)
void bt_driver_gatt_respond_read_subscription(uint32_t transaction_id, uint16_t response_code);
void bt_driver_gatt_send_changed_indication(uint32_t connection_id, const ATTHandleRange *data);
BTErrno bt_driver_gatt_write_without_response(GAPLEConnection *connection,
const uint8_t *value,
size_t value_length,
uint16_t att_handle);
BTErrno bt_driver_gatt_write(GAPLEConnection *connection,
const uint8_t *value,
size_t value_length,
uint16_t att_handle,
void *context);
BTErrno bt_driver_gatt_read(GAPLEConnection *connection,
uint16_t att_handle,
void *context);
//! The following are callbacks that the bt_driver implementation will call when handling events.
//! gatt callbacks
extern void bt_driver_cb_gatt_handle_connect(const GattDeviceConnectionEvent *event);
extern void bt_driver_cb_gatt_handle_disconnect(const GattDeviceDisconnectionEvent *event);
extern void bt_driver_cb_gatt_handle_buffer_empty(const GattDeviceBufferEmptyEvent *event);
extern void bt_driver_cb_gatt_handle_mtu_update(const GattDeviceMtuUpdateEvent *event);
extern void bt_driver_cb_gatt_handle_notification(const GattServerNotifIndicEvent *event);
//! @NOTE: The indication is unconditionally confirmed within the bt_driver as soon as one is
//! received.
extern void bt_driver_cb_gatt_handle_indication(const GattServerNotifIndicEvent *event);
//! gatt_service_changed callbacks
extern void bt_driver_cb_gatt_service_changed_server_confirmation(
const GattServerChangedConfirmationEvent *event);
extern void bt_driver_cb_gatt_service_changed_server_subscribe(
const GattServerSubscribeEvent *event);
extern void bt_driver_cb_gatt_service_changed_server_read_subscription(
const GattServerReadSubscriptionEvent *event);
extern void bt_driver_cb_gatt_client_discovery_handle_service_changed(GAPLEConnection *connection,
uint16_t handle);
extern void bt_driver_cb_gatt_client_operations_handle_response(GattClientOpResponseHdr *event);

View file

@ -0,0 +1,43 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <bluetooth/bluetooth_types.h>
#include <bluetooth/gatt_service_types.h>
#include <util/attributes.h>
#include <stdint.h>
typedef struct GAPLEConnection GAPLEConnection;
typedef struct GATTService GATTService;
typedef struct GATTServiceNode GATTServiceNode;
BTErrno bt_driver_gatt_start_discovery_range(
const GAPLEConnection *connection, const ATTHandleRange *data);
BTErrno bt_driver_gatt_stop_discovery(GAPLEConnection *connection);
//! It's possible we are disconnected or the stack gets torn down while in the
//! middle of a discovery. This routine gets invoked if the connection gets
//! torn down or goes away so that the implementation can clean up any tracking
//! it has waiting for a discovery to complete
void bt_driver_gatt_handle_discovery_abandoned(void);
//! gatt_service_discovery callbacks
//! cb returns true iff the driver completed, false if a discovery retry was initiated
extern bool bt_driver_cb_gatt_client_discovery_complete(GAPLEConnection *connection, BTErrno errno);
extern void bt_driver_cb_gatt_client_discovery_handle_indication(
GAPLEConnection *connection, GATTService *service_discovered, BTErrno error);

View file

@ -0,0 +1,114 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <util/uuid.h>
#include <stddef.h>
#include <stdint.h>
#include <util/attributes.h>
//! Below are the data structures to store information about a *remote* GATT
//! service and its characteristics and descriptors.
//!
//! It's designed for compactness and ease of serialization, at the cost of
//! CPU cycles to iterate over and access the data.
//! The GATTCharacteristic are tacked at the end of the struct. At the end of
//! each GATTCharacteristic, its descriptors are tacked on. Lastly, after all
//! the characteristics, an array of Included Service handles is tacked on.
//! Struct packing is not enabled at the moment, but could be if needed.
//! Handles for the Characteristics and Descriptors are stored as offsets from
//! the parent service handle to save one byte per characteristic.
//!
//! Ideas for more memory footprint optimizations:
//! - Create a shared list of UUIDs that can be referenced,
//! to avoid wasting 16 bytes of RAM per service, characteristic and descriptor?
typedef struct PACKED ATTHandleRange {
uint16_t start;
uint16_t end;
} ATTHandleRange;
//! Common header for GATTDescriptor, GATTCharacteristic and GATTService
typedef struct {
Uuid uuid;
} GATTObjectHeader;
typedef struct {
//! The UUID of the descriptor
Uuid uuid;
//! The offset of the handle with respect to service.att_handle
uint8_t att_handle_offset;
} GATTDescriptor;
_Static_assert(offsetof(GATTDescriptor, uuid) == offsetof(GATTObjectHeader, uuid), "");
typedef struct {
//! The UUID of the characteristic
Uuid uuid;
//! The offset of the handle with respect to service.att_handle
uint8_t att_handle_offset;
uint8_t properties;
uint8_t num_descriptors;
GATTDescriptor descriptors[];
} GATTCharacteristic;
_Static_assert(offsetof(GATTCharacteristic, uuid) == offsetof(GATTObjectHeader, uuid), "");
typedef struct GATTService {
//! The UUID of the service
Uuid uuid;
uint8_t discovery_generation;
//! The size in bytes of the GATTService blob, including all its
//! characteristics, descriptors and included service handles.
uint16_t size_bytes;
//! The ATT handle of the service
uint16_t att_handle;
//! Number of characteristics in the array
//! @note because GATTCharacteristic is variable length, it is not possible
//! to use array subscripting.
uint8_t num_characteristics;
//! The total number of descriptors in the service
uint8_t num_descriptors;
//! Size of the att_handles_included_services array
uint8_t num_att_handles_included_services;
//! Array with the characteristics of the service
GATTCharacteristic characteristics[];
//! Array with the ATT handles of Included Services
//! This array follows after the characteristics, when
//! num_att_handles_included_services > 0
//! uint16_t att_handles_included_services[];
} GATTService;
_Static_assert(offsetof(GATTService, uuid) == offsetof(GATTObjectHeader, uuid), "");
#define COMPUTE_GATTSERVICE_SIZE_BYTES(num_chars, num_descs, num_includes) \
(sizeof(GATTService) + sizeof(GATTCharacteristic) * (num_chars) + \
sizeof(GATTDescriptor) * (num_descs) + sizeof(uint16_t) * (num_includes))

View file

@ -0,0 +1,33 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
typedef enum {
HciStatusCode_Success = 0x00,
HciStatusCode_UnknownConnectionIdentifier = 0x02,
HciStatusCode_VS_Base = 0x50,
HciStatusCode_Max = UINT16_MAX
} HciStatusCode;
#ifndef __clang__
_Static_assert(sizeof(HciStatusCode) == 2, "packed structs expect the status code to be 2 bytes!");
#endif
// disconnect reasons are just status codes
typedef HciStatusCode HciDisconnectReason;

View file

@ -0,0 +1,43 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <bluetooth/bluetooth_types.h>
typedef struct {
uint16_t bpm;
bool is_on_wrist;
} BleHrmServiceMeasurement;
//! @return True if the BT driver lib supports exposing the GATT HRM service.
bool bt_driver_is_hrm_service_supported(void);
//! Adds or removes the HRM service from the GATT database, notifying any connected devices
//! by sending a "Service Changed" indication for the mutated handle range.
void bt_driver_hrm_service_enable(bool enable);
//! Sends the Heart Rate Measurement to all subscribed & connected devices.
void bt_driver_hrm_service_handle_measurement(const BleHrmServiceMeasurement *measurement,
const BTDeviceInternal *permitted_devices,
size_t num_permitted_devices);
//! Called when a connected device (un)subscribes to the GATT HRM service's "Heart Rate Measurement"
//! characteristic.
extern void bt_driver_cb_hrm_service_update_subscription(const BTDeviceInternal *device,
bool is_subscribed);

View file

@ -0,0 +1,42 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <bluetooth/bluetooth_types.h>
void bt_driver_id_set_local_device_name(const char device_name[BT_DEVICE_NAME_BUFFER_SIZE]);
void bt_driver_id_copy_local_identity_address(BTDeviceAddress *addr_out);
//! Configures the local address that the BT driver should use "on-air".
//! @note This address and the identity address are different things!
//! @note bt_lock() is held when this call is made.
//! @param allow_cycling True if the controller is allowed to cycle the address (implies address
//! pinning is *not* used!)
//! @param pinned_address The address to use, or NULL for "don't care".
void bt_driver_set_local_address(bool allow_cycling,
const BTDeviceAddress *pinned_address);
//! Copies a human-readable string of freeform info that uniquely identifies the Bluetooth chip.
//! Used by MFG for part tracking purposes.
//! @param[out] dest Buffer into which to copy the info.
//! @param[in] dest_size Size of dest in bytes.
void bt_driver_id_copy_chip_info_string(char *dest, size_t dest_size);
//! Generates a new private resolvable address using the current IRK (as passed with the
//! bt_driver_start() call when setting up the stack).
bool bt_driver_id_generate_private_resolvable_address(BTDeviceAddress *address_out);

View file

@ -0,0 +1,46 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "util/attributes.h"
#include <bluetooth/sm_types.h>
#include <bluetooth/dis.h>
#include <stdbool.h>
typedef struct PACKED BTDriverConfig {
SM128BitKey root_keys[SMRootKeyTypeNum];
DisInfo dis_info;
BTDeviceAddress identity_addr;
bool is_hrm_supported_and_enabled;
} BTDriverConfig;
//! Function that performs one-time initialization of the BT Driver.
//! The main FW is expected to call this once at boot.
void bt_driver_init(void);
//! Starts the Bluetooth stack.
//! @return True if the stack started successfully.
bool bt_driver_start(BTDriverConfig *config);
//! Stops the Bluetooth stack.
//! @return True if the stack stopped successfully.
void bt_driver_stop(void);
//! Powers down the BT controller if has yet to be used
void bt_driver_power_down_controller_on_boot(void);

View file

@ -0,0 +1,29 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#if BT_CONTROLLER_DA14681
// Larger MTU sizes appear to have a more considerable impact on throughput than one would expect
// (theoretical gain from 158 bytes - 512 bytes should only be ~3% but we are seeing up to ~30%
// bumps). More investigation needs to be done to understand exactly why. For now, let's bump the
// size so Android phones which support large MTUs can leverage it
#define ATT_MAX_SUPPORTED_MTU (339)
#else
// It's 158 bytes now because that's the maximum payload iOS 8 allows.
// On legacy products, only iOS uses LE so stick with this max buffer size
#define ATT_MAX_SUPPORTED_MTU (158)
#endif

View file

@ -0,0 +1,23 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
void bt_driver_le_pairability_set_enabled(bool enabled);
void bt_driver_classic_pairability_set_enabled(bool enabled);

View file

@ -0,0 +1,49 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
//! Forward declaration to internal, implementation specific state.
typedef struct PairingUserConfirmationCtx PairingUserConfirmationCtx;
//! Confirms a pairing request.
//! @param[in] ctx The pairing request context, as previously passed to
//! bt_driver_cb_pairing_confirm_handle_request.
//! @param[in] is_confirmed Pass true if the user confirmed the pairing.
void bt_driver_pairing_confirm(const PairingUserConfirmationCtx *ctx,
bool is_confirmed);
//! @param[in] ctx Pointer to opaque BT-driver-implementation specific context. The function can
//! use the pointer value this to distinguish one pairing process from another, but the pointer
//! should NOT be dereferenced by the FW side. Aside the fact that the struct is internal to
//! the FW and therefore shouldn't be able to look inside it, the memory can be free'd at all times
//! by the BT driver implementation. For example when the pairing process times out, the BT driver
//! might free the memory that ctx is pointing to.
//! @param[in] device_name Optional device name of the device that is attempting to pair. Pass NULL
//! if the device name is not available.
//! @param[in] confirmation_token Optional confirmation token. Pass NULL if not available.
//! @note This function should immediately copy the device name and confirmation token, so the
//! buffers do not have to continue existing after this function returns.
extern void bt_driver_cb_pairing_confirm_handle_request(const PairingUserConfirmationCtx *ctx,
const char *device_name,
const char *confirmation_token);
//! @param[in] ctx See bt_driver_cb_pairing_confirm_handle_request
//! @param[in] success True if the pairing process finished successfully.
extern void bt_driver_cb_pairing_confirm_handle_completed(const PairingUserConfirmationCtx *ctx,
bool success);

View file

@ -0,0 +1,71 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
#include "util/uuid.h"
//! @file This file contains Pebble-specific Bluetooth identifiers (numbers, UUIDs, etc.)
//! Also see https://pebbletechnology.atlassian.net/wiki/display/DEV/Pebble+GATT+Services
//! Bluetopia does not contain our Vendor ID, yet.
//! See Bluetooth Company Identifiers:
//! http://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm
//! Be careful not to use with with BT Classic! See sdp.c why.
#define PEBBLE_BT_VENDOR_ID (0x0154)
//! Our Bluetooth-SIG-Registered 16-bit UUID:
//! Pebble Technology Corporation
//! Pebble Smartwatch Service
#define PEBBLE_BT_PAIRING_SERVICE_UUID_16BIT (0xFED9)
//! The Service UUID of the "Pebble Protocol over GATT" (PPoGATT) service.
//! This UUID needs to be expanded using the Pebble Base UUID (@see pebble_bt_uuid_expand)
#define PEBBLE_BT_PPOGATT_SERVICE_UUID_32BIT (0x10000000)
#define PEBBLE_BT_PPOGATT_DATA_CHARACTERISTIC_UUID_32BIT (0x10000001)
#define PEBBLE_BT_PPOGATT_META_CHARACTERISTIC_UUID_32BIT (0x10000002)
//! The Service UUID of the "Pebble Protocol over GATT" (PPoGATT) service that the watch
//! publishes to operate as a Server instead of it's normal client role. This allows certain
//! sad Android phones to communicate with the watch
#define PEBBLE_BT_PPOGATT_WATCH_SERVER_SERVICE_UUID_32BIT (0x30000003)
#define PEBBLE_BT_PPOGATT_WATCH_SERVER_DATA_CHARACTERISTIC_UUID_32BIT (0x30000004)
#define PEBBLE_BT_PPOGATT_WATCH_SERVER_META_CHARACTERISTIC_UUID_32BIT (0x30000005)
#define PEBBLE_BT_PPOGATT_WATCH_SERVER_DATA_WR_CHARACTERISTIC_UUID_32BIT (0x30000006)
//! The Service UUID of the "Pebble App Launch" service.
//! This UUID needs to be expanded using the Pebble Base UUID (@see pebble_bt_uuid_expand)
#define PEBBLE_BT_APP_LAUNCH_SERVICE_UUID_32BIT (0x20000000)
#define PEBBLE_BT_APP_LAUNCH_CHARACTERISTIC_UUID_32BIT (0x20000001)
//! Assigns a 32-bit (or 16-bit) UUID that is based on the Pebble Base UUID,
//! XXXXXXXX-328E-0FBB-C642-1AA6699BDADA.
//! @param uuid The UUID storage to assign the constructed UUID to.
//! @param value The 32-bit (or 16-bit) UUID value to use.
//! @see bt_uuid_expand_32bit and bt_uuid_expand_16bit for functions that expand
//! using the BT SIG's Base UUID.
void pebble_bt_uuid_expand(Uuid *uuid, uint32_t value);
//! Macro that does the same as pebble_bt_uuid_expand, but then at compile-time
#define PEBBLE_BT_UUID_EXPAND(u) \
(0xff & ((uint32_t) u) >> 24), \
(0xff & ((uint32_t) u) >> 16), \
(0xff & ((uint32_t) u) >> 8), \
(0xff & ((uint32_t) u) >> 0), \
0x32, 0x8E, 0x0F, 0xBB, \
0xC6, 0x42, 0x1A, 0xA6, \
0x69, 0x9B, 0xDA, 0xDA

View file

@ -0,0 +1,248 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "util/attributes.h"
#include <bluetooth/pebble_bt.h>
#include <bluetooth/responsiveness.h>
#define PEBBLE_BT_PAIRING_SERVICE_CONNECTION_STATUS_UUID PEBBLE_BT_UUID_EXPAND(1)
#define PEBBLE_BT_PAIRING_SERVICE_TRIGGER_PAIRING_UUID PEBBLE_BT_UUID_EXPAND(2)
#define PEBBLE_BT_PAIRING_SERVICE_GATT_MTU_UUID PEBBLE_BT_UUID_EXPAND(3)
// Note: UUID 4 was used by the 3.14-rc Android App for V0 of the Connection Param characteristic
// but never shipped externally
#define PEBBLE_BT_PAIRING_SERVICE_CONNECTION_PARAMETERS_UUID PEBBLE_BT_UUID_EXPAND(5)
typedef enum {
PebblePairingServiceGATTError_UnknownCommandID =
BLEGATTErrorApplicationSpecificErrorStart,
PebblePairingServiceGATTError_ConnParamsInvalidRemoteDesiredState,
PebblePairingServiceGATTError_ConnParamsMinSlotsTooSmall,
PebblePairingServiceGATTError_ConnParamsMinSlotsTooLarge,
PebblePairingServiceGATTError_ConnParamsMaxSlotsTooLarge,
PebblePairingServiceGATTError_ConnParamsSupervisionTimeoutTooSmall,
PebblePairingServiceGATTError_DeviceDoesNotSupportPLE,
} PebblePairingServiceGATTError;
//! The connectivity status, with respect to the device reading it.
typedef struct PACKED {
union {
struct {
//! true if the device that is reading the status is connected (always true)
bool ble_is_connected:1;
//! true if the device that is reading the status is bonded, false if not
bool ble_is_bonded:1;
//! true if the current LE link is encrypted, false if not
bool ble_is_encrypted:1;
//! true if the watch has a bonding to a gateway (LE-based).
bool has_bonded_gateway:1;
//! true if the watch supports writing the "Don't send slave security request" bit.
//! See https://pebbletechnology.atlassian.net/wiki/display/DEV/Pebble+GATT+Services
bool supports_pinning_without_security_request:1;
//! true if the reversed ppogatt was enabled at the time of bonding
bool is_reversed_ppogatt_enabled:1;
//! Reserved, leave zero for future use.
uint32_t rsvd:18;
//! The error of the last pairing process or all zeroes, if no pairing process has completed
//! or when there were no errors. Also see BT Spec 4.2, Vol 3, Part H, 3.5.5 Pairing Failed.
uint8_t last_pairing_result;
};
uint8_t bytes[4];
};
} PebblePairingServiceConnectivityStatus;
_Static_assert(sizeof(PebblePairingServiceConnectivityStatus) == 4, "");
typedef struct PACKED {
bool should_pin_address:1;
//! @note Not available in Bluetopia/cc2564x implementation
//! This flag and should_force_slave_security_request are mutually exclusive!
bool no_slave_security_request:1;
//! @note Not available in Bluetopia/cc2564x implementation
//! This flag and no_slave_security_request are mutually exclusive!
bool should_force_slave_security_request:1;
//! @note Not available in Bluetopia/cc2564x implementation
//! Flag to indicate that when re-pairing this device, the re-pairing should be accepted
//! automatically for this remote device (matching IRK or matching identity address).
//! @note This is a work-around for an Android 4.4.x bug. This opens up a security hole :( where
//! a phone could pretend to be the "trusted" phone and pair w/o the user even knowing about it.
//! @see https://pebbletechnology.atlassian.net/browse/PBL-39369
bool should_auto_accept_re_pairing:1;
//! @note Not available in Bluetopia/cc2564x implementation
//! Flag to indicate that the PPoGATT server/client roles should be reversed to support the
//! connected phone. Some older Android phones' GATT service API is completely busted. For those
//! poor phones, this bit is set before pairing. The Pebble includes a "reversed" PPoGATT service
//! that the phone app can connect to as GATT client, but this service only works if this bit
//! gets set *before pairing*. This is a security measure: 1. to prevent non-paired devices from
//! talking to the "reversed" PPoGATT service. 2. to prevent non-Pebble apps on paired phone that
//! does support normal PPoGATT from connecting to the "reversed" PPoGATT service.
//! @see ppogatt_emulated_server_wa.c
//! @see https://pebbletechnology.atlassian.net/browse/PBL-39634
bool is_reversed_ppogatt_enabled:1;
} PairingTriggerRequestData;
typedef struct PACKED {
//! interval_min_ms / 1.25 msec valid range: 7.5 msec to 4 seconds
uint16_t interval_min_1_25ms;
//! (interval_max_ms - interval_min_ms) / 1.25 msec
//! @note To fit the parent struct in the minimum GATT MTU, this field is a delta and only one
//! byte instead of the uint16_t that the BT spec uses.
uint8_t interval_max_delta_1_25ms;
//! Slave latency (in number of connection events)
//! @note To fit the parent struct in the minimum GATT MTU, this field is only one byte instead
//! of the uint16_t that the BT spec uses.
uint8_t slave_latency_events;
//! Supervision Timeout / 30 msec valid range: 100 msec to 32 seconds. To fit this into one
//! byte and to fit the parent struct in the minimum GATT MTU, the increments is not the standard
//! 10msec!
uint8_t supervision_timeout_30ms;
} PebblePairingServiceConnParamSet;
//! The connection parameters settings, with respect to connection to the device reading them.
typedef struct PACKED PebblePairingServiceConnParamsReadNotif {
//! Capability bits. Reserved for future use.
uint8_t packet_length_extension_supported:1;
uint8_t rsvd:7;
//! Current interval / 1.25 msec valid range: 7.5 msec to 4 seconds
uint16_t current_interval_1_25ms;
//! Current Slave latency (in number of connection events) actual max is 0x01F3, but in
//! practice values are much lower.
uint16_t current_slave_latency_events;
//! Current Supervision Timeout / 10 msec valid range: 100 msec to 32 seconds.
uint16_t current_supervision_timeout_10ms;
} PebblePairingServiceConnParamsReadNotif;
typedef enum PebblePairingServiceConnParamsWriteCmd {
//! Allows phone to change connection parameter set and take over control of parameter management
PebblePairingServiceConnParamsWriteCmd_SetRemoteParamMgmtSettings = 0x00,
//! Issues a connection parameter change request if the watch is not in the desired state
PebblePairingServiceConnParamsWriteCmd_SetRemoteDesiredState = 0x01,
//! Controls settings for BLE 4.2 Packet Length Extension feature
PebblePairingServiceConnParamsWriteCmd_EnablePacketLengthExtension = 0x02,
//! If written to disables Dialog BLE sleep mode (safeguard against PBL-39777 in case it affects
//! more watches in the future)
PebblePairingServiceConnParamsWriteCmd_InhibitBLESleep = 0x03,
PebblePairingServiceConnParamsWriteCmdCount,
} PebblePairingServiceConnParamsWriteCmd;
typedef struct PACKED PebblePairingServiceRemoteParamMgmtSettings {
//! If false/zero, Pebble should manage the connection parameters. If true/one, Pebble should
//! NOT manage the connection parameters. In this mode, Pebble will never request a
//! connection parameter change.
bool is_remote_device_managing_connection_parameters:1;
uint8_t rsvd:7;
//! Optional. Current parameters sets used by Pebble's Connection Parameter manager.
PebblePairingServiceConnParamSet connection_parameter_sets[];
} PebblePairingServiceRemoteParamMgmtSettings;
typedef struct PACKED PebblePairingServiceRemoteDesiredState {
//! The desired ResponseTime as desired by the remote device. The remote end can set this
//! value to a faster mode when it's about to transfer/receive a lot of data. For example,
//! when a lot of BlobDB operations are queued up, the watch doesn't know how much data is
//! queued up on the remote end. In this case, the remote could write "ResponseTimeMin" so
//! increase the speed temporarily. It's the remote end's responsibility to reset this to
//! ResponseTimeMax when the bulk transfer is done. As a safety measure, the watch is will
//! reset it back to ResponseTimeMax after 5 minutes. In case the phone app still wants to
//! keep a particular desired ResponseTime, the phone app is responsible for making sure to
//! write the value again before the 5 minute timer expires.
uint8_t state:2;
uint8_t rsvd:6;
} PebblePairingServiceRemoteDesiredState;
typedef struct PACKED PebblePairingServicePacketLengthExtension {
uint8_t trigger_ll_length_req:1;
uint8_t rsvd:7;
} PebblePairingServicePacketLengthExtension;
typedef struct PACKED PebblePairingServiceInhibitBLESleep {
uint8_t rsvd; // for future use
} PebblePairingServiceInhibitBLESleep;
//! The connection parameters settings, with respect to connection to the device writing them.
typedef struct PACKED PebblePairingServiceConnParamsWrite {
PebblePairingServiceConnParamsWriteCmd cmd:8;
union PACKED {
//! Valid iff cmd == PebblePairingServiceConnParamsWriteCmd_SetRemoteParamMgmtSettings
PebblePairingServiceRemoteParamMgmtSettings remote_param_mgmt_settings;
//! Valid iff cmd == PebblePairingServiceConnParamsWriteCmd_SetRemoteDesiredState
PebblePairingServiceRemoteDesiredState remote_desired_state;
//! Valid iff cmd == PebblePairingServiceConnParamsWriteCmd_EnablePacketLengthExtension
PebblePairingServicePacketLengthExtension ple_req;
//! Valid iff cmd == PebblePairingServiceConnParamsWriteCmd_InhibitBLESleep
PebblePairingServiceInhibitBLESleep ble_sleep;
};
} PebblePairingServiceConnParamsWrite;
#define PEBBLE_PAIRING_SERVICE_REMOTE_PARAM_MGTM_SETTINGS_SIZE_WITH_PARAM_SETS \
(sizeof(PebblePairingServiceRemoteParamMgmtSettings) + \
(sizeof(PebblePairingServiceConnParamSet) * NumResponseTimeState))
#define PEBBLE_PAIRING_SERVICE_CONN_PARAMS_WRITE_SIZE_WITH_PARAM_SETS \
(offsetof(PebblePairingServiceConnParamsWrite, remote_param_mgmt_settings) + \
PEBBLE_PAIRING_SERVICE_REMOTE_PARAM_MGTM_SETTINGS_SIZE_WITH_PARAM_SETS)
_Static_assert(NumResponseTimeState == 3, "");
_Static_assert(sizeof(PebblePairingServiceConnParamsReadNotif) <= 20, "Larger than minimum MTU!");
_Static_assert(PEBBLE_PAIRING_SERVICE_CONN_PARAMS_WRITE_SIZE_WITH_PARAM_SETS <= 20,
"Larger than minimum MTU!");
_Static_assert(sizeof(PebblePairingServiceConnParamsWrite) <= 20, "Larger than minimum MTU!");
_Static_assert(sizeof(PebblePairingServiceConnectivityStatus) <= 20, "Larger than minimum MTU!");
typedef struct GAPLEConnection GAPLEConnection;
//! Signals to the Pebble GATT service that status change has occured (pairing, encryption, ...),
//! allowing it to notify any BLE devices that are subscribed to connectivity status updates of the
//! change.
//! @param connection The connection for which the status was changed.
void bt_driver_pebble_pairing_service_handle_status_change(const GAPLEConnection *connection);
//! Signals to the Pebble GATT service the GATT MTU has changed, allowing it to notify any BLE
//! devices that are subscribed to GATT MTU characteristic.
//! @param connection The connection for which the GATT MTU has changed.
//! @note the caller is responsible for taking bt_lock!
void bt_driver_pebble_pairing_service_handle_gatt_mtu_change(const GAPLEConnection *connection);
//! Indicate to the FW that Connectivity Status characteristic has been unsubscribed from.
//! This is used to detect that the Pebble iOS app has been terminated.
extern void bt_driver_cb_pebble_pairing_service_handle_ios_app_termination_detected(void);
//! Indicate to the FW that the Connection Parameters characteristic has been written to with a new
//! values.
//! @param conn_params The value as written to the Connection Parameters characteristic. The BT
//! driver lib is expected to validate any written values and only call this function with valid
//! values.
//! @param conn_params_length The length of conn_params in bytes.
extern void bt_driver_cb_pebble_pairing_service_handle_connection_parameter_write(
const BTDeviceInternal *device,
const PebblePairingServiceConnParamsWrite *conn_params,
size_t conn_params_length);

View file

@ -0,0 +1,28 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
//! Called by the QEMU serial driver whenever Pebble Protocol data is received.
void qemu_transport_handle_received_data(const uint8_t *data, uint32_t length);
//! Called by qemu version of comm_init() to tell ISPP that it is connected
void qemu_transport_set_connected(bool is_connected);
bool qemu_transport_is_connected(void);

View file

@ -0,0 +1,50 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
//! Increments the reconnect-pause counter. When the counter is above
//! 0, reconnection attempts will not occur.
void bt_driver_reconnect_pause(void);
//! Decrements the reconnect-pause counter. When the counter drops to
//! 0, reconnection attempts will be free to proceed.
void bt_driver_reconnect_resume(void);
//! Attempt to reconnect to the last connected remote device and restore
//! connections to the Bluetooth Classic profile (iSPP).
//! This is an asynchonous operation. A call to this function returns quickly.
//! If the last connected remote device and services are already connected, or
//! if the device is not an iOS device, this function does not do much.
//! @param ignore_paused If true, this call will attempt to reconnect,
//! even if the reconnection manager is paused. If false, the call will not
//! attempt to reconnect if the manager is paused.
void bt_driver_reconnect_try_now(bool ignore_paused);
//! Resets the reconnection manager's interval to the minimum interval, so
//! the rate of reconnection attempts is temporarily increased. This
//! should be called right after disconnecting or at any time that the remote
//! device might be suspected to be coming back in range.
void bt_driver_reconnect_reset_interval(void);
//! Notifies the BT Driver of the platform bitfield we received from the
//! 'session remote version endpoint'. (Some drivers cache this information to
//! determine BT connection behavior (such as the reconnection algorithm for
//! bluetooth classic)
void bt_driver_reconnect_notify_platform_bitfield(uint32_t platform_bitfield);

View file

@ -0,0 +1,83 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
#include <inttypes.h>
#include <bluetooth/bluetooth_types.h>
#include "bluetooth/gap_le_connect.h"
#include "util/attributes.h"
typedef enum {
BtConsumerNone = 0,
// Every sub-module has its own consumer name. We try to enter & exit
// from low latency states within the same module
BtConsumerApp,
BtConsumerLePairing,
BtConsumerLeServiceDiscovery,
BtConsumerMusicServiceIndefinite,
BtConsumerMusicServiceMomentary,
BtConsumerPpAppFetch,
BtConsumerPpAppMessage,
BtConsumerPpAudioEndpoint,
BtConsumerPpGetBytes,
BtConsumerPpLogDump,
BtConsumerPpPutBytes,
BtConsumerPpScreenshot,
BtConsumerPpVoiceEndpoint,
BtConsumerPrompt,
BtConsumerTimelineActionMenu,
BtConsumerPRF,
BtConsumerPebblePairingServiceRemoteDevice,
BtConsumerUnitTests, // For unit testing
NumBtConsumer,
} BtConsumer;
typedef enum {
ResponseTimeInvalid = -1,
ResponseTimeMax = 0, // lowest throughput, most friendly power profile
ResponseTimeMiddle,
ResponseTimeMin, // highest throughput, least friendly power profile
NumResponseTimeState,
} ResponseTimeState;
//! Callback to call when the requested response time has been negotiated and granted.
typedef void (*ResponsivenessGrantedHandler)(void);
// Longest duration we want to be in Min latency for different modules
#define MIN_LATENCY_MODE_TIMEOUT_AUDIO_SECS (10)
#define MIN_LATENCY_MODE_TIMEOUT_APP_FETCH_SECS (5)
#define MIN_LATENCY_MODE_TIMEOUT_APP_MESSAGE_SECS (10)
#define MIN_LATENCY_MODE_TIMEOUT_CD_SECS (10)
#define MIN_LATENCY_MODE_TIMEOUT_PROTOCOL_RECV_SECS (60)
#define MIN_LATENCY_MODE_TIMEOUT_PUT_BYTES_SECS (60)
#define MIN_LATENCY_MODE_TIMEOUT_SCREENSHOT_SECS (5)
#define MIN_LATENCY_MODE_TIMEOUT_TIMELINE_ACTION_MENU_SECS (10)
#define MIN_LATENCY_MODE_TIMEOUT_VOICE_SECS (10)
//! Connection Parameters Update Request Packet
typedef struct PACKED { // PACKED since this struct is serialized
uint16_t interval_min_1_25ms;
uint16_t interval_max_1_25ms;
uint16_t slave_latency_events;
uint16_t supervision_timeout_10ms;
} BleConnectionParamsUpdateReq;
bool bt_driver_le_connection_parameter_update(
const BTDeviceInternal *addr, const BleConnectionParamsUpdateReq *req);

View file

@ -0,0 +1,86 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <bluetooth/bluetooth_types.h>
#include <util/attributes.h>
typedef enum {
SMRootKeyTypeEncryption,
SMRootKeyTypeIdentity,
SMRootKeyTypeNum,
} SMRootKeyType;
typedef struct PACKED SM128BitKey {
uint8_t data[16];
} SM128BitKey;
typedef SM128BitKey SMLongTermKey;
typedef SM128BitKey SMIdentityResolvingKey;
typedef SM128BitKey SMConnectionSignatureResolvingKey;
typedef struct PACKED SMLocalEncryptionInfo {
uint16_t ediv;
//! @note Only used by cc2564x/Bluetopia driver!
uint16_t div;
//! @note Only used by Dialog driver!
SMLongTermKey ltk;
//! @note Only used by Dialog driver!
uint64_t rand;
} SMLocalEncryptionInfo;
typedef struct PACKED SMRemoteEncryptionInfo {
SMLongTermKey ltk;
uint64_t rand;
uint16_t ediv;
} SMRemoteEncryptionInfo;
//! @note Some fields might not get populated/used, this depends on the BT Driver implementation.
//! @note Packed, because this is used in HC protocol messages.
typedef struct PACKED SMPairingInfo {
//! The encryption info that will be used when the local device is the slave.
SMLocalEncryptionInfo local_encryption_info;
//! The encryption info that will be used when the local device is the master.
SMRemoteEncryptionInfo remote_encryption_info;
SMIdentityResolvingKey irk;
BTDeviceInternal identity;
SMConnectionSignatureResolvingKey csrk;
//! True if div and ediv are valid
bool is_local_encryption_info_valid;
//! True if remote_encryption_info is valid
bool is_remote_encryption_info_valid;
//! True if irk and identity are valid
bool is_remote_identity_info_valid;
//! True if csrk is valid
bool is_remote_signing_info_valid;
//! @note NOT valid for cc2564x BT lib, only for Dialog BT lib!
bool is_mitm_protection_enabled;
} SMPairingInfo;

View file

@ -0,0 +1,20 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
//! Should be called when a BT Classic disconnection occurs
void reconnect_android_update_disconnect_time(void);