diff --git a/nx/include/switch/services/btdrv.h b/nx/include/switch/services/btdrv.h index 1d2211d9..4c541568 100644 --- a/nx/include/switch/services/btdrv.h +++ b/nx/include/switch/services/btdrv.h @@ -21,22 +21,43 @@ typedef struct { } type0; ///< ::BtdrvEventType_Unknown0 struct { - char name[0xF9]; ///< Device name, NUL-terminated string. - BtdrvAddress addr; ///< Device address. - u8 reserved_xFF[0x10]; ///< Reserved - BtdrvClassOfDevice class_of_device; ///< Class of Device. - u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1. - u8 reserved_x116[0xFA]; ///< Reserved - u8 reserved_x210[0x5C]; ///< Reserved - char name2[0xF9]; ///< Device name, NUL-terminated string. Same as name above, except starting at index 1. - u8 rssi[0x4]; ///< s32 RSSI - u8 name3[0x4]; ///< Two bytes which are the same as name[11-12]. - u8 reserved_x36D[0x10]; ///< Reserved - } inquiry_device; ///< ::BtdrvEventType_InquiryDevice + union { + struct { + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvAddress addr; ///< Device address. + u8 reserved_xFF[0x10]; ///< Reserved + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1. + u8 reserved_x116[0xFA]; ///< Reserved + u8 reserved_x210[0x5C]; ///< Reserved + char name2[0xF9]; ///< Device name, NUL-terminated string. Same as name above, except starting at index 1. + u8 rssi[0x4]; ///< s32 RSSI + u8 name3[0x4]; ///< Two bytes which are the same as name[11-12]. + u8 reserved_x36D[0x10]; ///< Reserved + } v1; + + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 reserved[0x6]; + } v12; + }; + } inquiry_device; ///< ::BtdrvEventType_InquiryDevice struct { - BtdrvInquiryStatus status; ///< Status: 0 = stopped, 1 = started. - } inquiry_status; ///< ::BtdrvEventType_InquiryStatus + union { + struct { + BtdrvInquiryStatus status; ///< Status: 0 = stopped, 1 = started. + } v1; + + struct { + BtdrvInquiryStatus status; ///< Status: 0 = stopped, 1 = started. + u8 pad[3]; ///< Padding + u32 service_mask; + } v12; + }; + } inquiry_status; ///< ::BtdrvEventType_InquiryStatus struct { BtdrvAddress addr; ///< Device address. @@ -45,19 +66,43 @@ typedef struct { } pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest struct { - BtdrvAddress addr; ///< Device address. - char name[0xF9]; ///< Device name, NUL-terminated string. - BtdrvClassOfDevice class_of_device; ///< Class of Device. - u8 pad[2]; ///< Padding - u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification. - s32 passkey; ///< Passkey, only set when the above field is value 3. + union { + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 pad[2]; ///< Padding + u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification. + s32 passkey; ///< Passkey, only set when the above field is value 3. + } v1; + + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification. + u8 pad; ///< Padding + s32 passkey; ///< Passkey, only set when the above field is value 3. + } v12; + }; + } ssp_request; ///< ::BtdrvEventType_SspRequest struct { - u32 status; ///< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). - BtdrvAddress addr; ///< Device address. - u8 pad[2]; ///< Padding - u32 type; ///< \ref BtdrvConnectionEventType + union { + struct { + u32 status; ///< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + u32 type; ///< \ref BtdrvConnectionEventType + } v1; + + struct { + u32 type; ///< \ref BtdrvConnectionEventType + BtdrvAddress addr; ///< Device address. + u8 reserved[0xfe]; + } v12; + }; } connection; ///< ::BtdrvEventType_Connection struct { @@ -72,9 +117,18 @@ typedef struct { u8 data[0x480]; ///< Raw data. struct { - BtdrvAddress addr; ///< Device address. - u8 pad[2]; ///< Padding - BtdrvHidConnectionStatus status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection. + union { + struct { + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + BtdrvHidConnectionStatus status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection. + } v1; + + struct { + BtdrvHidConnectionStatusV12 status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection. + BtdrvAddress addr; ///< Device address. + } v12; + }; } connection; ///< ::BtdrvHidEventType_Connection struct { @@ -415,9 +469,9 @@ Result btdrvCancelBond(BtdrvAddress addr); * @param[in] addr \ref BtdrvAddress * @param[in] flag Flag * @param[in] pin_code \ref BtdrvBluetoothPinCode - * @param[in] unk Unknown + * @param[in] length Length of pin_code */ -Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 unk); +Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 length); /** * @brief RespondToSspRequest diff --git a/nx/include/switch/services/btdrv_types.h b/nx/include/switch/services/btdrv_types.h index 94618017..7a2a9e34 100644 --- a/nx/include/switch/services/btdrv_types.h +++ b/nx/include/switch/services/btdrv_types.h @@ -16,7 +16,7 @@ typedef enum { BtdrvBluetoothPropertyType_FeatureSet = 6, ///< 1-byte, FeatureSet. The default is value 0x68. } BtdrvBluetoothPropertyType; -/// EventType +/// EventType [1.0.0-11.0.1] typedef enum { BtdrvEventType_Unknown0 = 0, ///< Unused BtdrvEventType_InquiryDevice = 3, ///< Device found during Inquiry. @@ -27,7 +27,22 @@ typedef enum { BtdrvEventType_BluetoothCrash = 13, ///< BluetoothCrash } BtdrvEventType; -/// BtdrvInquiryStatus +/// EventType [12.0.0] +typedef enum { + BtdrvEventTypeV12_InquiryDevice = 0, ///< Device found during Inquiry. + BtdrvEventTypeV12_InquiryStatus = 1, ///< Inquiry status changed. + BtdrvEventTypeV12_PairingPinCodeRequest = 2, ///< Pairing PIN code request. + BtdrvEventTypeV12_SspRequest = 3, ///< SSP confirm request / SSP passkey notification. + BtdrvEventTypeV12_Connection = 4, ///< Connection + BtdrvEventTypeV12_Tsi = 5, ///< SetTsi (\ref btdrvSetTsi) + BtdrvEventTypeV12_BurstMode = 6, ///< SetBurstMode (\ref btdrvEnableBurstMode) + BtdrvEventTypeV12_SetZeroRetransmission = 7, ///< \ref btdrvSetZeroRetransmission + BtdrvEventTypeV12_PendingConnections = 8, ///< \ref btdrvGetPendingConnections + BtdrvEventTypeV12_MoveToSecondaryPiconet = 9, ///< \ref btdrvMoveToSecondaryPiconet + BtdrvEventTypeV12_BluetoothCrash = 10, ///< BluetoothCrash +} BtdrvEventTypeV12; + +/// BtdrvInquiryStatus typedef enum { BtdrvInquiryStatus_Stopped = 0, ///< Inquiry started. BtdrvInquiryStatus_Started = 1, ///< Inquiry stopped. @@ -40,7 +55,7 @@ typedef enum { BtdrvConnectionEventType_Suspended = 2, ///< ACL Link is now Suspended. } BtdrvConnectionEventType; -/// ExtEventType +/// ExtEventType [1.0.0-11.0.1] typedef enum { BtdrvExtEventType_SetTsi = 0, ///< SetTsi (\ref btdrvSetTsi) BtdrvExtEventType_ExitTsi = 1, ///< ExitTsi (\ref btdrvSetTsi) @@ -61,7 +76,7 @@ typedef enum { BtdrvBluetoothHhReportType_Feature = 3, ///< Feature } BtdrvBluetoothHhReportType; -/// HidEventType +/// HidEventType [1.0.0-11.0.1] typedef enum { BtdrvHidEventType_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo. BtdrvHidEventType_Data = 4, ///< DATA report on the Interrupt channel. @@ -70,6 +85,14 @@ typedef enum { BtdrvHidEventType_GetReport = 9, ///< Response to GET_REPORT. } BtdrvHidEventType; +/// HidEventType [12.0.0] +typedef enum { + BtdrvHidEventTypeV12_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventTypeV12_Data = 1, ///< DATA report on the Interrupt channel. + BtdrvHidEventTypeV12_SetReport = 2, ///< Response to SET_REPORT. + BtdrvHidEventTypeV12_GetReport = 3, ///< Response to GET_REPORT. +} BtdrvHidEventTypeV12; + /// HidConnectionStatus typedef enum { BtdrvHidConnectionStatus_Connected = 0, @@ -77,6 +100,12 @@ typedef enum { BtdrvHidConnectionStatus_FailedGeneric = 8, } BtdrvHidConnectionStatus; +/// HidConnectionStatusV12 +typedef enum { + BtdrvHidConnectionStatusV12_Disconnected = 0, + BtdrvHidConnectionStatusV12_Connected = 1, +} BtdrvHidConnectionStatusV12; + /// This determines the u16 data to write into a CircularBuffer. typedef enum { BtdrvFatalReason_Invalid = 0, ///< Only for \ref BtdrvEventInfo: invalid. @@ -127,6 +156,12 @@ typedef struct { char code[0x10]; ///< PinCode } BtdrvBluetoothPinCode; +/// BtdrvPinCode +typedef struct { + char code[0x10]; ///< PinCode + u8 length; ///< Length +} BtdrvPinCode; + /// HidData, for pre-9.0.0. typedef struct { u16 size; ///< Size of data. diff --git a/nx/source/services/btdrv.c b/nx/source/services/btdrv.c index fe0769e4..6a20dc72 100644 --- a/nx/source/services/btdrv.c +++ b/nx/source/services/btdrv.c @@ -213,15 +213,26 @@ Result btdrvCancelBond(BtdrvAddress addr) { return _btdrvCmdInAddrNoOut(addr, 12); } -Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 unk) { - const struct { - BtdrvAddress addr; - u8 flag; - u8 unk; - BtdrvBluetoothPinCode pin_code; - } in = { addr, flag!=0, unk, *pin_code }; +Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 length) { + if (hosversionBefore(12,0,0)) { + const struct { + BtdrvAddress addr; + u8 flag; + u8 length; + BtdrvBluetoothPinCode pin_code; + } in = { addr, flag!=0, length, *pin_code }; - return serviceDispatchIn(&g_btdrvSrv, 13, in); + return serviceDispatchIn(&g_btdrvSrv, 13, in); + } + else { + const struct { + BtdrvAddress addr; + BtdrvBluetoothPinCode pin_code; + uint8_t length; + } in = { addr, *pin_code, length }; + + return serviceDispatchIn(&g_btdrvSrv, 13, in); + } } Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 unk) {