From bf2e48e22aa3b70ce09bb7872731b151017946fd Mon Sep 17 00:00:00 2001 From: ndeadly Date: Fri, 24 Sep 2021 17:35:11 +0200 Subject: [PATCH] btm: update GetDeviceCondition and GetDeviceInfo service wrappers and related types for 13.0.0 (#576) --- nx/include/switch/services/btm.h | 26 ++++++++-- nx/include/switch/services/btm_types.h | 70 ++++++++++++++++++++------ nx/source/services/btm.c | 41 +++++++++++++-- 3 files changed, 115 insertions(+), 22 deletions(-) diff --git a/nx/include/switch/services/btm.h b/nx/include/switch/services/btm.h index f9192c76..b3d35145 100644 --- a/nx/include/switch/services/btm.h +++ b/nx/include/switch/services/btm.h @@ -40,10 +40,19 @@ Result btmGetHostDeviceProperty(BtmHostDeviceProperty *out); Result btmAcquireDeviceConditionEvent(Event* out_event); /** - * @brief GetDeviceCondition + * @brief GetDeviceCondition [1.0.0-12.1.0] * @param[out] out \ref BtmDeviceCondition */ -Result btmGetDeviceCondition(BtmDeviceCondition *out); +Result btmLegacyGetDeviceCondition(BtmDeviceCondition *out); + +/** + * @brief GetDeviceCondition [13.0.0+] + * @param[in] id Id + * @param[out] out \ref BtmConnectedDeviceV13 + * @param[in] count Size of the out array in entries. + * @param[out] total_out Total output entries. + */ +Result btmGetDeviceCondition(u32 id, BtmConnectedDeviceV13 *out, size_t count, s32 *total_out); /** * @brief SetBurstMode @@ -79,10 +88,19 @@ Result btmSetWlanMode(BtmWlanMode mode); Result btmAcquireDeviceInfoEvent(Event* out_event); /** - * @brief GetDeviceInfo + * @brief GetDeviceInfo [1.0.0-12.1.0] * @param[out] out \ref BtmDeviceInfoList */ -Result btmGetDeviceInfo(BtmDeviceInfoList *out); +Result btmLegacyGetDeviceInfo(BtmDeviceInfoList *out); + +/** + * @brief GetDeviceInfo [13.0.0+] + * @param[in] id Id + * @param[out] out \ref BtmDeviceInfoV13 + * @param[in] count Size of the out array in entries. + * @param[out] total_out Total output entries. + */ +Result btmGetDeviceInfo(u32 id, BtmDeviceInfoV13 *out, size_t count, s32 *total_out); /** * @brief AddDeviceInfo diff --git a/nx/include/switch/services/btm_types.h b/nx/include/switch/services/btm_types.h index 9d3436f8..46209a6c 100644 --- a/nx/include/switch/services/btm_types.h +++ b/nx/include/switch/services/btm_types.h @@ -85,13 +85,24 @@ typedef struct { /// HostDeviceProperty typedef struct { - BtdrvAddress addr; ///< Same as BtdrvAdapterProperty::addr. - BtmClassOfDevice class_of_device; ///< Same as BtdrvAdapterProperty::class_of_device. - BtmBdName name; ///< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). - u8 feature_set; ///< Same as BtdrvAdapterProperty::feature_set. + union { + struct { + BtdrvAddress addr; ///< Same as BtdrvAdapterProperty::addr. + BtmClassOfDevice class_of_device; ///< Same as BtdrvAdapterProperty::class_of_device. + BtmBdName name; ///< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + u8 feature_set; ///< Same as BtdrvAdapterProperty::feature_set. + } v1; ///< [1.0.0-12.1.0] + + struct { + BtdrvAddress addr; ///< Same as BtdrvAdapterProperty::addr. + BtmClassOfDevice class_of_device; ///< Same as BtdrvAdapterProperty::class_of_device. + char name[0xF9]; ///< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + u8 feature_set; ///< Same as BtdrvAdapterProperty::feature_set. + } v13; ///< [13.0.0+] + }; } BtmHostDeviceProperty; -/// BtmConnectedDevice +/// BtmConnectedDevice [1.0.0-12.1.0] typedef struct { BtdrvAddress address; u8 pad[2]; @@ -101,7 +112,17 @@ typedef struct { u16 vid; u16 pid; u8 unk_x4C[0x20]; -} BtmConnectedDevice; +} BtmConnectedDeviceV1; + +/// BtmConnectedDevice [13.0.0+] +typedef struct { + BtdrvAddress address; + u8 pad[2]; + u32 unk_x8; + u8 unk_xC[0x40]; + char name[0x20]; + u8 unk_x6C[0xdc]; +} BtmConnectedDeviceV13; /// DeviceCondition [1.0.0-5.0.2] typedef struct { @@ -111,7 +132,7 @@ typedef struct { u8 unk_x9; u8 max_count; u8 connected_count; - BtmConnectedDevice devices[8]; + BtmConnectedDeviceV1 devices[8]; } BtmDeviceConditionV100; /// DeviceCondition [5.1.0-7.0.1] @@ -123,7 +144,7 @@ typedef struct { u8 max_count; u8 connected_count; u8 pad[3]; - BtmConnectedDevice devices[8]; + BtmConnectedDeviceV1 devices[8]; } BtmDeviceConditionV510; /// DeviceCondition [8.0.0-8.1.1] @@ -134,20 +155,20 @@ typedef struct { u8 unk_x9; u8 max_count; u8 connected_count; - BtmConnectedDevice devices[8]; + BtmConnectedDeviceV1 devices[8]; } BtmDeviceConditionV800; -/// DeviceCondition [9.0.0+] +/// DeviceCondition [9.0.0-12.1.0] typedef struct { u32 unk_x0; u8 unk_x4; u8 unk_x5; u8 max_count; u8 connected_count; - BtmConnectedDevice devices[8]; + BtmConnectedDeviceV1 devices[8]; } BtmDeviceConditionV900; -/// DeviceCondition +/// DeviceCondition [1.0.0-12.1.0] typedef union { BtmDeviceConditionV100 v100; BtmDeviceConditionV510 v510; @@ -169,7 +190,7 @@ typedef struct { BtmDeviceSlotMode devices[8]; ///< Array of \ref BtmDeviceSlotMode with the above count. } BtmDeviceSlotModeList; -/// DeviceInfo +/// DeviceInfo [1.0.0-12.1.0] typedef struct { BtdrvAddress addr; ///< \ref BtdrvAddress BtmClassOfDevice class_of_device; ///< ClassOfDevice @@ -182,13 +203,34 @@ typedef struct { BtmHidDeviceInfo hid_device_info; ///< \ref BtmHidDeviceInfo (Profile = Hid) } profile_info; u8 reserved2[0x1C]; ///< Reserved +} BtmDeviceInfoV1; + +/// DeviceInfo [13.0.0+] +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + BtmClassOfDevice class_of_device; ///< ClassOfDevice + BtmLinkKey link_key; ///< LinkKey + u8 reserved[3]; ///< Reserved + u32 profile; ///< \ref BtmProfile + union { + u8 data[0x4]; ///< Empty (Profile = None) + BtmHidDeviceInfo hid_device_info; ///< \ref BtmHidDeviceInfo (Profile = Hid) + } profile_info; + u8 reserved2[0x1C]; ///< Reserved + char name[0xFC]; ///< Name +} BtmDeviceInfoV13; + +/// DeviceInfo [1.0.0-13.0.0] +typedef union { + BtmDeviceInfoV1 v1; + BtmDeviceInfoV13 v13; } BtmDeviceInfo; /// DeviceInfoList typedef struct { u8 device_count; ///< DeviceCount u8 reserved[3]; ///< Reserved - BtmDeviceInfo devices[10]; ///< Array of \ref BtmDeviceInfo with the above count. + BtmDeviceInfoV1 devices[10]; ///< Array of \ref BtmDeviceInfoV1 with the above count. } BtmDeviceInfoList; /// DeviceProperty diff --git a/nx/source/services/btm.c b/nx/source/services/btm.c index 3623ccd2..945cd526 100644 --- a/nx/source/services/btm.c +++ b/nx/source/services/btm.c @@ -108,6 +108,13 @@ static Result _btmCmdOutBufPtrFixed(void* buffer, size_t size, u32 cmd_id) { ); } +static Result _btmCmdInIdOutBufPtr(u32 id, void* buffer, size_t size, s32 *total_out, u32 cmd_id) { + return serviceDispatchInOut(&g_btmSrv, cmd_id, id, *total_out, + .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out }, + .buffers = { {buffer, size} }, + ); +} + static Result _btmGetBleScanResults(BtdrvBleScanResult *results, u8 count, u8 *total_out, u32 cmd_id) { return serviceDispatchOut(&g_btmSrv, cmd_id, *total_out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, @@ -149,14 +156,20 @@ Result btmGetState(BtmState *out) { } Result btmGetHostDeviceProperty(BtmHostDeviceProperty *out) { - return serviceDispatchOut(&g_btmSrv, 1, *out); + if (hosversionBefore(13,0,0)) + return serviceDispatchOut(&g_btmSrv, 1, (*out).v1); + + return _btmCmdOutBufPtrFixed(out, sizeof((*out).v13), 1); } Result btmAcquireDeviceConditionEvent(Event* out_event) { return _btmCmdGetEventOutFlag(out_event, true, 2); } -Result btmGetDeviceCondition(BtmDeviceCondition *out) { +Result btmLegacyGetDeviceCondition(BtmDeviceCondition *out) { + if (hosversionAtLeast(13,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + size_t buff_size; if (hosversionAtLeast(9,0,0)) buff_size = sizeof(BtmDeviceConditionV900); else if (hosversionAtLeast(8,0,0)) buff_size = sizeof(BtmDeviceConditionV800); @@ -165,6 +178,13 @@ Result btmGetDeviceCondition(BtmDeviceCondition *out) { return _btmCmdOutBufPtrFixed(out, buff_size, 3); } +Result btmGetDeviceCondition(u32 id, BtmConnectedDeviceV13 *out, size_t count, s32 *total_out) { + if (hosversionBefore(13,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _btmCmdInIdOutBufPtr(id, out, sizeof(BtmConnectedDeviceV13)*count, total_out, 3); +} + Result btmSetBurstMode(BtdrvAddress addr, bool flag) { return _btmCmdInAddrBoolNoOut(addr, flag, 4); } @@ -188,12 +208,25 @@ Result btmAcquireDeviceInfoEvent(Event* out_event) { return _btmCmdGetEventOutFlag(out_event, true, 8); } -Result btmGetDeviceInfo(BtmDeviceInfoList *out) { +Result btmLegacyGetDeviceInfo(BtmDeviceInfoList *out) { + if (hosversionAtLeast(13,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _btmCmdOutBufPtrFixed(out, sizeof(*out), 9); } +Result btmGetDeviceInfo(u32 id, BtmDeviceInfoV13 *out, size_t count, s32 *total_out) { + if (hosversionBefore(13,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _btmCmdInIdOutBufPtr(id, out, sizeof(BtmDeviceInfoV13)*count, total_out, 9); +} + Result btmAddDeviceInfo(const BtmDeviceInfo *info) { - return serviceDispatchIn(&g_btmSrv, 10, *info); + if (hosversionBefore(13,0,0)) + return serviceDispatchIn(&g_btmSrv, 10, (*info).v1); + + return _btmCmdInBufPtrFixed(info, sizeof((*info).v13), 10); } Result btmRemoveDeviceInfo(BtdrvAddress addr) {