From 94464baf3801435be57068a6e10b2e3da1b436d5 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sun, 2 Aug 2020 22:29:45 -0400 Subject: [PATCH] btdrv/btmu: Various improvements. --- nx/include/switch/services/btdrv.h | 4 +- nx/include/switch/services/btmu.h | 85 ++++++++++++++++-------------- nx/source/services/btmu.c | 64 +++++++++++----------- 3 files changed, 81 insertions(+), 72 deletions(-) diff --git a/nx/include/switch/services/btdrv.h b/nx/include/switch/services/btdrv.h index d10d8406..4e762d10 100644 --- a/nx/include/switch/services/btdrv.h +++ b/nx/include/switch/services/btdrv.h @@ -242,7 +242,9 @@ typedef struct { /// BleConnectionInfo typedef struct { - u8 unk_x0[0xC]; ///< Unknown + u32 id; ///< Id, 0xFFFFFFFF is invalid. + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 pad[2]; ///< Padding } BtdrvBleConnectionInfo; /// GattAttributeUuid diff --git a/nx/include/switch/services/btmu.h b/nx/include/switch/services/btmu.h index e62c693b..788602ee 100644 --- a/nx/include/switch/services/btmu.h +++ b/nx/include/switch/services/btmu.h @@ -12,7 +12,13 @@ /// GattService typedef struct { - u8 unk_x0[0x24]; ///< Unknown + u8 unk_x0[0x4]; ///< Unknown + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid + u16 unk_x18; ///< Unknown + u8 unk_x1A[0x4]; ///< Unknown + u16 unk_x1E; ///< Unknown + u8 unk_x20; ///< Unknown + u8 pad[3]; ///< Padding } BtmuGattService; /// GattCharacteristic @@ -51,15 +57,15 @@ Result btmuAcquireBleScanEvent(Event* out_event); /** * @brief GetBleScanFilterParameter - * @param[in] unk Unknown + * @param[in] unk Must be value 0x1 or 0xFFFF. * @param[out] out \ref BtdrvBleAdvertisePacketParameter */ Result btmuGetBleScanFilterParameter(u16 unk, BtdrvBleAdvertisePacketParameter *out); /** * @brief GetBleScanFilterParameter2 - * @param[in] unk Unknown - * @param[out] out \ref BtdrvGattAttributeUuid + * @param[in] unk Must be value 0x2. + * @param[out] out \ref BtdrvGattAttributeUuid. The first 4-bytes is always 0. */ Result btmuGetBleScanFilterParameter2(u16 unk, BtdrvGattAttributeUuid *out); @@ -77,7 +83,7 @@ Result btmuStopBleScanForGeneral(void); /** * @brief GetBleScanResultsForGeneral * @param[out] results Output array of \ref BtdrvBleScanResult. - * @param[in] count Size of the results array in entries. + * @param[in] count Size of the results array in entries. The max is 10. * @param[out] total_out Total output entries. */ Result btmuGetBleScanResultsForGeneral(BtdrvBleScanResult *results, u8 count, u8 *total_out); @@ -107,7 +113,7 @@ Result btmuStopBleScanForSmartDevice(void); /** * @brief GetBleScanResultsForSmartDevice * @param[out] results Output array of \ref BtdrvBleScanResult. - * @param[in] count Size of the results array in entries. + * @param[in] count Size of the results array in entries. The max is 10. * @param[out] total_out Total output entries. */ Result btmuGetBleScanResultsForSmartDevice(BtdrvBleScanResult *results, u8 count, u8 *total_out); @@ -121,20 +127,21 @@ Result btmuAcquireBleConnectionEvent(Event* out_event); /** * @brief BleConnect + * @note The \ref BtdrvAddress must not be already connected. A maximum of 4 devices can be connected. * @param[in] addr \ref BtdrvAddress */ Result btmuBleConnect(BtdrvAddress addr); /** * @brief BleDisconnect - * @param[in] unk Unknown + * @param[in] id This must match the first BtdrvBleConnectionInfo::id from \ref btmuBleGetConnectionState (0xFFFFFFFF is invalid). */ -Result btmuBleDisconnect(u32 unk); +Result btmuBleDisconnect(u32 id); /** * @brief BleGetConnectionState * @param[out] info Output array of \ref BtdrvBleConnectionInfo. - * @param[in] count Size of the info array in entries. + * @param[in] count Size of the info array in entries. Other cmds which use this internally use count=4. * @param[out] total_out Total output entries. */ Result btmuBleGetConnectionState(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out); @@ -149,16 +156,16 @@ Result btmuAcquireBlePairingEvent(Event* out_event); /** * @brief BlePairDevice * @param[in] param \ref BtdrvBleAdvertisePacketParameter - * @param[in] unk Unknown + * @param[in] id Same as \ref btmuBleDisconnect. */ -Result btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 unk); +Result btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 id); /** * @brief BleUnPairDevice * @param[in] param \ref BtdrvBleAdvertisePacketParameter - * @param[in] unk Unknown + * @param[in] id Same as \ref btmuBleDisconnect. */ -Result btmuBleUnPairDevice(BtdrvBleAdvertisePacketParameter param, u32 unk); +Result btmuBleUnPairDevice(BtdrvBleAdvertisePacketParameter param, u32 id); /** * @brief BleUnPairDevice2 @@ -172,7 +179,7 @@ Result btmuBleUnPairDevice2(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter * @param[in] param \ref BtdrvBleAdvertisePacketParameter * @param[out] addrs Output array of \ref BtdrvAddress. * @param[in] count Size of the addrs array in entries. - * @param[out] total_out Total output entries. + * @param[out] total_out Total output entries. The max is 10. */ Result btmuBleGetPairedDevices(BtdrvBleAdvertisePacketParameter param, BtdrvAddress *addrs, u8 count, u8 *total_out); @@ -185,60 +192,60 @@ Result btmuAcquireBleServiceDiscoveryEvent(Event* out_event); /** * @brief GetGattServices - * @param[in] unk Unknown + * @param[in] id Same as \ref btmuBleDisconnect. * @param[out] services Output array of \ref BtmuGattService. - * @param[in] count Size of the services array in entries. + * @param[in] count Size of the services array in entries. The max is 100. * @param[out] total_out Total output entries. */ -Result btmuGetGattServices(u32 unk, BtmuGattService *services, u8 count, u8 *total_out); +Result btmuGetGattServices(u32 id, BtmuGattService *services, u8 count, u8 *total_out); /** - * @brief GetGattService - * @param[in] unk Unknown + * @brief Same as \ref btmuGetGattServices except this only returns the \ref BtmuGattService which matches the input \ref BtdrvGattAttributeUuid. + * @param[in] id Same as \ref btmuBleDisconnect. * @param[in] uuid \ref BtdrvGattAttributeUuid * @param[out] service \ref BtmuGattService * @param[out] total_out Total output entries. */ -Result btmuGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid, BtmuGattService *service, u8 *total_out); +Result btmuGetGattService(u32 id, const BtdrvGattAttributeUuid *uuid, BtmuGattService *service, u8 *total_out); /** - * @brief GetGattIncludedServices - * @param[in] unk0 Unknown + * @brief Same as \ref btmuGetGattServices except this only returns \ref BtmuGattService entries where various checks pass with u16 fields. + * @param[in] id Same as \ref btmuBleDisconnect. * @param[in] unk1 Unknown * @param[out] services \ref BtmuGattService - * @param[in] count Size of the services array in entries. + * @param[in] count Size of the services array in entries. The max is 100. * @param[out] out Output value. */ -Result btmuGetGattIncludedServices(u32 unk0, u16 unk1, BtmuGattService *services, u8 count, u8 *out); +Result btmuGetGattIncludedServices(u32 id, u16 unk1, BtmuGattService *services, u8 count, u8 *out); /** - * @brief GetBelongingGattService - * @param[in] unk0 Unknown + * @brief This is similar to \ref btmuGetGattIncludedServices except this only returns 1 \ref BtmuGattService. + * @param[in] id Same as \ref btmuBleDisconnect. * @param[in] unk1 Unknown * @param[out] service \ref BtmuGattService * @param[out] total_out Total output entries. */ -Result btmuGetBelongingGattService(u32 unk0, u16 unk1, BtmuGattService *service, u8 *total_out); +Result btmuGetBelongingGattService(u32 id, u16 unk1, BtmuGattService *service, u8 *total_out); /** * @brief GetGattCharacteristics - * @param[in] unk0 Unknown - * @param[in] unk1 Unknown + * @param[in] id Same as \ref btmuBleDisconnect. + * @param[in] unk1 This controls which \ref BtmuGattCharacteristic entries to return. * @param[out] characteristics \ref BtmuGattCharacteristic - * @param[in] count Size of the characteristics array in entries. + * @param[in] count Size of the characteristics array in entries. The max is 100. * @param[out] total_out Total output entries. */ -Result btmuGetGattCharacteristics(u32 unk0, u16 unk1, BtmuGattCharacteristic *characteristics, u8 count, u8 *total_out); +Result btmuGetGattCharacteristics(u32 id, u16 unk1, BtmuGattCharacteristic *characteristics, u8 count, u8 *total_out); /** * @brief GetGattDescriptors - * @param[in] unk0 Unknown - * @param[in] unk1 Unknown + * @param[in] id Same as \ref btmuBleDisconnect. + * @param[in] unk1 This controls which \ref BtmuGattDescriptor entries to return. * @param[out] descriptors \ref BtmuGattDescriptor - * @param[in] count Size of the descriptors array in entries. + * @param[in] count Size of the descriptors array in entries. The max is 100. * @param[out] total_out Total output entries. */ -Result btmuGetGattDescriptors(u32 unk0, u16 unk1, BtmuGattDescriptor *descriptors, u8 count, u8 *total_out); +Result btmuGetGattDescriptors(u32 id, u16 unk1, BtmuGattDescriptor *descriptors, u8 count, u8 *total_out); /** * @brief AcquireBleMtuConfigEvent @@ -249,17 +256,17 @@ Result btmuAcquireBleMtuConfigEvent(Event* out_event); /** * @brief ConfigureBleMtu - * @param[in] unk Unknown + * @param[in] id Same as \ref btmuBleDisconnect. * @param[in] mtu MTU */ -Result btmuConfigureBleMtu(u32 unk, u16 mtu); +Result btmuConfigureBleMtu(u32 id, u16 mtu); /** * @brief GetBleMtu - * @param[in] unk Unknown + * @param[in] id Same as \ref btmuBleDisconnect. * @param[out] out Output MTU. */ -Result btmuGetBleMtu(u32 unk, u16 *out); +Result btmuGetBleMtu(u32 id, u16 *out); /** * @brief RegisterBleGattDataPath diff --git a/nx/source/services/btmu.c b/nx/source/services/btmu.c index eff456fa..617f644c 100644 --- a/nx/source/services/btmu.c +++ b/nx/source/services/btmu.c @@ -85,22 +85,22 @@ static Result _btmuGetBleScanResults(BtdrvBleScanResult *results, u8 count, u8 * ); } -static Result _btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 unk, u32 cmd_id) { +static Result _btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 id, u32 cmd_id) { const struct { BtdrvBleAdvertisePacketParameter param; - u32 unk; - } in = { param, unk }; + u32 id; + } in = { param, id }; return serviceDispatchIn(&g_btdrvIBtmUserCore, cmd_id, in); } -static Result _btmuGetGattServiceData(u32 unk0, u16 unk1, void* buffer, size_t entrysize, u8 count, u8 *out, u32 cmd_id) { +static Result _btmuGetGattServiceData(u32 id, u16 unk1, void* buffer, size_t entrysize, u8 count, u8 *out, u32 cmd_id) { const struct { u16 unk1; u16 pad; u32 unk0; u64 AppletResourceUserId; - } in = { unk1, 0, unk0, appletGetAppletResourceUserId() }; + } in = { unk1, 0, id, appletGetAppletResourceUserId() }; return serviceDispatchInOut(&g_btdrvIBtmUserCore, cmd_id, in, *out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, @@ -188,8 +188,8 @@ Result btmuBleConnect(BtdrvAddress addr) { ); } -Result btmuBleDisconnect(u32 unk) { - return _btmuCmdInU32NoOut(unk, 19); +Result btmuBleDisconnect(u32 id) { + return _btmuCmdInU32NoOut(id, 19); } Result btmuBleGetConnectionState(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out) { @@ -205,12 +205,12 @@ Result btmuAcquireBlePairingEvent(Event* out_event) { return _btmuCmdGetEventOutFlag(out_event, true, 21); } -Result btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 unk) { - return _btmuBlePairDevice(param, unk, 22); +Result btmuBlePairDevice(BtdrvBleAdvertisePacketParameter param, u32 id) { + return _btmuBlePairDevice(param, id, 22); } -Result btmuBleUnPairDevice(BtdrvBleAdvertisePacketParameter param, u32 unk) { - return _btmuBlePairDevice(param, unk, 23); +Result btmuBleUnPairDevice(BtdrvBleAdvertisePacketParameter param, u32 id) { + return _btmuBlePairDevice(param, id, 23); } Result btmuBleUnPairDevice2(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter param) { @@ -233,12 +233,12 @@ Result btmuAcquireBleServiceDiscoveryEvent(Event* out_event) { return _btmuCmdGetEventOutFlag(out_event, true, 26); } -Result btmuGetGattServices(u32 unk, BtmuGattService *services, u8 count, u8 *total_out) { +Result btmuGetGattServices(u32 id, BtmuGattService *services, u8 count, u8 *total_out) { const struct { - u32 unk; + u32 id; u32 pad; u64 AppletResourceUserId; - } in = { unk, 0, appletGetAppletResourceUserId() }; + } in = { id, 0, appletGetAppletResourceUserId() }; return serviceDispatchInOut(&g_btdrvIBtmUserCore, 27, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, @@ -247,12 +247,12 @@ Result btmuGetGattServices(u32 unk, BtmuGattService *services, u8 count, u8 *tot ); } -Result btmuGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid, BtmuGattService *service, u8 *total_out) { +Result btmuGetGattService(u32 id, const BtdrvGattAttributeUuid *uuid, BtmuGattService *service, u8 *total_out) { const struct { - u32 unk; + u32 id; BtdrvGattAttributeUuid uuid; u64 AppletResourceUserId; - } in = { unk, *uuid, appletGetAppletResourceUserId() }; + } in = { id, *uuid, appletGetAppletResourceUserId() }; return serviceDispatchInOut(&g_btdrvIBtmUserCore, 28, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, @@ -261,17 +261,17 @@ Result btmuGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid, BtmuGattS ); } -Result btmuGetGattIncludedServices(u32 unk0, u16 unk1, BtmuGattService *services, u8 count, u8 *out) { - return _btmuGetGattServiceData(unk0, unk1, services, sizeof(BtmuGattService), count, out, 29); +Result btmuGetGattIncludedServices(u32 id, u16 unk1, BtmuGattService *services, u8 count, u8 *out) { + return _btmuGetGattServiceData(id, unk1, services, sizeof(BtmuGattService), count, out, 29); } -Result btmuGetBelongingGattService(u32 unk0, u16 unk1, BtmuGattService *service, u8 *total_out) { +Result btmuGetBelongingGattService(u32 id, u16 unk1, BtmuGattService *service, u8 *total_out) { const struct { u16 unk1; u16 pad; - u32 unk0; + u32 id; u64 AppletResourceUserId; - } in = { unk1, 0, unk0, appletGetAppletResourceUserId() }; + } in = { unk1, 0, id, appletGetAppletResourceUserId() }; return serviceDispatchInOut(&g_btdrvIBtmUserCore, 30, in, *total_out, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, @@ -280,37 +280,37 @@ Result btmuGetBelongingGattService(u32 unk0, u16 unk1, BtmuGattService *service, ); } -Result btmuGetGattCharacteristics(u32 unk0, u16 unk1, BtmuGattCharacteristic *characteristics, u8 count, u8 *total_out) { - return _btmuGetGattServiceData(unk0, unk1, characteristics, sizeof(BtmuGattCharacteristic), count, total_out, 31); +Result btmuGetGattCharacteristics(u32 id, u16 unk1, BtmuGattCharacteristic *characteristics, u8 count, u8 *total_out) { + return _btmuGetGattServiceData(id, unk1, characteristics, sizeof(BtmuGattCharacteristic), count, total_out, 31); } -Result btmuGetGattDescriptors(u32 unk0, u16 unk1, BtmuGattDescriptor *descriptors, u8 count, u8 *total_out) { - return _btmuGetGattServiceData(unk0, unk1, descriptors, sizeof(BtmuGattDescriptor), count, total_out, 32); +Result btmuGetGattDescriptors(u32 id, u16 unk1, BtmuGattDescriptor *descriptors, u8 count, u8 *total_out) { + return _btmuGetGattServiceData(id, unk1, descriptors, sizeof(BtmuGattDescriptor), count, total_out, 32); } Result btmuAcquireBleMtuConfigEvent(Event* out_event) { return _btmuCmdGetEventOutFlag(out_event, true, 33); } -Result btmuConfigureBleMtu(u32 unk, u16 mtu) { +Result btmuConfigureBleMtu(u32 id, u16 mtu) { const struct { u16 mtu; u16 pad; - u32 unk; + u32 id; u64 AppletResourceUserId; - } in = { mtu, 0, unk, appletGetAppletResourceUserId() }; + } in = { mtu, 0, id, appletGetAppletResourceUserId() }; return serviceDispatchIn(&g_btdrvIBtmUserCore, 34, in, .in_send_pid = true, ); } -Result btmuGetBleMtu(u32 unk, u16 *out) { +Result btmuGetBleMtu(u32 id, u16 *out) { const struct { - u32 unk; + u32 id; u32 pad; u64 AppletResourceUserId; - } in = { unk, 0, appletGetAppletResourceUserId() }; + } in = { id, 0, appletGetAppletResourceUserId() }; return serviceDispatchInOut(&g_btdrvIBtmUserCore, 35, in, *out, .in_send_pid = true,