Compare commits

...

44 Commits

Author SHA1 Message Date
yellows8
dfee0c8ba2
ldn: Added ldnSetProtocol. 2025-06-18 18:17:05 -04:00
Dave Murphy
0a4ac1b87c
remove unused dist-bin target 2025-06-12 16:06:29 +01:00
Dave Murphy
638624cf02
actually install libs too. Closes #681 2025-06-12 08:40:44 +01:00
Dave Murphy
2f471a1c26
remove unused version number in Makefile (#679)
* remove unused version number in Makefile
* add dist-src target using git tag
2025-06-10 18:01:55 +01:00
ndeadly
d1dbd8db51 btdrv: fix struct alignment issue in BtdrvBleEventInfo 2025-06-09 21:26:36 +02:00
XorTroll
de7cfeb3d9
nfp: Improve types and enums 2025-05-18 01:09:53 +02:00
ndeadly
2fc81d8f35 btdrv: label proto_mode field in data_report event info 2025-05-18 01:08:51 +02:00
Luis Scheurenbrand
29f6f4fa7a update capsdc for 18.0.0 2025-05-07 23:19:48 +02:00
ndeadly
b88afc509c btmsys: add missing 13.0.0 commands 2025-05-07 23:19:05 +02:00
ndeadly
ceb7ee1cbf set: update SetSysBluetoothDevicesSettings with new fields found in recent firmwares 2025-05-07 23:18:38 +02:00
ndeadly
0ba4f96bfe btdrv: document timeout parameter to btdrvTriggerConnection 2025-05-07 23:18:16 +02:00
Michael Scire
17bcd07095 fsp-pr: update RegisterProgram for 20.0.0 change 2025-05-07 23:17:19 +02:00
Michael Scire
ce6bc0c3e8 ldr/fsldr: update for 20.0.0 2025-05-07 23:17:19 +02:00
Michael Scire
8f1cce6946 libnx: fix compilation with gcc15 2025-05-07 21:09:09 +02:00
ndeadly
60bf943ec1 btdrv: complete definition of BtdrvBleAdvertisePacketData struct and add supporting enums 2025-01-26 18:57:17 +01:00
ndeadly
0ae0792770 btdrv: update gatt server event names to better reflect usage 2025-01-26 18:57:17 +01:00
ndeadly
953c1b7a8a btdrv: fixed swapped permissions and property parameters for btdrvAddGattCharacteristic function 2025-01-26 18:57:17 +01:00
ndeadly
5da574f852 btdrv: add notes about broken gatt server function implementations 2025-01-26 18:57:17 +01:00
ndeadly
b2d7022e1b btdrv: change argument from service id to server interface for gatt server functions 2025-01-26 18:57:17 +01:00
ndeadly
29a6691b66 hidsys: add commands for setting/checking state of joycons attached via rails 2025-01-26 18:56:58 +01:00
averne
88de3cbea7 nvfence: expose nvhost-ctrl fd 2025-01-25 18:10:36 +01:00
averne
218e3f3a04 nvchannel: fix submit ioctl 2025-01-25 18:10:22 +01:00
MasaGratoR
a063ceb19c Fix wrong names in SetSysModeLine 2024-12-08 20:48:22 +01:00
MasaGratoR
e79dd7ac52
Update setsysEdid struct (#654) 2024-11-26 21:34:21 +01:00
Dave Murphy
2e2b110668
use nproc for max jobs on github workflow (#652) 2024-11-25 00:55:17 +00:00
yellows8
432b4e3900
hid: Use the Npad-revision for 18.0.0+. 2024-11-24 19:34:53 -05:00
ndeadly
eef44aa5e1
btm: add audio profile (#650)
Co-authored-by: ndeadly <24677491+ndeadly@users.noreply.github.com>
2024-11-25 00:31:32 +01:00
yellows8
688e4dd14e
hiddbg: Fixed crash when accessing Hdls tmem. Closes #653. 2024-11-24 16:46:45 -05:00
yellows8
d4f5f4b145
audctl: Updated sysver checks. 2024-11-24 16:19:59 -05:00
yellows8
6c430b273a
capsc: Pass CapsApplicationId/u64 for input as required by sysver. 2024-11-24 15:48:35 -05:00
Michael Scire
58f1fc6561 caps: add fields to AlbumFileId, simplify old invoke 2024-11-24 21:44:07 +01:00
Michael Scire
65c643f149 capsc: account for new command sizes 2024-11-24 21:44:07 +01:00
Michael Scire
73d79d4a0f fs: add GetContentStorageInfoIndex 2024-11-24 21:44:07 +01:00
Michael Scire
163fdddabf fs: add new outsize parameter to fsDeviceOperatorGetGameCardDeviceCertificate 2024-11-24 21:44:07 +01:00
Michael Scire
c7c9617290 switch.ld: fix absolute addressing, incompatible with relr relocations 2024-11-24 21:44:07 +01:00
Michael Scire
250a5777f7 ldr:pm: Update ProgramInfo 2024-11-24 21:44:07 +01:00
Michael Scire
5d5d13c9d6 svc: WaitIfEqual64 is value 3 2024-11-24 21:44:07 +01:00
Michael Scire
2bbf49377e svc: add new info type 2024-11-24 21:44:07 +01:00
Michael Scire
81bed00b5b svc: update WaitForAddress 2024-11-24 21:44:07 +01:00
fincs
8cff58d5af
dynamic: add support for ELF packed relocations (relr) 2024-08-31 00:40:56 +02:00
Irne Racoonovich
d66e3aa487 spl: add missing service header 2024-08-29 21:14:38 +02:00
fincs
7b4e02be35
nwindowReleaseBuffers: cancel dequeued buffer instead of failing 2024-08-19 17:43:51 +02:00
ndeadly
3c851a3443
bt: fill in unknowns and update function parameters to match their btdrv counterparts (#644) 2024-06-28 13:48:22 +01:00
ndeadly
df0508200b
Add missing hid shared memory structures and accessor functions for system buttons (#647)
* hid: add missing shared memory format structures
* hid: add functions for getting the state of the home, sleep and capture buttons from shmem
2024-06-28 13:48:02 +01:00
48 changed files with 1465 additions and 405 deletions

View File

@ -14,9 +14,9 @@ jobs:
image: 'devkitpro/devkita64'
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: build
run: make -C nx -j2
run: make -C nx -j$(nproc)

View File

@ -8,13 +8,6 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules
export LIBNX_MAJOR := 4
export LIBNX_MINOR := 7
export LIBNX_PATCH := 0
VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
@ -95,17 +88,14 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
#---------------------------------------------------------------------------------
all: lib/libnx.a lib/libnxd.a
dist-bin: all
@tar --exclude=*~ -cjf libnx-$(VERSION).tar.bz2 include lib default_icon.jpg switch_rules switch.ld switch.specs -C external/bsd include
install: lib/libnx.a lib/libnxd.a
@mkdir -p $(DESTDIR)$(DEVKITPRO)/libnx
@cp -v default_icon.jpg switch_rules switch.ld switch.specs $(DESTDIR)$(DEVKITPRO)/libnx/
@cp -rv include lib $(DESTDIR)$(DEVKITPRO)/libnx/
@cp -rv external/bsd/include $(DESTDIR)$(DEVKITPRO)/libnx/
dist-src:
@tar --exclude=*~ -cjf libnx-src-$(VERSION).tar.bz2 include source data external Makefile default_icon.jpg switch_rules switch.ld switch.specs
dist: dist-src dist-bin
install: dist-bin
mkdir -p $(DESTDIR)$(DEVKITPRO)/libnx
bzip2 -cd libnx-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/libnx
@tar -cjf libnx-`git describe --tags | sed 's/^v//'`.tar.bz2 include source data external Makefile default_icon.jpg switch_rules switch.ld switch.specs
#dox:
# @doxygen Doxyfile

View File

@ -212,6 +212,8 @@ typedef enum {
InfoType_IoRegionHint = 27, ///< [16.0.0+] Low bits of the physical address for a KIoRegion.
InfoType_AliasRegionExtraSize = 28, ///< [18.0.0+] Extra size added to the reserved region.
InfoType_TransferMemoryHint = 34, ///< [19.0.0+] Low bits of the process address for a KTransferMemory.
InfoType_ThreadTickCountDeprecated = 0xF0000002, ///< [1.0.0-12.1.0] Number of ticks spent on thread.
} InfoType;
@ -262,9 +264,10 @@ typedef enum {
/// WaitForAddress behaviors.
typedef enum {
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the value is less than argument.
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the value and wait if it is less than argument.
ArbitrationType_WaitIfEqual = 2, ///< Wait if the value is equal to argument.
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the 32-bit value is less than argument.
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the 32-bit value and wait if it is less than argument.
ArbitrationType_WaitIfEqual = 2, ///< Wait if the 32-bit value is equal to argument.
ArbitrationType_WaitIfEqual64 = 3, ///< [19.0.0+] Wait if the 64-bit value is equal to argument.
} ArbitrationType;
/// Context of a scheduled thread.
@ -809,7 +812,7 @@ Result svcGetThreadContext3(ThreadContext* ctx, Handle thread);
* @return Result code.
* @note Syscall number 0x34.
*/
Result svcWaitForAddress(void *address, u32 arb_type, s32 value, s64 timeout);
Result svcWaitForAddress(void *address, u32 arb_type, s64 value, s64 timeout);
/**
* @brief Signals (and updates) an address depending on type and value. [4.0.0+]

View File

@ -10,6 +10,7 @@ typedef struct {
Result nvFenceInit(void);
void nvFenceExit(void);
u32 nvFenceGetFd(void);
Result nvFenceWait(NvFence* f, s32 timeout_us);

View File

@ -154,6 +154,9 @@ typedef struct {
typedef struct {
u32 syncpt_id;
u32 syncpt_incrs;
u32 waitbase_id; // Always -1
u32 next; //< Next valid incr index, or -1
u32 prev; //< Previous valid incr index, or -1
} nvioctl_syncpt_incr;
typedef struct {

View File

@ -48,21 +48,21 @@ Result audctlGetTargetVolumeMin(s32* volume_out);
Result audctlGetTargetVolumeMax(s32* volume_out);
Result audctlIsTargetMute(bool* mute_out, AudioTarget target);
Result audctlSetTargetMute(AudioTarget target, bool mute);
Result audctlIsTargetConnected(bool* connected_out, AudioTarget target);
Result audctlIsTargetConnected(bool* connected_out, AudioTarget target); ///< [1.0.0-17.0.1]
Result audctlSetDefaultTarget(AudioTarget target, u64 fade_in_ns, u64 fade_out_ns);
Result audctlGetDefaultTarget(AudioTarget* target_out);
Result audctlGetAudioOutputMode(AudioOutputMode* mode_out, AudioTarget target);
Result audctlSetAudioOutputMode(AudioTarget target, AudioOutputMode mode);
Result audctlSetForceMutePolicy(AudioForceMutePolicy policy);
Result audctlGetForceMutePolicy(AudioForceMutePolicy* policy_out);
Result audctlSetForceMutePolicy(AudioForceMutePolicy policy); ///< [1.0.0-13.2.1]
Result audctlGetForceMutePolicy(AudioForceMutePolicy* policy_out); ///< [1.0.0-13.2.1]
Result audctlGetOutputModeSetting(AudioOutputMode* mode_out, AudioTarget target);
Result audctlSetOutputModeSetting(AudioTarget target, AudioOutputMode mode);
Result audctlSetOutputTarget(AudioTarget target);
Result audctlSetInputTargetForceEnabled(bool enable);
Result audctlSetHeadphoneOutputLevelMode(AudioHeadphoneOutputLevelMode mode); ///< [3.0.0+]
Result audctlGetHeadphoneOutputLevelMode(AudioHeadphoneOutputLevelMode* mode_out); ///< [3.0.0+]
Result audctlAcquireAudioVolumeUpdateEventForPlayReport(Event* event_out); ///< [3.0.0+]
Result audctlAcquireAudioOutputDeviceUpdateEventForPlayReport(Event* event_out); ///< [3.0.0+]
Result audctlAcquireAudioVolumeUpdateEventForPlayReport(Event* event_out); ///< [3.0.0-13.2.1]
Result audctlAcquireAudioOutputDeviceUpdateEventForPlayReport(Event* event_out); ///< [3.0.0-13.2.1]
Result audctlGetAudioOutputTargetForPlayReport(AudioTarget* target_out); ///< [3.0.0+]
Result audctlNotifyHeadphoneVolumeWarningDisplayedEvent(void); ///< [3.0.0+]
Result audctlSetSystemOutputMasterVolume(float volume); ///< [4.0.0+]

View File

@ -2,7 +2,7 @@
* @file bt.h
* @brief Bluetooth user (bt) service IPC wrapper.
* @note See also btdev.
* @author yellows8
* @author yellows8, ndeadly
* @copyright libnx Authors
*/
#pragma once
@ -24,93 +24,93 @@ Service* btGetServiceSession(void);
* @brief LeClientReadCharacteristic
* @note This is essentially the same as \ref btdrvReadGattCharacteristic.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] unk Unknown
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
* @param[in] auth_req \ref BtdrvGattAuthReqType
*/
Result btLeClientReadCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, u8 unk);
Result btLeClientReadCharacteristic(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, u8 auth_req);
/**
* @brief LeClientReadDescriptor
* @note This is essentially the same as \ref btdrvReadGattDescriptor.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] id2 \ref BtdrvGattId
* @param[in] unk Unknown
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
* @param[in] desc_id Descriptor GATT ID \ref BtdrvGattId
* @param[in] auth_req \ref BtdrvGattAuthReqType
*/
Result btLeClientReadDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, u8 unk);
Result btLeClientReadDescriptor(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const BtdrvGattId *desc_id, u8 auth_req);
/**
* @brief LeClientWriteCharacteristic
* @note This is essentially the same as \ref btdrvWriteGattCharacteristic.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
* @param[in] buffer Input buffer.
* @param[in] size Input buffer size, must be <=0x258.
* @param[in] unk Unknown
* @param[in] flag Flag
* @param[in] auth_req \ref BtdrvGattAuthReqType
* @param[in] with_response Whether to use Write-With-Response write type or not
*/
Result btLeClientWriteCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size, u8 unk, bool flag);
Result btLeClientWriteCharacteristic(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const void* buffer, size_t size, u8 auth_req, bool with_response);
/**
* @brief LeClientWriteDescriptor
* @note This is essentially the same as \ref btdrvWriteGattDescriptor.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] id2 \ref BtdrvGattId
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
* @param[in] desc_id Descriptor GATT ID \ref BtdrvGattId
* @param[in] buffer Input buffer.
* @param[in] size Input buffer size, must be <=0x258.
* @param[in] unk Unknown
* @param[in] auth_req \ref BtdrvGattAuthReqType
*/
Result btLeClientWriteDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const void* buffer, size_t size, u8 unk);
Result btLeClientWriteDescriptor(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const BtdrvGattId *desc_id, const void* buffer, size_t size, u8 auth_req);
/**
* @brief LeClientRegisterNotification
* @note This is essentially the same as \ref btdrvRegisterGattNotification.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
*/
Result btLeClientRegisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1);
Result btLeClientRegisterNotification(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id);
/**
* @brief LeClientDeregisterNotification
* @note This is essentially the same as \ref btdrvUnregisterGattNotification.
* @param[in] connection_handle ConnectionHandle
* @param[in] primary_service PrimaryService
* @param[in] id0 \ref BtdrvGattId
* @param[in] id1 \ref BtdrvGattId
* @param[in] is_primary Is a primary service or not
* @param[in] serv_id Service GATT ID \ref BtdrvGattId
* @param[in] char_id Characteristic GATT ID \ref BtdrvGattId
*/
Result btLeClientDeregisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1);
Result btLeClientDeregisterNotification(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id);
/**
* @brief SetLeResponse
* @param[in] unk Unknown
* @param[in] uuid0 \ref BtdrvGattAttributeUuid
* @param[in] uuid1 \ref BtdrvGattAttributeUuid
* @param[in] server_if Server interface ID
* @param[in] serv_uuid Service UUID \ref BtdrvGattAttributeUuid
* @param[in] char_uuid Characteristic UUID \ref BtdrvGattAttributeUuid
* @param[in] buffer Input buffer.
* @param[in] size Input buffer size, must be <=0x258.
*/
Result btSetLeResponse(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, const void* buffer, size_t size);
Result btSetLeResponse(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, const void* buffer, size_t size);
/**
* @brief LeSendIndication
* @param[in] unk Unknown
* @param[in] uuid0 \ref BtdrvGattAttributeUuid
* @param[in] uuid1 \ref BtdrvGattAttributeUuid
* @param[in] server_if Server interface ID
* @param[in] serv_uuid Service UUID \ref BtdrvGattAttributeUuid
* @param[in] char_uuid Characteristic UUID \ref BtdrvGattAttributeUuid
* @param[in] buffer Input buffer.
* @param[in] size Input buffer size, clamped to max size 0x258.
* @param[in] flag Flag
* @param[in] noconfirm Whether no confirmation is required (notification) or not (indication)
*/
Result btLeSendIndication(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, const void* buffer, size_t size, bool flag);
Result btLeSendIndication(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, const void* buffer, size_t size, bool noconfirm);
/**
* @brief GetLeEventInfo
@ -118,9 +118,9 @@ Result btLeSendIndication(u8 unk, const BtdrvGattAttributeUuid *uuid0, const Btd
* @note The state used by this is reset after writing the data to output.
* @param[in] buffer Output buffer. 0x400-bytes from state is written here. See \ref BtdrvLeEventInfo.
* @param[in] size Output buffer size.
* @param[out] type Output BleEventType.
* @param[out] type Output BtdrvBleEventType.
*/
Result btGetLeEventInfo(void* buffer, size_t size, u32 *type);
Result btGetLeEventInfo(void* buffer, size_t size, BtdrvBleEventType *type);
/**
* @brief RegisterBleEvent

View File

@ -242,7 +242,7 @@ typedef struct {
struct {
u32 res; ///< Always 0.
u8 unk_x4; ///< Always 0.
u8 proto_mode; ///< Protocol mode. Always 0 (report mode).
BtdrvAddress addr; ///< \ref BtdrvAddress
u8 pad; ///< Padding
BtdrvHidReport report;
@ -372,8 +372,8 @@ typedef struct {
struct {
u32 result; ///< 0 for success, non-zero for error.
u8 status; ///< Connection status. 0 = Connected, 2 = Disconnected
u16 server_if; ///< Server interface handle
u8 pad; ///< Padding
u8 server_if; ///< Server interface handle
u8 pad[2]; ///< Padding
u32 conn_id; ///< Connection ID
BtdrvAddress address; ///< Device address
u16 reason; ///< Disconnection reason
@ -439,21 +439,21 @@ typedef struct {
u8 property; ///< Characteristic properties. Only set if attr_type is 1 \ref BtdrvGattCharacteristicProperty
u8 is_primary; ///< Is a primary service or not
u8 pad; ///< Padding
} server_add_characteristic; ///< ::BtdrvBleEventType_ServerAddCharacteristic
} server_add_attribute; ///< ::BtdrvBleEventType_ServerAddAttribute
struct {
u32 result; ///< 0 for success, non-zero for error.
u16 conn_id; ///< Connection ID
u8 unk_x6; ///< Unknown. Always 1
u8 operation; ///< Operation. 0 = Read, 1 = Write
u8 pad; ///< Padding
u16 service_id; ///< Service ID
u16 attr_id; ///< Attribute ID
u8 attr_type; ///< Attribute type \ref BtdrvGattAttributeType
u8 data[0x200]; ///< Data
u8 data[0x200]; ///< Data written during write operation
u16 size; ///< Size of the above data
u16 offset; ///< Offset
u8 pad2[2]; ///< Padding
} server_write; ///< ::BtdrvBleEventType_ServerWrite
} server_attribute_operation; ///< ::BtdrvBleEventType_ServerAttributeOperation
};
} BtdrvBleEventInfo;
@ -670,9 +670,9 @@ Result btdrvGetHidReport(BtdrvAddress addr, u8 report_id, BtdrvBluetoothHhReport
* @brief TriggerConnection
* @note This is used by btm-sysmodule.
* @param[in] addr \ref BtdrvAddress
* @param[in] unk [9.0.0+] Unknown
* @param[in] timeout [9.0.0+] Host trigger timeout
*/
Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk);
Result btdrvTriggerConnection(BtdrvAddress addr, u16 timeout);
/**
* @brief AddPairedDeviceInfo
@ -1058,6 +1058,7 @@ Result btdrvConfigureAttMtu(u32 conn_id, u16 mtu);
/**
* @brief RegisterGattServer
* @note Only available on [5.0.0+].
* @note Event data generated by this call contains uninitialized junk instead of the server_if value received internally.
* @param[in] uuid \ref BtdrvGattAttributeUuid
*/
Result btdrvRegisterGattServer(const BtdrvGattAttributeUuid *uuid);
@ -1089,6 +1090,7 @@ Result btdrvDisconnectGattClient(u8 conn_id, BtdrvAddress addr);
/**
* @brief AddGattService
* @note Only available on [5.0.0+].
* @note Broken behaviour due to internal bugs.
* @param[in] server_if Server interface ID
* @param[in] uuid \ref BtdrvGattAttributeUuid
* @param[in] num_handle Number of handles
@ -1099,31 +1101,34 @@ Result btdrvAddGattService(u8 server_if, const BtdrvGattAttributeUuid *uuid, u8
/**
* @brief EnableGattService
* @note Only available on [5.0.0+].
* @param[in] service_id Service ID
* @note Broken behaviour due to internal bugs.
* @param[in] server_if Server interface ID
* @param[in] uuid \ref BtdrvGattAttributeUuid
*/
Result btdrvEnableGattService(u8 service_id, const BtdrvGattAttributeUuid *uuid);
Result btdrvEnableGattService(u8 server_if, const BtdrvGattAttributeUuid *uuid);
/**
* @brief AddGattCharacteristic
* @note Only available on [5.0.0+].
* @param[in] service_id Service ID
* @note Broken behaviour due to internal bugs.
* @param[in] server_if Server interface ID
* @param[in] serv_uuid Service UUID \ref BtdrvGattAttributeUuid
* @param[in] char_uuid Characteristic UUID \ref BtdrvGattAttributeUuid
* @param[in] permissions \ref BtdrvGattAttributePermission
* @param[in] property \ref BtdrvGattCharacteristicProperty
*/
Result btdrvAddGattCharacteristic(u8 service_id, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, u8 permissions, u16 property);
Result btdrvAddGattCharacteristic(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, u16 permissions, u8 property);
/**
* @brief AddGattDescriptor
* @note Only available on [5.0.0+].
* @param[in] service_id Service ID
* @note Broken behaviour due to internal bugs.
* @param[in] server_if Server interface ID
* @param[in] serv_uuid Service UUID \ref BtdrvGattAttributeUuid
* @param[in] desc_uuid Descriptor UUID \ref BtdrvGattAttributeUuid
* @param[in] permissions \ref BtdrvGattAttributePermission
*/
Result btdrvAddGattDescriptor(u8 service_id, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *desc_uuid, u16 permissions);
Result btdrvAddGattDescriptor(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *desc_uuid, u16 permissions);
/**
* @brief GetBleManagedEventInfo

View File

@ -137,8 +137,8 @@ typedef enum {
BtdrvBleEventType_ClientCacheSave = 9, ///< GATT client cache save.
BtdrvBleEventType_ClientCacheLoad = 10, ///< GATT client cache load.
BtdrvBleEventType_ClientConfigureMtu = 11, ///< GATT client configure MTU.
BtdrvBleEventType_ServerAddCharacteristic = 12, ///< GATT server add characteristic.
BtdrvBleEventType_ServerWrite = 13, ///< GATT server write.
BtdrvBleEventType_ServerAddAttribute = 12, ///< GATT server add attribute.
BtdrvBleEventType_ServerAttributeOperation = 13, ///< GATT server attribute operation.
} BtdrvBleEventType;
/// GattAttributeType
@ -193,6 +193,37 @@ typedef enum {
BtdrvGattAuthReqType_SignedMitm = 4,
} BtdrvGattAuthReqType;
/// BtdrvBleAdBit
typedef enum {
BtdrvBleAdBit_DeviceName = BIT(0),
BtdrvBleAdBit_Flags = BIT(1),
BtdrvBleAdBit_Manufacturer = BIT(2),
BtdrvBleAdBit_TxPower = BIT(3),
BtdrvBleAdBit_Service32 = BIT(4),
BtdrvBleAdBit_IntRange = BIT(5),
BtdrvBleAdBit_Service = BIT(6),
BtdrvBleAdBit_ServiceSol = BIT(7),
BtdrvBleAdBit_ServiceData = BIT(8),
BtdrvBleAdBit_SignData = BIT(9),
BtdrvBleAdBit_Service128Sol = BIT(10),
BtdrvBleAdBit_Appearance = BIT(11),
BtdrvBleAdBit_PublicAddress = BIT(12),
BtdrvBleAdBit_RandomAddress = BIT(13),
BtdrvBleAdBit_Service32Sol = BIT(14),
BtdrvBleAdBit_Proprietary = BIT(15),
BtdrvBleAdBit_Service128 = BIT(16),
} BtdrvBleAdBit;
/// BtdrvBleAdFlag
typedef enum {
BtdrvBleAdFlag_None = 0,
BtdrvBleAdFlag_LimitedDiscovery = BIT(0),
BtdrvBleAdFlag_GeneralDiscovery = BIT(1),
BtdrvBleAdFlag_BrEdrNotSupported = BIT(2),
BtdrvBleAdFlag_DualModeControllerSupport = BIT(3),
BtdrvBleAdFlag_DualModeHostSupport = BIT(4),
} BtdrvBleAdFlag;
/// AudioEventType
typedef enum {
BtdrvAudioEventType_None = 0, ///< None
@ -280,6 +311,29 @@ typedef struct {
u8 unk_x0[0x88]; ///< Unknown
} BtdrvChannelMapList;
/// 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 instance_id; ///< InstanceId
u8 pad[3]; ///< Padding
BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid
} BtdrvGattId;
/// GattAttribute
typedef struct {
BtdrvGattId id; ///< \ref BtdrvGattId
u16 type; ///< \ref BtdrvGattAttributeType
u16 handle;
u16 group_end_handle;
u8 property; ///< Only used when type is characteristic. \ref BtdrvGattCharacteristicProperty
bool is_primary; ///< Only used when type is service
} BtdrvGattAttribute;
/// LeConnectionParams [5.0.0-8.1.1]
typedef struct {
BtdrvAddress addr; ///< \ref BtdrvAddress
@ -303,30 +357,24 @@ typedef struct {
u16 supervision_tout; ///< Connection supervision timeout multiplier
} BtdrvBleConnectionParameter;
/// BtdrvBleAdvertisePacketDataEntry
/// BtdrvBleAdvertisePacketData
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
u32 adv_data_mask; ///< Bitmask of following AD data to be included in advertising packets \ref BtdrvBleAdBit
u8 flag; ///< AD flag value to be advertised \ref BtdrvBleAdFlag. Included with BtdrvBleAdBit_Flags
u8 manu_data_len; ///< Size of manu_data below
u8 manu_data[0x1F]; ///< Manufacturer-specific data to be advertised. Included with BtdrvBleAdBit_Manufacturer
u8 pad[1]; ///< Padding
u16 appearance_data; ///< Device appearance data to be advertised \ref BtdrvAppearanceType. Included with BtdrvBleAdBit_Appearance
u8 num_service; ///< Number of services in uuid_val array below
u8 pad2[3]; ///< Padding
BtdrvGattAttributeUuid uuid_val[0x6]; ///< Array of 16-bit UUIDs to be advertised \ref BtdrvGattAttributeUuid. Included with BtdrvBleAdBit_Service
u8 service_data_len; ///< Size of service_data below
u8 pad3[1]; ///< Padding
u16 service_data_uuid; ///< 16-bit UUID of service_data below
u8 service_data[0x1F]; ///< Service data to be advertised. Included with BtdrvBleAdBit_ServiceData
bool is_scan_rsp; ///< Whether this is an inquiry scan response or advertising data
u8 tx_power; ///< Inquiry transmit power to be advertised. Included with BtdrvBleAdBit_TxPower
u8 pad4[3]; ///< Padding
} BtdrvBleAdvertisePacketData;
/// BleAdvertisement
@ -366,29 +414,6 @@ typedef struct {
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 instance_id; ///< InstanceId
u8 pad[3]; ///< Padding
BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid
} BtdrvGattId;
/// GattAttribute
typedef struct {
BtdrvGattId id; ///< \ref BtdrvGattId
u16 type; ///< \ref BtdrvGattAttributeType
u16 handle;
u16 group_end_handle;
u8 property; ///< Only used when type is characteristic. \ref BtdrvGattCharacteristicProperty
bool is_primary; ///< Only used when type is service
} BtdrvGattAttribute;
/// LeEventInfo
typedef struct {
u32 unk_x0; ///< Unknown

View File

@ -60,6 +60,7 @@ typedef enum {
typedef enum {
BtmProfile_None = 0, ///< None
BtmProfile_Hid = 1, ///< Hid
BtmProfile_Audio = 2, ///< [13.0.0+] Audio
} BtmProfile;
/// BdName
@ -297,3 +298,8 @@ typedef struct {
BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid
} BtmBleDataPath;
/// AudioDevice
typedef struct {
BtdrvAddress addr; ///< Device address
char name[0xF9]; ///< Device name
} BtmAudioDevice;

View File

@ -6,6 +6,8 @@
#pragma once
#include "../types.h"
#include "../kernel/event.h"
#include "../services/btdrv_types.h"
#include "../services/btm_types.h"
#include "../sf/service.h"
/// Initialize btm:sys.
@ -80,3 +82,104 @@ Result btmsysAcquireGamepadPairingEvent(Event* out_event);
*/
Result btmsysIsGamepadPairingStarted(bool *out);
/**
* @brief StartAudioDeviceDiscovery
* @note Only available on [13.0.0+].
*/
Result btmsysStartAudioDeviceDiscovery(void);
/**
* @brief StopAudioDeviceDiscovery
* @note Only available on [13.0.0+].
*/
Result btmsysStopAudioDeviceDiscovery(void);
/**
* @brief IsDiscoveryingAudioDevice
* @note Only available on [13.0.0+].
* @param[out] out Output flag.
*/
Result btmsysIsDiscoveryingAudioDevice(bool *out);
/**
* @brief GetDiscoveredAudioDevice
* @note Only available on [13.0.0+].
* @param[out] out Output array of \ref BtmAudioDevice.
* @param[in] count Size of the out array in entries. The max is 15.
* @param[out] total_out Total output entries.
*/
Result btmsysGetDiscoveredAudioDevice(BtmAudioDevice *out, s32 count, s32 *total_out);
/**
* @brief AcquireAudioDeviceConnectionEvent
* @note Only available on [13.0.0+].
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=true.
*/
Result btmsysAcquireAudioDeviceConnectionEvent(Event* out_event);
/**
* @brief ConnectAudioDevice
* @note Only available on [13.0.0+].
* @param[in] addr \ref BtdrvAddress
*/
Result btmsysConnectAudioDevice(BtdrvAddress addr);
/**
* @brief IsConnectingAudioDevice
* @note Only available on [13.0.0+].
* @param[out] out Output flag.
*/
Result btmsysIsConnectingAudioDevice(bool *out);
/**
* @brief GetConnectedAudioDevices
* @note Only available on [13.0.0+].
* @param[out] out Output array of \ref BtmAudioDevice.
* @param[in] count Size of the out array in entries. The max is 8.
* @param[out] total_out Total output entries.
*/
Result btmsysGetConnectedAudioDevices(BtmAudioDevice *out, s32 count, s32 *total_out);
/**
* @brief DisconnectAudioDevice
* @note Only available on [13.0.0+].
* @param[in] addr \ref BtdrvAddress
*/
Result btmsysDisconnectAudioDevice(BtdrvAddress addr);
/**
* @brief AcquirePairedAudioDeviceInfoChangedEvent
* @note Only available on [13.0.0+].
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=true.
*/
Result btmsysAcquirePairedAudioDeviceInfoChangedEvent(Event* out_event);
/**
* @brief GetPairedAudioDevices
* @note Only available on [13.0.0+].
* @param[out] out Output array of \ref BtmAudioDevice.
* @param[in] count Size of the out array in entries. The max is 10.
* @param[out] total_out Total output entries.
*/
Result btmsysGetPairedAudioDevices(BtmAudioDevice *out, s32 count, s32 *total_out);
/**
* @brief RemoveAudioDevicePairing
* @note Only available on [13.0.0+].
* @param[in] addr \ref BtdrvAddress
*/
Result btmsysRemoveAudioDevicePairing(BtdrvAddress addr);
/**
* @brief RequestAudioDeviceConnectionRejection
* @note Only available on [13.0.0+].
*/
Result btmsysRequestAudioDeviceConnectionRejection(void);
/**
* @brief CancelAudioDeviceConnectionRejection
* @note Only available on [13.0.0+].
*/
Result btmsysCancelAudioDeviceConnectionRejection(void);

View File

@ -93,7 +93,9 @@ typedef struct {
CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime
u8 storage; ///< \ref CapsAlbumStorage
u8 content; ///< \ref CapsAlbumFileContents
u8 pad_x12[0x6]; ///< padding
u8 unknown_12; ///< [19.0.0+]
u8 unknown_13; ///< [19.0.0+]
u8 pad_x14[0x4]; ///< padding
} CapsAlbumFileId;
/// AlbumEntry

View File

@ -9,6 +9,13 @@
#include "../sf/service.h"
#include "../services/caps.h"
typedef struct {
u64 application_id;
u8 unknown_08;
u8 unknown_09;
u8 reserved[6];
} CapsApplicationId;
/// Initialize caps:c
Result capscInitialize(void);
@ -40,7 +47,7 @@ Result capscNotifyAlbumStorageIsUnAvailable(CapsAlbumStorage storage);
* @param[in] appletResourceUserId AppletResourceUserId.
* @param[in] application_id ApplicationId.
*/
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id);
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id);
/**
* @brief Unregister an applet.
@ -49,7 +56,7 @@ Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 applicati
* @param[in] appletResourceUserId AppletResourceUserId.
* @param[in] application_id ApplicationId.
*/
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id);
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id);
/**
* @brief Get an ApplicationId that corresponds to an AppletResourceUserId.
@ -58,7 +65,7 @@ Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 applica
* @param[out] application_id ApplicationId.
* @param[in] appletResourceUserId AppletResourceUserId.
*/
Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid);
Result capscGetApplicationIdFromAruid(CapsApplicationId *application_id, u64 aruid);
/**
* @brief Checks whether an ApplicationId is registered.
@ -74,7 +81,7 @@ Result capscCheckApplicationIdRegistered(u64 application_id);
* @param[in] contents \ref CapsAlbumFileContents
* @param[out] file_id \ref CapsAlbumFileId
*/
Result capscGenerateCurrentAlbumFileId(u64 application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id);
Result capscGenerateCurrentAlbumFileId(const CapsApplicationId *application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id);
/**
* @brief Generate an ApplicationAlbumEntry based on parameters.

View File

@ -33,5 +33,31 @@ Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption
/**
* @brief Shrinks a jpeg's dimensions by 2.
* @note Tries to compress with jpeg quality in this order: 98, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0.
* @note Only available on [17.0.0+].
* @param[in] width Input image width.
* @param[in] height Input image width.
* @param[in] opts \ref CapsScreenShotDecodeOption.
* @param[in] jpeg Jpeg image input buffer.
* @param[in] jpeg_size Input image buffer size.
* @param[out] out_jpeg Jpeg image output buffer
* @param[in] out_jpeg_size Output image buffer size.
* @param[out] out_result_size size of the resulting JPEG.
*/
Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size);
/**
* @brief Shrinks a jpeg.
* @note Fails if the scaled size is larger than the original or the output buffer isn't large enough.
* @note Only available on [19.0.0+].
* @param[in] scaled_width Wanted image width.
* @param[in] scaled_height Wanted image width.
* @param[in] jpeg_quality has to be in range 0-100.
* @param[in] opts \ref CapsScreenShotDecodeOption.
* @param[in] jpeg Jpeg image input buffer.
* @param[in] jpeg_size Input image buffer size.
* @param[out] out_jpeg Jpeg image output buffer
* @param[in] out_jpeg_size Output image buffer size.
* @param[out] out_result_size size of the resulting jpeg.
*/
Result capsdcShrinkJpegEx(u32 scaled_width, u32 scaled_height, u32 jpeg_quality, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size);

View File

@ -553,6 +553,8 @@ Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id);
/// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+], attr is ignored before [16.0.0].
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, FsContentAttributes attr, u8* out_key_generation, FsRightsId* out_rights_id);
Result fsGetContentStorageInfoIndex(s32 *out); ///< [19.0.0+]
Result fsDisableAutoSaveDataCreation(void);
Result fsSetGlobalAccessLogMode(u32 mode);
@ -683,7 +685,7 @@ Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out);
Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out);
Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const FsGameCardHandle* handle, FsGameCardUpdatePartitionInfo* out);
Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out);
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size);
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size);
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCardErrorReportInfo* out);
Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);

View File

@ -9,6 +9,7 @@
#include "../sf/service.h"
#include "../services/fs.h"
#include "../crypto/sha256.h"
#include "../services/ncm_types.h"
typedef struct {
u8 signature[0x100];
@ -26,5 +27,5 @@ void fsldrExit(void);
/// Gets the Service object for the actual fsp-ldr service session.
Service* fsldrGetServiceSession(void);
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, const char *path, FsContentAttributes attr, FsFileSystem* out);
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, NcmStorageId storage_id, const char *path, FsContentAttributes attr, FsFileSystem* out);
Result fsldrIsArchivedProgram(u64 pid, bool *out);

View File

@ -18,7 +18,7 @@ void fsprExit(void);
/// Gets the Service object for the actual fsp-pr service session.
Service* fsprGetServiceSession(void);
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size);
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size, u8 fs_access_control_restriction_mode);
Result fsprUnregisterProgram(u64 pid);
Result fsprSetCurrentProcess(void);
Result fsprSetEnabledProgramVerification(bool enabled);

View File

@ -755,6 +755,297 @@ typedef struct HidKeyboardSharedMemoryFormat {
// End HidKeyboard
// Begin HidBasicXpad
/// HidBasicXpadState
typedef struct {
u64 sampling_number;
u32 attributes;
u32 buttons;
u64 analog_stick_left;
u64 analog_stick_right;
} HidBasicXpadState;
/// HidBasicXpadStateAtomicStorage
typedef struct {
u64 sampling_number;
HidBasicXpadState state;
} HidBasicXpadStateAtomicStorage;
/// HidBasicXpadLifo
typedef struct {
HidCommonLifoHeader header;
HidBasicXpadStateAtomicStorage storage[17];
} HidBasicXpadLifo;
/// HidBasicXpadSharedMemoryEntry
typedef struct {
HidBasicXpadLifo lifo;
u8 padding[0x138];
} HidBasicXpadSharedMemoryEntry;
/// HidBasicXpadSharedMemoryFormat
typedef struct {
HidBasicXpadSharedMemoryEntry entries[4];
} HidBasicXpadSharedMemoryFormat;
// End HidBasicXpad
// Begin HidDigitizer
/// HidDigitizerState
typedef struct {
u64 sampling_number;
u32 unk_0x8;
u32 unk_0xC;
u32 attributes;
u32 buttons;
u32 unk_0x18;
u32 unk_0x1C;
u32 unk_0x20;
u32 unk_0x24;
u32 unk_0x28;
u32 unk_0x2C;
u32 unk_0x30;
u32 unk_0x34;
u32 unk_0x38;
u32 unk_0x3C;
u32 unk_0x40;
u32 unk_0x44;
u32 unk_0x48;
u32 unk_0x4C;
u32 unk_0x50;
u32 unk_0x54;
} HidDigitizerState;
/// HidDigitizerStateAtomicStorage
typedef struct {
u64 sampling_number;
HidDigitizerState state;
} HidDigitizerStateAtomicStorage;
/// HidDigitizerLifo
typedef struct {
HidCommonLifoHeader header;
HidDigitizerStateAtomicStorage storage[17];
} HidDigitizerLifo;
/// HidDigitizerSharedMemoryFormat
typedef struct {
HidDigitizerLifo lifo;
u8 padding[0x980];
} HidDigitizerSharedMemoryFormat;
// End HidDigitizer
// Begin HidHomeButton
/// HidHomeButtonState
typedef struct {
u64 sampling_number;
u64 buttons;
} HidHomeButtonState;
/// HidHomeButtonStateAtomicStorage
typedef struct {
u64 sampling_number;
HidHomeButtonState state;
} HidHomeButtonStateAtomicStorage;
/// HidHomeButtonLifo
typedef struct {
HidCommonLifoHeader header;
HidHomeButtonStateAtomicStorage storage[17];
} HidHomeButtonLifo;
/// HidHomeButtonSharedMemoryFormat
typedef struct {
HidHomeButtonLifo lifo;
u8 padding[0x48];
} HidHomeButtonSharedMemoryFormat;
// End HidHomeButton
// Begin HidSleepButton
/// HidSleepButtonState
typedef struct {
u64 sampling_number;
u64 buttons;
} HidSleepButtonState;
/// HidSleepButtonStateAtomicStorage
typedef struct {
u64 sampling_number;
HidSleepButtonState state;
} HidSleepButtonStateAtomicStorage;
/// HidSleepButtonLifo
typedef struct {
HidCommonLifoHeader header;
HidSleepButtonStateAtomicStorage storage[17];
} HidSleepButtonLifo;
/// HidSleepButtonSharedMemoryFormat
typedef struct {
HidSleepButtonLifo lifo;
u8 padding[0x48];
} HidSleepButtonSharedMemoryFormat;
// End HidSleepButton
// Begin HidCaptureButton
/// HidCaptureButtonState
typedef struct {
u64 sampling_number;
u64 buttons;
} HidCaptureButtonState;
/// HidCaptureButtonStateAtomicStorage
typedef struct {
u64 sampling_number;
HidCaptureButtonState state;
} HidCaptureButtonStateAtomicStorage;
/// HidCaptureButtonLifo
typedef struct {
HidCommonLifoHeader header;
HidCaptureButtonStateAtomicStorage storage[17];
} HidCaptureButtonLifo;
/// HidCaptureButtonSharedMemoryFormat
typedef struct {
HidCaptureButtonLifo lifo;
u8 padding[0x48];
} HidCaptureButtonSharedMemoryFormat;
// End HidCaptureButton
// Begin HidInputDetector
/// HidInputDetectorState
typedef struct {
u64 input_source_state;
u64 sampling_number;
} HidInputDetectorState;
/// HidInputDetectorStateAtomicStorage
typedef struct {
u64 sampling_number;
HidInputDetectorState state;
} HidInputDetectorStateAtomicStorage;
/// HidInputDetectorLifo
typedef struct {
HidCommonLifoHeader header;
HidInputDetectorStateAtomicStorage storage[2];
} HidInputDetectorLifo;
/// HidInputDetectorSharedMemoryEntry
typedef struct {
HidInputDetectorLifo lifo;
u8 padding[0x30];
} HidInputDetectorSharedMemoryEntry;
/// HidInputDetectorSharedMemoryFormat
typedef struct {
HidInputDetectorSharedMemoryEntry entries[16];
} HidInputDetectorSharedMemoryFormat;
// End HidInputDetector
// Begin HidUniquePad
/// HidUniquePadConfigMutex
typedef struct {
u8 unk_0x0[0x20];
} HidUniquePadConfigMutex;
/// HidSixAxisSensorUserCalibrationState
typedef struct {
u32 flags;
u8 reserved[4];
u64 stage;
u64 sampling_number;
} HidSixAxisSensorUserCalibrationState;
/// HidSixAxisSensorUserCalibrationStateAtomicStorage
typedef struct {
u64 sampling_number;
HidSixAxisSensorUserCalibrationState calib_state;
} HidSixAxisSensorUserCalibrationStateAtomicStorage;
/// HidSixAxisSensorUserCalibrationStateLifo
typedef struct {
HidCommonLifoHeader header;
HidSixAxisSensorUserCalibrationStateAtomicStorage storage[2];
} HidSixAxisSensorUserCalibrationStateLifo;
/// HidAnalogStickCalibrationStateImpl
typedef struct {
u64 state;
u64 flags;
u64 stage;
u64 sampling_number;
} HidAnalogStickCalibrationStateImpl;
/// HidAnalogStickCalibrationStateImplAtomicStorage
typedef struct {
u64 sampling_number;
HidAnalogStickCalibrationStateImpl calib_state;
} HidAnalogStickCalibrationStateImplAtomicStorage;
/// HidAnalogStickCalibrationStateImplLifo
typedef struct {
HidCommonLifoHeader header;
HidAnalogStickCalibrationStateImplAtomicStorage storage[2];
} HidAnalogStickCalibrationStateImplLifo;
/// HidUniquePadConfig
typedef struct {
u32 type;
u32 interface;
u8 serial_number[0x10];
u32 controller_number;
bool is_active;
u8 reserved[3];
u64 sampling_number;
} HidUniquePadConfig;
/// HidUniquePadConfigAtomicStorage
typedef struct {
u64 sampling_number;
HidUniquePadConfig config;
} HidUniquePadConfigAtomicStorage;
/// HidUniquePadConfigLifo
typedef struct {
HidCommonLifoHeader header;
HidUniquePadConfigAtomicStorage storage[2];
} HidUniquePadConfigLifo;
/// HidUniquePadLifo
typedef struct {
HidUniquePadConfigLifo config_lifo;
HidAnalogStickCalibrationStateImplLifo analog_stick_calib_lifo[2];
HidSixAxisSensorUserCalibrationStateLifo sixaxis_calib_lifo;
HidUniquePadConfigMutex mutex;
} HidUniquePadLifo;
/// HidUniquePadSharedMemoryEntry
typedef struct {
HidUniquePadLifo lifo;
u8 padding[0x220];
} HidUniquePadSharedMemoryEntry;
/// HidUniquePadSharedMemoryFormat
typedef struct {
HidUniquePadSharedMemoryEntry entries[16];
} HidUniquePadSharedMemoryFormat;
// End HidUniquePad
// Begin HidNpad
/// Npad colors.
@ -1080,12 +1371,15 @@ typedef struct HidSharedMemory {
HidTouchScreenSharedMemoryFormat touchscreen;
HidMouseSharedMemoryFormat mouse;
HidKeyboardSharedMemoryFormat keyboard;
u8 digitizer[0x1000]; ///< [10.0.0+] Digitizer [1.0.0-9.2.0] BasicXpad
u8 home_button[0x200];
u8 sleep_button[0x200];
u8 capture_button[0x200];
u8 input_detector[0x800];
u8 unique_pad[0x4000]; ///< [1.0.0-4.1.0] UniquePad
union {
HidBasicXpadSharedMemoryFormat basic_xpad; ///< [1.0.0-9.2.0] BasicXpad
HidDigitizerSharedMemoryFormat digitizer; ///< [10.0.0+] Digitizer
};
HidHomeButtonSharedMemoryFormat home_button;
HidSleepButtonSharedMemoryFormat sleep_button;
HidCaptureButtonSharedMemoryFormat capture_button;
HidInputDetectorSharedMemoryFormat input_detector;
HidUniquePadSharedMemoryFormat unique_pad; ///< [1.0.0-4.1.0] UniquePad
HidNpadSharedMemoryFormat npad;
HidGestureSharedMemoryFormat gesture;
HidConsoleSixAxisSensor console_six_axis_sensor; ///< [5.0.0+] ConsoleSixAxisSensor
@ -1245,6 +1539,48 @@ NX_CONSTEXPR bool hidKeyboardStateGetKey(const HidKeyboardState *state, HidKeybo
///@}
///@name HomeButton
///@{
/**
* @brief Gets \ref HidHomeButtonState.
* @note Home button shmem must be activated with \ref hidsysActivateHomeButton
* @param[out] states Output array of \ref HidHomeButtonState.
* @param[in] count Size of the states array in entries.
* @return Total output entries.
*/
size_t hidGetHomeButtonStates(HidHomeButtonState *states, size_t count);
///@}
///@name SleepButton
///@{
/**
* @brief Gets \ref HidSleepButtonState.
* @note Sleep button shmem must be activated with \ref hidsysActivateSleepButton
* @param[out] states Output array of \ref HidSleepButtonState.
* @param[in] count Size of the states array in entries.
* @return Total output entries.
*/
size_t hidGetSleepButtonStates(HidSleepButtonState *states, size_t count);
///@}
///@name CaptureButton
///@{
/**
* @brief Gets \ref HidCaptureButtonState.
* @note Capture button shmem must be activated with \ref hidsysActivateCaptureButton
* @param[out] states Output array of \ref HidCaptureButtonState.
* @param[in] count Size of the states array in entries.
* @return Total output entries.
*/
size_t hidGetCaptureButtonStates(HidCaptureButtonState *states, size_t count);
///@}
///@name Npad
///@{

View File

@ -323,6 +323,51 @@ Result hidsysGetUniquePadsFromNpad(HidNpadIdType id, HidsysUniquePadId *unique_p
**/
Result hidsysEnableAppletToGetInput(bool enable);
/**
* @brief EnableHandheldHids
**/
Result hidsysEnableHandheldHids(void);
/**
* @brief DisableHandheldHids
**/
Result hidsysDisableHandheldHids(void);
/**
* @brief SetJoyConRailEnabled
* @note Only available on [9.0.0+].
* @param[in] enable Input flag.
**/
Result hidsysSetJoyConRailEnabled(bool enable);
/**
* @brief IsJoyConRailEnabled
* @note Only available on [9.0.0+].
* @param[out] out Output flag.
**/
Result hidsysIsJoyConRailEnabled(bool *out);
/**
* @brief IsHandheldHidsEnabled
* @note Only available on [10.0.0+].
* @param[out] out Output flag.
**/
Result hidsysIsHandheldHidsEnabled(bool *out);
/**
* @brief IsJoyConAttachedOnAllRail
* @note Only available on [11.0.0+].
* @param[out] out Output flag.
**/
Result hidsysIsJoyConAttachedOnAllRail(bool *out);
/**
* @brief IsInvertedControllerConnectedOnRail
* @note Only available on [19.0.0+].
* @param[out] out Output flag.
**/
Result hidsysIsInvertedControllerConnectedOnRail(bool *out);
/**
* @brief AcquireUniquePadConnectionEventHandle
* @param[out] out_event Output Event.

View File

@ -67,6 +67,12 @@ typedef enum {
LdnWirelessControllerRestriction_Unknown1 = 1, ///< Unknown
} LdnWirelessControllerRestriction;
/// Protocol
typedef enum {
LdnProtocol_NX = 1, ///< NX (default)
LdnProtocol_Unknown3 = 3, ///< (NXAndOunce?)
} LdnProtocol;
/// Ipv4Address. This is essentially the same as struct in_addr - hence this can be used with standard sockets (byteswap required).
typedef struct {
u32 addr; ///< Address
@ -331,6 +337,13 @@ Result ldnScanPrivate(s32 channel, const LdnScanFilter *filter, LdnNetworkInfo *
*/
Result ldnSetWirelessControllerRestriction(LdnWirelessControllerRestriction restriction);
/**
* @brief SetProtocol
* @note This is only usable with [20.0.0+] (with [18.0.0-19-0.1] this is available but not usable).
* @param[in] protocol \ref LdnProtocol
*/
Result ldnSetProtocol(LdnProtocol protocol);
/**
* @brief OpenAccessPoint
* @note \ref LdnState must be ::LdnState_Initialized, this eventually sets the State to ::LdnState_AccessPointOpened.

View File

@ -20,6 +20,20 @@ typedef struct {
u32 acid_fac_size;
u32 aci0_fah_size;
u8 ac_buffer[0x3E0];
} LoaderProgramInfoV1;
typedef struct {
u8 main_thread_priority;
u8 default_cpu_id;
u16 application_type;
u32 main_thread_stack_size;
u64 program_id;
u32 acid_sac_size;
u32 aci0_sac_size;
u32 acid_fac_size;
u32 aci0_fah_size;
u8 unused_20[0x10];
u8 ac_buffer[0x3E0];
} LoaderProgramInfo;
typedef struct {
@ -28,6 +42,11 @@ typedef struct {
u64 size;
} LoaderModuleInfo;
typedef struct {
u8 platform; ///< NcmContentMetaPlatform
u8 content_attributes; ///< FsContentAttributes
} LoaderProgramAttributes;
/// Initialize ldr:shel.
Result ldrShellInitialize(void);
@ -62,8 +81,9 @@ Result ldrDmntSetProgramArguments(u64 program_id, const void *args, size_t args_
Result ldrDmntFlushArguments(void);
Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, s32 *num_out);
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_process_h);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info);
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, const LoaderProgramAttributes *attrs, Handle *out_process_h);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, const LoaderProgramAttributes *attrs, LoaderProgramInfo *out_program_info); ///< [19.0.0+/Atmosphere]
Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info); ///< [1.0.0-18.1.0/Non-Atmosphere]
Result ldrPmPinProgram(const NcmProgramLocation *loc, u64 *out_pin_id);
Result ldrPmUnpinProgram(u64 pin_id);
Result ldrPmSetEnabledProgramVerification(bool enabled); ///< [10.0.0+]

View File

@ -113,6 +113,15 @@ typedef struct {
u8 unk_x57;
} MiiCharInfo;
typedef struct {
u8 data[0x44];
} MiiStoreData;
// Mii format used in 3DS (https://www.3dbrew.org/wiki/Mii#Mii_format).
typedef struct {
u8 data[0x5C];
} MiiVer3StoreData;
// Original Mii colors and types before Ver3StoreData conversion
typedef struct {
u8 faceline_color;

View File

@ -23,11 +23,6 @@ typedef enum {
NfcServiceType_System = 1, ///< Initializes nfc:sys.
} NfcServiceType;
typedef enum {
NfpState_NonInitialized = 0,
NfpState_Initialized = 1,
} NfpState;
typedef enum {
NfcState_NonInitialized = 0,
NfcState_Initialized = 1,
@ -40,7 +35,6 @@ typedef enum {
NfpDeviceState_TagRemoved = 3,
NfpDeviceState_TagMounted = 4,
NfpDeviceState_Unavailable = 5,
NfpDeviceState_Finalized = 6,
} NfpDeviceState;
typedef enum {
@ -49,16 +43,23 @@ typedef enum {
NfcDeviceState_TagFound = 2,
NfcDeviceState_TagRemoved = 3,
NfcDeviceState_TagMounted = 4,
NfcDeviceState_Unavailable = 5,
NfcDeviceState_Finalized = 6,
} NfcDeviceState;
typedef enum {
NfpApplicationAreaVersion_3DS = 0,
NfpApplicationAreaVersion_WiiU = 1,
NfpApplicationAreaVersion_3DSv2 = 2,
NfpApplicationAreaVersion_Switch = 3,
NfpApplicationAreaVersion_NotSet = 0xFF,
NfcMifareDeviceState_Initialized = 0,
NfcMifareDeviceState_SearchingForTag = 1,
NfcMifareDeviceState_TagFound = 2,
NfcMifareDeviceState_TagRemoved = 3,
NfcMifareDeviceState_TagMounted = 4,
NfcMifareDeviceState_Unavailable = 5,
} NfcMifareDeviceState;
typedef enum {
NfpApplicationAreaVersion_3DS = 0, ///< Application area created by a 3DS game.
NfpApplicationAreaVersion_WiiU = 1, ///< Application area created by a Wii U game.
NfpApplicationAreaVersion_3DSv2 = 2, ///< Application area created by a (new?) 3DS game.
NfpApplicationAreaVersion_Switch = 3, ///< Application area created by a Switch game.
NfpApplicationAreaVersion_Invalid = 0xFF, ///< Invalid value (application area not created).
} NfpApplicationAreaVersion;
typedef enum {
@ -66,9 +67,9 @@ typedef enum {
} NfpDeviceType;
typedef enum {
NfpMountTarget_Rom = 1,
NfpMountTarget_Ram = 2,
NfpMountTarget_All = 3,
NfpMountTarget_Rom = BIT(0),
NfpMountTarget_Ram = BIT(1),
NfpMountTarget_All = NfpMountTarget_Rom | NfpMountTarget_Ram,
} NfpMountTarget;
typedef enum {
@ -102,104 +103,123 @@ typedef enum {
NfcMifareCommand_Store = 0xC2,
} NfcMifareCommand;
typedef struct {
u8 uuid[10];
u8 uuid_length;
u8 reserved1[0x15];
u32 protocol;
u32 tag_type;
u8 reserved2[0x30];
} NX_PACKED NfpTagInfo;
typedef enum {
NfpAmiiboFlag_Valid = BIT(0), ///< Initialized in system settings.
NfpAmiiboFlag_ApplicationAreaExists = BIT(1), ///< Application area exists.
} NfpAmiiboFlag;
typedef enum {
NfpBreakType_Flush = 0,
NfpBreakType_Break1 = 1,
NfpBreakType_Break2 = 2,
} NfpBreakType;
typedef struct {
u8 uuid[10];
u8 uuid_length;
u8 reserved1[0x15];
u32 protocol;
u32 tag_type;
u8 reserved2[0x30];
} NX_PACKED NfcTagInfo;
u16 year;
u8 month;
u8 day;
} NfpDate;
typedef struct {
u16 last_write_year;
u8 last_write_month;
u8 last_write_day;
u8 uid[10]; ///< UUID.
u8 uid_length; ///< UUID length.
u8 reserved[0x15];
} NfcTagUid;
typedef struct {
NfcTagUid uid; ///< UUID.
u32 protocol; ///< \ref NfcProtocol
u32 tag_type; ///< \ref NfcTagType
u8 reserved[0x30];
} NfpTagInfo;
typedef struct {
NfcTagUid uid; ///< UUID.
u32 protocol; ///< \ref NfcProtocol
u32 tag_type; ///< \ref NfcTagType
u8 reserved[0x30];
} NfcTagInfo;
typedef struct {
NfpDate last_write_date;
u16 write_counter;
u16 version;
u32 application_area_size;
u8 reserved[0x34];
} NX_PACKED NfpCommonInfo;
u8 reserved[0x34];
} NfpCommonInfo;
typedef struct {
u8 amiibo_id[0x8];
u8 reserved[0x38];
} NX_PACKED NfpModelInfo;
union {
u8 character_id[3];
struct {
u16 game_character_id;
u8 character_variant;
} NX_PACKED;
};
u8 series_id; ///< Series.
u16 numbering_id; ///< Model number.
u8 nfp_type; ///< Figure type.
u8 reserved[0x39];
} NfpModelInfo;
typedef struct {
MiiCharInfo mii;
u16 first_write_year;
u8 first_write_month;
u8 first_write_day;
char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
NfpDate first_write_date;
char amiibo_name[(10*4)+1]; ///< Amiibo name (utf-8, null-terminated).
u8 font_region;
u8 reserved[0x7A];
} NX_PACKED NfpRegisterInfo;
} NfpRegisterInfo;
typedef struct {
u8 mii_store_data[0x44];
u16 first_write_year;
u8 first_write_month;
u8 first_write_day;
char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
MiiStoreData mii_store_data;
NfpDate first_write_date;
char amiibo_name[(10*4)+1]; ///< Amiibo name (utf-8, null-terminated).
u8 font_region;
u8 reserved[0x8E];
} NX_PACKED NfpRegisterInfoPrivate;
} NfpRegisterInfoPrivate;
typedef struct {
u64 application_id;
u32 application_area_id;
u16 crc_change_counter;
u32 access_id;
u16 crc32_change_counter;
u8 flags;
u8 tag_type;
u8 application_area_version;
u8 reserved[0x2F];
} NX_PACKED NfpAdminInfo;
} NfpAdminInfo;
typedef struct {
u8 magic;
u8 tag_magic; ///< Tag magic (always 0xA5: https://www.3dbrew.org/wiki/Amiibo#Page_layout).
u8 reserved1[0x1];
u8 write_counter;
u8 reserved2[0x1];
u32 settings_crc;
u8 reserved3[0x38];
u16 last_write_year;
u8 last_write_month;
u8 last_write_day;
u16 application_write_counter;
u16 version;
u32 application_area_size;
u8 reserved4[0x34];
MiiCharInfo mii;
MiiNfpStoreDataExtension mii_store_data_extension;
u16 first_write_year;
u8 first_write_month;
u8 first_write_day;
u16 amiibo_name[10+1]; ///< utf-16, null-terminated
u8 settings_flag; ///< bit4 = amiibo was initialized in console settings, bit5 = has application area
u8 unknown1; ///< Normally zero
u32 register_info_crc;
u32 unknown2[0x5]; ///< Normally zero
u8 reserved5[0x64];
u64 application_id;
u32 access_id;
u16 settings_crc_counter;
u8 font_region;
u8 tag_type;
u8 console_type;
u8 application_id_byte; ///< (Original Program ID >> 0x24) & 0xF byte (Program ID has this byte swapped with console type)
u8 reserved6[0x2E];
u8 application_area[0xD8];
} NX_PACKED NfpData;
u16 tag_write_counter; ///< Incremented every tag write.
u32 crc32_1; ///< CRC32 of some internal 8-byte data.
u8 reserved2[0x38];
NfpDate last_write_date; ///< Updated every write.
u16 write_counter; ///< Incremented every write, until it maxes out at 0xFFFF.
u16 version; ///< Version.
u32 application_area_size; ///< Size of the application area.
u8 reserved3[0x34];
MiiVer3StoreData mii_v3; ///< Ver3StoreData (Mii format used in 3DS).
u8 pad[0x2];
u16 mii_v3_crc16; ///< CRC16 of Ver3StoreData.
MiiNfpStoreDataExtension mii_store_data_extension; ///< StoreDataExtension
NfpDate first_write_date; ///< Set when the amiibo is first written to.
u16 amiibo_name[10+1]; ///< Amiibo name (utf-16, null-terminated).
u8 font_region; ///< Font region.
u8 unknown1; ///< Normally zero
u32 crc32_2; ///< CRC32 of Ver3StoreData + application_id_byte + unknown1 + StoreDataExtension + unknown2 (0x7E bytes total)
u32 unknown2[0x5]; ///< Normally zero
u8 reserved4[0x64];
u64 application_id; ///< Modified application ID (Application ID & 0xFFFFFFFF0FFFFFFF | 0x30000000)
u32 access_id; ///< Application area access ID
u16 settings_crc32_change_counter;
u8 flags; ///< \ref NfpAmiiboFlag
u8 tag_type; ///< \ref NfcTagType
u8 application_area_version; ///< \ref NfpApplicationAreaVersion
u8 application_id_byte; ///< Application ID byte ((Application ID >> 28) & 0xFF)
u8 reserved5[0x2E];
u8 application_area[0xD8]; ///< Application area.
} NfpData;
typedef struct {
u8 mifare_command;
@ -292,21 +312,29 @@ Result nfcMfStartDetection(const NfcDeviceHandle *handle);
Result nfcMfStopDetection(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_System.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id);
/// Not available with ::NfpServiceType_System.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram, and the application area to be opened.
Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size, u32 *out_size);
/// Not available with ::NfpServiceType_System.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram, and the application area to be opened.
Result nfpSetApplicationArea(const NfcDeviceHandle *handle, const void* buf, size_t buf_size);
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpFlush(const NfcDeviceHandle *handle);
Result nfpRestore(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_System.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size);
/// Not available with ::NfpServiceType_System.
/// Only available with [3.0.0+].
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram, and the application area to be opened.
Result nfpRecreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size);
/// Not available with ::NfpServiceType_System.
@ -319,10 +347,18 @@ Result nfpDeleteApplicationArea(const NfcDeviceHandle *handle);
Result nfpExistsApplicationArea(const NfcDeviceHandle *handle, bool *out);
Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out);
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out);
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpGetCommonInfo(const NfcDeviceHandle *handle, NfpCommonInfo *out);
/// Requires the amiibo to be mounted with ::NfpMountTarget_Rom.
Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out);
/// Not available with ::NfpServiceType_User.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpGetAdminInfo(const NfcDeviceHandle *handle, NfpAdminInfo *out);
/// Only available with [4.0.0+].
@ -347,7 +383,7 @@ Result nfcMfAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event)
/// Returned event will have autoclear off.
Result nfcMfAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event);
Result nfpGetState(NfpState *out);
Result nfpGetState(NfcState *out);
Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out);
Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out);
@ -359,7 +395,7 @@ Result nfcGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out);
Result nfcGetNpadId(const NfcDeviceHandle *handle, u32 *out);
Result nfcMfGetState(NfcState *out);
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out);
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcMifareDeviceState *out);
Result nfcMfGetNpadId(const NfcDeviceHandle *handle, u32 *out);
/// Returned event will have autoclear on.
@ -375,25 +411,39 @@ Result nfcMfAttachAvailabilityChangeEvent(Event *out_event);
Result nfpFormat(const NfcDeviceHandle *handle);
/// Not available with ::NfpServiceType_User.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpGetRegisterInfoPrivate(const NfcDeviceHandle *handle, NfpRegisterInfoPrivate *out);
/// Not available with ::NfpServiceType_User.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpSetRegisterInfoPrivate(const NfcDeviceHandle *handle, const NfpRegisterInfoPrivate *register_info_private);
/// Not available with ::NfpServiceType_User.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpDeleteRegisterInfo(const NfcDeviceHandle *handle);
/// Only available with ::NfpServiceType_Debug.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpGetAll(const NfcDeviceHandle *handle, NfpData *out);
/// Only available with ::NfpServiceType_Debug.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpSetAll(const NfcDeviceHandle *handle, const NfpData *nfp_data);
/// Only available with ::NfpServiceType_Debug.
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpFlushDebug(const NfcDeviceHandle *handle);
/// Only available with ::NfpServiceType_Debug.
Result nfpBreakTag(const NfcDeviceHandle *handle, u32 break_type);
/// Requires the amiibo to be mounted with ::NfpMountTarget_Ram.
Result nfpBreakTag(const NfcDeviceHandle *handle, NfpBreakType break_type);
/// Only available with ::NfpServiceType_Debug.
Result nfpReadBackupData(const NfcDeviceHandle *handle, void* out_buf, size_t buf_size, u32 *out_size);
/// Only available with ::NfpServiceType_Debug.
Result nfpWriteBackupData(const NfcDeviceHandle *handle, const void* buf, size_t buf_size);
/// Only available with ::NfpServiceType_Debug.
Result nfpWriteNtf(const NfcDeviceHandle *handle, u32 write_type, const void* buf, size_t buf_size);

View File

@ -312,7 +312,7 @@ typedef struct {
/// BluetoothDevicesSettings
typedef struct {
BtdrvAddress addr; ///< \ref BtdrvAddress
BtmBdName name; ///< BdName. Unused on 13.0.0+
BtmBdName name; ///< [1.0.0-12.1.0] BdName. On 13.0.0+ name2 is used instead.
BtmClassOfDevice class_of_device; ///< ClassOfDevice
u8 link_key[0x10]; ///< LinkKey
u8 link_key_present; ///< LinkKeyPresent
@ -328,14 +328,11 @@ typedef struct {
u8 device_type; ///< DeviceType
u16 brr_size; ///< BrrSize
u8 brr[0x9]; ///< Brr
union {
u8 reserved[0x12B]; ///< Reserved [1.0.0-12.1.0]
struct {
u8 pad; ///< Padding
char name2[0xF9]; ///< Name
}; ///< [13.0.0+]
};
u8 audio_source_volume; ///< [13.0.0+] AudioSourceVolume
char name2[0xF9]; ///< [13.0.0+] Name
u8 audio_sink_volume; ///< [15.0.0+] AudioSinkVolume
u32 audio_flags; ///< [14.0.0+] AudioFlags
u8 reserved[0x2C]; ///< Reserved
} SetSysBluetoothDevicesSettings;
/// Structure returned by \ref setsysGetFirmwareVersion.
@ -440,8 +437,8 @@ typedef struct {
u8 vertical_active_lines_msb : 4;
u8 horizontal_sync_offset_pixels_lsb;
u8 horizontal_sync_pulse_width_pixels_lsb;
u8 horizontal_sync_pulse_width_lines_lsb : 4;
u8 horizontal_sync_offset_lines_lsb : 4;
u8 vertical_sync_pulse_width_lines_lsb : 4;
u8 vertical_sync_offset_lines_lsb : 4;
u8 vertical_sync_pulse_width_lines_msb : 2;
u8 vertical_sync_offset_lines_msb : 2;
u8 horizontal_sync_pulse_width_pixels_msb : 2;
@ -497,7 +494,7 @@ typedef struct {
u16 product_code;
u32 serial_number;
u8 manufacture_week;
u8 manufacture_year;
u8 manufacture_year; ///< Real value is val - 10.
u8 edid_version;
u8 edid_revision;
u8 video_input_parameters_bitmap;
@ -560,6 +557,8 @@ typedef struct {
SetSysModeLine extended_timing_descriptor[5];
u8 padding[5];
u8 extended_checksum; ///< Sum of 128 extended bytes should equal 0 mod 256.
u8 data2[0x80]; ///< [13.0.0+]
u8 data3[0x80]; ///< [13.0.0+]
} SetSysEdid;
/// DataDeletionSettings

View File

@ -7,6 +7,7 @@
#pragma once
#include "../types.h"
#include "../kernel/event.h"
#include "../sf/service.h"
#define SPL_RSA_BUFFER_SIZE (0x100)

View File

@ -163,7 +163,7 @@ static void _sha256ProcessBlocks(Sha256Context *ctx, const u8 *src_u8, size_t nu
[cur_hash0]"+w"(cur_hash0), [cur_hash1]"+w"(cur_hash1),
[prev_hash0]"+w"(prev_hash0), [prev_hash1]"+w"(prev_hash1),
[tmp_hash]"=w"(tmp_hash), [src_u8]"+r"(src_u8)
: [round_constants]"r"(s_roundConstants)
: "m"(*(const u8 (*)[num_blocks*SHA256_BLOCK_SIZE])src_u8), [round_constants]"r"(s_roundConstants)
:
);

View File

@ -27,6 +27,19 @@ static Result _nwindowConnect(NWindow* nw)
return rc;
}
static Result _nwindowCancelBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence)
{
static const NvMultiFence s_emptyFence = {0};
if (!fence)
fence = &s_emptyFence;
Result rc = bqCancelBuffer(&nw->bq, slot, fence);
if (R_SUCCEEDED(rc))
nw->cur_slot = -1;
return rc;
}
static Result _nwindowDisconnect(NWindow* nw)
{
Result rc = bqDisconnect(&nw->bq, NATIVE_WINDOW_API_CPU);
@ -267,13 +280,7 @@ Result nwindowCancelBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence)
return MAKERESULT(Module_Libnx, LibnxError_BadGfxQueueBuffer);
}
static const NvMultiFence s_emptyFence = {0};
if (!fence)
fence = &s_emptyFence;
Result rc = bqCancelBuffer(&nw->bq, slot, fence);
if (R_SUCCEEDED(rc))
nw->cur_slot = -1;
Result rc = _nwindowCancelBuffer(nw, slot, fence);
mutexUnlock(&nw->mutex);
return rc;
@ -323,8 +330,9 @@ Result nwindowReleaseBuffers(NWindow* nw)
mutexLock(&nw->mutex);
if (nw->cur_slot >= 0)
rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
else if (nw->is_connected && nw->slots_configured)
rc = _nwindowCancelBuffer(nw, nw->cur_slot, NULL);
if (R_SUCCEEDED(rc) && nw->is_connected && nw->slots_configured)
rc = _nwindowDisconnect(nw);
mutexUnlock(&nw->mutex);

View File

@ -82,6 +82,11 @@ void _nvFenceCleanup(void)
}
}
u32 nvFenceGetFd(void)
{
return g_ctrl_fd;
}
static Result _nvFenceEventWaitCommon(Event* event, u32 event_id, s32 timeout_us)
{
u64 timeout_ns = UINT64_MAX;

View File

@ -204,16 +204,15 @@ Result nvioctlChannel_Submit(u32 fd, const nvioctl_cmdbuf *cmdbufs, u32 num_cmdb
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
struct {
__nv_in u32 num_cmdbufs;
__nv_in u32 num_relocs;
__nv_in u32 num_syncpt_incrs;
__nv_in u32 num_fences;
__nv_in nvioctl_cmdbuf cmdbufs [num_cmdbufs];
__nv_in nvioctl_reloc relocs [num_relocs];
__nv_in nvioctl_reloc_shift reloc_shifts[num_relocs];
__nv_in nvioctl_syncpt_incr syncpt_incrs[num_syncpt_incrs];
__nv_in nvioctl_syncpt_incr wait_checks [num_syncpt_incrs];
__nv_out nvioctl_fence fences [num_fences];
__nv_in u32 num_cmdbufs;
__nv_in u32 num_relocs;
__nv_in u32 num_syncpt_incrs;
__nv_in u32 num_fences;
__nv_in nvioctl_cmdbuf cmdbufs [num_cmdbufs];
__nv_in nvioctl_reloc relocs [num_relocs];
__nv_in nvioctl_reloc_shift reloc_shifts[num_relocs];
__nv_in nvioctl_syncpt_incr syncpt_incrs[num_syncpt_incrs];
__nv_inout u32 thresholds [num_fences];
} data;
memset(&data, 0, sizeof(data));
@ -229,9 +228,12 @@ Result nvioctlChannel_Submit(u32 fd, const nvioctl_cmdbuf *cmdbufs, u32 num_cmdb
Result rc = nvIoctl(fd, _NV_IOWR(0, 0x01, data), &data);
if (R_SUCCEEDED(rc)) {
memcpy(fences, data.fences, num_fences * sizeof(nvioctl_fence));
for (int i = 0; i < num_fences; ++i)
fences[i].id = data.syncpt_incrs[i].syncpt_id;
for (int i = 0; i < num_fences; ++i) {
fences[i] = (nvioctl_fence){
.id = syncpt_incrs[i].syncpt_id,
.value = data.thresholds[i],
};
}
}
return rc;

View File

@ -36,6 +36,10 @@ static void _dynProcessRela(uintptr_t base, const Elf64_Rela* rela, size_t relas
break;
}
case R_AARCH64_NONE: {
break;
}
case R_AARCH64_RELATIVE: {
u64* ptr = (u64*)(base + rela->r_offset);
*ptr = base + rela->r_addend;
@ -45,6 +49,25 @@ static void _dynProcessRela(uintptr_t base, const Elf64_Rela* rela, size_t relas
}
}
static void _dynProcessRelr(uintptr_t base, const Elf64_Relr* relr, size_t relrsz)
{
u64* ptr = NULL;
for (; relrsz--; relr++) {
if ((*relr & 1) == 0) {
ptr = (u64*)(base + *relr);
*ptr++ += base;
} else {
u64 bitmap = *relr >> 1;
while (bitmap) {
unsigned id = __builtin_ffsl(bitmap)-1;
bitmap &= ~(1UL << id);
ptr[id] += base;
}
ptr += 63;
}
}
}
void __nx_dynamic(uintptr_t base, const Mod0Header* mod0)
{
// Return early if MOD0 header has been invalidated
@ -65,6 +88,8 @@ void __nx_dynamic(uintptr_t base, const Mod0Header* mod0)
// Extract relevant information from the ELF dynamic section
const Elf64_Rela* rela = NULL;
size_t relasz = 0;
const Elf64_Relr* relr = NULL;
size_t relrsz = 0;
for (; dyn->d_tag != DT_NULL; dyn++) {
switch (dyn->d_tag) {
case DT_RELA:
@ -74,6 +99,14 @@ void __nx_dynamic(uintptr_t base, const Mod0Header* mod0)
case DT_RELASZ:
relasz = dyn->d_un.d_val / sizeof(Elf64_Rela);
break;
case DT_RELR:
relr = (const Elf64_Relr*)(base + dyn->d_un.d_ptr);
break;
case DT_RELRSZ:
relrsz = dyn->d_un.d_val / sizeof(Elf64_Relr);
break;
}
}
@ -82,6 +115,11 @@ void __nx_dynamic(uintptr_t base, const Mod0Header* mod0)
_dynProcessRela(base, rela, relasz);
}
// Apply RELR relocations if present
if (relr && relrsz) {
_dynProcessRelr(base, relr, relrsz);
}
// Return early if LNY0/LNY1 extensions are not present
if (mod0->magic_lny0 != 0x30594e4c || mod0->magic_lny1 != 0x31594e4c) { // LNY0, LNY1
return;

View File

@ -160,10 +160,7 @@ static int inet_pton4(const char *src, void *dst) {
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(src, dst, size)
const u_char *src;
char *dst;
size_t size;
inet_ntop6(const u_char *src, char *dst, size_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
@ -276,9 +273,7 @@ inet_ntop6(src, dst, size)
* Paul Vixie, 1996.
*/
static int
inet_pton6(src, dst)
const char *src;
u_char *dst;
inet_pton6(const char *src, u_char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";

View File

@ -99,6 +99,9 @@ Result audctlSetTargetMute(AudioTarget target, bool mute) {
}
Result audctlIsTargetConnected(bool* connected_out, AudioTarget target) {
if (hosversionAtLeast(18,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 target;
} in = { target };
@ -166,6 +169,9 @@ Result audctlSetAudioOutputMode(AudioTarget target, AudioOutputMode mode) {
}
Result audctlSetForceMutePolicy(AudioForceMutePolicy policy) {
if (hosversionAtLeast(14,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 policy;
} in = { policy };
@ -174,6 +180,9 @@ Result audctlSetForceMutePolicy(AudioForceMutePolicy policy) {
}
Result audctlGetForceMutePolicy(AudioForceMutePolicy* policy_out) {
if (hosversionAtLeast(14,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
struct {
u32 policy;
} out;
@ -256,7 +265,7 @@ Result audctlGetHeadphoneOutputLevelMode(AudioHeadphoneOutputLevelMode* mode_out
}
Result audctlAcquireAudioVolumeUpdateEventForPlayReport(Event* event_out) {
if (hosversionBefore(3,0,0))
if (!hosversionBetween(3,14))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Handle tmp_handle;
@ -274,7 +283,7 @@ Result audctlAcquireAudioVolumeUpdateEventForPlayReport(Event* event_out) {
}
Result audctlAcquireAudioOutputDeviceUpdateEventForPlayReport(Event* event_out) {
if (hosversionBefore(3,0,0))
if (!hosversionBetween(3,14))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Handle tmp_handle;

View File

@ -24,50 +24,50 @@ Service* btGetServiceSession(void) {
return &g_btSrv;
}
Result btLeClientReadCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, u8 unk) {
Result btLeClientReadCharacteristic(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, u8 auth_req) {
const struct {
u8 primary_service;
u8 unk;
u8 is_primary;
u8 auth_req;
u8 pad[2];
u32 connection_handle;
BtdrvGattId id0;
BtdrvGattId id1;
BtdrvGattId serv_id;
BtdrvGattId char_id;
u64 AppletResourceUserId;
} in = { primary_service!=0, unk, {0}, connection_handle, *id0, *id1, appletGetAppletResourceUserId() };
} in = { is_primary!=0, auth_req, {0}, connection_handle, *serv_id, *char_id, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 0, in,
.in_send_pid = true,
);
}
Result btLeClientReadDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, u8 unk) {
Result btLeClientReadDescriptor(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const BtdrvGattId *desc_id, u8 auth_req) {
const struct {
u8 primary_service;
u8 unk;
u8 is_primary;
u8 auth_req;
u8 pad[2];
u32 connection_handle;
BtdrvGattId id0;
BtdrvGattId id1;
BtdrvGattId id2;
BtdrvGattId serv_id;
BtdrvGattId char_id;
BtdrvGattId desc_id;
u64 AppletResourceUserId;
} in = { primary_service!=0, unk, {0}, connection_handle, *id0, *id1, *id2, appletGetAppletResourceUserId() };
} in = { is_primary!=0, auth_req, {0}, connection_handle, *serv_id, *char_id, *desc_id, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 1, in,
.in_send_pid = true,
);
}
Result btLeClientWriteCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size, u8 unk, bool flag) {
Result btLeClientWriteCharacteristic(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const void* buffer, size_t size, u8 auth_req, bool with_response) {
const struct {
u8 primary_service;
u8 unk;
u8 flag;
u8 is_primary;
u8 auth_req;
u8 with_response;
u8 pad;
u32 connection_handle;
BtdrvGattId id0;
BtdrvGattId id1;
BtdrvGattId serv_id;
BtdrvGattId char_id;
u64 AppletResourceUserId;
} in = { primary_service!=0, unk, flag!=0, 0, connection_handle, *id0, *id1, appletGetAppletResourceUserId() };
} in = { is_primary!=0, auth_req, with_response!=0, 0, connection_handle, *serv_id, *char_id, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 2, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
@ -76,17 +76,17 @@ Result btLeClientWriteCharacteristic(u32 connection_handle, bool primary_service
);
}
Result btLeClientWriteDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const void* buffer, size_t size, u8 unk) {
Result btLeClientWriteDescriptor(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, const BtdrvGattId *desc_id, const void* buffer, size_t size, u8 auth_req) {
const struct {
u8 primary_service;
u8 unk;
u8 is_primary;
u8 auth_req;
u8 pad[2];
u32 connection_handle;
BtdrvGattId id0;
BtdrvGattId id1;
BtdrvGattId id2;
BtdrvGattId serv_id;
BtdrvGattId char_id;
BtdrvGattId desc_id;
u64 AppletResourceUserId;
} in = { primary_service!=0, unk, {0}, connection_handle, *id0, *id1, *id2, appletGetAppletResourceUserId() };
} in = { is_primary!=0, auth_req, {0}, connection_handle, *serv_id, *char_id, *desc_id, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 3, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
@ -95,38 +95,38 @@ Result btLeClientWriteDescriptor(u32 connection_handle, bool primary_service, co
);
}
static Result _btLeClientNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, u32 cmd_id) {
static Result _btLeClientNotification(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id, u32 cmd_id) {
const struct {
u8 primary_service;
u8 is_primary;
u8 pad[3];
u32 connection_handle;
BtdrvGattId id0;
BtdrvGattId id1;
BtdrvGattId serv_id;
BtdrvGattId char_id;
u64 AppletResourceUserId;
} in = { primary_service!=0, {0}, connection_handle, *id0, *id1, appletGetAppletResourceUserId() };
} in = { is_primary!=0, {0}, connection_handle, *serv_id, *char_id, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, cmd_id, in,
.in_send_pid = true,
);
}
Result btLeClientRegisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1) {
return _btLeClientNotification(connection_handle, primary_service, id0, id1, 4);
Result btLeClientRegisterNotification(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id) {
return _btLeClientNotification(connection_handle, is_primary, serv_id, char_id, 4);
}
Result btLeClientDeregisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1) {
return _btLeClientNotification(connection_handle, primary_service, id0, id1, 5);
Result btLeClientDeregisterNotification(u32 connection_handle, bool is_primary, const BtdrvGattId *serv_id, const BtdrvGattId *char_id) {
return _btLeClientNotification(connection_handle, is_primary, serv_id, char_id, 5);
}
Result btSetLeResponse(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, const void* buffer, size_t size) {
Result btSetLeResponse(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, const void* buffer, size_t size) {
const struct {
u8 unk;
u8 server_if;
u8 pad[3];
BtdrvGattAttributeUuid uuid0;
BtdrvGattAttributeUuid uuid1;
BtdrvGattAttributeUuid serv_uuid;
BtdrvGattAttributeUuid char_uuid;
u8 pad2[4];
u64 AppletResourceUserId;
} in = { unk, {0}, *uuid0, *uuid1, {0}, appletGetAppletResourceUserId() };
} in = { server_if, {0}, *serv_uuid, *char_uuid, {0}, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 6, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
@ -135,16 +135,16 @@ Result btSetLeResponse(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvG
);
}
Result btLeSendIndication(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, const void* buffer, size_t size, bool flag) {
Result btLeSendIndication(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, const void* buffer, size_t size, bool noconfirm) {
const struct {
u8 unk;
u8 flag;
u8 server_if;
u8 noconfirm;
u8 pad[2];
BtdrvGattAttributeUuid uuid0;
BtdrvGattAttributeUuid uuid1;
BtdrvGattAttributeUuid serv_uuid;
BtdrvGattAttributeUuid char_uuid;
u8 pad2[4];
u64 AppletResourceUserId;
} in = { unk, flag!=0, {0}, *uuid0, *uuid1, {0}, appletGetAppletResourceUserId() };
} in = { server_if, noconfirm!=0, {0}, *serv_uuid, *char_uuid, {0}, appletGetAppletResourceUserId() };
return serviceDispatchIn(&g_btSrv, 7, in,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
@ -153,7 +153,7 @@ Result btLeSendIndication(u8 unk, const BtdrvGattAttributeUuid *uuid0, const Btd
);
}
Result btGetLeEventInfo(void* buffer, size_t size, u32 *type) {
Result btGetLeEventInfo(void* buffer, size_t size, BtdrvBleEventType *type) {
u64 AppletResourceUserId = appletGetAppletResourceUserId();
return serviceDispatchInOut(&g_btSrv, 8, AppletResourceUserId, *type,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },

View File

@ -417,13 +417,13 @@ Result btdrvGetHidReport(BtdrvAddress addr, u8 report_id, BtdrvBluetoothHhReport
return serviceDispatchIn(&g_btdrvSrv, 22, in);
}
Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk) {
Result btdrvTriggerConnection(BtdrvAddress addr, u16 timeout) {
if (hosversionBefore(9,0,0)) return _btdrvCmdInAddrNoOut(addr, 23);
const struct {
BtdrvAddress addr;
u16 unk;
} in = { addr, unk };
u16 timeout;
} in = { addr, timeout };
return serviceDispatchIn(&g_btdrvSrv, 23, in);
}
@ -930,47 +930,47 @@ Result btdrvAddGattService(u8 server_if, const BtdrvGattAttributeUuid *uuid, u8
return serviceDispatchIn(&g_btdrvSrv, 75, in);
}
Result btdrvEnableGattService(u8 service_id, const BtdrvGattAttributeUuid *uuid) {
Result btdrvEnableGattService(u8 server_if, const BtdrvGattAttributeUuid *uuid) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 74 : 76;
const struct {
u8 service_id;
u8 server_if;
u8 pad[3];
BtdrvGattAttributeUuid uuid;
} in = { service_id, {0}, *uuid };
} in = { server_if, {0}, *uuid };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
Result btdrvAddGattCharacteristic(u8 service_id, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, u8 permissions, u16 property) {
Result btdrvAddGattCharacteristic(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *char_uuid, u16 permissions, u8 property) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 service_id;
u8 permissions;
u16 property;
u8 server_if;
u8 property;
u16 permissions;
BtdrvGattAttributeUuid serv_uuid;
BtdrvGattAttributeUuid char_uuid;
} in = { service_id, permissions, property, *serv_uuid, *char_uuid };
} in = { server_if, property, permissions, *serv_uuid, *char_uuid };
return serviceDispatchIn(&g_btdrvSrv, 77, in);
}
Result btdrvAddGattDescriptor(u8 service_id, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *desc_uuid, u16 permissions) {
Result btdrvAddGattDescriptor(u8 server_if, const BtdrvGattAttributeUuid *serv_uuid, const BtdrvGattAttributeUuid *desc_uuid, u16 permissions) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 cmd_id = hosversionBefore(5,1,0) ? 76 : 78;
const struct {
u8 service_id;
u8 server_if;
u8 pad;
u16 permissions;
BtdrvGattAttributeUuid serv_uuid;
BtdrvGattAttributeUuid desc_uuid;
} in = { service_id, 0, permissions, *serv_uuid, *desc_uuid };
} in = { server_if, 0, permissions, *serv_uuid, *desc_uuid };
return serviceDispatchIn(&g_btdrvSrv, cmd_id, in);
}
@ -1493,7 +1493,7 @@ bool btdrvCircularBufferFree(BtdrvCircularBuffer *c) {
if (read_offset == write_offset) return false;
u8 *data_ptr = &c->data[read_offset];
if (read_offset >= sizeof(c->data)) false;
if (read_offset >= sizeof(c->data)) return false;
u64 tmpsize = read_offset + 0x18;
if (tmpsize < sizeof(c->data)) tmpsize += *((u64*)&data_ptr[0x10]);

View File

@ -2,6 +2,7 @@
#include <string.h>
#include "service_guard.h"
#include "runtime/hosversion.h"
#include "services/applet.h"
#include "services/btmsys.h"
static Service g_btmIBtmSystemCore;
@ -54,6 +55,18 @@ static Result _btmsysCmdNoInOutBool(bool *out, u32 cmd_id) {
return rc;
}
static Result _btmsysCmdGetEvent(Event* out_event, bool autoclear, u32 cmd_id) {
Handle tmp_handle = INVALID_HANDLE;
Result rc = 0;
rc = serviceDispatch(&g_btmIBtmSystemCore, cmd_id,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &tmp_handle,
);
if (R_SUCCEEDED(rc)) eventLoadRemote(out_event, tmp_handle, autoclear);
return rc;
}
static Result _btmsysCmdGetEventOutFlag(Event* out_event, bool autoclear, u32 cmd_id) {
Handle tmp_handle = INVALID_HANDLE;
Result rc = 0;
@ -68,6 +81,24 @@ static Result _btmsysCmdGetEventOutFlag(Event* out_event, bool autoclear, u32 cm
return rc;
}
static Result _btmsysCmdOutBufPtr(void* buffer, size_t size, s32 *total_out, u32 cmd_id) {
return serviceDispatchOut(&g_btmIBtmSystemCore, cmd_id, *total_out,
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
.buffers = { {buffer, size} },
);
}
static Result _btmsysCmdInAddrNoOut(BtdrvAddress addr, u32 cmd_id) {
return serviceDispatchIn(&g_btmIBtmSystemCore, cmd_id, addr);
}
static Result _btmsysCmdAruidNoOutput(u32 cmd_id) {
u64 AppletResourceUserId = appletGetAppletResourceUserId();
return serviceDispatchIn(&g_btmIBtmSystemCore, cmd_id, AppletResourceUserId,
.in_send_pid = true,
);
}
Result btmsysStartGamepadPairing(void) {
return _btmsysCmdNoIO(0);
}
@ -117,3 +148,100 @@ Result btmsysIsGamepadPairingStarted(bool *out) {
return _btmsysCmdNoInOutBool(out, 9);
}
Result btmsysStartAudioDeviceDiscovery(void) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdNoIO(10);
}
Result btmsysStopAudioDeviceDiscovery(void) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdNoIO(11);
}
Result btmsysIsDiscoveryingAudioDevice(bool *out) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdNoInOutBool(out, 12);
}
Result btmsysGetDiscoveredAudioDevice(BtmAudioDevice *out, s32 count, s32 *total_out) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdOutBufPtr(out, sizeof(BtmAudioDevice)*count, total_out, 13);
}
Result btmsysAcquireAudioDeviceConnectionEvent(Event* out_event) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdGetEvent(out_event, true, 14);
}
Result btmsysConnectAudioDevice(BtdrvAddress addr) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdInAddrNoOut(addr, 15);
}
Result btmsysIsConnectingAudioDevice(bool *out) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdNoInOutBool(out, 16);
}
Result btmsysGetConnectedAudioDevices(BtmAudioDevice *out, s32 count, s32 *total_out) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdOutBufPtr(out, sizeof(BtmAudioDevice)*count, total_out, 17);
}
Result btmsysDisconnectAudioDevice(BtdrvAddress addr) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdInAddrNoOut(addr, 18);
}
Result btmsysAcquirePairedAudioDeviceInfoChangedEvent(Event* out_event) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdGetEvent(out_event, true, 19);
}
Result btmsysGetPairedAudioDevices(BtmAudioDevice *out, s32 count, s32 *total_out) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdOutBufPtr(out, sizeof(BtmAudioDevice)*count, total_out, 20);
}
Result btmsysRemoveAudioDevicePairing(BtdrvAddress addr) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdInAddrNoOut(addr, 21);
}
Result btmsysRequestAudioDeviceConnectionRejection(void) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdAruidNoOutput(22);
}
Result btmsysCancelAudioDeviceConnectionRejection(void) {
if (hosversionBefore(13,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _btmsysCmdAruidNoOutput(23);
}

View File

@ -54,30 +54,54 @@ Result capscNotifyAlbumStorageIsUnAvailable(CapsAlbumStorage storage) {
return _capscCmdInU8NoOut(&g_capscSrv, 2002, storage);
}
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id) {
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
if (hosversionAtLeast(19,0,0)) {
const struct {
u64 appletResourceUserId;
CapsApplicationId applicationId;
} in = { appletResourceUserId, *application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
}
else {
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id->application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
}
}
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id) {
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
return serviceDispatchIn(&g_capscSrv, 2012, in);
if (hosversionAtLeast(19,0,0)) {
const struct {
u64 appletResourceUserId;
CapsApplicationId applicationId;
} in = { appletResourceUserId, *application_id };
return serviceDispatchIn(&g_capscSrv, 2012, in);
}
else {
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id->application_id };
return serviceDispatchIn(&g_capscSrv, 2012, in);
}
}
Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid) {
Result capscGetApplicationIdFromAruid(CapsApplicationId *application_id, u64 aruid) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, *application_id);
if (hosversionAtLeast(19,0,0))
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, *application_id);
else
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, application_id->application_id);
}
Result capscCheckApplicationIdRegistered(u64 application_id) {
@ -86,14 +110,24 @@ Result capscCheckApplicationIdRegistered(u64 application_id) {
return serviceDispatchIn(&g_capscSrv, 2014, application_id);
}
Result capscGenerateCurrentAlbumFileId(u64 application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id) {
Result capscGenerateCurrentAlbumFileId(const CapsApplicationId *application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 type;
u64 applicationId;
} in = { contents, application_id };
return serviceDispatchInOut(&g_capscSrv, 2101, in, *file_id);
if (hosversionAtLeast(19,0,0)) {
const struct {
u8 type;
CapsApplicationId applicationId;
} in = { contents, *application_id };
return serviceDispatchInOut(&g_capscSrv, 2101, in, *file_id);
}
else {
const struct {
u8 type;
u64 applicationId;
} in = { contents, application_id->application_id };
return serviceDispatchInOut(&g_capscSrv, 2101, in, *file_id);
}
}
Result capscGenerateApplicationAlbumEntry(CapsApplicationAlbumEntry *appEntry, const CapsAlbumEntry *entry, u64 application_id) {

View File

@ -41,6 +41,9 @@ Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption
}
Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size) {
if (hosversionBefore(17,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 width;
u32 height;
@ -57,3 +60,26 @@ Result capsdcShrinkJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption
}
);
}
Result capsdcShrinkJpegEx(u32 scaled_width, u32 scaled_height, u32 jpeg_quality, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_jpeg, size_t out_jpeg_size, u64 *out_result_size) {
if (hosversionBefore(18,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 scaled_width;
u32 scaled_height;
u32 jpeg_quality;
u8 pad[4];
CapsScreenShotDecodeOption opts;
} in = { scaled_width, scaled_height, jpeg_quality, {}, *opts };
return serviceDispatchInOut(&g_capsdcSrv, 4002, in, *out_result_size,
.buffer_attrs = {
SfBufferAttr_In | SfBufferAttr_HipcMapAlias,
SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_HipcMapTransferAllowsNonSecure,
},
.buffers = {
{ jpeg, jpeg_size },
{ out_jpeg, out_jpeg_size },
}
);
}

View File

@ -623,6 +623,13 @@ Result fsGetAndClearErrorInfo(FsFileSystemProxyErrorInfo *out) {
return _fsObjectDispatchOut(&g_fsSrv, 800, *out);
}
Result fsGetContentStorageInfoIndex(s32 *out) {
if (hosversionBefore(19,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _fsCmdNoInOutU32(&g_fsSrv, (u32 *)out, 820);
}
Result fsDisableAutoSaveDataCreation(void) {
return _fsCmdNoIO(&g_fsSrv, 1003);
}
@ -1233,15 +1240,30 @@ Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCar
return _fsObjectDispatchInOut(&d->s, 205, *handle, *out);
}
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size) {
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size) {
const struct {
FsGameCardHandle handle;
s64 buffer_size;
} in = { *handle, size };
return _fsObjectDispatchIn(&d->s, 206, in,
// Assume old gamecard certificate size on pre-19.0.0
s64 os = 0x200;
Result rc;
if (hosversionAtLeast(19,0,0)) {
rc = _fsObjectDispatchInOut(&d->s, 206, in, os,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { dst, dst_size } });
} else {
rc = _fsObjectDispatchIn(&d->s, 206, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { dst, dst_size } });
}
if (R_SUCCEEDED(rc))
*out_size = os;
return rc;
}
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) {

View File

@ -32,13 +32,32 @@ Service* fsldrGetServiceSession(void) {
return &g_fsldrSrv;
}
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, const char *path, FsContentAttributes attr, FsFileSystem* out) {
Result fsldrOpenCodeFileSystem(FsCodeInfo* out_code_info, u64 tid, NcmStorageId storage_id, const char *path, FsContentAttributes attr, FsFileSystem* out) {
memset(out_code_info, 0, sizeof(*out_code_info));
char send_path[FS_MAX_PATH]={0};
strncpy(send_path, path, FS_MAX_PATH-1);
if (hosversionBefore(20,0,0))
strncpy(send_path, path, FS_MAX_PATH-1);
if (hosversionAtLeast(17,0,0)) {
if (hosversionAtLeast(20,0,0)) {
const struct {
u8 attr;
u8 storage_id;
u64 tid;
} in = { attr, storage_id, tid };
serviceAssumeDomain(&g_fsldrSrv);
return serviceDispatchIn(&g_fsldrSrv, 0, in,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
},
.buffers = {
{ out_code_info, sizeof(*out_code_info) },
},
.out_num_objects = 1,
.out_objects = &out->s,
);
} else if (hosversionAtLeast(17,0,0)) {
const struct {
u8 attr;
u64 tid;

View File

@ -32,7 +32,7 @@ Service* fsprGetServiceSession(void) {
static const uint32_t g_fspr_default_fah[] = {0x1, 0xFFFFFFFF, 0xFFFFFFFF, 0x1C, 0, 0x1C, 0};
static const uint32_t g_fspr_default_fac[] = {0x1, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF};
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size) {
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size, u8 fs_access_control_restriction_mode) {
if (fs_access_header == NULL) {
fs_access_header = g_fspr_default_fah;
fah_size = sizeof(g_fspr_default_fah);
@ -44,12 +44,13 @@ Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_ac
const struct {
u8 sid;
u8 pad[7];
u8 fs_access_control_restriction_mode;
u8 pad[6];
u64 pid;
u64 tid;
u64 fah_size;
u64 fac_size;
} in = { sid, {0}, pid, tid, fah_size, fac_size };
} in = { sid, fs_access_control_restriction_mode, {0}, pid, tid, fah_size, fac_size };
serviceAssumeDomain(&g_fsprSrv);
return serviceDispatchIn(&g_fsprSrv, 0, in,
.buffer_attrs = {

View File

@ -275,6 +275,33 @@ size_t hidGetKeyboardStates(HidKeyboardState *states, size_t count) {
return total;
}
size_t hidGetHomeButtonStates(HidHomeButtonState *states, size_t count) {
HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr();
if (sharedmem == NULL)
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized));
size_t total = _hidGetStates(&sharedmem->home_button.lifo.header, sharedmem->home_button.lifo.storage, 17, offsetof(HidHomeButtonStateAtomicStorage,state), offsetof(HidHomeButtonState,sampling_number), states, sizeof(HidHomeButtonState), count);
return total;
}
size_t hidGetSleepButtonStates(HidSleepButtonState *states, size_t count) {
HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr();
if (sharedmem == NULL)
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized));
size_t total = _hidGetStates(&sharedmem->sleep_button.lifo.header, sharedmem->sleep_button.lifo.storage, 17, offsetof(HidSleepButtonStateAtomicStorage,state), offsetof(HidSleepButtonState,sampling_number), states, sizeof(HidSleepButtonState), count);
return total;
}
size_t hidGetCaptureButtonStates(HidCaptureButtonState *states, size_t count) {
HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr();
if (sharedmem == NULL)
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized));
size_t total = _hidGetStates(&sharedmem->capture_button.lifo.header, sharedmem->capture_button.lifo.storage, 17, offsetof(HidCaptureButtonStateAtomicStorage,state), offsetof(HidCaptureButtonState,sampling_number), states, sizeof(HidCaptureButtonState), count);
return total;
}
void hidInitializeNpad(void) {
Result rc = _hidActivateNpad();
if (R_FAILED(rc)) diagAbortWithResult(rc);
@ -948,6 +975,8 @@ static Result _hidActivateNpad(void) {
revision = 0x2; // [6.0.0+]
if (hosversionAtLeast(8,0,0))
revision = 0x3; // [8.0.0+]
if (hosversionAtLeast(18,0,0))
revision = 0x5; // [18.0.0+]
return _hidCmdInU32AruidNoOut(revision, 109); // ActivateNpadWithRevision
}

View File

@ -9,6 +9,7 @@ static Service g_hiddbgSrv;
static bool g_hiddbgHdlsInitialized;
static TransferMemory g_hiddbgHdlsTmem;
static void* g_hiddbgHdlsWorkmem;
static const u32 g_hiddbgDeviceTypeInternalTable[] = {
BIT(20), // DeviceType 0 Invalid
@ -483,7 +484,10 @@ Result hiddbgAttachHdlsWorkBuffer(HiddbgHdlsSessionId *session_id, void *buffer,
rc = _hiddbgAttachHdlsWorkBuffer(session_id, &g_hiddbgHdlsTmem);
if (R_FAILED(rc)) tmemClose(&g_hiddbgHdlsTmem);
if (R_SUCCEEDED(rc)) g_hiddbgHdlsInitialized = true;
if (R_SUCCEEDED(rc)) {
g_hiddbgHdlsInitialized = true;
g_hiddbgHdlsWorkmem = buffer;
}
return rc;
}
@ -504,6 +508,7 @@ Result hiddbgReleaseHdlsWorkBuffer(HiddbgHdlsSessionId session_id) {
rc = _hiddbgCmdInU64NoOut(session_id.id, 325);
tmemClose(&g_hiddbgHdlsTmem);
g_hiddbgHdlsWorkmem = NULL;
return rc;
}
@ -525,7 +530,7 @@ Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsSessionId session_id, HiddbgH
if (out) {
*out = false;
if (hosversionBefore(9,0,0)) {
HiddbgHdlsStateListV7 *stateList = (HiddbgHdlsStateListV7*)(g_hiddbgHdlsTmem.src_addr);
HiddbgHdlsStateListV7 *stateList = (HiddbgHdlsStateListV7*)g_hiddbgHdlsWorkmem;
for (s32 i=0; i<stateList->total_entries; i++) {
if (stateList->entries[i].handle.handle == handle.handle) {
*out = true;
@ -534,7 +539,7 @@ Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsSessionId session_id, HiddbgH
}
}
else if (hosversionBefore(12,0,0)) {
HiddbgHdlsStateListV9 *stateList = (HiddbgHdlsStateListV9*)(g_hiddbgHdlsTmem.src_addr);
HiddbgHdlsStateListV9 *stateList = (HiddbgHdlsStateListV9*)g_hiddbgHdlsWorkmem;
for (s32 i=0; i<stateList->total_entries; i++) {
if (stateList->entries[i].handle.handle == handle.handle) {
*out = true;
@ -543,7 +548,7 @@ Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsSessionId session_id, HiddbgH
}
}
else {
HiddbgHdlsStateList *stateList = (HiddbgHdlsStateList*)(g_hiddbgHdlsTmem.src_addr);
HiddbgHdlsStateList *stateList = (HiddbgHdlsStateList*)g_hiddbgHdlsWorkmem;
for (s32 i=0; i<stateList->total_entries; i++) {
if (stateList->entries[i].handle.handle == handle.handle) {
*out = true;
@ -570,7 +575,7 @@ Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, HiddbgH
rc = _hiddbgCmdInU64NoOut(session_id.id, 326);
if (R_FAILED(rc)) return rc;
if (state) memcpy(state, g_hiddbgHdlsTmem.src_addr, sizeof(*state));
if (state) memcpy(state, g_hiddbgHdlsWorkmem, sizeof(*state));
return rc;
}
@ -592,16 +597,16 @@ Result hiddbgDumpHdlsStates(HiddbgHdlsSessionId session_id, HiddbgHdlsStateList
if (state) {
if (hosversionBefore(9,0,0)) {
HiddbgHdlsStateListV7 statev7;
memcpy(&statev7, g_hiddbgHdlsTmem.src_addr, sizeof(statev7));
memcpy(&statev7, g_hiddbgHdlsWorkmem, sizeof(statev7));
_hiddbgConvertHdlsStateListFromV7(state, &statev7);
}
else if (hosversionBefore(12,0,0)) {
HiddbgHdlsStateListV9 statev9;
memcpy(&statev9, g_hiddbgHdlsTmem.src_addr, sizeof(statev9));
memcpy(&statev9, g_hiddbgHdlsWorkmem, sizeof(statev9));
_hiddbgConvertHdlsStateListFromV9(state, &statev9);
}
else
memcpy(state, g_hiddbgHdlsTmem.src_addr, sizeof(*state));
memcpy(state, g_hiddbgHdlsWorkmem, sizeof(*state));
}
return rc;
}
@ -616,7 +621,7 @@ Result hiddbgApplyHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, const
if (state==NULL)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
memcpy(g_hiddbgHdlsTmem.src_addr, state, sizeof(*state));
memcpy(g_hiddbgHdlsWorkmem, state, sizeof(*state));
if (hosversionBefore(13,0,0))
return _hiddbgCmdInBoolNoOut(flag, 328);
@ -644,15 +649,15 @@ Result hiddbgApplyHdlsStateList(HiddbgHdlsSessionId session_id, const HiddbgHdls
if (hosversionBefore(9,0,0)) {
HiddbgHdlsStateListV7 statev7;
_hiddbgConvertHdlsStateListToV7(&statev7, state);
memcpy(g_hiddbgHdlsTmem.src_addr, &statev7, sizeof(statev7));
memcpy(g_hiddbgHdlsWorkmem, &statev7, sizeof(statev7));
}
else if (hosversionBefore(12,0,0)) {
HiddbgHdlsStateListV9 statev9;
_hiddbgConvertHdlsStateListToV9(&statev9, state);
memcpy(g_hiddbgHdlsTmem.src_addr, &statev9, sizeof(statev9));
memcpy(g_hiddbgHdlsWorkmem, &statev9, sizeof(statev9));
}
else
memcpy(g_hiddbgHdlsTmem.src_addr, state, sizeof(*state));
memcpy(g_hiddbgHdlsWorkmem, state, sizeof(*state));
if (hosversionBefore(13,0,0))
return _hiddbgCmdNoIO(329);

View File

@ -340,6 +340,49 @@ Result hidsysEnableAppletToGetInput(bool enable) {
return serviceDispatchIn(&g_hidsysSrv, 503, in);
}
Result hidsysEnableHandheldHids(void) {
return _hidsysCmdNoIO(520);
}
Result hidsysDisableHandheldHids(void) {
return _hidsysCmdNoIO(521);
}
Result hidsysSetJoyConRailEnabled(bool enable) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInBoolNoOut(enable, 522);
}
Result hidsysIsJoyConRailEnabled(bool *out) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 523);
}
Result hidsysIsHandheldHidsEnabled(bool *out) {
if (hosversionBefore(10,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 524);
}
Result hidsysIsJoyConAttachedOnAllRail(bool *out) {
if (hosversionBefore(11,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 525);
}
Result hidsysIsInvertedControllerConnectedOnRail(bool *out) {
if (hosversionBefore(19,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 526);
}
Result hidsysAcquireUniquePadConnectionEventHandle(Event *out_event) {
Handle tmp_handle = INVALID_HANDLE;

View File

@ -289,6 +289,13 @@ Result ldnSetWirelessControllerRestriction(LdnWirelessControllerRestriction rest
return _ldnCmdInU32NoOut(&g_ldnSrv, restriction, 104);
}
Result ldnSetProtocol(LdnProtocol protocol) {
if (hosversionBefore(18,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _ldnCmdInU32NoOut(&g_ldnSrv, protocol, 106);
}
Result ldnOpenAccessPoint(void) {
return _ldnCmdNoIO(&g_ldnSrv, 200);
}

View File

@ -79,21 +79,63 @@ Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos,
);
}
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_process_h) {
const struct {
u32 flags;
u32 pad;
u64 pin_id;
} in = { flags, 0, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, const LoaderProgramAttributes *attrs, Handle *out_process_h) {
if (hosversionIsAtmosphere() || hosversionAtLeast(20,0,0)) {
const struct {
LoaderProgramAttributes attr;
u16 pad;
u32 flags;
u64 pin_id;
} in = { *attrs, 0, flags, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
} else {
const struct {
u32 flags;
u32 pad;
u64 pin_id;
} in = { flags, 0, pin_id };
return serviceDispatchIn(&g_ldrPmSrv, 0, in,
.in_num_handles = 1,
.in_handles = { reslimit_h },
.out_handle_attrs = { SfOutHandleAttr_HipcMove },
.out_handles = out_process_h,
);
}
}
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info) {
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, const LoaderProgramAttributes *attrs, LoaderProgramInfo *out_program_info) {
if (!hosversionIsAtmosphere() && hosversionBefore(19, 0, 0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
if (hosversionIsAtmosphere() || hosversionAtLeast(20,0,0)) {
const struct {
LoaderProgramAttributes attr;
u16 pad1;
u32 pad2;
NcmProgramLocation loc;
} in = { *attrs, 0, 0, *loc };
_Static_assert(sizeof(in) == 0x18);
return serviceDispatchIn(&g_ldrPmSrv, 1, in,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
} else {
return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
}
}
Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info) {
if (hosversionIsAtmosphere() || hosversionAtLeast(19,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },

View File

@ -493,7 +493,7 @@ Result nfcMfAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_even
return _nfcCmdInDevhandleOutEvent(&g_nfcMfInterface, handle, out_event, 9);
}
Result nfpGetState(NfpState *out) {
Result nfpGetState(NfcState *out) {
u32 tmp=0;
Result rc = _nfcCmdNoInOutU32(&g_nfpInterface, &tmp, 19);
if (R_SUCCEEDED(rc) && out) *out = tmp;
@ -531,7 +531,7 @@ Result nfcGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out) {
return rc;
}
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcDeviceState *out) {
Result nfcMfGetDeviceState(const NfcDeviceHandle *handle, NfcMifareDeviceState *out) {
u32 tmp=0;
Result rc = _nfcCmdInDevhandleOutU32(&g_nfcMfInterface, handle, &tmp, 11);
if (R_SUCCEEDED(rc) && out) *out = tmp;
@ -620,7 +620,7 @@ Result nfpFlushDebug(const NfcDeviceHandle *handle) {
return _nfcCmdInDevhandleNoOut(&g_nfcInterface, handle, 202);
}
Result nfpBreakTag(const NfcDeviceHandle *handle, u32 break_type) {
Result nfpBreakTag(const NfcDeviceHandle *handle, NfpBreakType break_type) {
if (g_nfpServiceType != NfpServiceType_Debug)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);

View File

@ -181,11 +181,11 @@ SECTIONS
PROVIDE_HIDDEN( __bss_start__ = ADDR(.bss) );
PROVIDE_HIDDEN( __bss_end__ = __tls_end );
PROVIDE_HIDDEN( __end__ = ABSOLUTE(.) );
PROVIDE_HIDDEN( __end__ = . );
/* =========== Argument buffer =========== */
. = ALIGN(0x1000);
PROVIDE_HIDDEN( __argdata__ = ABSOLUTE(.) );
PROVIDE_HIDDEN( __argdata__ = . );
/* ==================
==== Metadata ====

View File

@ -1,5 +1,5 @@
*link:
+ -T %:getenv(DEVKITPRO /libnx/switch.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z now -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
+ -T %:getenv(DEVKITPRO /libnx/switch.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z now -z nodynamic-undefined-weak -z pack-relative-relocs --build-id=sha1 --nx-module-name
*startfile:
crti%O%s crtbegin%O%s --require-defined=main