mirror of
https://github.com/google/pebble.git
synced 2025-05-19 01:44:53 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
21
src/include/bluetooth/adv_reconnect.h
Normal file
21
src/include/bluetooth/adv_reconnect.h
Normal 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);
|
48
src/include/bluetooth/analytics.h
Normal file
48
src/include/bluetooth/analytics.h
Normal 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);
|
281
src/include/bluetooth/bluetooth_types.h
Normal file
281
src/include/bluetooth/bluetooth_types.h
Normal 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
|
54
src/include/bluetooth/bonding_sync.h
Normal file
54
src/include/bluetooth/bonding_sync.h
Normal 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);
|
41
src/include/bluetooth/bt_driver_advert.h
Normal file
41
src/include/bluetooth/bt_driver_advert.h
Normal 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);
|
31
src/include/bluetooth/bt_driver_comm.h
Normal file
31
src/include/bluetooth/bt_driver_comm.h
Normal 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);
|
67
src/include/bluetooth/bt_test.h
Normal file
67
src/include/bluetooth/bt_test.h
Normal 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);
|
30
src/include/bluetooth/classic_connect.h
Normal file
30
src/include/bluetooth/classic_connect.h
Normal 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]);
|
29
src/include/bluetooth/conn_event_stats.h
Normal file
29
src/include/bluetooth/conn_event_stats.h
Normal 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;
|
21
src/include/bluetooth/connectability.h
Normal file
21
src/include/bluetooth/connectability.h
Normal 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);
|
39
src/include/bluetooth/dis.h
Normal file
39
src/include/bluetooth/dis.h
Normal 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;
|
21
src/include/bluetooth/features.h
Normal file
21
src/include/bluetooth/features.h
Normal 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);
|
29
src/include/bluetooth/gap_le_advert_workaround.h
Normal file
29
src/include/bluetooth/gap_le_advert_workaround.h
Normal 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);
|
124
src/include/bluetooth/gap_le_connect.h
Normal file
124
src/include/bluetooth/gap_le_connect.h
Normal 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);
|
27
src/include/bluetooth/gap_le_device_name.h
Normal file
27
src/include/bluetooth/gap_le_device_name.h
Normal 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);
|
30
src/include/bluetooth/gap_le_scan.h
Normal file
30
src/include/bluetooth/gap_le_scan.h
Normal 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);
|
164
src/include/bluetooth/gatt.h
Normal file
164
src/include/bluetooth/gatt.h
Normal 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);
|
43
src/include/bluetooth/gatt_discovery.h
Normal file
43
src/include/bluetooth/gatt_discovery.h
Normal 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);
|
114
src/include/bluetooth/gatt_service_types.h
Normal file
114
src/include/bluetooth/gatt_service_types.h
Normal 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))
|
33
src/include/bluetooth/hci_types.h
Normal file
33
src/include/bluetooth/hci_types.h
Normal 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;
|
43
src/include/bluetooth/hrm_service.h
Normal file
43
src/include/bluetooth/hrm_service.h
Normal 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);
|
42
src/include/bluetooth/id.h
Normal file
42
src/include/bluetooth/id.h
Normal 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);
|
46
src/include/bluetooth/init.h
Normal file
46
src/include/bluetooth/init.h
Normal 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);
|
29
src/include/bluetooth/mtu.h
Normal file
29
src/include/bluetooth/mtu.h
Normal 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
|
23
src/include/bluetooth/pairability.h
Normal file
23
src/include/bluetooth/pairability.h
Normal 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);
|
49
src/include/bluetooth/pairing_confirm.h
Normal file
49
src/include/bluetooth/pairing_confirm.h
Normal 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);
|
71
src/include/bluetooth/pebble_bt.h
Normal file
71
src/include/bluetooth/pebble_bt.h
Normal 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
|
248
src/include/bluetooth/pebble_pairing_service.h
Normal file
248
src/include/bluetooth/pebble_pairing_service.h
Normal 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);
|
28
src/include/bluetooth/qemu_transport.h
Normal file
28
src/include/bluetooth/qemu_transport.h
Normal 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);
|
50
src/include/bluetooth/reconnect.h
Normal file
50
src/include/bluetooth/reconnect.h
Normal 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);
|
83
src/include/bluetooth/responsiveness.h
Normal file
83
src/include/bluetooth/responsiveness.h
Normal 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);
|
86
src/include/bluetooth/sm_types.h
Normal file
86
src/include/bluetooth/sm_types.h
Normal 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;
|
20
src/include/bluetooth/temp.h
Normal file
20
src/include/bluetooth/temp.h
Normal 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);
|
224
src/include/logging/binary_logging.h
Normal file
224
src/include/logging/binary_logging.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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 <logging/log_hashing.h>
|
||||
/*
|
||||
* This file defines the structures required for Binary Logging. Please see
|
||||
* https://docs.google.com/document/d/1AyRGwr8CiilAViha56EiuRSZFiW0fWMcsTfzkNxByZ8
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
// SLIP Framing (if not using PULSE). Packet is: END, <packet>, <crc32>, END
|
||||
#define END 0xC0
|
||||
#define ESC 0xDB
|
||||
#define ESC_END 0xDC
|
||||
#define ESC_ESC 0xDD
|
||||
|
||||
// Version
|
||||
typedef struct BinLogMessage_Version {
|
||||
union {
|
||||
struct {
|
||||
uint8_t reserved:4;
|
||||
uint8_t unhashed_msg:1;
|
||||
uint8_t parameterized:1;
|
||||
uint8_t tick_count:1;
|
||||
uint8_t time_date:1;
|
||||
};
|
||||
uint8_t version;
|
||||
};
|
||||
} BinLogMessage_Version;
|
||||
|
||||
#define BINLOGMSG_VERSION_UNHASHED_MSG (1 << 3)
|
||||
#define BINLOGMSG_VERSION_PARAMETERIZED (1 << 2)
|
||||
#define BINLOGMSG_VERSION_TICK_COUNT (1 << 1)
|
||||
#define BINLOGMSG_VERSION_TIME_DATE (1 << 0)
|
||||
|
||||
_Static_assert(sizeof(BinLogMessage_Version) == 1, "BinLogMessage_Version size != 1");
|
||||
|
||||
// Time_Full
|
||||
// The times are in UTC. All values are 0 based (i.e., hour is [0,23], minute is [0,59],
|
||||
// second is [0,59], millisecond is [0,999]).
|
||||
typedef struct Time_Full {
|
||||
uint32_t reserved:5;
|
||||
uint32_t hour:5;
|
||||
uint32_t minute:6;
|
||||
uint32_t second:6;
|
||||
uint32_t millisecond:10;
|
||||
} Time_Full;
|
||||
|
||||
// Time_Tick
|
||||
// Total ticks = (count_high << 32) | count.
|
||||
typedef struct Time_Tick {
|
||||
uint16_t reserved;
|
||||
uint16_t count_high;
|
||||
uint32_t count;
|
||||
} Time_Tick;
|
||||
|
||||
// Date
|
||||
// The year is an offset from 2000 (e.g. year = 16 is 2016).
|
||||
// All remaining values are 1 based (i.e., month is [1,12], day is [1,31]).
|
||||
// An invalid/unknown date is identified by (year, month, day) = (0, 0, 0). Thus, Date = 0 is an
|
||||
// invalid date, not the start of the epoch, which would be (0, 1, 1).
|
||||
typedef struct Date {
|
||||
uint16_t year:7;
|
||||
uint16_t month:4;
|
||||
uint16_t day:5;
|
||||
} Date;
|
||||
|
||||
// MessageID
|
||||
typedef struct MessageID {
|
||||
union {
|
||||
struct {
|
||||
uint32_t msg_number:19; // LSB
|
||||
uint32_t task_id:4;
|
||||
uint32_t str_index_1:3;
|
||||
uint32_t str_index_2:3;
|
||||
uint32_t reserved:1;
|
||||
uint32_t core_number:2; // MSB
|
||||
};
|
||||
uint32_t msg_id;
|
||||
};
|
||||
} MessageID;
|
||||
|
||||
_Static_assert(sizeof(MessageID) == 4, "MessageID size != 4");
|
||||
|
||||
typedef struct BinLogMessage_Header {
|
||||
uint8_t version;
|
||||
uint8_t length;
|
||||
} BinLogMessage_Header;
|
||||
|
||||
typedef struct BinLogMessage_Header_v0 {
|
||||
uint8_t version;
|
||||
uint8_t length;
|
||||
uint8_t reserved[2];
|
||||
} BinLogMessage_Header_v0;
|
||||
#define BINLOGMSG_VERSION_HEADER_V0 (0)
|
||||
|
||||
typedef struct BinLogMessage_Header_v1 {
|
||||
uint8_t version;
|
||||
uint8_t length;
|
||||
Date date;
|
||||
Time_Full time;
|
||||
} BinLogMessage_Header_v1;
|
||||
#define BINLOGMSG_VERSION_HEADER_V1 (BINLOGMSG_VERSION_TIME_DATE)
|
||||
|
||||
typedef struct BinLogMessage_Header_v2 {
|
||||
uint8_t version;
|
||||
uint8_t length;
|
||||
uint8_t reserved[2];
|
||||
Time_Tick tick_count;
|
||||
} BinLogMessage_Header_v2;
|
||||
#define BINLOGMSG_VERSION_HEADER_V2 (BINLOGMSG_VERSION_TICK_COUNT)
|
||||
|
||||
typedef struct BinLogMessage_Header_v3 {
|
||||
uint8_t version;
|
||||
uint8_t length;
|
||||
Date date;
|
||||
Time_Full time;
|
||||
Time_Tick tick_count;
|
||||
} BinLogMessage_Header_v3;
|
||||
#define BINLOGMSG_VERSION_HEADER_V3 (BINLOGMSG_VERSION_TIME_DATE | BINLOGMSG_VERSION_TICK_COUNT)
|
||||
|
||||
typedef struct BinLogMessage_ParamBody {
|
||||
MessageID msgid;
|
||||
uint32_t payload[0];
|
||||
} BinLogMessage_ParamBody;
|
||||
|
||||
typedef struct BinLogMessage_StringParam {
|
||||
uint8_t length;
|
||||
uint8_t string[0]; // string[length]
|
||||
// uint8_t padding[((length + sizeof(length) + 3) % 4)]
|
||||
} BinLogMessage_StringParam;
|
||||
|
||||
typedef uint32_t BinLogMessage_IntParam;
|
||||
|
||||
typedef struct BinLogMessage_UnhashedBody {
|
||||
uint16_t line_number;
|
||||
uint8_t filename[16];
|
||||
uint8_t reserved:2;
|
||||
uint8_t core_number:2;
|
||||
uint8_t task_id:4;
|
||||
uint8_t level;
|
||||
uint8_t length;
|
||||
uint8_t string[0]; // string[length];
|
||||
// uint8_t padding[];
|
||||
} BinLogMessage_UnhashedBody;
|
||||
|
||||
|
||||
/*
|
||||
int len = MAX(strlen(log_string), 255 - sizeof(BinLogMessage_Header_vX))
|
||||
typedef struct BinLogMessage_SimpleBody {
|
||||
uint8_t string[len];
|
||||
uint8_t padding[((sizeof(BinLogMessage_Header_vX) + len + 3) % 4)];
|
||||
} BinLogMessage_SimpleBody;
|
||||
*/
|
||||
|
||||
|
||||
typedef struct BinLogMessage_Param_v0 {
|
||||
BinLogMessage_Header_v0 header;
|
||||
BinLogMessage_ParamBody body;
|
||||
} BinLogMessage_Param_v0;
|
||||
#define BINLOGMSG_VERSION_PARAM_V0 (BINLOGMSG_VERSION_HEADER_V0 | BINLOGMSG_VERSION_PARAMETERIZED)
|
||||
|
||||
typedef struct BinLogMessage_Param_v1 {
|
||||
BinLogMessage_Header_v1 header;
|
||||
BinLogMessage_ParamBody body;
|
||||
} BinLogMessage_Param_v1;
|
||||
#define BINLOGMSG_VERSION_PARAM_V1 (BINLOGMSG_VERSION_HEADER_V1 | BINLOGMSG_VERSION_PARAMETERIZED)
|
||||
|
||||
typedef struct BinLogMessage_Param_v2 {
|
||||
BinLogMessage_Header_v2 header;
|
||||
BinLogMessage_ParamBody body;
|
||||
} BinLogMessage_Param_v2;
|
||||
#define BINLOGMSG_VERSION_PARAM_V2 (BINLOGMSG_VERSION_HEADER_V2 | BINLOGMSG_VERSION_PARAMETERIZED)
|
||||
|
||||
typedef struct BinLogMessage_Param_v3 {
|
||||
BinLogMessage_Header_v3 header;
|
||||
BinLogMessage_ParamBody body;
|
||||
} BinLogMessage_Param_v3;
|
||||
#define BINLOGMSG_VERSION_PARAM_V3 (BINLOGMSG_VERSION_HEADER_V3 | BINLOGMSG_VERSION_PARAMETERIZED)
|
||||
|
||||
typedef struct BinLogMessage_Unhashed_v0 {
|
||||
BinLogMessage_Header_v0 header;
|
||||
BinLogMessage_UnhashedBody body;
|
||||
} BinLogMessage_Unhashed_v0;
|
||||
#define BINLOGMSG_VERSION_UNHASHED_V0 (BINLOGMSG_VERSION_HEADER_V0 | BINLOGMSG_VERSION_UNHASHED_MSG)
|
||||
|
||||
typedef struct BinLogMessage_Unhashed_v1 {
|
||||
BinLogMessage_Header_v1 header;
|
||||
BinLogMessage_UnhashedBody body;
|
||||
} BinLogMessage_Unhashed_v1;
|
||||
#define BINLOGMSG_VERSION_UNHASHED_V1 (BINLOGMSG_VERSION_HEADER_V1 | BINLOGMSG_VERSION_UNHASHED_MSG)
|
||||
|
||||
typedef struct BinLogMessage_Unhashed_v2 {
|
||||
BinLogMessage_Header_v2 header;
|
||||
BinLogMessage_UnhashedBody body;
|
||||
} BinLogMessage_Unhashed_v2;
|
||||
#define BINLOGMSG_VERSION_UNHASHED_V2 (BINLOGMSG_VERSION_HEADER_V2 | BINLOGMSG_VERSION_UNHASHED_MSG)
|
||||
|
||||
typedef struct BinLogMessage_Unhashed_v3 {
|
||||
BinLogMessage_Header_v3 header;
|
||||
BinLogMessage_UnhashedBody body;
|
||||
} BinLogMessage_Unhashed_v3;
|
||||
#define BINLOGMSG_VERSION_UNHASHED_V3 (BINLOGMSG_VERSION_HEADER_V3 | BINLOGMSG_VERSION_UNHASHED_MSG)
|
||||
|
||||
typedef struct BinLogMessage_String_v1 {
|
||||
BinLogMessage_Header_v1 header;
|
||||
uint8_t string[0];
|
||||
} BinLogMessage_String_v1;
|
||||
#define BINLOGMSG_VERSION_STRING_V1 (BINLOGMSG_VERSION_HEADER_V1)
|
232
src/include/logging/log_hashing.h
Normal file
232
src/include/logging/log_hashing.h
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************************************
|
||||
* New Logging
|
||||
*
|
||||
* The NewLogging system provides in place hashing during the compile stage of building, removing
|
||||
* logging strings from the source code and replacing them with a unique token, conserving space in
|
||||
* the firmware.
|
||||
*
|
||||
* The unique token is (well, see below) actually just a pointer to a new section in the .elf
|
||||
* named .log_strings. The .log_strings section is mapped to an unused portion of memory and
|
||||
* isn't compiled into the final firmware binary image.
|
||||
*
|
||||
* Token format:
|
||||
* The token is acually a packed uint32_t. The format is as follows:
|
||||
* 31-29: num fmt conversions [0-7]
|
||||
* 28-26: string index 2 [0-7], 1 based. 0 if no second string. 1-7 otherwise
|
||||
* 25-23: string index 1 [0-7], 1 based. 0 if no first string. 1-7 otherwise
|
||||
* 22-20: log level [0-5] mapped onto LOG_LEVEL_ALWAYS through LOG_LEVEL_DEBUG_VERBOSE
|
||||
* 19: reserved
|
||||
* 18- 0: Offset info .log_strings section. This allows 512 KB of strings.
|
||||
*
|
||||
* Note: it might not be necessary to use so many bits for the log level. Dynamic flitering might
|
||||
* not be so important, and 'log to flash' could be 1 bit, or Curried to a set of function calls.
|
||||
* These changes would require more work in the logging infrastructure.
|
||||
*
|
||||
* .log_strings Section is formatted as follows:
|
||||
* - .log_string.header: "NL<M><m>:<offset-mask>=<token-list>"
|
||||
* where:
|
||||
* - <M> is XX major version -- increase means not backwards compatible change
|
||||
* - <m> is YY minor version -- increase means backwards compatible change
|
||||
* - <offset-mask> defines the number of bits used in the token for the section offset
|
||||
* - <token-list>: <token>:<token-list>
|
||||
* : '\0'
|
||||
* - <token>: <file>
|
||||
* : <line>
|
||||
* : <level>
|
||||
* : <color>
|
||||
* : <fmt>
|
||||
* - .log_core_number: "CORE<C>"
|
||||
* where:
|
||||
* - <C> is the core number. This will be two bits.
|
||||
* For now, the primary core will be 00; the Bluetooth chip will be 01.
|
||||
* These definitions will be different for every system -- all that matters is that they're
|
||||
* internally consistent.
|
||||
* - .log_string
|
||||
* which is a list of <token-list> representing the log strings from the source code.
|
||||
*
|
||||
* Note: this code must be compiled with -Os or the codesize will explode!
|
||||
*
|
||||
* Limitations:
|
||||
* - maximum 7 format conversions per print
|
||||
* - maximum 2 string conversions per print
|
||||
* - string parameters may not be flagged or formatted in any way --'%s' only.
|
||||
* - printing the '%' is not supported -- '%%' is not allowed.
|
||||
* - only 32 bit (or fewer) parameters currently supported automatically. Multi-word parameters
|
||||
* require special handling.
|
||||
* - errors are not automatically detected. This will have to be done later by a script. Sorry.
|
||||
*
|
||||
* Extensions (to be implemented at some point):
|
||||
* - Colour groups/overrides
|
||||
* - MAC/BT address print: format specifier: %M/m
|
||||
* - ENUM print: %u[<enum name>]
|
||||
*
|
||||
* LogHash.dict:
|
||||
* See https://pebbletechnology.atlassian.net/wiki/display/DEV/New+Logging.
|
||||
***********************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "util/attributes.h"
|
||||
|
||||
#define NEW_LOG_VERSION "0101"
|
||||
|
||||
#define LOG_STRINGS_SECTION_ADDRESS 0xC0000000
|
||||
|
||||
#define PACKED_CORE_OFFSET 30 // 2 bits - Core number
|
||||
#define PACKED_CORE_MASK 0x03
|
||||
|
||||
#define PACKED_NUM_FMT_OFFSET 29 // 3 bits - Number format conversions
|
||||
#define PACKED_NUM_FMT_MASK 0x07
|
||||
#define PACKED_STR1FMT_OFFSET 26 // 3 bits - indicies of string parameter 1 format conversion
|
||||
#define PACKED_STR1FMT_MASK 0x07
|
||||
#define PACKED_STR2FMT_OFFSET 23 // 3 bits - indicies of string parameter 2 format conversion
|
||||
#define PACKED_STR2FMT_MASK 0x07
|
||||
#define PACKED_STRFMTS_OFFSET 23 // 6 bits - indicies of string parameters 1 & 2.
|
||||
#define PACKED_STRFMTS_MASK 0x3f
|
||||
#define PACKED_LEVEL_OFFSET 20 // 3 bits - log level
|
||||
#define PACKED_LEVEL_MASK 0x07
|
||||
#define PACKED_HASH_OFFSET 0
|
||||
#define PACKED_HASH_MASK 0x7FFFF // 19 bits - string table offset (512 KB)
|
||||
|
||||
#define MSGID_STR_AND_HASH_MASK ((PACKED_STRFMTS_MASK << PACKED_STRFMTS_OFFSET) | \
|
||||
(PACKED_HASH_MASK << PACKED_HASH_OFFSET))
|
||||
#define MSGID_CORE_AND_HASH_MASK ((PACKED_CORE_MASK << PACKED_CORE_OFFSET) | \
|
||||
(PACKED_HASH_MASK << PACKED_HASH_OFFSET))
|
||||
|
||||
#ifndef STRINGIFY
|
||||
#define STRINGIFY_NX(a) #a
|
||||
#define STRINGIFY(a) STRINGIFY_NX(a)
|
||||
#endif // STRINGIFY
|
||||
|
||||
/* Printf Format argument checking.
|
||||
*
|
||||
* NB: it's critical that the 'if (false)' tag is included before the call to
|
||||
* PBL_LOG_x_printf_arg_check(). Without this obviously useless check, PBL_LOG_x_printf_arg_check()
|
||||
* would not be optimised out and cause a) a linker error (missing function body), b) take up
|
||||
* code space & time, and c) would cause the arguments passed to PBL_LOG (NEW_LOG_HASH) to be
|
||||
* evaluated twice. This is fine with normal parameters, but could result in macros or functions
|
||||
* being called twice and messing up globals in unexpected ways.
|
||||
*/
|
||||
void PBL_LOG_x_printf_arg_check(const char *fmt, ...) FORMAT_PRINTF(1, 2);
|
||||
|
||||
#define NEW_LOG_HASH(logfunc, level, color, fmt, ...) \
|
||||
{ \
|
||||
static const char str[] __attribute__((nocommon, section(".log_strings"))) = \
|
||||
__FILE__ ":" STRINGIFY(__LINE__) ":" STRINGIFY(level) ":" color ":" fmt; \
|
||||
logfunc((uint32_t)&str[LOG_SECTION_OFFSET(level, fmt)], ##__VA_ARGS__); \
|
||||
if (0) PBL_LOG_x_printf_arg_check(fmt, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static uint32_t LOG_SECTION_OFFSET(const uint8_t level, const char *fmt) {
|
||||
const char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
|
||||
const char *p5 = NULL, *p6 = NULL, *p7 = NULL, *p8 = NULL;
|
||||
const char *s1 = NULL, *s2 = NULL, *s3 = NULL, *s4 = NULL;
|
||||
const char *s5 = NULL, *s6 = NULL, *s7 = NULL;
|
||||
|
||||
// Search for % characters in fmt. p1-p8 point to the character immediately succeeding the first
|
||||
// 8 % characters in fmt (or NULL, if there aren't 8 % characters in fmt).
|
||||
p1 = __builtin_strchr(fmt, '%') ? (__builtin_strchr(fmt, '%') + 1) : NULL;
|
||||
if (p1) p2 = __builtin_strchr(p1, '%') ? (__builtin_strchr(p1, '%') + 1) : NULL;
|
||||
if (p2) p3 = __builtin_strchr(p2, '%') ? (__builtin_strchr(p2, '%') + 1) : NULL;
|
||||
if (p3) p4 = __builtin_strchr(p3, '%') ? (__builtin_strchr(p3, '%') + 1) : NULL;
|
||||
if (p4) p5 = __builtin_strchr(p4, '%') ? (__builtin_strchr(p4, '%') + 1) : NULL;
|
||||
if (p5) p6 = __builtin_strchr(p5, '%') ? (__builtin_strchr(p5, '%') + 1) : NULL;
|
||||
if (p6) p7 = __builtin_strchr(p6, '%') ? (__builtin_strchr(p6, '%') + 1) : NULL;
|
||||
if (p7) p8 = __builtin_strchr(p7, '%') ? (__builtin_strchr(p7, '%') + 1) : NULL;
|
||||
|
||||
// Check that fmt doesn't contain the escaped % symbol, '%%'. It's too hard to handle correctly
|
||||
// in every case.
|
||||
if ((p1 + 1 == p2) || (p2 + 1 == p3) || (p3 + 1 == p4) || (p4 + 1 == p5) ||
|
||||
(p5 + 1 == p6) || (p6 + 1 == p7) || (p7 + 1 == p8)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Count number of valid pointers by bool-inversion-twice
|
||||
uint8_t num_params = !!p1 + !!p2 + !!p3 + !!p4 + !!p5 + !!p6 + !!p7 + !!p8;
|
||||
|
||||
// Check that there aren't more than 7 format conversions. We have only 3 bits per string index.
|
||||
if (num_params > 7) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Search for an 's' character succeeding the % characters in fmt. s1-s7 point to the first 's'
|
||||
// charactres in fmt after the previously found % characters (or NULL if there aren't 7 's'
|
||||
// characters in fmt).
|
||||
if (p1) s1 = __builtin_strchr(p1, 's');
|
||||
if (p2) s2 = __builtin_strchr(p2, 's');
|
||||
if (p3) s3 = __builtin_strchr(p3, 's');
|
||||
if (p4) s4 = __builtin_strchr(p4, 's');
|
||||
if (p5) s5 = __builtin_strchr(p5, 's');
|
||||
if (p6) s6 = __builtin_strchr(p6, 's');
|
||||
if (p7) s7 = __builtin_strchr(p7, 's');
|
||||
|
||||
// See if the 's' characters immediately succeed the '%' characters. If so, set flag psX.
|
||||
const int ps1 = p1 ? (p1 == s1) : 0;
|
||||
const int ps2 = p2 ? (p2 == s2) : 0;
|
||||
const int ps3 = p3 ? (p3 == s3) : 0;
|
||||
const int ps4 = p4 ? (p4 == s4) : 0;
|
||||
const int ps5 = p5 ? (p5 == s5) : 0;
|
||||
const int ps6 = p6 ? (p6 == s6) : 0;
|
||||
const int ps7 = p7 ? (p7 == s7) : 0;
|
||||
|
||||
// Count the number of '%s' parameters
|
||||
const int num_s_params = ps1 + ps2 + ps3 + ps4 + ps5 + ps6 + ps7;
|
||||
|
||||
// We currently support only 2 string parameters.
|
||||
if (num_s_params > 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Format the (maximum) two string parameter indicies as:
|
||||
// (1-based index of first %s << 3) | (1-based index of second %s << 0)
|
||||
// If there is only one %s parameter, the index will be formatted as:
|
||||
// (1-based index of first %s << 0)
|
||||
const int a1 = ps1 ? 1 : 0;
|
||||
const int a2 = ps2 ? (a1 << 3) + 2 : a1;
|
||||
const int a3 = ps3 ? (a2 << 3) + 3 : a2;
|
||||
const int a4 = ps4 ? (a3 << 3) + 4 : a3;
|
||||
const int a5 = ps5 ? (a4 << 3) + 5 : a4;
|
||||
const int a6 = ps6 ? (a5 << 3) + 6 : a5;
|
||||
const int a7 = ps7 ? (a6 << 3) + 7 : a6;
|
||||
const int string_indicies = a7;
|
||||
|
||||
|
||||
// Convert level to packed_level
|
||||
int packed_level = LOG_LEVEL_ALWAYS;
|
||||
if (level == LOG_LEVEL_ERROR) {
|
||||
packed_level = 1;
|
||||
} else if (level == LOG_LEVEL_WARNING) {
|
||||
packed_level = 2;
|
||||
} else if (level == LOG_LEVEL_INFO) {
|
||||
packed_level = 3;
|
||||
} else if (level == LOG_LEVEL_DEBUG) {
|
||||
packed_level = 4;
|
||||
} else if (level == LOG_LEVEL_DEBUG_VERBOSE) {
|
||||
packed_level = 5;
|
||||
}
|
||||
|
||||
const uint32_t offset = (((num_params & PACKED_NUM_FMT_MASK) << PACKED_NUM_FMT_OFFSET) |
|
||||
((packed_level & PACKED_LEVEL_MASK) << PACKED_LEVEL_OFFSET) |
|
||||
((string_indicies & PACKED_STRFMTS_MASK) << PACKED_STRFMTS_OFFSET));
|
||||
|
||||
return (offset - LOG_STRINGS_SECTION_ADDRESS);
|
||||
}
|
31
src/include/pebbleos/chip_id.h
Normal file
31
src/include/pebbleos/chip_id.h
Normal 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
|
||||
|
||||
/*
|
||||
* chip_id.h
|
||||
*
|
||||
* This file specifies IDs for the different processors on our multi-processor devices.
|
||||
* The IDs are used to differenetiate the source of system logs, core dumps, etc.
|
||||
*
|
||||
* The IDs must be unique within a platform and must fit in 2 bits.
|
||||
* If we build a device with more than 4 log/core dump producing processors, this will need to be
|
||||
* addressed.
|
||||
*/
|
||||
|
||||
#define CORE_ID_MAIN_MCU 0
|
||||
#define CORE_ID_BLE 1
|
59
src/include/pebbleos/core_dump_structs.h
Normal file
59
src/include/pebbleos/core_dump_structs.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* core_dump_structs.h
|
||||
*
|
||||
* This file specifies core_dump structures previously defined in fw/kernel/core_dump_private.h
|
||||
* This is so the Dialog BLE core_dump code can use the same structures.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "portmacro.h"
|
||||
#include "util/attributes.h"
|
||||
|
||||
// Structure of thread info stored within a CORE_DUMP_CHUNK_KEY_THREAD chunk in the core dump
|
||||
#define CORE_DUMP_THREAD_NAME_SIZE 16
|
||||
typedef struct PACKED {
|
||||
int8_t name[CORE_DUMP_THREAD_NAME_SIZE]; // Name, includes null termination
|
||||
uint32_t id; // thread id
|
||||
uint8_t running; // true if this thread is running
|
||||
uint32_t registers[portCANONICAL_REG_COUNT]; // registers [r0-r12, sp, lr, pc, xpsr]
|
||||
} CoreDumpThreadInfo;
|
||||
|
||||
// Structure of extra registers stored within a CORE_DUMP_CHUNK_KEY_EXTRA_REG chunk in the
|
||||
// core dump
|
||||
typedef struct PACKED {
|
||||
uint32_t msp;
|
||||
uint32_t psp;
|
||||
uint8_t primask;
|
||||
uint8_t basepri;
|
||||
uint8_t faultmask;
|
||||
uint8_t control;
|
||||
} CoreDumpExtraRegInfo;
|
||||
|
||||
|
||||
|
||||
// We save all the important registers on entry to core_dump_reset() in a structure of this type
|
||||
// on the core_dump_reset() stack and save a pointer to it in the s_saved_registers global.
|
||||
// IMPORTANT!: There is assembly code near the top of core_dump_reset() that makes assumptions
|
||||
// about the order and packing of this structure.
|
||||
typedef struct PACKED {
|
||||
uint32_t core_reg[portCANONICAL_REG_COUNT];
|
||||
CoreDumpExtraRegInfo extra_reg;
|
||||
} CoreDumpSavedRegisters;
|
141
src/include/pebbleos/cron.h
Normal file
141
src/include/pebbleos/cron.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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 <time.h>
|
||||
|
||||
#include "util/list.h"
|
||||
|
||||
//! @file cron.h
|
||||
//! Wall-clock based timer system. Designed for use in things such as alarms, calendar events, etc.
|
||||
//! Properly handles DST, etc.
|
||||
|
||||
typedef struct CronJob CronJob;
|
||||
|
||||
typedef void (*CronJobCallback)(CronJob *job, void* data);
|
||||
|
||||
//! Matches any possible value.
|
||||
#define CRON_MINUTE_ANY (-1)
|
||||
#define CRON_HOUR_ANY (-1)
|
||||
#define CRON_MDAY_ANY (-1)
|
||||
#define CRON_MONTH_ANY (-1)
|
||||
|
||||
#define WDAY_SUNDAY (1 << 0)
|
||||
#define WDAY_MONDAY (1 << 1)
|
||||
#define WDAY_TUESDAY (1 << 2)
|
||||
#define WDAY_WEDNESDAY (1 << 3)
|
||||
#define WDAY_THURSDAY (1 << 4)
|
||||
#define WDAY_FRIDAY (1 << 5)
|
||||
#define WDAY_SATURDAY (1 << 6)
|
||||
|
||||
#define WDAY_WEEKDAYS (WDAY_MONDAY | WDAY_TUESDAY | WDAY_WEDNESDAY | WDAY_THURSDAY | WDAY_FRIDAY)
|
||||
#define WDAY_WEEKENDS (WDAY_SUNDAY | WDAY_SATURDAY)
|
||||
#define WDAY_ANY (WDAY_WEEKENDS | WDAY_WEEKDAYS)
|
||||
|
||||
struct CronJob {
|
||||
//! internal, no touchy
|
||||
ListNode list_node;
|
||||
|
||||
//! Cached execution timestamp in UTC.
|
||||
//! This is set by `cron_job_schedule`, and is required to never be changed once the job has been
|
||||
//! added.
|
||||
time_t cached_execute_time;
|
||||
|
||||
//! Callback that is called when the job fires.
|
||||
CronJobCallback cb;
|
||||
void* cb_data;
|
||||
|
||||
//! Occasionally, the system gets a clock change event for various reasons:
|
||||
//! - User changed time-zones or a DST transition happened
|
||||
//! - User changed the time
|
||||
//! - Phone sent the current time and was different from ours, so we took theirs.
|
||||
//! In the first case, the cron job's execute time will always be recalculated.
|
||||
//! In the other two, we see if the time difference from the old time is >= this.
|
||||
//! If it is, then we'll recalculate. Otherwise, we leave the calculated time alone.
|
||||
//! In this way, 0 will always recalculate, and UINT32_MAX will never recalculate.
|
||||
//!
|
||||
//! Recalculating would essentially mean that a job that was "skipped over" will not fire until
|
||||
//! the next match. If recalculation is not done, but the job was skipped over, it will fire
|
||||
//! instantly.
|
||||
//!
|
||||
//! This value is specified in seconds.
|
||||
uint32_t clock_change_tolerance;
|
||||
|
||||
int8_t minute; //!< 0-59, or CRON_MINUTE_ANY
|
||||
int8_t hour; //!< 0-23, or CRON_HOUR_ANY
|
||||
int8_t mday; //!< 0-30, or CRON_MDAY_ANY
|
||||
int8_t month; //!< 0-11, or CRON_MONTH_ANY
|
||||
|
||||
//! Seconds to offset the cron execution time applied after regular cron job time calculation.
|
||||
//! For example, a cron scheduled for Monday at 0:15 with an offset of negative 30min will fire
|
||||
//! on Sunday at 23:45.
|
||||
int32_t offset_seconds;
|
||||
|
||||
union {
|
||||
uint8_t flags;
|
||||
|
||||
struct {
|
||||
//! This should be any combination of WDAY_*. If zero, acts like WDAY_ANY.
|
||||
uint8_t wday : 7;
|
||||
|
||||
//! If this flag is set, the resulting execution time may be equal to the local epoch.
|
||||
//! Having it set could be used for some event that must happen at the specified time even if
|
||||
//! that time is right now.
|
||||
bool may_be_instant : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//! Add a cron job. This will make the service hold a reference to the specified job, so it must
|
||||
//! not leave scope or be destroyed until it is unscheduled.
|
||||
//! The job only gets scheduled once. For re-scheduling, you can call this on the job again.
|
||||
//! @params job pointer to the CronJob struct to be scheduled.
|
||||
//! @returns time_t for when the job is destined to go off.
|
||||
time_t cron_job_schedule(CronJob *job);
|
||||
|
||||
//! Schedule a cron job to run after another cron job.
|
||||
//! This will make the service hold a reference to the new job, so it must
|
||||
//! not leave scope or be destroyed until it is unscheduled.
|
||||
//! @param job pointer to the CronJob after which we want our job to run. job must be scheduled.
|
||||
//! @params new_job pointer to the CronJob struct to be scheduled. new_job must be unscheduled.
|
||||
//! @returns time_t for when the job is destined to go off.
|
||||
//! @note This API makes no guarantee that the two jobs will be scheduled back to back,
|
||||
//! only that new_job will have the same scheduled time as job and that it will trigger
|
||||
//! strictly after job.
|
||||
time_t cron_job_schedule_after(CronJob *new_job, CronJob *job);
|
||||
|
||||
//! Remove a scheduled cron job.
|
||||
//! @params job pointer to the CronJob struct to be unscheduled.
|
||||
//! @return true if the job was successfully removed (false may indicate no job was
|
||||
//! scheduled at all or the cb is currently executing)
|
||||
bool cron_job_unschedule(CronJob *job);
|
||||
|
||||
//! Check if a cron job is scheduled.
|
||||
//! @params job pointer to the CronJob struct to be checked for being scheduled.
|
||||
//! @returns true if scheduled or pending deletion, false otherwise
|
||||
bool cron_job_is_scheduled(CronJob *job);
|
||||
|
||||
//! Calculate cron job's destined execution time, from the current time.
|
||||
//! @params job pointer to the CronJob struct to get the execution time for.
|
||||
//! @returns time_t for when the job is destined to go off.
|
||||
time_t cron_job_get_execute_time(const CronJob *job);
|
||||
|
||||
//! Calculate cron job's destined execution time if it were scheduled at the given time.
|
||||
//! @params job pointer to the CronJob struct to get the execution time for.
|
||||
//! @params local_epoch the epoch for getting the job's execution time.
|
||||
//! @returns time_t for when the job is destined to go off.
|
||||
time_t cron_job_get_execute_time_from_epoch(const CronJob *job, time_t local_epoch);
|
138
src/include/pebbleos/firmware_metadata.h
Normal file
138
src/include/pebbleos/firmware_metadata.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* firmware_metadata.h
|
||||
*
|
||||
* This file specifies the Firmware Metadata structure used in the .elf & .bin files to
|
||||
* identify the build info, etc.
|
||||
*/
|
||||
|
||||
#include "util/attributes.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#define FW_METADATA_CURRENT_STRUCT_VERSION 0x1
|
||||
#define FW_METADATA_VERSION_SHORT_BYTES 8
|
||||
#define FW_METADATA_VERSION_TAG_BYTES 32
|
||||
|
||||
// NOTE: When adding new platforms, if they use the legacy defective CRC, the list in
|
||||
// tools/fw_binary_info.py needs to be updated with the platform value.
|
||||
typedef enum FirmwareMetadataPlatform {
|
||||
FirmwareMetadataPlatformUnknown = 0,
|
||||
FirmwareMetadataPlatformPebbleOneEV1 = 1,
|
||||
FirmwareMetadataPlatformPebbleOneEV2 = 2,
|
||||
FirmwareMetadataPlatformPebbleOneEV2_3 = 3,
|
||||
FirmwareMetadataPlatformPebbleOneEV2_4 = 4,
|
||||
FirmwareMetadataPlatformPebbleOnePointFive = 5,
|
||||
FirmwareMetadataPlatformPebbleTwoPointZero = 6,
|
||||
FirmwareMetadataPlatformPebbleSnowyEVT2 = 7,
|
||||
FirmwareMetadataPlatformPebbleSnowyDVT = 8,
|
||||
FirmwareMetadataPlatformPebbleSpaldingEVT = 9,
|
||||
FirmwareMetadataPlatformPebbleBobbyDVT = 10,
|
||||
FirmwareMetadataPlatformPebbleSpalding = 11,
|
||||
FirmwareMetadataPlatformPebbleSilkEVT = 12,
|
||||
FirmwareMetadataPlatformPebbleRobertEVT = 13,
|
||||
FirmwareMetadataPlatformPebbleSilk = 14,
|
||||
|
||||
FirmwareMetadataPlatformPebbleOneBigboard = 0xff,
|
||||
FirmwareMetadataPlatformPebbleOneBigboard2 = 0xfe,
|
||||
FirmwareMetadataPlatformPebbleSnowyBigboard = 0xfd,
|
||||
FirmwareMetadataPlatformPebbleSnowyBigboard2 = 0xfc,
|
||||
FirmwareMetadataPlatformPebbleSpaldingBigboard = 0xfb,
|
||||
FirmwareMetadataPlatformPebbleSilkBigboard = 0xfa,
|
||||
FirmwareMetadataPlatformPebbleRobertBigboard = 0xf9,
|
||||
FirmwareMetadataPlatformPebbleSilkBigboard2 = 0xf8,
|
||||
FirmwareMetadataPlatformPebbleRobertBigboard2 = 0xf7,
|
||||
} FirmwareMetadataPlatform;
|
||||
|
||||
// WARNING: changes in this struct must be reflected in:
|
||||
// - iOS/PebblePrivateKit/PebblePrivateKit/PBBundle.m
|
||||
|
||||
struct PACKED FirmwareMetadata {
|
||||
uint32_t version_timestamp;
|
||||
char version_tag[FW_METADATA_VERSION_TAG_BYTES];
|
||||
char version_short[FW_METADATA_VERSION_SHORT_BYTES];
|
||||
bool is_recovery_firmware:1;
|
||||
bool is_ble_firmware:1;
|
||||
uint8_t reserved:6;
|
||||
uint8_t hw_platform;
|
||||
//! This should be the last field, since we put the meta data struct at the end of the fw binary.
|
||||
uint8_t metadata_version;
|
||||
};
|
||||
typedef struct FirmwareMetadata FirmwareMetadata;
|
||||
|
||||
_Static_assert(sizeof(struct FirmwareMetadata) == (sizeof(uint32_t) +
|
||||
FW_METADATA_VERSION_SHORT_BYTES + FW_METADATA_VERSION_TAG_BYTES + sizeof(uint8_t) +
|
||||
sizeof(uint8_t) + sizeof(uint8_t)),
|
||||
"FirmwareMetadata bitfields not packed correctly");
|
||||
|
||||
|
||||
// Shared defines. Let's not duplicate this everywhere.
|
||||
|
||||
#ifdef RECOVERY_FW
|
||||
#define FIRMWARE_METADATA_IS_RECOVERY_FIRMWARE (true)
|
||||
#else
|
||||
#define FIRMWARE_METADATA_IS_RECOVERY_FIRMWARE (false)
|
||||
#endif
|
||||
|
||||
#if BOARD_BIGBOARD
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneBigboard)
|
||||
#elif BOARD_BB2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneBigboard2)
|
||||
#elif BOARD_SNOWY_BB
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyBigboard)
|
||||
#elif BOARD_SNOWY_BB2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyBigboard2)
|
||||
#elif BOARD_SNOWY_EVT2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyEVT2)
|
||||
#elif BOARD_SNOWY_DVT
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSnowyDVT)
|
||||
#elif BOARD_SNOWY_S3
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleBobbyDVT)
|
||||
#elif BOARD_V2_0
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleTwoPointZero)
|
||||
#elif BOARD_V1_5
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOnePointFive)
|
||||
#elif BOARD_EV2_4
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleOneEV2_4)
|
||||
#elif BOARD_SPALDING_BB2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpaldingBigboard)
|
||||
#elif BOARD_SPALDING_EVT
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpaldingEVT)
|
||||
#elif BOARD_SPALDING
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSpalding)
|
||||
#elif BOARD_SILK_EVT
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkEVT)
|
||||
#elif BOARD_SILK_BB
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkBigboard)
|
||||
#elif BOARD_SILK
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilk)
|
||||
#elif BOARD_SILK_BB2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleSilkBigboard2)
|
||||
#elif BOARD_ROBERT_BB
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertBigboard)
|
||||
#elif BOARD_ROBERT_BB2
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertBigboard2)
|
||||
#elif BOARD_ROBERT_EVT
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformPebbleRobertEVT)
|
||||
#else
|
||||
#define FIRMWARE_METADATA_HW_PLATFORM (FirmwareMetadataPlatformUnknown)
|
||||
#endif
|
6
src/include/wscript
Normal file
6
src/include/wscript
Normal file
|
@ -0,0 +1,6 @@
|
|||
def build(bld):
|
||||
bld(export_includes=['.'],
|
||||
use=['libc_includes', 'libutil_includes'],
|
||||
name='root_includes')
|
||||
|
||||
# vim:filetype=python
|
Loading…
Add table
Add a link
Reference in a new issue