btdrv: expand upon and refine event data definitions

(cherry picked from commit c71718916bc325ad671d2e427e3fe5923d962983)
This commit is contained in:
ndeadly 2021-03-17 02:34:28 +01:00 committed by Dave Murphy
parent 5d448a1048
commit 65bdff6b52
3 changed files with 226 additions and 117 deletions

View File

@ -21,37 +21,37 @@ typedef struct {
} type0; ///< ::BtdrvEventType_Unknown0 } type0; ///< ::BtdrvEventType_Unknown0
struct { struct {
u8 name[0xF9]; ///< Device name, NUL-terminated string. char name[0xF9]; ///< Device name, NUL-terminated string.
BtdrvAddress addr; ///< Device address. BtdrvAddress addr; ///< Device address.
u8 reserved_xFF[0x10]; ///< Reserved u8 reserved_xFF[0x10]; ///< Reserved
u8 class_of_device[0x3]; ///< Class of Device. BtdrvClassOfDevice class_of_device; ///< Class of Device.
u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1. u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1.
u8 reserved_x116[0xFA]; ///< Reserved u8 reserved_x116[0xFA]; ///< Reserved
u8 reserved_x210[0x5C]; ///< Reserved u8 reserved_x210[0x5C]; ///< Reserved
u8 name2[0xF9]; ///< Device name, NUL-terminated string. Same as name above, except starting at index 1. char name2[0xF9]; ///< Device name, NUL-terminated string. Same as name above, except starting at index 1.
u8 rssi[0x4]; ///< s32 RSSI u8 rssi[0x4]; ///< s32 RSSI
u8 name3[0x4]; ///< Two bytes which are the same as name[11-12]. u8 name3[0x4]; ///< Two bytes which are the same as name[11-12].
u8 reserved_x36D[0x10]; ///< Reserved u8 reserved_x36D[0x10]; ///< Reserved
} inquiry_device; ///< ::BtdrvEventType_InquiryDevice } inquiry_device; ///< ::BtdrvEventType_InquiryDevice
struct { struct {
u32 status; ///< Status: 0 = stopped, 1 = started. BtdrvInquiryStatus status; ///< Status: 0 = stopped, 1 = started.
} inquiry_status; ///< ::BtdrvEventType_InquiryStatus } inquiry_status; ///< ::BtdrvEventType_InquiryStatus
struct { struct {
BtdrvAddress addr; ///< Device address. BtdrvAddress addr; ///< Device address.
u8 name[0xF9]; ///< Device name, NUL-terminated string. char name[0xF9]; ///< Device name, NUL-terminated string.
u8 class_of_device[0x3]; ///< Class of Device. BtdrvClassOfDevice class_of_device; ///< Class of Device.
} pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest } pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest
struct { struct {
BtdrvAddress addr; ///< Device address. BtdrvAddress addr; ///< Device address.
u8 name[0xF9]; ///< Device name, NUL-terminated string. char name[0xF9]; ///< Device name, NUL-terminated string.
u8 class_of_device[0x3]; ///< Class of Device. BtdrvClassOfDevice class_of_device; ///< Class of Device.
u8 pad[2]; ///< Padding u8 pad[2]; ///< Padding
u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification. u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification.
s32 passkey; ///< Passkey, only set when the above field is value 3. s32 passkey; ///< Passkey, only set when the above field is value 3.
} ssp_request; ///< ::BtdrvEventType_SspRequest } ssp_request; ///< ::BtdrvEventType_SspRequest
struct { 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). 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).
@ -72,10 +72,10 @@ typedef struct {
u8 data[0x480]; ///< Raw data. u8 data[0x480]; ///< Raw data.
struct { struct {
BtdrvAddress addr; ///< Device address. BtdrvAddress addr; ///< Device address.
u8 pad[2]; ///< Padding u8 pad[2]; ///< Padding
u32 status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection. BtdrvHidConnectionStatus status; ///< Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection.
} connection; ///< ::BtdrvHidEventType_Connection } connection; ///< ::BtdrvHidEventType_Connection
struct { struct {
u32 type; ///< \ref BtdrvExtEventType, controls which data is stored below. u32 type; ///< \ref BtdrvExtEventType, controls which data is stored below.
@ -130,25 +130,48 @@ typedef struct {
u8 data[0x480]; ///< Raw data. u8 data[0x480]; ///< Raw data.
struct { struct {
u32 unk_x0; ///< Always 0. union {
u8 unk_x4; ///< Always 0. struct {
BtdrvAddress addr; ///< \ref BtdrvAddress struct {
u8 pad; ///< Padding BtdrvAddress addr;
u16 size; ///< Size of the below data. u8 pad[2]; // Todo: check if padding used here
u8 data[]; ///< Data. u32 res;
} data_report; ///< ::BtdrvHidEventType_Data u32 size;
} hdr;
u8 unused[0x3]; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 unused2[0x3]; ///< Unused
BtdrvHidData report;
} v1; ///< Pre-7.0.0
struct {
u8 unused[0x3]; ///< Unused
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 unused2[0x3]; ///< Unused
BtdrvHidData report;
} v7; ///< Pre-9.0.0
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 { struct {
union { union {
u8 data[0xC]; ///< Raw data. u8 rawdata[0xC]; ///< Raw data.
struct { struct {
u32 res; ///< 0 = success, non-zero = error. u32 res; ///< 0 = success, non-zero = error.
BtdrvAddress addr; ///< \ref BtdrvAddress BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding u8 pad[2]; ///< Padding
}; };
}; };
} set_report; ///< ::BtdrvHidEventType_SetReport } set_report; ///< ::BtdrvHidEventType_SetReport
struct { struct {
union { union {
@ -158,21 +181,21 @@ typedef struct {
struct { struct {
BtdrvAddress addr; ///< \ref BtdrvAddress BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding u8 pad[2]; ///< Padding
u32 res; ///< 0 = success, non-zero = error. hid-sysmodule only uses the below data when this field is 0. u32 res; ///< Unknown. hid-sysmodule only uses the below data when this field is 0.
BtdrvHidData data; ///< \ref BtdrvHidData BtdrvHidData report; ///< \ref BtdrvHidData
u8 pad2[2]; ///< Padding u8 pad2[2]; ///< Padding
}; };
} hid_data; ///< Pre-9.0.0 } v1; ///< Pre-9.0.0
union { union {
u8 rawdata[0x2C8]; ///< Raw data. u8 rawdata[0x2C8]; ///< Raw data.
struct { struct {
u32 res; ///< 0 = success, non-zero = error. hid-sysmodule only uses the below report when this field is 0. u32 res; ///< Unknown. hid-sysmodule only uses the below report when this field is 0.
BtdrvAddress addr; ///< \ref BtdrvAddress BtdrvAddress addr; ///< \ref BtdrvAddress
BtdrvHidReport report; ///< \ref BtdrvHidReport BtdrvHidReport report; ///< \ref BtdrvHidReport
}; };
} hid_report; ///< [9.0.0+] } v9; ///< [9.0.0+]
}; };
} get_report; ///< ::BtdrvHidEventType_GetReport } get_report; ///< ::BtdrvHidEventType_GetReport
}; };
@ -187,42 +210,7 @@ typedef struct {
u64 size; u64 size;
} hdr; } hdr;
union { BtdrvHidReportEventInfo data;
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;
} BtdrvHidReportEventInfoBufferData; } BtdrvHidReportEventInfoBufferData;
/// Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType. /// Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType.
@ -246,6 +234,99 @@ typedef struct {
u8 initialized; u8 initialized;
} BtdrvCircularBuffer; } 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;
bool 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. /// Initialize btdrv.
Result btdrvInitialize(void); Result btdrvInitialize(void);
@ -363,9 +444,9 @@ Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 un
* @note This is used by btm-sysmodule. * @note This is used by btm-sysmodule.
* @param[out] buffer Output buffer, see \ref BtdrvEventInfo. * @param[out] buffer Output buffer, see \ref BtdrvEventInfo.
* @param[in] size Output buffer size. * @param[in] size Output buffer size.
* @oaram[out] type Output EventType. * @oaram[out] type Output BtdrvEventType.
*/ */
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type); Result btdrvGetEventInfo(void* buffer, size_t size, BtdrvEventType *type);
/** /**
* @brief InitializeHid * @brief InitializeHid
@ -885,9 +966,9 @@ Result btdrvAddGattDescriptor(u8 unk0, const BtdrvGattAttributeUuid *uuid0, cons
* @note This is used by btm-sysmodule. * @note This is used by btm-sysmodule.
* @param[out] buffer Output buffer. 0x400-bytes from state is written here. * @param[out] buffer Output buffer. 0x400-bytes from state is written here.
* @param[in] size Output buffer size. * @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 * @brief GetGattFirstCharacteristic

View File

@ -27,6 +27,12 @@ typedef enum {
BtdrvEventType_BluetoothCrash = 13, ///< BluetoothCrash BtdrvEventType_BluetoothCrash = 13, ///< BluetoothCrash
} BtdrvEventType; } BtdrvEventType;
/// BtdrvInquiryStatus
typedef enum {
BtdrvInquiryStatus_Stopped = 0, ///< Inquiry started.
BtdrvInquiryStatus_Started = 1, ///< Inquiry stopped.
} BtdrvInquiryStatus;
/// ConnectionEventType /// ConnectionEventType
typedef enum { typedef enum {
BtdrvConnectionEventType_Status = 0, ///< BtdrvEventInfo::connection::status BtdrvConnectionEventType_Status = 0, ///< BtdrvEventInfo::connection::status
@ -64,6 +70,13 @@ typedef enum {
BtdrvHidEventType_GetReport = 9, ///< Response to GET_REPORT. BtdrvHidEventType_GetReport = 9, ///< Response to GET_REPORT.
} BtdrvHidEventType; } BtdrvHidEventType;
/// HidConnectionStatus
typedef enum {
BtdrvHidConnectionStatus_Connected = 0,
BtdrvHidConnectionStatus_Disconnected = 2,
BtdrvHidConnectionStatus_FailedGeneric = 8,
} BtdrvHidConnectionStatus;
/// This determines the u16 data to write into a CircularBuffer. /// This determines the u16 data to write into a CircularBuffer.
typedef enum { typedef enum {
BtdrvFatalReason_Invalid = 0, ///< Only for \ref BtdrvEventInfo: invalid. BtdrvFatalReason_Invalid = 0, ///< Only for \ref BtdrvEventInfo: invalid.
@ -73,34 +86,40 @@ typedef enum {
BtdrvFatalReason_Enable = 7, ///< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field. BtdrvFatalReason_Enable = 7, ///< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field.
} BtdrvFatalReason; } BtdrvFatalReason;
/// AudioEventType /// BleEventType
typedef enum { typedef enum {
BtdrvAudioEventType_None = 0, ///< None BtdrvBleEventType_Unknown0 = 0, ///< Unknown.
BtdrvAudioEventType_Connection = 1, ///< Connection BtdrvBleEventType_Unknown1 = 1, ///< Unknown.
} BtdrvAudioEventType; BtdrvBleEventType_Unknown2 = 2, ///< Unknown.
BtdrvBleEventType_Unknown3 = 3, ///< Unknown.
/// AudioOutState BtdrvBleEventType_Unknown4 = 4, ///< Unknown.
typedef enum { BtdrvBleEventType_Unknown5 = 5, ///< Unknown.
BtdrvAudioOutState_Stopped = 0, ///< Stopped BtdrvBleEventType_Unknown6 = 6, ///< Unknown.
BtdrvAudioOutState_Started = 1, ///< Started BtdrvBleEventType_Unknown7 = 7, ///< Unknown.
} BtdrvAudioOutState; BtdrvBleEventType_Unknown8 = 8, ///< Unknown.
BtdrvBleEventType_Unknown9 = 9, ///< Unknown.
/// AudioCodec BtdrvBleEventType_Unknown10 = 10, ///< Unknown.
typedef enum { BtdrvBleEventType_Unknown11 = 11, ///< Unknown.
BtdrvAudioCodec_Pcm = 0, ///< Raw PCM BtdrvBleEventType_Unknown12 = 12, ///< Unknown.
} BtdrvAudioCodec; BtdrvBleEventType_Unknown13 = 13, ///< Unknown.
} BtdrvBleEventType;
/// Address /// Address
typedef struct { typedef struct {
u8 address[0x6]; ///< Address u8 address[0x6]; ///< Address
} BtdrvAddress; } BtdrvAddress;
/// ClassOfDevice
typedef struct {
u8 class_of_device[0x3]; ///< ClassOfDevice
} BtdrvClassOfDevice;
/// AdapterProperty /// AdapterProperty
typedef struct { typedef struct {
BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address. BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address.
u8 class_of_device[0x3]; ///< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. 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 (last byte is not initialized).
u8 feature_set; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet). u8 feature_set; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet).
} BtdrvAdapterProperty; } BtdrvAdapterProperty;
/// BluetoothPinCode /// BluetoothPinCode
@ -171,6 +190,12 @@ typedef struct {
u8 pad5[3]; ///< Padding u8 pad5[3]; ///< Padding
} BtdrvBleAdvertisePacketData; } BtdrvBleAdvertisePacketData;
typedef struct {
u8 length;
u8 type;
u8 value[0x1d];
} BtdrvBleAdvertisementData;
/// BleAdvertiseFilter /// BleAdvertiseFilter
typedef struct { typedef struct {
u8 unk_x0[0x3E]; ///< Unknown u8 unk_x0[0x3E]; ///< Unknown

View File

@ -251,7 +251,7 @@ Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 un
return serviceDispatchIn(&g_btdrvSrv, 14, in); return serviceDispatchIn(&g_btdrvSrv, 14, in);
} }
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type) { Result btdrvGetEventInfo(void* buffer, size_t size, BtdrvEventType *type) {
return _btdrvCmdOutU32OutBuf(buffer, size, type, 15); return _btdrvCmdOutU32OutBuf(buffer, size, type, 15);
} }
@ -442,21 +442,24 @@ Result btdrvGetHidReportEventInfo(void* buffer, size_t size, BtdrvHidEventType *
return 0; return 0;
} }
if (*type == BtdrvHidEventType_GetReport) { 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)); 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.hid_report.rawdata, data_ptr->data.get_report.hid_report.rawdata, sizeof(info->get_report.hid_report.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_SetReport) memcpy(info->set_report.rawdata, data_ptr->data.set_report.rawdata, sizeof(info->set_report.rawdata));
else if (*type == BtdrvHidEventType_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; 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 (size < 0xE) return MAKERESULT(Module_Libnx, LibnxError_BadInput);
if (tmpsize > size-0xE) tmpsize = size-0xE; if (tmpsize > size-0xE) tmpsize = size-0xE;
info->data_report.unk_x0 = 0; if (hosversionBefore(9,0,0)) info->data_report.v7.report.size = tmpsize;
info->data_report.size = tmpsize; else {
if (hosversionBefore(9,0,0)) memcpy(info->data_report.data, data_ptr->data.data_report.v1.data, tmpsize); info->data_report.v9.res = 0;
else memcpy(info->data_report.data, data_ptr->data.data_report.v9.data, tmpsize); 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)); 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.addr, &data_ptr->data.data_report.v9.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. else return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); // sdknso would Abort here.
btdrvCircularBufferFree(g_btdrvCircularBuffer); btdrvCircularBufferFree(g_btdrvCircularBuffer);
@ -873,7 +876,7 @@ Result btdrvAddGattDescriptor(u8 unk0, const BtdrvGattAttributeUuid *uuid0, cons
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in); 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)) if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 78 : 79; u32 cmd_id = hosversionBefore(5,1,0) ? 78 : 79;
@ -1106,7 +1109,7 @@ Result btdrvUnregisterGattNotification(u32 connection_handle, bool primary_servi
return _btdrvGattNotification(connection_handle, primary_service, id0, id1, cmd_id); 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)) if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 95 : 96; u32 cmd_id = hosversionBefore(5,1,0) ? 95 : 96;