Bluetooth pr rebased (#552 and #540)

* btdrv: expand upon and refine event data definitions

* btdrv changes for 12.0.0

* btdrv: Various fixes, added enums, etc.

Co-authored-by: ndeadly <24677491+ndeadly@users.noreply.github.com>
This commit is contained in:
yellows8 2021-05-30 13:47:36 -04:00 committed by GitHub
parent 5d448a1048
commit f486127615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 593 additions and 219 deletions

View File

@ -1,7 +1,7 @@
/**
* @file btdrv.h
* @brief Bluetooth driver (btdrv) service IPC wrapper.
* @author yellows8
* @author yellows8, ndeadly
* @copyright libnx Authors
*/
#pragma once
@ -14,215 +14,276 @@
/// Data for \ref btdrvGetEventInfo. The data stored here depends on the \ref BtdrvEventType.
typedef struct {
union {
u8 data[0x400]; ///< Raw data.
u8 data[0x400]; ///< Raw data.
struct {
u32 val; ///< Value
} type0; ///< ::BtdrvEventType_Unknown0
u32 val; ///< Value
} type0; ///< ::BtdrvEventTypeOld_Unknown0
struct {
u8 name[0xF9]; ///< Device name, NUL-terminated string.
BtdrvAddress addr; ///< Device address.
u8 reserved_xFF[0x10]; ///< Reserved
u8 class_of_device[0x3]; ///< Class of Device.
u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1.
u8 reserved_x116[0xFA]; ///< Reserved
u8 reserved_x210[0x5C]; ///< Reserved
u8 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; ///< [1.0.0-11.0.1]
struct {
BtdrvAddress addr; ///< Device address.
char name[0xF9]; ///< Device name, NUL-terminated string.
BtdrvClassOfDevice class_of_device; ///< Class of Device.
u8 reserved[0x6]; ///< Reserved
} v12; ///< [12.0.0+]
};
} inquiry_device; ///< ::BtdrvEventType_InquiryDevice
struct {
u32 status; ///< Status: 0 = stopped, 1 = started.
} inquiry_status; ///< ::BtdrvEventType_InquiryStatus
union {
struct {
BtdrvInquiryStatus status; ///< \ref BtdrvInquiryStatus
} v1; ///< [1.0.0-11.0.1]
struct {
u8 status; ///< \ref BtdrvInquiryStatus
u8 pad[3]; ///< Padding
u32 service_mask; ///< Services value from \ref btdrvStartInquiry when starting, otherwise this is value 0.
} v12; ///< [12.0.0+]
};
} inquiry_status; ///< ::BtdrvEventType_InquiryStatus
struct {
BtdrvAddress addr; ///< Device address.
u8 name[0xF9]; ///< Device name, NUL-terminated string.
u8 class_of_device[0x3]; ///< Class of Device.
} pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest
BtdrvAddress addr; ///< Device address.
char name[0xF9]; ///< Device name, NUL-terminated string.
BtdrvClassOfDevice class_of_device; ///< Class of Device.
} pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest
struct {
BtdrvAddress addr; ///< Device address.
u8 name[0xF9]; ///< Device name, NUL-terminated string.
u8 class_of_device[0x3]; ///< 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.
} ssp_request; ///< ::BtdrvEventType_SspRequest
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; ///< [1.0.0-11.0.1]
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 pad; ///< Padding
s32 passkey; ///< Passkey
} v12; ///< [12.0.0+]
};
} 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
} connection; ///< ::BtdrvEventType_Connection
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; ///< [1.0.0-11.0.1]
struct {
u32 type; ///< \ref BtdrvConnectionEventType
BtdrvAddress addr; ///< Device address.
u8 reserved[0xfe]; ///< Reserved
} v12; ///< [12.0.0+]
};
} connection; ///< ::BtdrvEventType_Connection
struct {
u16 reason; ///< \ref BtdrvFatalReason
} bluetooth_crash; ///< ::BtdrvEventType_BluetoothCrash
BtdrvAddress addr; ///< Device address.
u8 status; ///< Status flag: 1 = success, 0 = failure.
u8 value; ///< Tsi value, when the above indicates success.
} tsi; ///< ::BtdrvEventType_Tsi
struct {
BtdrvAddress addr; ///< Device address.
u8 status; ///< Status flag: 1 = success, 0 = failure.
u8 value; ///< Input bool value from \ref btdrvEnableBurstMode, when the above indicates success.
} burst_mode; ///< ::BtdrvEventType_BurstMode
struct {
BtdrvAddress addr; ///< Device address.
u8 status; ///< Status flag: 1 = success, 0 = failure.
u8 flag; ///< Bool flag, when the above indicates success.
} set_zero_retransmission; ///< ::BtdrvEventType_SetZeroRetransmission
struct {
u8 status; ///< Status flag: 1 = success, 0 = failure.
u8 pad[0x3]; ///< Padding
u32 count; ///< Count value.
} pending_connections; ///< ::BtdrvEventType_PendingConnections
struct {
BtdrvAddress addr; ///< Device address.
u8 status; ///< Status flag: 1 = success, 0 = failure.
} move_to_secondary_piconet; ///< ::BtdrvEventType_MoveToSecondaryPiconet
struct {
u16 reason; ///< \ref BtdrvFatalReason
} bluetooth_crash; ///< ::BtdrvEventType_BluetoothCrash
};
} BtdrvEventInfo;
/// Data for \ref btdrvGetHidEventInfo. The data stored here depends on the \ref BtdrvHidEventType.
typedef struct {
union {
u8 data[0x480]; ///< Raw data.
u8 data[0x480]; ///< Raw data.
struct {
BtdrvAddress addr; ///< Device address.
u8 pad[2]; ///< Padding
u32 status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection.
} connection; ///< ::BtdrvHidEventType_Connection
BtdrvAddress addr; ///< Device address.
u8 pad[2]; ///< Padding
BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus
} connection; ///< ::BtdrvHidEventType_Connection
struct {
u32 type; ///< \ref BtdrvExtEventType, controls which data is stored below.
u32 type; ///< \ref BtdrvExtEventType, controls which data is stored below.
union {
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} set_tsi; ///< ::BtdrvExtEventType_SetTsi
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} set_tsi; ///< ::BtdrvExtEventType_SetTsi
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} exit_tsi; ///< ::BtdrvExtEventType_ExitTsi
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} exit_tsi; ///< ::BtdrvExtEventType_ExitTsi
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} set_burst_mode; ///< ::BtdrvExtEventType_SetBurstMode
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} set_burst_mode; ///< ::BtdrvExtEventType_SetBurstMode
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} exit_burst_mode; ///< ::BtdrvExtEventType_ExitBurstMode
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} exit_burst_mode; ///< ::BtdrvExtEventType_ExitBurstMode
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
u8 pad[2]; ///< Padding
u8 flag; ///< Flag
} set_zero_retransmission; ///< ::BtdrvExtEventType_SetZeroRetransmission
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
u8 pad[2]; ///< Padding
u8 flag; ///< Flag
} set_zero_retransmission; ///< ::BtdrvExtEventType_SetZeroRetransmission
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Unused
u8 pad[2]; ///< Padding
u32 count; ///< Count value.
} pending_connections; ///< ::BtdrvExtEventType_PendingConnections
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Unused
u8 pad[2]; ///< Padding
u32 count; ///< Count value.
} pending_connections; ///< ::BtdrvExtEventType_PendingConnections
struct {
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} move_to_secondary_piconet; ///< ::BtdrvExtEventType_MoveToSecondaryPiconet
u32 status; ///< 0 for success, non-zero for error.
BtdrvAddress addr; ///< Device address.
} move_to_secondary_piconet; ///< ::BtdrvExtEventType_MoveToSecondaryPiconet
};
} ext; ///< ::BtdrvHidEventType_Ext
} ext; ///< ::BtdrvHidEventType_Ext [1.0.0-11.0.1]
};
} BtdrvHidEventInfo;
/// Data for \ref btdrvGetHidReportEventInfo. The data stored here depends on the \ref BtdrvHidEventType.
typedef struct {
union {
u8 data[0x480]; ///< Raw data.
struct {
u32 unk_x0; ///< Always 0.
u8 unk_x4; ///< Always 0.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad; ///< Padding
u16 size; ///< Size of the below data.
u8 data[]; ///< Data.
} data_report; ///< ::BtdrvHidEventType_Data
u8 data[0x480]; ///< Raw data.
struct {
union {
u8 data[0xC]; ///< Raw data.
struct {
struct {
BtdrvAddress addr;
u8 pad[2];
u32 res;
u32 size;
} hdr;
u8 unused[0x3]; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 unused2[0x3]; ///< Unused
BtdrvHidData report;
} v1; ///< [1.0.0-6.2.0]
struct {
u32 res; ///< 0 = success, non-zero = error.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
u8 unused[0x3]; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 unused2[0x3]; ///< Unused
BtdrvHidData report;
} v7; ///< [7.0.0-8.1.1]
struct {
u32 res; ///< Always 0.
u8 unk_x4; ///< Always 0.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad; ///< Padding
BtdrvHidReport report;
} v9; ///< [9.0.0+]
};
} data_report; ///< ::BtdrvHidEventType_DataReport
struct {
union {
u8 rawdata[0xC]; ///< Raw data.
struct {
u32 res; ///< 0 = success, non-zero = error.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
};
};
} set_report; ///< ::BtdrvHidEventType_SetReport
} set_report; ///< ::BtdrvHidEventType_SetReport
struct {
union {
union {
u8 rawdata[0x290]; ///< Raw data.
u8 rawdata[0x290]; ///< Raw data.
struct {
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
u32 res; ///< 0 = success, non-zero = error. hid-sysmodule only uses the below data when this field is 0.
BtdrvHidData data; ///< \ref BtdrvHidData
u8 pad2[2]; ///< Padding
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
u32 res; ///< Unknown. hid-sysmodule only uses the below data when this field is 0.
BtdrvHidData report; ///< \ref BtdrvHidData
u8 pad2[2]; ///< Padding
};
} hid_data; ///< Pre-9.0.0
} v1; ///< [1.0.0-8.1.1]
union {
u8 rawdata[0x2C8]; ///< Raw data.
u8 rawdata[0x2C8]; ///< Raw data.
struct {
u32 res; ///< 0 = success, non-zero = error. hid-sysmodule only uses the below report when this field is 0.
BtdrvAddress addr; ///< \ref BtdrvAddress
BtdrvHidReport report; ///< \ref BtdrvHidReport
u32 res; ///< Unknown. hid-sysmodule only uses the below report when this field is 0.
BtdrvAddress addr; ///< \ref BtdrvAddress
BtdrvHidReport report; ///< \ref BtdrvHidReport
};
} hid_report; ///< [9.0.0+]
} v9; ///< [9.0.0+]
};
} get_report; ///< ::BtdrvHidEventType_GetReport
} get_report; ///< ::BtdrvHidEventType_GetReport
};
} BtdrvHidReportEventInfo;
/// The raw sharedmem data for HidReportEventInfo.
typedef struct {
struct {
u8 type; ///< \ref BtdrvHidEventType
u8 type; ///< \ref BtdrvHidEventType
u8 pad[7];
u64 tick;
u64 size;
} hdr;
union {
struct {
struct {
u8 unused[0x3]; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 unused2[0x3]; ///< Unused
u16 size; ///< Size of the below data.
u8 data[]; ///< Data.
} v1; ///< Pre-9.0.0
struct {
u8 unused[0x4]; ///< Unused
u8 unused_x4; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad; ///< Padding
u16 size; ///< Size of the below data.
u8 data[]; ///< Data.
} v9; ///< [9.0.0+]
} data_report; ///< ::BtdrvHidEventType_Data
struct {
u8 data[0xC]; ///< Raw data.
} set_report; ///< ::BtdrvHidEventType_SetReport
struct {
union {
struct {
u8 rawdata[0x290]; ///< Raw data.
} hid_data; ///< Pre-9.0.0
struct {
u8 rawdata[0x2C8]; ///< Raw data.
} hid_report; ///< [9.0.0+]
};
} get_report; ///< ::BtdrvHidEventType_GetReport
} data;
BtdrvHidReportEventInfo data;
} BtdrvHidReportEventInfoBufferData;
/// Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType.
@ -237,7 +298,7 @@ typedef union {
/// CircularBuffer
typedef struct {
Mutex mutex;
void* event_type; ///< Not set with sharedmem.
void* event_type; ///< Not set with sharedmem.
u8 data[0x2710];
s32 write_offset;
s32 read_offset;
@ -246,6 +307,99 @@ typedef struct {
u8 initialized;
} BtdrvCircularBuffer;
/// Data for \ref btdrvGetBleManagedEventInfo. The data stored here depends on the \ref BtdrvBleEventType.
typedef struct {
union {
u8 data[0x400];
struct {
u32 status;
u8 handle;
u8 registered;
} type0;
struct {
u32 status;
u32 conn_id;
u32 unk_x8;
u32 unk_xC;
} type2;
struct {
u32 conn_id;
u16 min_interval;
u16 max_interval;
u16 slave_latency;
u16 timeout_multiplier;
} type3; ///< Connection params?
struct {
u32 status;
u8 unk_x4;
u8 unk_x5;
u8 unk_x6;
u8 unk_x7;
u32 conn_id;
BtdrvAddress address;
u16 unk_x12;
} type4; ///< Connection status?
struct {
u32 status;
u8 unk_x4;
u8 unk_x5;
u8 unk_x6;
BtdrvAddress address;
BtdrvBleAdvertisementData adv[10];
u8 count;
u32 unk_x144;
} type6; ///< Scan result?
struct {
u32 status;
u32 conn_id;
} type7;
struct {
u32 status;
u8 interface;
u8 unk_x5;
u16 unk_x6;
u32 unk_x8;
BtdrvGattAttributeUuid svc_uuid;
BtdrvGattAttributeUuid char_uuid;
BtdrvGattAttributeUuid descr_uuid;
u16 size;
u8 data[0x202];
} type8; ///< Notification?
struct {
u32 status;
u32 conn_id;
u32 unk_x8;
u8 unk_xC[0x140];
} type9;
struct {
u32 status;
u32 conn_id;
u8 unk_x8[0x24];
u32 unk_x2C;
u8 unk_x30[0x11c];
} type10;
struct {
u32 status;
u32 conn_id;
u16 unk_x8;
} type11;
struct {
u8 unk_x0[0x218];
} type13;
};
} BtdrvBleEventInfo;
/// Initialize btdrv.
Result btdrvInitialize(void);
@ -282,32 +436,60 @@ Result btdrvDisableBluetooth(void);
Result btdrvFinalizeBluetooth(void);
/**
* @brief GetAdapterProperties
* @param[out] property \ref BtdrvAdapterProperty
* @brief GetAdapterProperties [1.0.0-11.0.1]
* @param[out] properties \ref BtdrvAdapterPropertyOld
*/
Result btdrvGetAdapterProperties(BtdrvAdapterProperty *property);
Result btdrvLegacyGetAdapterProperties(BtdrvAdapterPropertyOld *properties);
/**
* @brief GetAdapterProperty
* @brief GetAdapterProperties [12.0.0+]
* @param[out] properties \ref BtdrvAdapterPropertySet
*/
Result btdrvGetAdapterProperties(BtdrvAdapterPropertySet *properties);
/**
* @brief GetAdapterProperty [1.0.0-11.0.1]
* @param[in] type \ref BtdrvBluetoothPropertyType
* @param[out] buffer Output buffer, see \ref BtdrvBluetoothPropertyType for the contents.
* @param[in] size Output buffer size.
*/
Result btdrvGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, size_t size);
Result btdrvLegacyGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, size_t size);
/**
* @brief SetAdapterProperty
* @brief GetAdapterProperty [12.0.0+]
* @param[in] type \ref BtdrvAdapterPropertyType
* @param[in] property \ref BtdrvAdapterProperty
*/
Result btdrvGetAdapterProperty(BtdrvAdapterPropertyType type, BtdrvAdapterProperty *property);
/**
* @brief SetAdapterProperty [1.0.0-11.0.1]
* @param[in] type \ref BtdrvBluetoothPropertyType
* @param[in] buffer Input buffer, see \ref BtdrvBluetoothPropertyType for the contents.
* @param[in] size Input buffer size.
*/
Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size);
Result btdrvLegacySetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size);
/**
* @brief This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. Inquiry will automatically stop in 10.24 seconds.
* @brief SetAdapterProperty [12.0.0+]
* @param[in] type \ref BtdrvAdapterPropertyType
* @param[in] property \ref BtdrvAdapterProperty
*/
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.
* @note This is used by btm-sysmodule.
*/
Result btdrvStartInquiry(void);
Result btdrvLegacyStartInquiry(void);
/**
* @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.
*/
Result btdrvStartInquiry(u32 services, s64 duration);
/**
* @brief This stops Inquiry which was started by \ref btdrvStartInquiry, if it's still active.
@ -338,14 +520,21 @@ Result btdrvRemoveBond(BtdrvAddress addr);
Result btdrvCancelBond(BtdrvAddress addr);
/**
* @brief RespondToPinRequest
* @brief RespondToPinRequest [1.0.0-11.0.1]
* @note The official sysmodule only uses the input \ref BtdrvAddress.
* @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 btdrvLegacyRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 length);
/**
* @brief RespondToPinRequest [12.0.0+]
* @param[in] addr \ref BtdrvAddress
* @param[in] pin_code \ref BtdrvPinCode
*/
Result btdrvRespondToPinRequest(BtdrvAddress addr, const BtdrvPinCode *pin_code);
/**
* @brief RespondToSspRequest
@ -353,19 +542,19 @@ Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoo
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] variant BluetoothSspVariant
* @param[in] flag Whether the request is accepted.
* @param[in] unk Unknown
* @param[in] accept Whether the request is accepted.
* @param[in] passkey Passkey.
*/
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 unk);
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool accept, u32 passkey);
/**
* @brief GetEventInfo
* @note This is used by btm-sysmodule.
* @param[out] buffer Output buffer, see \ref BtdrvEventInfo.
* @param[in] size Output buffer size.
* @oaram[out] type Output EventType.
* @param[out] type Output BtdrvEventType.
*/
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type);
Result btdrvGetEventInfo(void* buffer, size_t size, BtdrvEventType *type);
/**
* @brief InitializeHid
@ -460,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.
@ -469,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.
@ -478,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.
@ -558,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+].
*/
@ -885,9 +1074,9 @@ Result btdrvAddGattDescriptor(u8 unk0, const BtdrvGattAttributeUuid *uuid0, cons
* @note This is used by btm-sysmodule.
* @param[out] buffer Output buffer. 0x400-bytes from state is written here.
* @param[in] size Output buffer size.
* @oaram[out] type Output BleEventType.
* @oaram[out] type Output BtdrvBleEventType.
*/
Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, u32 *type);
Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, BtdrvBleEventType *type);
/**
* @brief GetGattFirstCharacteristic
@ -1086,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
*/

View File

@ -1,32 +1,60 @@
/**
* @file btdrv_types.h
* @brief Bluetooth driver (btdrv) service types (see btdrv.h for the rest).
* @author yellows8
* @author yellows8, ndeadly
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
/// BluetoothPropertyType
/// BluetoothPropertyType [1.0.0-11.0.1]
typedef enum {
BtdrvBluetoothPropertyType_Name = 1, ///< Name. String, max length 0xF8 excluding NUL-terminator.
BtdrvBluetoothPropertyType_Address = 2, ///< \ref BtdrvAddress
BtdrvBluetoothPropertyType_Unknown3 = 3, ///< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress.
BtdrvBluetoothPropertyType_ClassOfDevice = 5, ///< 3-bytes, Class of Device.
BtdrvBluetoothPropertyType_FeatureSet = 6, ///< 1-byte, FeatureSet. The default is value 0x68.
BtdrvBluetoothPropertyType_Name = 1, ///< Name. String, max length 0xF8 excluding NUL-terminator.
BtdrvBluetoothPropertyType_Address = 2, ///< \ref BtdrvAddress
BtdrvBluetoothPropertyType_Unknown3 = 3, ///< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress.
BtdrvBluetoothPropertyType_ClassOfDevice = 5, ///< 3-bytes, Class of Device.
BtdrvBluetoothPropertyType_FeatureSet = 6, ///< 1-byte, FeatureSet. The default is value 0x68.
} BtdrvBluetoothPropertyType;
/// AdapterPropertyType [12.0.0+]
typedef enum {
BtdrvAdapterPropertyType_Address = 0, ///< \ref BtdrvAddress
BtdrvAdapterPropertyType_Name = 1, ///< Name. String, max length 0xF8 excluding NUL-terminator.
BtdrvAdapterPropertyType_ClassOfDevice = 2, ///< 3-bytes, Class of Device.
BtdrvAdapterPropertyType_Unknown3 = 3, ///< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress.
} BtdrvAdapterPropertyType;
/// EventType
typedef enum {
BtdrvEventType_Unknown0 = 0, ///< Unused
BtdrvEventType_InquiryDevice = 3, ///< Device found during Inquiry.
BtdrvEventType_InquiryStatus = 4, ///< Inquiry status changed.
BtdrvEventType_PairingPinCodeRequest = 5, ///< Pairing PIN code request.
BtdrvEventType_SspRequest = 6, ///< SSP confirm request / SSP passkey notification.
BtdrvEventType_Connection = 7, ///< Connection
BtdrvEventType_BluetoothCrash = 13, ///< BluetoothCrash
///< BtdrvEventType_* should be used on [12.0.0+]
BtdrvEventType_InquiryDevice = 0, ///< Device found during Inquiry.
BtdrvEventType_InquiryStatus = 1, ///< Inquiry status changed.
BtdrvEventType_PairingPinCodeRequest = 2, ///< Pairing PIN code request.
BtdrvEventType_SspRequest = 3, ///< SSP confirm request / SSP passkey notification.
BtdrvEventType_Connection = 4, ///< Connection
BtdrvEventType_Tsi = 5, ///< SetTsi (\ref btdrvSetTsi)
BtdrvEventType_BurstMode = 6, ///< SetBurstMode (\ref btdrvEnableBurstMode)
BtdrvEventType_SetZeroRetransmission = 7, ///< \ref btdrvSetZeroRetransmission
BtdrvEventType_PendingConnections = 8, ///< \ref btdrvGetPendingConnections
BtdrvEventType_MoveToSecondaryPiconet = 9, ///< \ref btdrvMoveToSecondaryPiconet
BtdrvEventType_BluetoothCrash = 10, ///< BluetoothCrash
///< BtdrvEventTypeOld_* should be used on [1.0.0-11.0.1]
BtdrvEventTypeOld_Unknown0 = 0, ///< Unused
BtdrvEventTypeOld_InquiryDevice = 3, ///< Device found during Inquiry.
BtdrvEventTypeOld_InquiryStatus = 4, ///< Inquiry status changed.
BtdrvEventTypeOld_PairingPinCodeRequest = 5, ///< Pairing PIN code request.
BtdrvEventTypeOld_SspRequest = 6, ///< SSP confirm request / SSP passkey notification.
BtdrvEventTypeOld_Connection = 7, ///< Connection
BtdrvEventTypeOld_BluetoothCrash = 13, ///< BluetoothCrash
} BtdrvEventType;
/// BtdrvInquiryStatus
typedef enum {
BtdrvInquiryStatus_Stopped = 0, ///< Inquiry stopped.
BtdrvInquiryStatus_Started = 1, ///< Inquiry started.
} BtdrvInquiryStatus;
/// ConnectionEventType
typedef enum {
BtdrvConnectionEventType_Status = 0, ///< BtdrvEventInfo::connection::status
@ -34,7 +62,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)
@ -49,21 +77,41 @@ typedef enum {
/// Bit0-1 directly control the HID bluetooth transaction report-type value.
/// Bit2-3: these directly control the Parameter Reserved field for SetReport, for GetReport these control the Parameter Reserved and Size bits.
typedef enum {
BtdrvBluetoothHhReportType_Other = 0, ///< Other
BtdrvBluetoothHhReportType_Input = 1, ///< Input
BtdrvBluetoothHhReportType_Output = 2, ///< Output
BtdrvBluetoothHhReportType_Feature = 3, ///< Feature
BtdrvBluetoothHhReportType_Other = 0, ///< Other
BtdrvBluetoothHhReportType_Input = 1, ///< Input
BtdrvBluetoothHhReportType_Output = 2, ///< Output
BtdrvBluetoothHhReportType_Feature = 3, ///< Feature
} BtdrvBluetoothHhReportType;
/// HidEventType
typedef enum {
BtdrvHidEventType_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Data = 4, ///< DATA report on the Interrupt channel.
BtdrvHidEventType_Ext = 7, ///< Response for extensions. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_SetReport = 8, ///< Response to SET_REPORT.
BtdrvHidEventType_GetReport = 9, ///< Response to GET_REPORT.
///< BtdrvHidEventType_* should be used on [12.0.0+]
BtdrvHidEventType_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Data = 1, ///< DATA report on the Interrupt channel.
BtdrvHidEventType_SetReport = 2, ///< Response to SET_REPORT.
BtdrvHidEventType_GetReport = 3, ///< Response to GET_REPORT.
///< BtdrvHidEventTypeOld_* should be used on [1.0.0-11.0.1]
BtdrvHidEventTypeOld_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventTypeOld_Data = 4, ///< DATA report on the Interrupt channel.
BtdrvHidEventTypeOld_Ext = 7, ///< Response for extensions. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventTypeOld_SetReport = 8, ///< Response to SET_REPORT.
BtdrvHidEventTypeOld_GetReport = 9, ///< Response to GET_REPORT.
} BtdrvHidEventType;
/// HidConnectionStatus [12.0.0+]
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,
BtdrvHidConnectionStatusOld_Closed = 2,
BtdrvHidConnectionStatusOld_Failed = 8,
} BtdrvHidConnectionStatus;
/// This determines the u16 data to write into a CircularBuffer.
typedef enum {
BtdrvFatalReason_Invalid = 0, ///< Only for \ref BtdrvEventInfo: invalid.
@ -71,8 +119,27 @@ 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
typedef enum {
BtdrvBleEventType_Unknown0 = 0, ///< Unknown.
BtdrvBleEventType_Unknown1 = 1, ///< Unknown.
BtdrvBleEventType_Unknown2 = 2, ///< Unknown.
BtdrvBleEventType_Unknown3 = 3, ///< Unknown.
BtdrvBleEventType_Unknown4 = 4, ///< Unknown.
BtdrvBleEventType_Unknown5 = 5, ///< Unknown.
BtdrvBleEventType_Unknown6 = 6, ///< Unknown.
BtdrvBleEventType_Unknown7 = 7, ///< Unknown.
BtdrvBleEventType_Unknown8 = 8, ///< Unknown.
BtdrvBleEventType_Unknown9 = 9, ///< Unknown.
BtdrvBleEventType_Unknown10 = 10, ///< Unknown.
BtdrvBleEventType_Unknown11 = 11, ///< Unknown.
BtdrvBleEventType_Unknown12 = 12, ///< Unknown.
BtdrvBleEventType_Unknown13 = 13, ///< Unknown.
} BtdrvBleEventType;
/// AudioEventType
typedef enum {
BtdrvAudioEventType_None = 0, ///< None
@ -95,26 +162,51 @@ typedef struct {
u8 address[0x6]; ///< Address
} BtdrvAddress;
/// AdapterProperty
/// ClassOfDevice
typedef struct {
BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address.
u8 class_of_device[0x3]; ///< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice.
char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized).
u8 feature_set; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet).
u8 class_of_device[0x3]; ///< ClassOfDevice
} BtdrvClassOfDevice;
/// AdapterProperty [1.0.0-11.0.1]
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).
u8 feature_set; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet).
} BtdrvAdapterPropertyOld;
/// AdapterProperty [12.0.0+]
typedef struct {
u8 type; ///< \ref BtdrvAdapterPropertyType
u8 size; ///< Data size.
u8 data[0x100]; ///< Data (above size), as specified by the type.
} BtdrvAdapterProperty;
/// BluetoothPinCode
/// 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.
} BtdrvAdapterPropertySet;
/// BluetoothPinCode [1.0.0-11.0.1]
typedef struct {
char code[0x10]; ///< PinCode
} BtdrvBluetoothPinCode;
/// HidData, for pre-9.0.0.
/// BtdrvPinCode [12.0.0+]
typedef struct {
char code[0x10]; ///< PinCode
u8 length; ///< Length
} BtdrvPinCode;
/// HidData [1.0.0-8.1.1]
typedef struct {
u16 size; ///< Size of data.
u8 data[0x280]; ///< Data
} BtdrvHidData;
/// HidReport, for [9.0.0+].
/// HidReport [9.0.0+].
typedef struct {
u16 size; ///< Size of data.
u8 data[0x2BC]; ///< Data
@ -171,6 +263,12 @@ typedef struct {
u8 pad5[3]; ///< Padding
} BtdrvBleAdvertisePacketData;
typedef struct {
u8 length;
u8 type;
u8 value[0x1d];
} BtdrvBleAdvertisementData;
/// BleAdvertiseFilter
typedef struct {
u8 unk_x0[0x3E]; ///< Unknown

View File

@ -173,14 +173,30 @@ Result btdrvFinalizeBluetooth(void) {
return _btdrvCmdNoIO(4);
}
Result btdrvGetAdapterProperties(BtdrvAdapterProperty *property) {
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 = { { property, sizeof(*property) } },
.buffers = { { properties, sizeof(*properties) } },
);
}
Result btdrvGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, size_t size) {
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) } },
);
}
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 },
@ -188,7 +204,21 @@ Result btdrvGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, si
);
}
Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size) {
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 },
.buffers = { { property, sizeof(*property) } },
);
}
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 },
@ -196,10 +226,36 @@ Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buff
);
}
Result btdrvStartInquiry(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 },
.buffers = { { property, sizeof(*property) } },
);
}
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;
} in = { services, duration };
return serviceDispatchIn(&g_btdrvSrv, 8, in);
}
Result btdrvStopInquiry(void) {
return _btdrvCmdNoIO(9);
}
@ -229,29 +285,56 @@ Result btdrvCancelBond(BtdrvAddress addr) {
return _btdrvCmdInAddrNoOut(addr, 12);
}
Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 unk) {
Result btdrvLegacyRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 length) {
if (hosversionAtLeast(12,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
BtdrvAddress addr;
u8 flag;
u8 unk;
u8 length;
BtdrvBluetoothPinCode pin_code;
} in = { addr, flag!=0, unk, *pin_code };
} in = { addr, flag!=0, length, *pin_code };
return serviceDispatchIn(&g_btdrvSrv, 13, in);
}
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 unk) {
Result btdrvRespondToPinRequest(BtdrvAddress addr, const BtdrvPinCode *pin_code) {
if (hosversionBefore(12,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
BtdrvAddress addr;
u8 variant;
u8 flag;
u32 unk;
} in = { addr, variant, flag!=0, unk };
BtdrvPinCode pin_code;
} in = { addr, *pin_code };
return serviceDispatchIn(&g_btdrvSrv, 14, in);
return serviceDispatchIn(&g_btdrvSrv, 13, in);
}
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type) {
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool accept, u32 passkey) {
if (hosversionBefore(12,0,0)) {
const struct {
BtdrvAddress addr;
u8 variant;
u8 accept;
u32 passkey;
} in = { addr, variant, accept!=0, passkey };
return serviceDispatchIn(&g_btdrvSrv, 14, in);
}
else {
const struct {
BtdrvAddress addr;
u8 accept;
u8 variant;
u32 passkey;
} in = { addr, accept!=0, variant, passkey };
return serviceDispatchIn(&g_btdrvSrv, 14, in);
}
}
Result btdrvGetEventInfo(void* buffer, size_t size, BtdrvEventType *type) {
return _btdrvCmdOutU32OutBuf(buffer, size, type, 15);
}
@ -441,22 +524,26 @@ Result btdrvGetHidReportEventInfo(void* buffer, size_t size, BtdrvHidEventType *
*type = BtdrvHidEventType_Data;
return 0;
}
if (*type == BtdrvHidEventType_GetReport) {
if (hosversionBefore(9,0,0)) memcpy(info->get_report.hid_data.rawdata, data_ptr->data.get_report.hid_data.rawdata, sizeof(info->get_report.hid_data.rawdata));
else memcpy(info->get_report.hid_report.rawdata, data_ptr->data.get_report.hid_report.rawdata, sizeof(info->get_report.hid_report.rawdata));
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.data, data_ptr->data.set_report.data, sizeof(info->set_report.data));
else if (*type == BtdrvHidEventType_Data) {
u16 tmpsize = hosversionBefore(9,0,0) ? data_ptr->data.data_report.v1.size : data_ptr->data.data_report.v9.size;
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;
info->data_report.unk_x0 = 0;
info->data_report.size = tmpsize;
if (hosversionBefore(9,0,0)) memcpy(info->data_report.data, data_ptr->data.data_report.v1.data, tmpsize);
else memcpy(info->data_report.data, data_ptr->data.data_report.v9.data, tmpsize);
if (hosversionBefore(9,0,0)) info->data_report.v7.report.size = tmpsize;
else {
info->data_report.v9.res = 0;
info->data_report.v9.report.size = tmpsize;
}
if (hosversionBefore(9,0,0)) memcpy(info->data_report.v7.report.data, data_ptr->data.data_report.v7.report.data, tmpsize);
else memcpy(info->data_report.v9.report.data, data_ptr->data.data_report.v9.report.data, tmpsize);
if (hosversionBefore(9,0,0)) memcpy(&info->data_report.addr, &data_ptr->data.data_report.v1.addr, sizeof(BtdrvAddress));
else memcpy(&info->data_report.addr, &data_ptr->data.data_report.v9.addr, sizeof(BtdrvAddress));
if (hosversionBefore(9,0,0)) memcpy(&info->data_report.v7.addr, &data_ptr->data.data_report.v7.addr, sizeof(BtdrvAddress));
else memcpy(&info->data_report.v9.addr, &data_ptr->data.data_report.v9.addr, sizeof(BtdrvAddress));
}
else return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); // sdknso would Abort here.
btdrvCircularBufferFree(g_btdrvCircularBuffer);
@ -873,7 +960,7 @@ Result btdrvAddGattDescriptor(u8 unk0, const BtdrvGattAttributeUuid *uuid0, cons
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, u32 *type) {
Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, BtdrvBleEventType *type) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 78 : 79;
@ -1106,7 +1193,7 @@ Result btdrvUnregisterGattNotification(u32 connection_handle, bool primary_servi
return _btdrvGattNotification(connection_handle, primary_service, id0, id1, cmd_id);
}
Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *type) {
Result btdrvGetLeHidEventInfo(void* buffer, size_t size, BtdrvBleEventType *type) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 95 : 96;