diff --git a/nx/include/switch/services/btdrv.h b/nx/include/switch/services/btdrv.h index e3e37745..0126d8e1 100644 --- a/nx/include/switch/services/btdrv.h +++ b/nx/include/switch/services/btdrv.h @@ -18,7 +18,7 @@ typedef struct { struct { u32 val; ///< Value - } type0; ///< ::BtdrvEventType_Unknown0 + } type0; ///< ::BtdrvEventTypeOld_Unknown0 struct { union { @@ -54,7 +54,7 @@ typedef struct { struct { u8 status; ///< \ref BtdrvInquiryStatus u8 pad[3]; ///< Padding - u32 service_mask; ///< Services value from \ref btdrvStartInquiry when starting, otherwise this is value 0 + u32 service_mask; ///< Services value from \ref btdrvStartInquiry when starting, otherwise this is value 0. } v12; ///< [12.0.0+] }; } inquiry_status; ///< ::BtdrvEventType_InquiryStatus @@ -80,7 +80,7 @@ typedef struct { BtdrvAddress addr; ///< Device address. char name[0xF9]; ///< Device name, NUL-terminated string. BtdrvClassOfDevice class_of_device; ///< Class of Device. - u8 flag; ///< bool flag for Just Works. With SSP passkey notification this is always 0 + u8 flag; ///< bool flag for Just Works. With SSP passkey notification this is always 0. u8 pad; ///< Padding s32 passkey; ///< Passkey } v12; ///< [12.0.0+] @@ -145,18 +145,9 @@ typedef struct { u8 data[0x480]; ///< Raw data. struct { - union { - struct { - BtdrvAddress addr; ///< Device address. - u8 pad[2]; ///< Padding - BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus - } v1; ///< [1.0.0-11.0.1] - - struct { - BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus - BtdrvAddress addr; ///< Device address. - } v12; ///< [12.0.0+] - }; + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus } connection; ///< ::BtdrvHidEventType_Connection struct { @@ -446,7 +437,7 @@ Result btdrvFinalizeBluetooth(void); /** * @brief GetAdapterProperties [1.0.0-11.0.1] - * @param[out] properties \ref BtdrvAdapterProperty + * @param[out] properties \ref BtdrvAdapterPropertyOld */ Result btdrvLegacyGetAdapterProperties(BtdrvAdapterPropertyOld *properties); @@ -487,14 +478,14 @@ Result btdrvLegacySetAdapterProperty(BtdrvBluetoothPropertyType type, const void Result btdrvSetAdapterProperty(BtdrvAdapterPropertyType type, const BtdrvAdapterProperty *property); /** - * @brief StartInquiry [1.0.0-11.0.1] This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. Inquiry will automatically stop in 10.24 seconds. + * @brief StartInquiry [1.0.0-11.0.1]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. Inquiry will automatically stop in 10.24 seconds. * @note This is used by btm-sysmodule. */ Result btdrvLegacyStartInquiry(void); /** - * @brief StartInquiry [12.0.0+] This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. - * @param[in] services Bitmask of allowed services. When -1 the original defaults from pre-12.0.0 are used. + * @brief StartInquiry [12.0.0+]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. + * @param[in] services Bitfield of allowed services. When -1 the original defaults from pre-12.0.0 are used. * @param[in] duration Inquiry duration in nanoseconds. * @note This is used by btm-sysmodule. */ @@ -658,7 +649,7 @@ Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type); /** * @brief SetTsi - * @note The response will be available via \ref btdrvGetHidEventInfo. + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). * @note This is used by btm-sysmodule. * @param[in] addr \ref BtdrvAddress * @param[in] tsi Tsi: non-value-0xFF to Set, value 0xFF to Exit. See also \ref BtmTsiMode. @@ -667,7 +658,7 @@ Result btdrvSetTsi(BtdrvAddress addr, u8 tsi); /** * @brief EnableBurstMode - * @note The response will be available via \ref btdrvGetHidEventInfo. + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). * @note This is used by btm-sysmodule. * @param[in] addr \ref BtdrvAddress * @param[in] flag Flag: true = Set, false = Exit. @@ -676,7 +667,7 @@ Result btdrvEnableBurstMode(BtdrvAddress addr, bool flag); /** * @brief SetZeroRetransmission - * @note The response will be available via \ref btdrvGetHidEventInfo. + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). * @note This is used by btm-sysmodule. * @param[in] addr \ref BtdrvAddress * @param[in] report_ids Input buffer containing an array of u8s. @@ -756,7 +747,7 @@ Result btdrvGetLatestPlr(BtdrvPlrList *out); /** * @brief GetPendingConnections - * @note The output data will be available via \ref btdrvGetHidEventInfo. + * @note The output data will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). * @note This is used by btm-sysmodule. * @note Only available on [3.0.0+]. */ @@ -1284,7 +1275,7 @@ Result btdrvSetBleScanParameter(u16 unk0, u16 unk1); /** * @brief MoveToSecondaryPiconet - * @note The response will be available via \ref btdrvGetHidEventInfo. + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). * @note Only available on [10.0.0+]. * @param[in] addr \ref BtdrvAddress */ diff --git a/nx/include/switch/services/btdrv_types.h b/nx/include/switch/services/btdrv_types.h index 8dbb5d86..a5fb5803 100644 --- a/nx/include/switch/services/btdrv_types.h +++ b/nx/include/switch/services/btdrv_types.h @@ -51,8 +51,8 @@ typedef enum { /// BtdrvInquiryStatus typedef enum { - BtdrvInquiryStatus_Stopped = 0, ///< Inquiry started. - BtdrvInquiryStatus_Started = 1, ///< Inquiry stopped. + BtdrvInquiryStatus_Stopped = 0, ///< Inquiry stopped. + BtdrvInquiryStatus_Started = 1, ///< Inquiry started. } BtdrvInquiryStatus; /// ConnectionEventType @@ -104,6 +104,7 @@ typedef enum { ///< BtdrvHidConnectionStatus_* should be used on [12.0.0+] BtdrvHidConnectionStatus_Closed = 0, BtdrvHidConnectionStatus_Opened = 1, + BtdrvHidConnectionStatus_Failed = 2, ///< BtdrvHidConnectionStatusOld_* should be used on [1.0.0-11.0.1] BtdrvHidConnectionStatusOld_Opened = 0, @@ -118,6 +119,7 @@ typedef enum { BtdrvFatalReason_CommandTimeout = 2, ///< HCI command timeout. BtdrvFatalReason_HardwareError = 3, ///< HCI event HCI_Hardware_Error occurred. BtdrvFatalReason_Enable = 7, ///< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field. + BtdrvFatalReason_Audio = 9, ///< [12.0.0+] Only for \ref BtdrvEventInfo: triggered by Audio cmds in some cases. } BtdrvFatalReason; /// BleEventType @@ -177,14 +179,14 @@ typedef struct { typedef struct { u8 type; ///< \ref BtdrvAdapterPropertyType u8 size; ///< Data size. - u8 data[0x100]; ///< Data (Above size), as specified by the type. + u8 data[0x100]; ///< Data (above size), as specified by the type. } BtdrvAdapterProperty; /// AdapterPropertySet [12.0.0+] typedef struct { BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address. BtdrvClassOfDevice class_of_device; ///< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. - char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized). + char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name. } BtdrvAdapterPropertySet; /// BluetoothPinCode [1.0.0-11.0.1] diff --git a/nx/source/services/btdrv.c b/nx/source/services/btdrv.c index 474a1533..8f24fefc 100644 --- a/nx/source/services/btdrv.c +++ b/nx/source/services/btdrv.c @@ -174,6 +174,9 @@ Result btdrvFinalizeBluetooth(void) { } Result btdrvLegacyGetAdapterProperties(BtdrvAdapterPropertyOld *properties) { + if (hosversionAtLeast(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return serviceDispatch(&g_btdrvSrv, 5, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, .buffers = { { properties, sizeof(*properties) } }, @@ -181,6 +184,9 @@ Result btdrvLegacyGetAdapterProperties(BtdrvAdapterPropertyOld *properties) { } Result btdrvGetAdapterProperties(BtdrvAdapterPropertySet *properties) { + if (hosversionBefore(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return serviceDispatch(&g_btdrvSrv, 5, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, .buffers = { { properties, sizeof(*properties) } }, @@ -188,6 +194,9 @@ Result btdrvGetAdapterProperties(BtdrvAdapterPropertySet *properties) { } Result btdrvLegacyGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, size_t size) { + if (hosversionAtLeast(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u32 tmp=type; return serviceDispatchIn(&g_btdrvSrv, 6, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out }, @@ -196,6 +205,9 @@ Result btdrvLegacyGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buff } Result btdrvGetAdapterProperty(BtdrvAdapterPropertyType type, BtdrvAdapterProperty *property) { + if (hosversionBefore(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u32 tmp=type; return serviceDispatchIn(&g_btdrvSrv, 6, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, @@ -204,6 +216,9 @@ Result btdrvGetAdapterProperty(BtdrvAdapterPropertyType type, BtdrvAdapterProper } Result btdrvLegacySetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size) { + if (hosversionAtLeast(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u32 tmp=type; return serviceDispatchIn(&g_btdrvSrv, 7, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In }, @@ -212,6 +227,9 @@ Result btdrvLegacySetAdapterProperty(BtdrvBluetoothPropertyType type, const void } Result btdrvSetAdapterProperty(BtdrvAdapterPropertyType type, const BtdrvAdapterProperty *property) { + if (hosversionBefore(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u32 tmp=type; return serviceDispatchIn(&g_btdrvSrv, 7, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In | SfBufferAttr_FixedSize }, @@ -220,10 +238,16 @@ Result btdrvSetAdapterProperty(BtdrvAdapterPropertyType type, const BtdrvAdapter } Result btdrvLegacyStartInquiry(void) { + if (hosversionAtLeast(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _btdrvCmdNoIO(8); } Result btdrvStartInquiry(u32 services, s64 duration) { + if (hosversionBefore(12,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + const struct { u32 services; s64 duration; @@ -500,12 +524,13 @@ Result btdrvGetHidReportEventInfo(void* buffer, size_t size, BtdrvHidEventType * *type = BtdrvHidEventType_Data; return 0; } - if (*type == BtdrvHidEventType_GetReport) { + bool is_old = hosversionBefore(12,0,0); + if ((is_old && *type == BtdrvHidEventTypeOld_GetReport) || (!is_old && *type == BtdrvHidEventType_GetReport)) { if (hosversionBefore(9,0,0)) memcpy(info->get_report.v1.rawdata, data_ptr->data.get_report.v1.rawdata, sizeof(info->get_report.v1.rawdata)); else memcpy(info->get_report.v9.rawdata, data_ptr->data.get_report.v9.rawdata, sizeof(info->get_report.v9.rawdata)); } - else if (*type == BtdrvHidEventType_SetReport) memcpy(info->set_report.rawdata, data_ptr->data.set_report.rawdata, sizeof(info->set_report.rawdata)); - else if (*type == BtdrvHidEventType_Data) { + else if ((is_old && *type == BtdrvHidEventTypeOld_SetReport) || (!is_old && *type == BtdrvHidEventType_SetReport)) memcpy(info->set_report.rawdata, data_ptr->data.set_report.rawdata, sizeof(info->set_report.rawdata)); + else if ((is_old && *type == BtdrvHidEventTypeOld_Data) || (!is_old && *type == BtdrvHidEventType_Data)) { u16 tmpsize = hosversionBefore(9,0,0) ? data_ptr->data.data_report.v7.report.size : data_ptr->data.data_report.v9.report.size; if (size < 0xE) return MAKERESULT(Module_Libnx, LibnxError_BadInput); if (tmpsize > size-0xE) tmpsize = size-0xE;