btdrv: Added the remaining cmds, various fixes, and added a types .h.

This commit is contained in:
yellows8 2020-08-12 10:33:58 -04:00
parent ab9ce7c330
commit 3b670bc652
5 changed files with 906 additions and 191 deletions

View File

@ -7,73 +7,10 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../kernel/event.h" #include "../kernel/event.h"
#include "../services/btdrv_types.h"
#include "../services/set.h"
#include "../sf/service.h" #include "../sf/service.h"
/// BluetoothPropertyType
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. 3-bytes.
BtdrvBluetoothPropertyType_Unknown5 = 5, ///< Unknown. 3-bytes.
BtdrvBluetoothPropertyType_Unknown6 = 6, ///< Unknown. 1-byte. The default is value 0x68.
} BtdrvBluetoothPropertyType;
/// BluetoothHhReportType
/// 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;
/// HidEventType
typedef enum {
BtdrvHidEventType_Unknown0 = 0, ///< Unknown. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Unknown4 = 4, ///< Unknown.
BtdrvHidEventType_Unknown7 = 7, ///< Unknown. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Unknown8 = 8, ///< Unknown.
BtdrvHidEventType_Unknown9 = 9, ///< Unknown.
} BtdrvHidEventType;
/// This determines the u16 data to write into the CircularBuffer (name "BLE CORE").
typedef enum {
BtdrvFatalReason_Unknown1 = 1, ///< u16 data = 0x850.
BtdrvFatalReason_Unknown2 = 2, ///< u16 data = 0x851.
BtdrvFatalReason_Unknown3 = 3, ///< Reason values which aren't 1/2: u16 data = 0x852.
} BtdrvFatalReason;
/// Address
typedef struct {
u8 address[0x6]; ///< Address
} BtdrvAddress;
/// AdapterProperty
typedef struct {
BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address.
u8 type5[0x3]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Unknown5.
char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized).
u8 type6; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_Unknown6).
} BtdrvAdapterProperty;
/// BluetoothPinCode
typedef struct {
char code[0x10]; ///< PinCode
} BtdrvBluetoothPinCode;
/// HidData, for pre-9.0.0.
typedef struct {
u16 size; ///< Size of data.
u8 data[0x280]; ///< Data
} BtdrvHidData;
/// HidReport, for [9.0.0+].
typedef struct {
u16 size; ///< Size of data.
u8 data[0x2BC]; ///< Data
} BtdrvHidReport;
/// Data for \ref btdrvGetHidReportEventInfo. The data stored here depends on the \ref BtdrvHidEventType. /// Data for \ref btdrvGetHidReportEventInfo. The data stored here depends on the \ref BtdrvHidEventType.
typedef struct { typedef struct {
union { union {
@ -174,90 +111,6 @@ typedef struct {
} data; } data;
} BtdrvHidReportEventInfoBufferData; } BtdrvHidReportEventInfoBufferData;
/// PlrStatistics
typedef struct {
u8 unk_x0[0x84]; ///< Unknown
} BtdrvPlrStatistics;
/// PlrList
typedef struct {
u8 unk_x0[0xA4]; ///< Unknown
} BtdrvPlrList;
/// ChannelMapList
typedef struct {
u8 unk_x0[0x88]; ///< Unknown
} BtdrvChannelMapList;
/// LeConnectionParams
typedef struct {
u8 unk_x0[0x14]; ///< Unknown
} BtdrvLeConnectionParams;
/// BleConnectionParameter
typedef struct {
u8 unk_x0[0xC]; ///< Unknown
} BtdrvBleConnectionParameter;
/// BtdrvBleAdvertisePacketDataEntry
typedef struct {
u16 unk_x0; ///< Unknown
u8 unused[0x12]; ///< Unused
} BtdrvBleAdvertisePacketDataEntry;
/// BleAdvertisePacketData
typedef struct {
u32 unk_x0; ///< Unknown
u8 unk_x4; ///< Unknown
u8 size0; ///< Size of the data at unk_x6.
u8 unk_x6[0x1F]; ///< Unknown, see size0.
u8 pad[3]; ///< Padding
u8 count; ///< Total array entries, see entries.
u8 pad2[7]; ///< Padding
BtdrvBleAdvertisePacketDataEntry entries[0x5]; ///< \ref BtdrvBleAdvertisePacketDataEntry
u8 pad3[0x10]; ///< Padding
u8 size2; ///< Size of the data at unk_xA8.
u8 unk_xA5; ///< Unknown
u8 pad4[2]; ///< Padding
u8 unk_xA8[0x1F]; ///< Unknown, see size2.
u8 unk_xC7; ///< Unknown
u8 unk_xC8; ///< Unknown
u8 pad5[3]; ///< Padding
} BtdrvBleAdvertisePacketData;
/// BleAdvertiseFilter
typedef struct {
u8 unk_x0[0x3E]; ///< Unknown
} BtdrvBleAdvertiseFilter;
/// BleAdvertisePacketParameter
typedef struct {
u8 data[0x8]; ///< Unknown
} BtdrvBleAdvertisePacketParameter;
/// BleScanResult
typedef struct {
u8 unk_x0[0x148]; ///< Unknown
} BtdrvBleScanResult;
/// BleConnectionInfo
typedef struct {
u32 id; ///< Id, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
} BtdrvBleConnectionInfo;
/// GattAttributeUuid
typedef struct {
u32 size; ///< UUID size, must be 0x2, 0x4, or 0x10.
u8 uuid[0x10]; ///< UUID with the above size.
} BtdrvGattAttributeUuid;
/// GattId
typedef struct {
u8 unk_x0[0x18]; ///< Unknown
} BtdrvGattId;
/// CircularBuffer /// CircularBuffer
typedef struct { typedef struct {
Mutex mutex; Mutex mutex;
@ -279,6 +132,32 @@ void btdrvExit(void);
/// Gets the Service object for the actual btdrv service session. /// Gets the Service object for the actual btdrv service session.
Service* btdrvGetServiceSession(void); Service* btdrvGetServiceSession(void);
/**
* @brief InitializeBluetooth
* @note This is used by btm-sysmodule, this should not be used by other processes.
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=true.
*/
Result btdrvInitializeBluetooth(Event* out_event);
/**
* @brief EnableBluetooth
* @note This is used by btm-sysmodule.
*/
Result btdrvEnableBluetooth(void);
/**
* @brief DisableBluetooth
* @note This is used by btm-sysmodule.
*/
Result btdrvDisableBluetooth(void);
/**
* @brief FinalizeBluetooth
* @note This is not used by btm-sysmodule, this should not be used by other processes.
*/
Result btdrvFinalizeBluetooth(void);
/** /**
* @brief GetAdapterProperties * @brief GetAdapterProperties
* @param[out] property \ref BtdrvAdapterProperty * @param[out] property \ref BtdrvAdapterProperty
@ -301,6 +180,59 @@ Result btdrvGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, si
*/ */
Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size); Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size);
/**
* @brief StartInquiry
* @note This is used by btm-sysmodule.
*/
Result btdrvStartInquiry(void);
/**
* @brief StopInquiry
* @note This is used by btm-sysmodule.
*/
Result btdrvStopInquiry(void);
/**
* @brief CreateBond
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] type TransportType
*/
Result btdrvCreateBond(BtdrvAddress addr, u32 type);
/**
* @brief RemoveBond
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
*/
Result btdrvRemoveBond(BtdrvAddress addr);
/**
* @brief CancelBond
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
*/
Result btdrvCancelBond(BtdrvAddress addr);
/**
* @brief RespondToPinRequest
* @param[in] addr \ref BtdrvAddress
* @param[in] flag Flag
* @param[in] pin_code \ref BtdrvBluetoothPinCode
* @param[in] unk Unknown
*/
Result btdrvRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 unk);
/**
* @brief RespondToSspRequest
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] variant BluetoothSspVariant
* @param[in] flag Flag
* @param[in] unk Unknown
*/
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 unk);
/** /**
* @brief GetEventInfo * @brief GetEventInfo
* @note This is used by btm-sysmodule. * @note This is used by btm-sysmodule.
@ -310,6 +242,28 @@ Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buff
*/ */
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type); Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type);
/**
* @brief InitializeHid
* @note This is used by btm-sysmodule, this should not be used by other processes.
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=true.
*/
Result btdrvInitializeHid(Event* out_event);
/**
* @brief OpenHidConnection
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
*/
Result btdrvOpenHidConnection(BtdrvAddress addr);
/**
* @brief CloseHidConnection
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
*/
Result btdrvCloseHidConnection(BtdrvAddress addr);
/** /**
* @brief This sends a HID DATA transaction packet with report-type Output. * @brief This sends a HID DATA transaction packet with report-type Output.
* @param[in] addr \ref BtdrvAddress * @param[in] addr \ref BtdrvAddress
@ -349,6 +303,27 @@ Result btdrvGetHidReport(BtdrvAddress addr, u8 report_id, BtdrvBluetoothHhReport
*/ */
Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk); Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk);
/**
* @brief AddPairedDeviceInfo
* @note This is used by btm-sysmodule.
* @param[in] settings \ref SetSysBluetoothDevicesSettings
*/
Result btdrvAddPairedDeviceInfo(const SetSysBluetoothDevicesSettings *settings);
/**
* @brief GetPairedDeviceInfo
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[out] settings \ref SetSysBluetoothDevicesSettings
*/
Result btdrvGetPairedDeviceInfo(BtdrvAddress addr, SetSysBluetoothDevicesSettings *settings);
/**
* @brief FinalizeHid
* @note This is not used by btm-sysmodule, this should not be used by other processes.
*/
Result btdrvFinalizeHid(void);
/** /**
* @brief GetHidEventInfo * @brief GetHidEventInfo
* @note This is used by btm-sysmodule. * @note This is used by btm-sysmodule.
@ -358,6 +333,73 @@ Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk);
*/ */
Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type); Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type);
/**
* @brief SetTsi
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] unk Unknown
*/
Result btdrvSetTsi(BtdrvAddress addr, u8 unk);
/**
* @brief EnableBurstMode
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] flag Flag
*/
Result btdrvEnableBurstMode(BtdrvAddress addr, bool flag);
/**
* @brief SetZeroRetransmission
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] buf Input buffer containing an array of u8s.
* @param[in] count Total u8s in the input buffer. This can be 0, the max is 5.
*/
Result btdrvSetZeroRetransmission(BtdrvAddress addr, u8 *buf, u8 count);
/**
* @brief EnableMcMode
* @note This is used by btm-sysmodule.
* @param[in] flag Flag
*/
Result btdrvEnableMcMode(bool flag);
/**
* @brief EnableLlrScan
* @note This is used by btm-sysmodule.
*/
Result btdrvEnableLlrScan(void);
/**
* @brief DisableLlrScan
* @note This is used by btm-sysmodule.
*/
Result btdrvDisableLlrScan(void);
/**
* @brief EnableRadio
* @note This is used by btm-sysmodule.
* @param[in] flag Flag
*/
Result btdrvEnableRadio(bool flag);
/**
* @brief SetVisibility
* @note This is used by btm-sysmodule.
* @param[in] flag0 Unknown flag.
* @param[in] flag1 Unknown flag.
*/
Result btdrvSetVisibility(bool flag0, bool flag1);
/**
* @brief EnableTbfcScan
* @note Only available on [4.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] flag Flag
*/
Result btdrvEnableTbfcScan(bool flag);
/** /**
* @brief RegisterHidReportEvent * @brief RegisterHidReportEvent
* @note This also does sharedmem init/handling if needed, on [7.0.0+]. * @note This also does sharedmem init/handling if needed, on [7.0.0+].
@ -386,6 +428,13 @@ void* btdrvGetHidReportEventInfoSharedmemAddr(void);
*/ */
Result btdrvGetLatestPlr(BtdrvPlrList *out); Result btdrvGetLatestPlr(BtdrvPlrList *out);
/**
* @brief GetPendingConnections
* @note This is used by btm-sysmodule.
* @note Only available on [3.0.0+].
*/
Result btdrvGetPendingConnections(void);
/** /**
* @brief GetChannelMap * @brief GetChannelMap
* @note Only available on [3.0.0+]. * @note Only available on [3.0.0+].
@ -421,6 +470,35 @@ Result btdrvEnableAfhSetting(bool flag);
*/ */
Result btdrvIsAfhSettingEnabled(bool *out); Result btdrvIsAfhSettingEnabled(bool *out);
/**
* @brief InitializeBle
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=true.
*/
Result btdrvInitializeBle(Event* out_event);
/**
* @brief EnableBle
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
*/
Result btdrvEnableBle(void);
/**
* @brief DisableBle
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
*/
Result btdrvDisableBle(void);
/**
* @brief FinalizeBle
* @note Only available on [5.0.0+].
*/
Result btdrvFinalizeBle(void);
/** /**
* @brief SetBleVisibility * @brief SetBleVisibility
* @note Only available on [5.0.0+]. * @note Only available on [5.0.0+].
@ -429,6 +507,36 @@ Result btdrvIsAfhSettingEnabled(bool *out);
*/ */
Result btdrvSetBleVisibility(bool flag0, bool flag1); Result btdrvSetBleVisibility(bool flag0, bool flag1);
/**
* @brief SetLeConnectionParameter
* @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleConnectionParameter.
* @param[in] param \ref BtdrvLeConnectionParams
*/
Result btdrvSetLeConnectionParameter(const BtdrvLeConnectionParams *param);
/**
* @brief SetBleConnectionParameter
* @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeConnectionParameter.
* @param[in] addr \ref BtdrvAddress
* @param[in] param \ref BtdrvBleConnectionParameter
* @param[in] flag Flag
*/
Result btdrvSetBleConnectionParameter(BtdrvAddress addr, const BtdrvBleConnectionParameter *param, bool flag);
/**
* @brief SetLeDefaultConnectionParameter
* @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleDefaultConnectionParameter.
* @param[in] param \ref BtdrvLeConnectionParams
*/
Result btdrvSetLeDefaultConnectionParameter(const BtdrvLeConnectionParams *param);
/**
* @brief SetBleDefaultConnectionParameter
* @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeDefaultConnectionParameter.
* @param[in] param \ref BtdrvBleConnectionParameter
*/
Result btdrvSetBleDefaultConnectionParameter(const BtdrvBleConnectionParameter *param);
/** /**
* @brief SetBleAdvertiseData * @brief SetBleAdvertiseData
* @note Only available on [5.0.0+]. * @note Only available on [5.0.0+].
@ -445,6 +553,58 @@ Result btdrvSetBleAdvertiseData(const BtdrvBleAdvertisePacketData *data);
*/ */
Result btdrvSetBleAdvertiseParameter(BtdrvAddress addr, u16 unk0, u16 unk1); Result btdrvSetBleAdvertiseParameter(BtdrvAddress addr, u16 unk0, u16 unk1);
/**
* @brief StartBleScan
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
*/
Result btdrvStartBleScan(void);
/**
* @brief StopBleScan
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
*/
Result btdrvStopBleScan(void);
/**
* @brief AddBleScanFilterCondition
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] filter \ref BtdrvBleAdvertiseFilter
*/
Result btdrvAddBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter);
/**
* @brief DeleteBleScanFilterCondition
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] filter \ref BtdrvBleAdvertiseFilter
*/
Result btdrvDeleteBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter);
/**
* @brief DeleteBleScanFilter
* @note Only available on [5.0.0+].
* @param[in] unk Unknown
*/
Result btdrvDeleteBleScanFilter(u8 unk);
/**
* @brief ClearBleScanFilters
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
*/
Result btdrvClearBleScanFilters(void);
/**
* @brief EnableBleScanFilter
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] flag Flag
*/
Result btdrvEnableBleScanFilter(bool flag);
/** /**
* @brief RegisterGattClient * @brief RegisterGattClient
* @note Only available on [5.0.0+]. * @note Only available on [5.0.0+].
@ -466,6 +626,35 @@ Result btdrvUnregisterGattClient(u8 unk);
*/ */
Result btdrvUnregisterAllGattClients(void); Result btdrvUnregisterAllGattClients(void);
/**
* @brief ConnectGattServer
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] unk Unknown
* @param[in] addr \ref BtdrvAddress
* @param[in] flag Flag
* @param[in] AppletResourceUserId AppletResourceUserId
*/
Result btdrvConnectGattServer(u8 unk, BtdrvAddress addr, bool flag, u64 AppletResourceUserId);
/**
* @brief CancelConnectGattServer
* @note Only available on [5.1.0+].
* @note This is used by btm-sysmodule.
* @param[in] unk Unknown
* @param[in] addr \ref BtdrvAddress
* @param[in] flag Flag
*/
Result btdrvCancelConnectGattServer(u8 unk, BtdrvAddress addr, bool flag);
/**
* @brief DisconnectGattServer
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] unk Unknown
*/
Result btdrvDisconnectGattServer(u32 unk);
/** /**
* @brief GetGattAttribute * @brief GetGattAttribute
* @note Only available on [5.0.0+]. * @note Only available on [5.0.0+].
@ -482,6 +671,15 @@ Result btdrvGetGattAttribute(BtdrvAddress addr, u32 unk);
*/ */
Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid); Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid);
/**
* @brief ConfigureAttMtu
* @note Only available on [5.0.0+].
* @note This is used by btm-sysmodule.
* @param[in] unk Unknown
* @param[in] mtu MTU
*/
Result btdrvConfigureAttMtu(u32 unk, u16 mtu);
/** /**
* @brief RegisterGattServer * @brief RegisterGattServer
* @note Only available on [5.0.0+]. * @note Only available on [5.0.0+].
@ -748,6 +946,15 @@ Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *type);
*/ */
Result btdrvRegisterBleHidEvent(Event* out_event); Result btdrvRegisterBleHidEvent(Event* out_event);
/**
* @brief SetBleScanParameter
* @note Only available on [5.1.0+].
* @note This is used by btm-sysmodule.
* @param[in] unk0 Unknown
* @param[in] unk1 Unknown
*/
Result btdrvSetBleScanParameter(u16 unk0, u16 unk1);
/** /**
* @brief MoveToSecondaryPiconet * @brief MoveToSecondaryPiconet
* @note Only available on [10.0.0+]. * @note Only available on [10.0.0+].

View File

@ -0,0 +1,158 @@
/**
* @file btdrv_types.h
* @brief Bluetooth driver (btdrv) service types (see btdrv.h for the rest).
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
/// BluetoothPropertyType
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. 3-bytes.
BtdrvBluetoothPropertyType_Unknown5 = 5, ///< Unknown. 3-bytes.
BtdrvBluetoothPropertyType_Unknown6 = 6, ///< Unknown. 1-byte. The default is value 0x68.
} BtdrvBluetoothPropertyType;
/// BluetoothHhReportType
/// 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;
/// HidEventType
typedef enum {
BtdrvHidEventType_Unknown0 = 0, ///< Unknown. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Unknown4 = 4, ///< Unknown.
BtdrvHidEventType_Unknown7 = 7, ///< Unknown. Only used with \ref btdrvGetHidEventInfo.
BtdrvHidEventType_Unknown8 = 8, ///< Unknown.
BtdrvHidEventType_Unknown9 = 9, ///< Unknown.
} BtdrvHidEventType;
/// This determines the u16 data to write into the CircularBuffer (name "BLE CORE").
typedef enum {
BtdrvFatalReason_Unknown1 = 1, ///< u16 data = 0x850.
BtdrvFatalReason_Unknown2 = 2, ///< u16 data = 0x851.
BtdrvFatalReason_Unknown3 = 3, ///< Reason values which aren't 1/2: u16 data = 0x852.
} BtdrvFatalReason;
/// Address
typedef struct {
u8 address[0x6]; ///< Address
} BtdrvAddress;
/// AdapterProperty
typedef struct {
BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address.
u8 type5[0x3]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Unknown5.
char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized).
u8 type6; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_Unknown6).
} BtdrvAdapterProperty;
/// BluetoothPinCode
typedef struct {
char code[0x10]; ///< PinCode
} BtdrvBluetoothPinCode;
/// HidData, for pre-9.0.0.
typedef struct {
u16 size; ///< Size of data.
u8 data[0x280]; ///< Data
} BtdrvHidData;
/// HidReport, for [9.0.0+].
typedef struct {
u16 size; ///< Size of data.
u8 data[0x2BC]; ///< Data
} BtdrvHidReport;
/// PlrStatistics
typedef struct {
u8 unk_x0[0x84]; ///< Unknown
} BtdrvPlrStatistics;
/// PlrList
typedef struct {
u8 unk_x0[0xA4]; ///< Unknown
} BtdrvPlrList;
/// ChannelMapList
typedef struct {
u8 unk_x0[0x88]; ///< Unknown
} BtdrvChannelMapList;
/// LeConnectionParams
typedef struct {
u8 unk_x0[0x14]; ///< Unknown
} BtdrvLeConnectionParams;
/// BleConnectionParameter
typedef struct {
u8 unk_x0[0xC]; ///< Unknown
} BtdrvBleConnectionParameter;
/// BtdrvBleAdvertisePacketDataEntry
typedef struct {
u16 unk_x0; ///< Unknown
u8 unused[0x12]; ///< Unused
} BtdrvBleAdvertisePacketDataEntry;
/// BleAdvertisePacketData
typedef struct {
u32 unk_x0; ///< Unknown
u8 unk_x4; ///< Unknown
u8 size0; ///< Size of the data at unk_x6.
u8 unk_x6[0x1F]; ///< Unknown, see size0.
u8 pad[3]; ///< Padding
u8 count; ///< Total array entries, see entries.
u8 pad2[7]; ///< Padding
BtdrvBleAdvertisePacketDataEntry entries[0x5]; ///< \ref BtdrvBleAdvertisePacketDataEntry
u8 pad3[0x10]; ///< Padding
u8 size2; ///< Size of the data at unk_xA8.
u8 unk_xA5; ///< Unknown
u8 pad4[2]; ///< Padding
u8 unk_xA8[0x1F]; ///< Unknown, see size2.
u8 unk_xC7; ///< Unknown
u8 unk_xC8; ///< Unknown
u8 pad5[3]; ///< Padding
} BtdrvBleAdvertisePacketData;
/// BleAdvertiseFilter
typedef struct {
u8 unk_x0[0x3E]; ///< Unknown
} BtdrvBleAdvertiseFilter;
/// BleAdvertisePacketParameter
typedef struct {
u8 data[0x8]; ///< Unknown
} BtdrvBleAdvertisePacketParameter;
/// BleScanResult
typedef struct {
u8 unk_x0[0x148]; ///< Unknown
} BtdrvBleScanResult;
/// BleConnectionInfo
typedef struct {
u32 id; ///< Id, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid.
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad[2]; ///< Padding
} BtdrvBleConnectionInfo;
/// GattAttributeUuid
typedef struct {
u32 size; ///< UUID size, must be 0x2, 0x4, or 0x10.
u8 uuid[0x10]; ///< UUID with the above size.
} BtdrvGattAttributeUuid;
/// GattId
typedef struct {
u8 unk_x0[0x18]; ///< Unknown
} BtdrvGattId;

View File

@ -6,7 +6,7 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../kernel/event.h" #include "../kernel/event.h"
#include "../services/btdrv.h" #include "../services/btdrv_types.h"
#include "../sf/service.h" #include "../sf/service.h"
/// HostDeviceProperty /// HostDeviceProperty

View File

@ -7,7 +7,7 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../kernel/event.h" #include "../kernel/event.h"
#include "../services/btdrv.h" #include "../services/btdrv_types.h"
#include "../services/btm.h" #include "../services/btm.h"
#include "../sf/service.h" #include "../sf/service.h"

View File

@ -54,6 +54,15 @@ static Result _btdrvCmdInBoolNoOut(bool inval, u32 cmd_id) {
return _btdrvCmdInU8NoOut(inval!=0, cmd_id); return _btdrvCmdInU8NoOut(inval!=0, cmd_id);
} }
static Result _btdrvCmdTwoInBoolsNoOut(bool flag0, bool flag1, u32 cmd_id) {
const struct {
u8 flag;
u8 flag2;
} in = { flag0!=0, flag1!=0 };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
static Result _btdrvCmdInU32NoOut(u32 inval, u32 cmd_id) { static Result _btdrvCmdInU32NoOut(u32 inval, u32 cmd_id) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, inval); return serviceDispatchIn(&g_btdrvSrv, cmd_id, inval);
} }
@ -62,6 +71,19 @@ static Result _btdrvCmdInAddrNoOut(BtdrvAddress addr, u32 cmd_id) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, addr); return serviceDispatchIn(&g_btdrvSrv, cmd_id, addr);
} }
static Result _btmCmdInAddrU8NoOut(BtdrvAddress addr, u8 inval, u32 cmd_id) {
const struct {
BtdrvAddress addr;
u8 inval;
} in = { addr, inval };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
static Result _btdrvCmdInLeConnectionParameterNoOut(const BtdrvLeConnectionParams *param, u32 cmd_id) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, *param);
}
static Result _btdrvCmdInUuidNoOut(const BtdrvGattAttributeUuid *uuid, u32 cmd_id) { static Result _btdrvCmdInUuidNoOut(const BtdrvGattAttributeUuid *uuid, u32 cmd_id) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, *uuid); return serviceDispatchIn(&g_btdrvSrv, cmd_id, *uuid);
} }
@ -107,6 +129,34 @@ static Result _btdrvCmdOutU32OutBuf(void* buffer, size_t size, u32 *out, u32 cmd
); );
} }
static Result _btdrvGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, u32 cmd_id) {
const struct {
u8 flag;
u8 pad[3];
u32 unk;
BtdrvGattId id0;
BtdrvGattId id1;
} in = { flag!=0, {0}, unk, *id0, *id1 };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
Result btdrvInitializeBluetooth(Event* out_event) {
return _btdrvCmdGetEvent(out_event, true, 1);
}
Result btdrvEnableBluetooth(void) {
return _btdrvCmdNoIO(2);
}
Result btdrvDisableBluetooth(void) {
return _btdrvCmdNoIO(3);
}
Result btdrvFinalizeBluetooth(void) {
return _btdrvCmdNoIO(4);
}
Result btdrvGetAdapterProperties(BtdrvAdapterProperty *property) { Result btdrvGetAdapterProperties(BtdrvAdapterProperty *property) {
return serviceDispatch(&g_btdrvSrv, 5, return serviceDispatch(&g_btdrvSrv, 5,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize },
@ -130,10 +180,88 @@ Result btdrvSetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buff
); );
} }
Result btdrvStartInquiry(void) {
return _btdrvCmdNoIO(8);
}
Result btdrvStopInquiry(void) {
return _btdrvCmdNoIO(9);
}
Result btdrvCreateBond(BtdrvAddress addr, u32 type) {
if (hosversionBefore(9,0,0)) {
return serviceDispatchIn(&g_btdrvSrv, 10, addr,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In | SfBufferAttr_FixedSize },
.buffers = { { &type, sizeof(type) } },
);
}
const struct {
BtdrvAddress addr;
u8 pad[2];
u32 type;
} in = { addr, {0}, type };
return serviceDispatchIn(&g_btdrvSrv, 10, in);
}
Result btdrvRemoveBond(BtdrvAddress addr) {
return _btdrvCmdInAddrNoOut(addr, 11);
}
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 };
return serviceDispatchIn(&g_btdrvSrv, 13, in);
}
Result btdrvRespondToSspRequest(BtdrvAddress addr, u8 variant, bool flag, u32 unk) {
const struct {
BtdrvAddress addr;
u8 variant;
u8 flag;
u32 unk;
} in = { addr, variant, flag!=0, unk };
return serviceDispatchIn(&g_btdrvSrv, 14, in);
}
Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type) { Result btdrvGetEventInfo(void* buffer, size_t size, u32 *type) {
return _btdrvCmdOutU32OutBuf(buffer, size, type, 15); return _btdrvCmdOutU32OutBuf(buffer, size, type, 15);
} }
Result btdrvInitializeHid(Event* out_event) {
Handle tmp_handle = INVALID_HANDLE;
Result rc = 0;
u16 tmp=0x1;
if (R_SUCCEEDED(rc)) {
rc = serviceDispatchIn(&g_btdrvSrv, 16, tmp,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &tmp_handle,
);
}
if (R_SUCCEEDED(rc)) eventLoadRemote(out_event, tmp_handle, true);
return rc;
}
Result btdrvOpenHidConnection(BtdrvAddress addr) {
return _btdrvCmdInAddrNoOut(addr, 17);
}
Result btdrvCloseHidConnection(BtdrvAddress addr) {
return _btdrvCmdInAddrNoOut(addr, 18);
}
Result btdrvWriteHidData(BtdrvAddress addr, BtdrvHidReport *buffer) { Result btdrvWriteHidData(BtdrvAddress addr, BtdrvHidReport *buffer) {
size_t size = hosversionBefore(9,0,0) ? sizeof(BtdrvHidData) : sizeof(BtdrvHidReport); size_t size = hosversionBefore(9,0,0) ? sizeof(BtdrvHidData) : sizeof(BtdrvHidReport);
return serviceDispatchIn(&g_btdrvSrv, 19, addr, return serviceDispatchIn(&g_btdrvSrv, 19, addr,
@ -154,8 +282,9 @@ Result btdrvSetHidReport(BtdrvAddress addr, BtdrvBluetoothHhReportType type, Btd
const struct { const struct {
BtdrvAddress addr; BtdrvAddress addr;
u8 pad[2];
u32 type; u32 type;
} in = { addr, type }; } in = { addr, {0}, type };
return serviceDispatchIn(&g_btdrvSrv, 21, in, return serviceDispatchIn(&g_btdrvSrv, 21, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In | SfBufferAttr_FixedSize }, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In | SfBufferAttr_FixedSize },
@ -185,6 +314,21 @@ Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk) {
return serviceDispatchIn(&g_btdrvSrv, 23, in); return serviceDispatchIn(&g_btdrvSrv, 23, in);
} }
Result btdrvAddPairedDeviceInfo(const SetSysBluetoothDevicesSettings *settings) {
return _btdrvCmdInBufPtrFixed(settings, sizeof(*settings), 24);
}
Result btdrvGetPairedDeviceInfo(BtdrvAddress addr, SetSysBluetoothDevicesSettings *settings) {
return serviceDispatchIn(&g_btdrvSrv, 25, addr,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize },
.buffers = { { settings, sizeof(*settings) } },
);
}
Result btdrvFinalizeHid(void) {
return _btdrvCmdNoIO(26);
}
Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type) { Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type) {
u32 tmp=0; u32 tmp=0;
Result rc = _btdrvCmdOutU32OutBuf(buffer, size, &tmp, 27); Result rc = _btdrvCmdOutU32OutBuf(buffer, size, &tmp, 27);
@ -192,6 +336,48 @@ Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type)
return rc; return rc;
} }
Result btdrvSetTsi(BtdrvAddress addr, u8 unk) {
return _btmCmdInAddrU8NoOut(addr, unk, 28);
}
Result btdrvEnableBurstMode(BtdrvAddress addr, bool flag) {
return _btmCmdInAddrU8NoOut(addr, flag!=0, 29);
}
Result btdrvSetZeroRetransmission(BtdrvAddress addr, u8 *buf, u8 count) {
return serviceDispatchIn(&g_btdrvSrv, 30, addr,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { buf, count } },
);
}
Result btdrvEnableMcMode(bool flag) {
return _btdrvCmdInBoolNoOut(flag, 31);
}
Result btdrvEnableLlrScan(void) {
return _btdrvCmdNoIO(32);
}
Result btdrvDisableLlrScan(void) {
return _btdrvCmdNoIO(33);
}
Result btdrvEnableRadio(bool flag) {
return _btdrvCmdInBoolNoOut(flag, 34);
}
Result btdrvSetVisibility(bool flag0, bool flag1) {
return _btdrvCmdTwoInBoolsNoOut(flag0, flag1, 35);
}
Result btdrvEnableTbfcScan(bool flag) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInBoolNoOut(flag, 36);
}
Result btdrvRegisterHidReportEvent(Event* out_event) { Result btdrvRegisterHidReportEvent(Event* out_event) {
Result rc=0; Result rc=0;
Handle tmphandle=0; Handle tmphandle=0;
@ -279,6 +465,14 @@ Result btdrvGetLatestPlr(BtdrvPlrList *out) {
return _btdrvCmdOutBufAliasFixed(out, size, cmd_id); return _btdrvCmdOutBufAliasFixed(out, size, cmd_id);
} }
Result btdrvGetPendingConnections(void) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(4,0,0) ? 39 : 40;
return _btdrvCmdNoIO(cmd_id);
}
Result btdrvGetChannelMap(BtdrvChannelMapList *out) { Result btdrvGetChannelMap(BtdrvChannelMapList *out) {
if (hosversionBefore(3,0,0)) if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -319,16 +513,74 @@ Result btdrvIsAfhSettingEnabled(bool *out) {
return _btdrvCmdNoInOutBool(out, cmd_id); return _btdrvCmdNoInOutBool(out, cmd_id);
} }
Result btdrvInitializeBle(Event* out_event) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdGetEvent(out_event, true, 46);
}
Result btdrvEnableBle(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(47);
}
Result btdrvDisableBle(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(48);
}
Result btdrvFinalizeBle(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(49);
}
Result btdrvSetBleVisibility(bool flag0, bool flag1) { Result btdrvSetBleVisibility(bool flag0, bool flag1) {
if (hosversionBefore(5,0,0)) if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct { return _btdrvCmdTwoInBoolsNoOut(flag0, flag1, 50);
u8 flag; }
u8 flag2;
} in = { flag0!=0, flag1!=0 };
return serviceDispatchIn(&g_btdrvSrv, 50, in); Result btdrvSetLeConnectionParameter(const BtdrvLeConnectionParams *param) {
if (hosversionBefore(5,0,0) || hosversionAtLeast(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInLeConnectionParameterNoOut(param, 51);
}
Result btdrvSetBleConnectionParameter(BtdrvAddress addr, const BtdrvBleConnectionParameter *param, bool flag) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
BtdrvAddress addr;
u8 flag;
u8 pad;
BtdrvBleConnectionParameter param;
} in = { addr, flag!=0, 0, *param };
return serviceDispatchIn(&g_btdrvSrv, 51, in);
}
Result btdrvSetLeDefaultConnectionParameter(const BtdrvLeConnectionParams *param) {
if (hosversionBefore(5,0,0) || hosversionAtLeast(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInLeConnectionParameterNoOut(param, 52);
}
Result btdrvSetBleDefaultConnectionParameter(const BtdrvBleConnectionParameter *param) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchIn(&g_btdrvSrv, 52, *param);
} }
Result btdrvSetBleAdvertiseData(const BtdrvBleAdvertisePacketData *data) { Result btdrvSetBleAdvertiseData(const BtdrvBleAdvertisePacketData *data) {
@ -351,6 +603,55 @@ Result btdrvSetBleAdvertiseParameter(BtdrvAddress addr, u16 unk0, u16 unk1) {
return serviceDispatchIn(&g_btdrvSrv, 54, in); return serviceDispatchIn(&g_btdrvSrv, 54, in);
} }
Result btdrvStartBleScan(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(55);
}
Result btdrvStopBleScan(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(56);
}
Result btdrvAddBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInBufPtrFixed(filter, sizeof(*filter), 57);
}
Result btdrvDeleteBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInBufPtrFixed(filter, sizeof(*filter), 58);
}
Result btdrvDeleteBleScanFilter(u8 unk) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInU8NoOut(unk, 59);
}
Result btdrvClearBleScanFilters(void) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdNoIO(60);
}
Result btdrvEnableBleScanFilter(bool flag) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btdrvCmdInBoolNoOut(flag, 61);
}
Result btdrvRegisterGattClient(const BtdrvGattAttributeUuid *uuid) { Result btdrvRegisterGattClient(const BtdrvGattAttributeUuid *uuid) {
if (hosversionBefore(5,0,0)) if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -372,10 +673,45 @@ Result btdrvUnregisterAllGattClients(void) {
return _btdrvCmdNoIO(64); return _btdrvCmdNoIO(64);
} }
Result btdrvConnectGattServer(u8 unk, BtdrvAddress addr, bool flag, u64 AppletResourceUserId) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 unk;
BtdrvAddress addr;
u8 flag;
u64 AppletResourceUserId;
} in = { unk, addr, flag!=0, AppletResourceUserId };
return serviceDispatchIn(&g_btdrvSrv, 65, in);
}
Result btdrvCancelConnectGattServer(u8 unk, BtdrvAddress addr, bool flag) {
if (hosversionBefore(5,1,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 unk;
BtdrvAddress addr;
u8 flag;
} in = { unk, addr, flag!=0 };
return serviceDispatchIn(&g_btdrvSrv, 66, in);
}
Result btdrvDisconnectGattServer(u32 unk) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 66 : 67;
return _btdrvCmdInU32NoOut(unk, cmd_id);
}
Result btdrvGetGattAttribute(BtdrvAddress addr, u32 unk) { Result btdrvGetGattAttribute(BtdrvAddress addr, u32 unk) {
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(6,0,0) ? 67 : 68; u32 cmd_id = hosversionBefore(5,1,0) ? 67 : 68;
if (hosversionBefore(9,0,0)) { if (hosversionBefore(9,0,0)) {
const struct { const struct {
@ -385,13 +721,13 @@ Result btdrvGetGattAttribute(BtdrvAddress addr, u32 unk) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in); return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
} }
return serviceDispatchIn(&g_btdrvSrv, cmd_id, unk); return _btdrvCmdInU32NoOut(unk, cmd_id);
} }
Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid) { Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid) {
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(6,0,0) ? 68 : 69; u32 cmd_id = hosversionBefore(5,1,0) ? 68 : 69;
const struct { const struct {
u32 unk0; u32 unk0;
@ -401,10 +737,24 @@ Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid) {
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in); return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
} }
Result btdrvConfigureAttMtu(u32 unk, u16 mtu) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 69 : 70;
const struct {
u16 mtu;
u16 pad;
u32 unk;
} in = { mtu, 0, unk };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
Result btdrvRegisterGattServer(const BtdrvGattAttributeUuid *uuid) { Result btdrvRegisterGattServer(const BtdrvGattAttributeUuid *uuid) {
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(6,0,0) ? 71 : 70; u32 cmd_id = hosversionBefore(5,1,0) ? 70 : 71;
return _btdrvCmdInUuidNoOut(uuid, cmd_id); return _btdrvCmdInUuidNoOut(uuid, cmd_id);
} }
@ -412,7 +762,7 @@ Result btdrvRegisterGattServer(const BtdrvGattAttributeUuid *uuid) {
Result btdrvUnregisterGattServer(u8 unk) { Result btdrvUnregisterGattServer(u8 unk) {
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(6,0,0) ? 71 : 72; u32 cmd_id = hosversionBefore(5,1,0) ? 71 : 72;
return _btdrvCmdInU8NoOut(unk, cmd_id); return _btdrvCmdInU8NoOut(unk, cmd_id);
} }
@ -420,7 +770,7 @@ Result btdrvUnregisterGattServer(u8 unk) {
Result btdrvConnectGattClient(u8 unk, BtdrvAddress addr, bool flag) { Result btdrvConnectGattClient(u8 unk, BtdrvAddress addr, bool flag) {
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(6,0,0) ? 72 : 73; u32 cmd_id = hosversionBefore(5,1,0) ? 72 : 73;
const struct { const struct {
u8 unk; u8 unk;
@ -434,7 +784,7 @@ Result btdrvConnectGattClient(u8 unk, BtdrvAddress addr, bool flag) {
Result btdrvDisconnectGattClient(u8 unk, BtdrvAddress addr) { Result btdrvDisconnectGattClient(u8 unk, BtdrvAddress addr) {
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(6,0,0) ? 73 : 74; u32 cmd_id = hosversionBefore(5,1,0) ? 73 : 74;
if (hosversionBefore(9,0,0)) { if (hosversionBefore(9,0,0)) {
const struct { const struct {
@ -465,7 +815,7 @@ Result btdrvAddGattService(u8 unk0, u8 unk1, bool flag, const BtdrvGattAttribute
Result btdrvEnableGattService(u8 unk, const BtdrvGattAttributeUuid *uuid) { Result btdrvEnableGattService(u8 unk, const BtdrvGattAttributeUuid *uuid) {
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(6,0,0) ? 74 : 76; u32 cmd_id = hosversionBefore(5,1,0) ? 74 : 76;
const struct { const struct {
u8 unk; u8 unk;
@ -494,7 +844,7 @@ Result btdrvAddGattCharacteristic(u8 unk0, u8 unk1, u16 unk2, const BtdrvGattAtt
Result btdrvAddGattDescriptor(u8 unk0, u16 unk1, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1) { Result btdrvAddGattDescriptor(u8 unk0, u16 unk1, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1) {
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(6,0,0) ? 76 : 78; u32 cmd_id = hosversionBefore(5,1,0) ? 76 : 78;
const struct { const struct {
u8 unk0; u8 unk0;
@ -510,7 +860,7 @@ Result btdrvAddGattDescriptor(u8 unk0, u16 unk1, const BtdrvGattAttributeUuid *u
Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, u32 *type) { Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, u32 *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(6,0,0) ? 78 : 79; u32 cmd_id = hosversionBefore(5,1,0) ? 78 : 79;
return _btdrvCmdOutU32OutBuf(buffer, size, type, cmd_id); return _btdrvCmdOutU32OutBuf(buffer, size, type, cmd_id);
} }
@ -518,7 +868,7 @@ Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, u32 *type) {
Result btdrvGetGattFirstCharacteristic(bool flag, u32 unk, const BtdrvGattId *id, const BtdrvGattAttributeUuid *uuid, u8 *unk_out, BtdrvGattId *id_out) { Result btdrvGetGattFirstCharacteristic(bool flag, u32 unk, const BtdrvGattId *id, const BtdrvGattAttributeUuid *uuid, u8 *unk_out, BtdrvGattId *id_out) {
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(6,0,0) ? 79 : 80; u32 cmd_id = hosversionBefore(5,1,0) ? 79 : 80;
const struct { const struct {
u8 flag; u8 flag;
@ -545,7 +895,7 @@ Result btdrvGetGattFirstCharacteristic(bool flag, u32 unk, const BtdrvGattId *id
Result btdrvGetGattNextCharacteristic(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, u8 *unk_out, BtdrvGattId *id_out) { Result btdrvGetGattNextCharacteristic(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, u8 *unk_out, BtdrvGattId *id_out) {
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(6,0,0) ? 80 : 81; u32 cmd_id = hosversionBefore(5,1,0) ? 80 : 81;
const struct { const struct {
u8 flag; u8 flag;
@ -573,7 +923,7 @@ Result btdrvGetGattNextCharacteristic(bool flag, u32 unk, const BtdrvGattId *id0
Result btdrvGetGattFirstDescriptor(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *id_out) { Result btdrvGetGattFirstDescriptor(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *id_out) {
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(6,0,0) ? 81 : 82; u32 cmd_id = hosversionBefore(5,1,0) ? 81 : 82;
const struct { const struct {
u8 flag; u8 flag;
@ -590,7 +940,7 @@ Result btdrvGetGattFirstDescriptor(bool flag, u32 unk, const BtdrvGattId *id0, c
Result btdrvGetGattNextDescriptor(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *id_out) { Result btdrvGetGattNextDescriptor(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *id_out) {
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(6,0,0) ? 82 : 83; u32 cmd_id = hosversionBefore(5,1,0) ? 82 : 83;
const struct { const struct {
u8 flag; u8 flag;
@ -643,7 +993,7 @@ Result btdrvRegisterGattDataPath(const BtdrvGattAttributeUuid *uuid) {
Result btdrvUnregisterGattDataPath(const BtdrvGattAttributeUuid *uuid) { Result btdrvUnregisterGattDataPath(const BtdrvGattAttributeUuid *uuid) {
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(6,0,0) ? 83 : 89; u32 cmd_id = hosversionBefore(5,1,0) ? 83 : 89;
return _btdrvCmdInUuidNoOut(uuid, cmd_id); return _btdrvCmdInUuidNoOut(uuid, cmd_id);
} }
@ -651,7 +1001,7 @@ Result btdrvUnregisterGattDataPath(const BtdrvGattAttributeUuid *uuid) {
Result btdrvReadGattCharacteristic(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1) { Result btdrvReadGattCharacteristic(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1) {
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(6,0,0) ? 89 : 90; u32 cmd_id = hosversionBefore(5,1,0) ? 89 : 90;
const struct { const struct {
u8 flag; u8 flag;
@ -668,7 +1018,7 @@ Result btdrvReadGattCharacteristic(bool flag, u8 unk, u32 unk2, const BtdrvGattI
Result btdrvReadGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2) { Result btdrvReadGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2) {
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(6,0,0) ? 90 : 91; u32 cmd_id = hosversionBefore(5,1,0) ? 90 : 91;
const struct { const struct {
u8 flag; u8 flag;
@ -686,7 +1036,7 @@ Result btdrvReadGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *i
Result btdrvWriteGattCharacteristic(bool flag, u8 unk, bool flag2, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size) { Result btdrvWriteGattCharacteristic(bool flag, u8 unk, bool flag2, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size) {
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(6,0,0) ? 91 : 92; u32 cmd_id = hosversionBefore(5,1,0) ? 91 : 92;
const struct { const struct {
u8 flag; u8 flag;
@ -707,7 +1057,7 @@ Result btdrvWriteGattCharacteristic(bool flag, u8 unk, bool flag2, u32 unk2, con
Result btdrvWriteGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const void* buffer, size_t size) { Result btdrvWriteGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const void* buffer, size_t size) {
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(6,0,0) ? 92 : 93; u32 cmd_id = hosversionBefore(5,1,0) ? 92 : 93;
const struct { const struct {
u8 flag; u8 flag;
@ -725,18 +1075,6 @@ Result btdrvWriteGattDescriptor(bool flag, u8 unk, u32 unk2, const BtdrvGattId *
); );
} }
static Result _btdrvGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1, u32 cmd_id) {
const struct {
u8 flag;
u8 pad[3];
u32 unk;
BtdrvGattId id0;
BtdrvGattId id1;
} in = { flag!=0, {0}, unk, *id0, *id1 };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
Result btdrvRegisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1) { Result btdrvRegisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1) {
if (hosversionBefore(5,0,0)) if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -747,7 +1085,7 @@ Result btdrvRegisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id0,
Result btdrvUnregisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1) { Result btdrvUnregisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id0, const BtdrvGattId *id1) {
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(6,0,0) ? 93 : 95; u32 cmd_id = hosversionBefore(5,1,0) ? 93 : 95;
return _btdrvGattNotification(flag, unk, id0, id1, cmd_id); return _btdrvGattNotification(flag, unk, id0, id1, cmd_id);
} }
@ -755,7 +1093,7 @@ Result btdrvUnregisterGattNotification(bool flag, u32 unk, const BtdrvGattId *id
Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *type) { Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *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(6,0,0) ? 95 : 96; u32 cmd_id = hosversionBefore(5,1,0) ? 95 : 96;
return _btdrvCmdOutU32OutBuf(buffer, size, type, cmd_id); return _btdrvCmdOutU32OutBuf(buffer, size, type, cmd_id);
} }
@ -763,11 +1101,23 @@ Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *type) {
Result btdrvRegisterBleHidEvent(Event* out_event) { Result btdrvRegisterBleHidEvent(Event* out_event) {
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(6,0,0) ? 96 : 97; u32 cmd_id = hosversionBefore(5,1,0) ? 96 : 97;
return _btdrvCmdGetEvent(out_event, true, cmd_id); return _btdrvCmdGetEvent(out_event, true, cmd_id);
} }
Result btdrvSetBleScanParameter(u16 unk0, u16 unk1) {
if (hosversionBefore(5,1,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u16 unk0;
u16 unk1;
} in = { unk0, unk1 };
return serviceDispatchIn(&g_btdrvSrv, 98, in);
}
Result btdrvMoveToSecondaryPiconet(BtdrvAddress addr) { Result btdrvMoveToSecondaryPiconet(BtdrvAddress addr) {
if (hosversionBefore(10,0,0)) if (hosversionBefore(10,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);