/** * @file btdev.h * @brief Wrapper around the bt/btmu services for using bluetooth BLE. * @note Only available on [5.0.0+]. * @note See also: https://switchbrew.org/wiki/BTM_services * @author yellows8 * @copyright libnx Authors */ #pragma once #include "../types.h" #include "../kernel/event.h" #include "../services/btdrv_types.h" /// GattAttribute typedef struct { u8 type; ///< Type BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid u16 handle; ///< Handle u32 connection_handle; ///< ConnectionHandle } BtdevGattAttribute; /// GattService typedef struct { BtdevGattAttribute attr; ///< \ref BtdevGattAttribute u16 instance_id; ///< InstanceId u16 end_group_handle; ///< EndGroupHandle bool primary_service; ///< PrimaryService } BtdevGattService; /// GattCharacteristic typedef struct { BtdevGattAttribute attr; ///< \ref BtdevGattAttribute u16 instance_id; ///< InstanceId u8 properties; ///< Properties u64 value_size; ///< Size of value. u8 value[0x200]; ///< Value } BtdevGattCharacteristic; /// GattDescriptor typedef struct { BtdevGattAttribute attr; ///< \ref BtdevGattAttribute u64 value_size; ///< Size of value. u8 value[0x200]; ///< Value } BtdevGattDescriptor; /// Initialize bt/btmu. Result btdevInitialize(void); /// Exit bt/btmu. void btdevExit(void); /// Compares two \ref BtdrvGattAttributeUuid, returning whether these match. bool btdevGattAttributeUuidIsSame(const BtdrvGattAttributeUuid *a, const BtdrvGattAttributeUuid *b); /// Wrapper for \ref btmuAcquireBleScanEvent. Result btdevAcquireBleScanEvent(Event* out_event); /// Wrapper for \ref btmuGetBleScanFilterParameter. Result btdevGetBleScanParameter(u16 parameter_id, BtdrvBleAdvertisePacketParameter *out); /// Wrapper for \ref btmuGetBleScanFilterParameter2. Result btdevGetBleScanParameter2(u16 parameter_id, BtdrvGattAttributeUuid *out); /// Wrapper for \ref btdevStartBleScanGeneral. Result btdevStartBleScanGeneral(BtdrvBleAdvertisePacketParameter param); /// Wrapper for \ref btmuStopBleScanForGeneral. Result btdevStopBleScanGeneral(void); /** * @brief Wrapper for \ref btmuGetBleScanResultsForGeneral and \ref btmuGetBleScanResultsForSmartDevice. * @param[out] results Output array of \ref BtdrvBleScanResult. * @param[in] count Size of the results array in entries. * @param[out] total_out Total output entries. */ Result btdevGetBleScanResult(BtdrvBleScanResult *results, u8 count, u8 *total_out); /// Wrapper for \ref btmuStartBleScanForPaired. Result btdevEnableBleAutoConnection(BtdrvBleAdvertisePacketParameter param); /// Wrapper for \ref btmuStopBleScanForPaired. Result btdevDisableBleAutoConnection(void); /// Wrapper for \ref btmuStartBleScanForSmartDevice. Result btdevStartBleScanSmartDevice(const BtdrvGattAttributeUuid *uuid); /// Wrapper for \ref btmuStopBleScanForSmartDevice. Result btdevStopBleScanSmartDevice(void); /// Wrapper for \ref btmuAcquireBleConnectionEvent. Result btdevAcquireBleConnectionStateChangedEvent(Event* out_event); /// Wrapper for \ref btmuBleConnect. Result btdevConnectToGattServer(BtdrvAddress addr); /// Wrapper for \ref btmuBleDisconnect. Result btdevDisconnectFromGattServer(u32 connection_handle); /// Wrapper for \ref btmuBleGetConnectionState. Result btdevGetBleConnectionInfoList(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out); /// Wrapper for \ref btmuAcquireBleServiceDiscoveryEvent. Result btdevAcquireBleServiceDiscoveryEvent(Event* out_event); /** * @brief Wrapper for \ref btmuGetGattServices. * @param[in] connection_handle ConnectionHandle * @param[out] services Output array of \ref BtdevGattService. * @param[in] count Size of the services array in entries. The max is 100. * @param[out] total_out Total output entries. */ Result btdevGetGattServices(u32 connection_handle, BtdevGattService *services, u8 count, u8 *total_out); /** * @brief Wrapper for \ref btmuGetGattService. * @param[in] connection_handle ConnectionHandle * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[out] service \ref BtdevGattService * @param[out] flag Whether a \ref BtdevGattService was returned. */ Result btdevGetGattService(u32 connection_handle, const BtdrvGattAttributeUuid *uuid, BtdevGattService *service, bool *flag); /// Wrapper for \ref btmuAcquireBlePairingEvent. Result btdevAcquireBlePairingEvent(Event* out_event); /// Wrapper for \ref btmuBlePairDevice. Result btdevPairGattServer(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); /// Wrapper for \ref btmuBleUnPairDevice. Result btdevUnpairGattServer(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); /// Wrapper for \ref btmuBleUnPairDevice2. Result btdevUnpairGattServer2(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter param); /// Wrapper for \ref btmuBleGetPairedDevices. Result btdevGetPairedGattServerAddress(BtdrvBleAdvertisePacketParameter param, BtdrvAddress *addrs, u8 count, u8 *total_out); /// Wrapper for \ref btmuAcquireBleMtuConfigEvent. Result btdevAcquireBleMtuConfigEvent(Event* out_event); /** * @brief Wrapper for \ref btmuConfigureBleMtu. * @param[in] connection_handle Same as \ref btmuBleDisconnect. * @param[in] mtu MTU, must be 0x18-0x200. */ Result btdevConfigureBleMtu(u32 connection_handle, u16 mtu); /// Wrapper for \ref btmuGetBleMtu. Result btdevGetBleMtu(u32 connection_handle, u16 *out); /// Wrapper for \ref btRegisterBleEvent. Result btdevAcquireBleGattOperationEvent(Event* out_event); /** * @brief Wrapper for \ref btmuRegisterBleGattDataPath. * @param[in] uuid \ref BtdrvGattAttributeUuid */ Result btdevRegisterGattOperationNotification(const BtdrvGattAttributeUuid *uuid); /** * @brief Wrapper for \ref btmuUnregisterBleGattDataPath. * @param[in] uuid \ref BtdrvGattAttributeUuid */ Result btdevUnregisterGattOperationNotification(const BtdrvGattAttributeUuid *uuid); /** * @brief Wrapper for \ref btGetLeEventInfo. * @param[out] out \ref BtdrvBleClientGattOperationInfo */ Result btdevGetGattOperationResult(BtdrvBleClientGattOperationInfo *out); /** * @brief Wrapper for \ref btLeClientReadCharacteristic. * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. * @param c \ref BtdevGattCharacteristic */ Result btdevReadGattCharacteristic(BtdevGattCharacteristic *c); /** * @brief Wrapper for \ref btLeClientWriteCharacteristic. * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. * @note This uses the Value from \ref btdevGattCharacteristicSetValue. * @param c \ref BtdevGattCharacteristic */ Result btdevWriteGattCharacteristic(BtdevGattCharacteristic *c); /** * @brief Wrapper for \ref btLeClientRegisterNotification / \ref btLeClientDeregisterNotification. * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. * @param c \ref BtdevGattCharacteristic * @param[in] flag Whether to enable/disable, controls which func to call. */ Result btdevEnableGattCharacteristicNotification(BtdevGattCharacteristic *c, bool flag); /** * @brief Wrapper for \ref btLeClientReadDescriptor. * @param d \ref BtdevGattDescriptor */ Result btdevReadGattDescriptor(BtdevGattDescriptor *d); /** * @brief Wrapper for \ref btLeClientWriteDescriptor. * @note This uses the Value from \ref btdevGattDescriptorSetValue. * @param d \ref BtdevGattDescriptor */ Result btdevWriteGattDescriptor(BtdevGattDescriptor *d); ///@name GattAttribute ///@{ /** * @brief Creates a \ref BtdevGattAttribute object. This is intended for internal use. * @param a \ref BtdevGattAttribute * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[in] handle Handle * @param[in] connection_handle ConnectionHandle */ void btdevGattAttributeCreate(BtdevGattAttribute *a, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle); /** * @brief Gets the Type. * @param a \ref BtdevGattAttribute */ NX_CONSTEXPR u8 btdevGattAttributeGetType(BtdevGattAttribute *a) { return a->type; } /** * @brief Gets the Uuid. * @param a \ref BtdevGattAttribute * @param[out] out \ref BtdrvGattAttributeUuid */ NX_CONSTEXPR void btdevGattAttributeGetUuid(BtdevGattAttribute *a, BtdrvGattAttributeUuid *out) { *out = a->uuid; } /** * @brief Gets the Handle. * @param a \ref BtdevGattAttribute */ NX_CONSTEXPR u16 btdevGattAttributeGetHandle(BtdevGattAttribute *a) { return a->handle; } /** * @brief Gets the ConnectionHandle. * @param a \ref BtdevGattAttribute */ NX_CONSTEXPR u32 btdevGattAttributeGetConnectionHandle(BtdevGattAttribute *a) { return a->connection_handle; } ///@} ///@name GattService ///@{ /** * @brief Creates a \ref BtdevGattService object. This is intended for internal use. * @param s \ref BtdevGattService * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[in] handle Handle * @param[in] connection_handle ConnectionHandle * @param[in] instance_id InstanceId * @param[in] end_group_handle EndGroupHandle * @param[in] primary_service PrimaryService */ void btdevGattServiceCreate(BtdevGattService *s, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle, u16 instance_id, u16 end_group_handle, bool primary_service); /** * @brief Gets the InstanceId. * @param s \ref BtdevGattService */ NX_CONSTEXPR u16 btdevGattServiceGetInstanceId(BtdevGattService *s) { return s->instance_id; } /** * @brief Gets the EndGroupHandle. * @param s \ref BtdevGattService */ NX_CONSTEXPR u16 btdevGattServiceGetEndGroupHandle(BtdevGattService *s) { return s->end_group_handle; } /** * @brief Gets whether this is the PrimaryService. * @param s \ref BtdevGattService */ NX_CONSTEXPR u16 btdevGattServiceIsPrimaryService(BtdevGattService *s) { return s->primary_service; } /** * @brief Wrapper for \ref btmuGetGattIncludedServices. * @param s \ref BtdevGattService * @param[out] services Output array of \ref BtdevGattService. * @param[in] count Size of the services array in entries. The max is 100. * @param[out] total_out Total output entries. */ Result btdevGattServiceGetIncludedServices(BtdevGattService *s, BtdevGattService *services, u8 count, u8 *total_out); /** * @brief Wrapper for \ref btmuGetGattCharacteristics. * @param s \ref BtdevGattService * @param[out] characteristics Output array of \ref BtdevGattCharacteristic. * @param[in] count Size of the characteristics array in entries. The max is 100. * @param[out] total_out Total output entries. */ Result btdevGattServiceGetCharacteristics(BtdevGattService *s, BtdevGattCharacteristic *characteristics, u8 count, u8 *total_out); /** * @brief Same as \ref btdevGattServiceGetCharacteristics except this only returns the \ref BtdevGattCharacteristic which contains a matching \ref BtdrvGattAttributeUuid. * @param s \ref BtdevGattService * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[out] characteristic \ref BtdevGattCharacteristic * @param[out] flag Whether a \ref BtdevGattService was returned. */ Result btdevGattServiceGetCharacteristic(BtdevGattService *s, const BtdrvGattAttributeUuid *uuid, BtdevGattCharacteristic *characteristic, bool *flag); ///@} ///@name GattCharacteristic ///@{ /** * @brief Creates a \ref BtdevGattCharacteristic object. This is intended for internal use. * @param c \ref BtdevGattCharacteristic * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[in] handle Handle * @param[in] connection_handle ConnectionHandle * @param[in] instance_id InstanceId * @param[in] properties Properties */ void btdevGattCharacteristicCreate(BtdevGattCharacteristic *c, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle, u16 instance_id, u8 properties); /** * @brief Gets the InstanceId. * @param c \ref BtdevGattCharacteristic */ NX_CONSTEXPR u16 btdevGattCharacteristicGetInstanceId(BtdevGattCharacteristic *c) { return c->instance_id; } /** * @brief Gets the Properties. * @param c \ref BtdevGattCharacteristic */ NX_CONSTEXPR u8 btdevGattCharacteristicGetProperties(BtdevGattCharacteristic *c) { return c->properties; } /** * @brief Wrapper for \ref btmuGetBelongingGattService. * @note Gets the \ref BtdevGattService which belongs to this object. * @param c \ref BtdevGattCharacteristic. * @param[out] service \ref BtdevGattService */ Result btdevGattCharacteristicGetService(BtdevGattCharacteristic *c, BtdevGattService *service); /** * @brief Wrapper for \ref btmuGetGattDescriptors. * @note Gets the descriptors which belongs to this object. * @param c \ref BtdevGattCharacteristic * @param[out] descriptors Output array of \ref BtdevGattDescriptor. * @param[in] count Size of the descriptors array in entries. The max is 100. * @param[out] total_out Total output entries. */ Result btdevGattCharacteristicGetDescriptors(BtdevGattCharacteristic *c, BtdevGattDescriptor *descriptors, u8 count, u8 *total_out); /** * @brief Same as \ref btdevGattCharacteristicGetDescriptors except this only returns a \ref BtdevGattDescriptor which contains a matching \ref BtdrvGattAttributeUuid. * @param c \ref BtdevGattCharacteristic * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[out] descriptor \ref BtdevGattDescriptor * @param[out] flag Whether a \ref BtdevGattDescriptor was returned. */ Result btdevGattCharacteristicGetDescriptor(BtdevGattCharacteristic *c, const BtdrvGattAttributeUuid *uuid, BtdevGattDescriptor *descriptor, bool *flag); /** * @brief Sets the Value in the object. * @note See also \ref btdevWriteGattCharacteristic. * @param c \ref BtdevGattCharacteristic * @param[in] buffer Input buffer. * @param[in] size Input buffer size, max is 0x200. */ void btdevGattCharacteristicSetValue(BtdevGattCharacteristic *c, const void* buffer, size_t size); /** * @brief Gets the Value in the object, returns the copied value size. * @param c \ref BtdevGattCharacteristic * @param[out] buffer Output buffer. * @param[in] size Output buffer size, max is 0x200. */ u64 btdevGattCharacteristicGetValue(BtdevGattCharacteristic *c, void* buffer, size_t size); ///@} ///@name GattDescriptor ///@{ /** * @brief Creates a \ref BtdevGattDescriptor object. This is intended for internal use. * @param d \ref BtdevGattDescriptor * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[in] handle Handle * @param[in] connection_handle ConnectionHandle */ void btdevGattDescriptorCreate(BtdevGattDescriptor *d, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle); /** * @brief Wrapper for \ref btmuGetBelongingGattService. * @note Gets the \ref BtdevGattService which belongs to this object. * @param d \ref BtdevGattDescriptor * @param[out] service \ref BtdevGattService */ Result btdevGattDescriptorGetService(BtdevGattDescriptor *d, BtdevGattService *service); /** * @brief Wrapper for \ref btmuGetGattCharacteristics. * @note Gets the \ref BtdevGattCharacteristic which belongs to this object. * @param d \ref BtdevGattDescriptor * @param[out] characteristic \ref BtdevGattCharacteristic */ Result btdevGattDescriptorGetCharacteristic(BtdevGattDescriptor *d, BtdevGattCharacteristic *characteristic); /** * @brief Sets the Value in the object. * @note See also \ref btdevWriteGattDescriptor. * @param d \ref BtdevGattDescriptor * @param[in] buffer Input buffer. * @param[in] size Input buffer size, max is 0x200. */ void btdevGattDescriptorSetValue(BtdevGattDescriptor *d, const void* buffer, size_t size); /** * @brief Gets the Value in the object, returns the copied value size. * @param d \ref BtdevGattDescriptor * @param[out] buffer Output buffer. * @param[in] size Output buffer size, max is 0x200. */ u64 btdevGattDescriptorGetValue(BtdevGattDescriptor *d, void* buffer, size_t size); ///@}