Compare commits

...

63 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
Dave Murphy
c769852631
update Makefile version 2024-05-31 17:28:15 +01:00
Dave Murphy
e8341a00fe
4.7.0 changelog 2024-05-31 17:22:52 +01:00
Dave Murphy
e570e67704
add changelog for 4.6.0 2024-05-31 17:20:52 +01:00
Michael Scire
bb65fec6eb hidsys: use hosversionBetween 2024-05-30 21:41:06 +02:00
Michael Scire
510d85bf48 hidsys: add version checking to removed commands 2024-05-30 21:41:06 +02:00
Michael Scire
ff2e76daf9 ns: Add version checking for ns:dev commands 2024-05-30 21:41:06 +02:00
Michael Scire
c8c4406467 svc: Add new InfoTypes 2024-05-30 21:41:06 +02:00
Pablo Curiel
b69d2fa95e fs: add GetFileSystemAttribute cmd 2024-05-07 14:58:51 -04:00
averne
919e3d3938 Update for review 2024-02-04 00:57:09 +01:00
averne
b615b01d44 nvchannel: Implement GET_CLK_RATE and SET_SUBMIT_TIMEOUT 2024-02-04 00:57:09 +01:00
averne
be45a91b9c nvchannel: Fix SET_CLK_RATE 2024-02-04 00:57:09 +01:00
Rambo6Glaz
827c6b6ddf Implement IFSDeviceOperator "ChallengeCardExistence" and "GetGameCardDeviceCertificate" 2024-02-04 00:56:19 +01:00
MasaGratoR
ce1f87050d Update SetSysProductModel_Aula comment 2024-02-04 00:11:36 +01:00
Dave Murphy
99edb1c0f0
libnx 4.6.0 2023-12-17 20:21:05 +00:00
ThisALV
7d68ad6bd4
fix: avoid segfault at static dtors (#638) 2023-12-17 14:15:33 +00:00
ITotalJustice
fda4e6b105
add fsDeviceOperatorGetGameCardUpdatePartitionInfo (#635) 2023-11-23 20:46:29 +01:00
yellows8
8d10ef8745
nv: Added __nx_nv_service_type. Closes #633. 2023-11-20 14:12:52 -05:00
Ghabry
a215ae2da2 Add NX_ prefix to PACKED, NORETURN, IGNORE_ARG and DEPRECATED macros 2023-11-20 19:22:12 +01:00
Michael Scire
933c5a12f0 svc: fix query/insecure names 2023-11-01 19:06:56 +01:00
73 changed files with 1758 additions and 527 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

@ -1,5 +1,30 @@
# Changelog
## Version 4.7.0
#### system
* Basic support for 18.0.0
#### services
* fs: add GetFileSystemAttribute cmd
* fs: Implement "ChallengeCardExistence" and "GetGameCardDeviceCertificate"
#### graphics
* nvchannel: Fix SET_CLK_RATE, implement GET_CLK_RATE and SET_SUBMIT_TIMEOUT
#### miscellaneous
* Update SetSysProductModel_Aula comment
## Version 4.6.0
#### system
* svc: fix query/insecure names
#### miscellaneous
* add fsDeviceOperatorGetGameCardUpdatePartitionInfo
* Add NX_ prefix to PACKED, NORETURN, IGNORE_ARG and DEPRECATED macros
* Fix: avoid segfault at static destructors
## Version 4.5.0
#### services

View File

@ -8,13 +8,6 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules
export LIBNX_MAJOR := 4
export LIBNX_MINOR := 5
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

@ -111,7 +111,7 @@ typedef struct {
u64 languageCode; ///< See set.h.
char dialogMessage[0x800]; ///< UTF-8 Dialog message.
char fullscreenMessage[0x800]; ///< UTF-8 Fullscreen message (displayed when the user clicks on "Details").
} PACKED ErrorApplicationArg;
} NX_PACKED ErrorApplicationArg;
/// Error application config.
typedef struct {

View File

@ -116,7 +116,7 @@ typedef struct {
u32 buffer_size; ///< 0x1000-byte aligned buffer size.
u64 entries[0x18];
u16 total_entries;
} PACKED SwkbdCustomizedDictionarySet;
} NX_PACKED SwkbdCustomizedDictionarySet;
/// Base swkbd arg struct.
typedef struct {

View File

@ -95,21 +95,21 @@ typedef struct {
u32 pad; ///< Padding
char lastUrl[0x1000]; ///< LastUrl string
u64 lastUrlSize; ///< Size of LastUrl, including NUL-terminator.
} PACKED WebCommonReturnValue;
} NX_PACKED WebCommonReturnValue;
/// Header struct at offset 0 in the web Arg storage (non-webWifi).
typedef struct {
u16 total_entries; ///< Total \ref WebArgTLV entries following this struct.
u16 pad; ///< Padding
WebShimKind shimKind; ///< ShimKind
} PACKED WebArgHeader;
} NX_PACKED WebArgHeader;
/// Web TLV used in the web Arg storage.
typedef struct {
u16 type; ///< Type of this arg.
u16 size; ///< Size of the arg data following this struct.
u8 pad[4]; ///< Padding
} PACKED WebArgTLV;
} NX_PACKED WebArgTLV;
/// Config struct for web applets, non-WebWifi.
typedef struct {
@ -133,7 +133,7 @@ typedef struct {
u8 visible;
u16 unk_x5;
u8 unk_x7;
} PACKED WebBootFooterButtonEntry;
} NX_PACKED WebBootFooterButtonEntry;
/// StorageHandleQueue
typedef struct {

View File

@ -11,7 +11,7 @@ typedef struct {
} BqRect;
typedef struct {
struct { s64 timestamp; } PACKED;
struct { s64 timestamp; } NX_PACKED;
s32 isAutoTimestamp;
BqRect crop;
s32 scalingMode;

View File

@ -41,7 +41,7 @@ typedef enum {
MemType_CodeReadOnly=0x14, ///< Mapped in kernel during \ref svcControlCodeMemory.
MemType_CodeWritable=0x15, ///< Mapped in kernel during \ref svcControlCodeMemory.
MemType_Coverage=0x16, ///< Not available.
MemType_Insecure=0x17, ///< Mapped in kernel during \ref svcMapInsecureMemory.
MemType_Insecure=0x17, ///< Mapped in kernel during \ref svcMapInsecurePhysicalMemory.
} MemoryType;
/// Memory state bitmasks.
@ -109,7 +109,7 @@ typedef struct {
/// Secure monitor arguments.
typedef struct {
u64 X[8]; ///< Values of X0 through X7.
} PACKED SecmonArgs;
} NX_PACKED SecmonArgs;
/// Break reasons
typedef enum {
@ -209,6 +209,10 @@ typedef enum {
InfoType_FreeThreadCount = 24, ///< [11.0.0+] The number of free threads available to the process's resource limit.
InfoType_ThreadTickCount = 25, ///< [13.0.0+] Number of ticks spent on thread.
InfoType_IsSvcPermitted = 26, ///< [14.0.0+] Does process have access to SVC (only usable with \ref svcSynchronizePreemptionState at present).
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;
@ -260,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.
@ -362,7 +367,7 @@ Result svcQueryMemory(MemoryInfo* meminfo_ptr, u32 *pageinfo, u64 addr);
* @note Syscall number 0x07.
*/
void NORETURN svcExitProcess(void);
void NX_NORETURN svcExitProcess(void);
/**
* @brief Creates a thread.
@ -382,7 +387,7 @@ Result svcStartThread(Handle handle);
* @brief Exits the current thread.
* @note Syscall number 0x0A.
*/
void NORETURN svcExitThread(void);
void NX_NORETURN svcExitThread(void);
/**
* @brief Sleeps the current thread for the specified amount of time.
@ -668,7 +673,7 @@ Result svcOutputDebugString(const char *str, u64 size);
* @param[in] res Result code.
* @note Syscall number 0x28.
*/
void NORETURN svcReturnFromException(Result res);
void NX_NORETURN svcReturnFromException(Result res);
/**
* @brief Retrieves information about the system, or a certain kernel object.
@ -807,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+]
@ -1118,14 +1123,14 @@ Result svcQueryPhysicalAddress(PhysicalMemoryInfo *out, u64 virtaddr);
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping.
*/
Result svcQueryIoMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size);
Result svcQueryMemoryMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size);
/**
* @brief Returns a virtual address mapped to a given IO range.
* @return Result code.
* @note Syscall number 0x55.
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
* @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping.
* @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryMemoryMapping.
*/
Result svcLegacyQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
@ -1580,13 +1585,13 @@ void svcCallSecureMonitor(SecmonArgs* regs);
* @return Result code.
* @note Syscall number 0x90.
*/
Result svcMapInsecureMemory(void *address, u64 size);
Result svcMapInsecurePhysicalMemory(void *address, u64 size);
/**
* @brief Undoes the effects of \ref svcMapInsecureMemory. [15.0.0+]
* @return Result code.
* @note Syscall number 0x91.
*/
Result svcUnmapInsecureMemory(void *address, u64 size);
Result svcUnmapInsecurePhysicalMemory(void *address, u64 size);
///@}

View File

@ -52,7 +52,7 @@ Result threadStart(Thread* t);
/**
* @brief Exits the current thread immediately.
*/
void NORETURN threadExit(void);
void NX_NORETURN threadExit(void);
/**
* @brief Waits for a thread to finish executing.

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 {
@ -161,6 +164,11 @@ typedef struct {
u32 iova;
} nvioctl_command_buffer_map;
typedef struct {
u32 rate;
u32 moduleid;
} nvioctl_clk_rate;
#define NVGPU_ZBC_TYPE_INVALID 0
#define NVGPU_ZBC_TYPE_COLOR 1
#define NVGPU_ZBC_TYPE_DEPTH 2
@ -284,5 +292,7 @@ Result nvioctlChannel_Submit(u32 fd, const nvioctl_cmdbuf *cmdbufs, u32 num_cmdb
const nvioctl_syncpt_incr *syncpt_incrs, u32 num_syncpt_incrs, nvioctl_fence *fences, u32 num_fences);
Result nvioctlChannel_GetSyncpt(u32 fd, u32 module_id, u32 *syncpt);
Result nvioctlChannel_GetModuleClockRate(u32 fd, u32 module_id, u32 *freq);
Result nvioctlChannel_SetModuleClockRate(u32 fd, u32 module_id, u32 freq);
Result nvioctlChannel_MapCommandBuffer(u32 fd, nvioctl_command_buffer_map *maps, u32 num_maps, bool compressed);
Result nvioctlChannel_UnmapCommandBuffer(u32 fd, const nvioctl_command_buffer_map *maps, u32 num_maps, bool compressed);
Result nvioctlChannel_SetSubmitTimeout(u32 fd, u32 timeout);

View File

@ -12,4 +12,4 @@
* @brief Aborts program execution with a result code.
* @param[in] res Result code.
*/
void NORETURN diagAbortWithResult(Result res);
void NX_NORETURN diagAbortWithResult(Result res);

View File

@ -45,7 +45,7 @@ enum {
};
/// Loader return function.
typedef void NORETURN (*LoaderReturnFn)(int result_code);
typedef void NX_NORETURN (*LoaderReturnFn)(int result_code);
/**
* @brief Parses the homebrew loader environment block (internally called).

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

@ -79,7 +79,7 @@ typedef struct {
* @note This function does not return.
* @note This uses \ref fatalThrowWithPolicy with \ref FatalPolicy_ErrorScreen internally.
*/
void NORETURN fatalThrow(Result err);
void NX_NORETURN fatalThrow(Result err);
/**
* @brief Triggers a system fatal error with a custom \ref FatalPolicy.

View File

@ -265,6 +265,12 @@ typedef struct {
u32 value;
} FsGameCardHandle;
typedef struct {
u32 version;
u8 pad[0x4];
u64 id;
} FsGameCardUpdatePartitionInfo;
typedef struct {
u32 aes_ctr_key_type; ///< Contains bitflags describing how data is AES encrypted.
u32 speed_emulation_type; ///< Contains bitflags describing how data is emulated.
@ -320,6 +326,38 @@ typedef enum {
FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard = 2, ///< [8.0.0+]
} FsFileSystemQueryId;
/// FileSystemAttribute
typedef struct {
bool directory_name_length_max_has_value;
bool file_name_length_max_has_value;
bool directory_path_length_max_has_value;
bool file_path_length_max_has_value;
bool utf16_create_directory_path_length_max_has_value;
bool utf16_delete_directory_path_length_max_has_value;
bool utf16_rename_source_directory_path_length_max_has_value;
bool utf16_rename_destination_directory_path_length_max_has_value;
bool utf16_open_directory_path_length_max_has_value;
bool utf16_directory_name_length_max_has_value;
bool utf16_file_name_length_max_has_value;
bool utf16_directory_path_length_max_has_value;
bool utf16_file_path_length_max_has_value;
u8 reserved1[0x1B];
s32 directory_name_length_max;
s32 file_name_length_max;
s32 directory_path_length_max;
s32 file_path_length_max;
s32 utf16_create_directory_path_length_max;
s32 utf16_delete_directory_path_length_max;
s32 utf16_rename_source_directory_path_length_max;
s32 utf16_rename_destination_directory_path_length_max;
s32 utf16_open_directory_path_length_max;
s32 utf16_directory_name_length_max;
s32 utf16_file_name_length_max;
s32 utf16_directory_path_length_max;
s32 utf16_file_path_length_max;
u8 reserved2[0x64];
} FsFileSystemAttribute;
/// FsPriority
typedef enum {
FsPriority_Normal = 0,
@ -515,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);
@ -585,6 +625,7 @@ Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out);
Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out); ///< [3.0.0+]
Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path); ///< [3.0.0+]
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id); ///< [4.0.0+]
Result fsFsGetFileSystemAttribute(FsFileSystem* fs, FsFileSystemAttribute *out); ///< [15.0.0+]
void fsFsClose(FsFileSystem* fs);
/// Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path.
@ -642,8 +683,11 @@ Result fsDeviceOperatorGetAndClearMmcErrorInfo(FsDeviceOperator* d, FsStorageErr
Result fsDeviceOperatorGetMmcExtendedCsd(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
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* 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);
Result fsDeviceOperatorChallengeCardExistence(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, void* seed, size_t seed_size, void* value, size_t value_size);
void fsDeviceOperatorClose(FsDeviceOperator* d);

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.
@ -448,7 +493,7 @@ Result hidsysIsFirmwareUpdateNeededForNotification(HidsysUniquePadId unique_pad_
/**
* @brief Legacy IsButtonConfigSupported.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigSupported instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysIsButtonConfigSupported instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] out Output bool flag.
*/
@ -456,7 +501,7 @@ Result hidsysLegacyIsButtonConfigSupported(HidsysUniquePadId unique_pad_id, bool
/**
* @brief IsButtonConfigSupported
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigSupported instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigSupported instead.
* @param[in] addr \ref BtdrvAddress
* @param[out] out Output bool flag.
*/
@ -464,34 +509,34 @@ Result hidsysIsButtonConfigSupported(BtdrvAddress addr, bool *out);
/**
* @brief IsButtonConfigEmbeddedSupported
* @note Only available on [11.0.0+].
* @note Only available on [11.0.0-17.0.1].
* @param[out] out Output bool flag.
*/
Result hidsysIsButtonConfigEmbeddedSupported(bool *out);
/**
* @brief Legacy DeleteButtonConfig.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysDeleteButtonConfig instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysDeleteButtonConfig instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
*/
Result hidsysLegacyDeleteButtonConfig(HidsysUniquePadId unique_pad_id);
/**
* @brief DeleteButtonConfig
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyDeleteButtonConfig instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyDeleteButtonConfig instead.
* @param[in] addr \ref BtdrvAddress
*/
Result hidsysDeleteButtonConfig(BtdrvAddress addr);
/**
* @brief DeleteButtonConfigEmbedded
* @note Only available on [11.0.0+].
* @note Only available on [11.0.0-17.0.1].
*/
Result hidsysDeleteButtonConfigEmbedded(void);
/**
* @brief Legacy SetButtonConfigEnabled.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEnabled instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysSetButtonConfigEnabled instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[in] flag Input flag.
*/
@ -499,7 +544,7 @@ Result hidsysLegacySetButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool
/**
* @brief SetButtonConfigEnabled
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEnabled instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEnabled instead.
* @param[in] addr \ref BtdrvAddress
* @param[in] flag Input flag.
*/
@ -507,14 +552,14 @@ Result hidsysSetButtonConfigEnabled(BtdrvAddress addr, bool flag);
/**
* @brief SetButtonConfigEmbeddedEnabled
* @note Only available on [11.0.0+].
* @note Only available on [11.0.0-17.0.1].
* @param[in] flag Input flag.
*/
Result hidsysSetButtonConfigEmbeddedEnabled(bool flag);
/**
* @brief Legacy IsButtonConfigEnabled.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigEnabled instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysIsButtonConfigEnabled instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] out Output bool flag.
*/
@ -522,7 +567,7 @@ Result hidsysLegacyIsButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool *
/**
* @brief IsButtonConfigEnabled
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigEnabled instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigEnabled instead.
* @param[in] addr \ref BtdrvAddress
* @param[in] out Output bool flag.
*/
@ -530,14 +575,14 @@ Result hidsysIsButtonConfigEnabled(BtdrvAddress addr, bool *out);
/**
* @brief IsButtonConfigEmbeddedEnabled
* @note Only available on [11.0.0+].
* @note Only available on [11.0.0-17.0.1].
* @param[out] out Output bool flag.
*/
Result hidsysIsButtonConfigEmbeddedEnabled(bool *out);
/**
* @brief Legacy SetButtonConfigEmbedded.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEmbedded instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysSetButtonConfigEmbedded instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[in] config \ref HidsysButtonConfigEmbedded
*/
@ -545,14 +590,14 @@ Result hidsysLegacySetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, cons
/**
* @brief SetButtonConfigEmbedded
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEmbedded instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEmbedded instead.
* @param[in] config \ref HidsysButtonConfigEmbedded
*/
Result hidsysSetButtonConfigEmbedded(const HidsysButtonConfigEmbedded *config);
/**
* @brief Legacy SetButtonConfigFull.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigFull instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysSetButtonConfigFull instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[in] config \ref HidsysButtonConfigFull
*/
@ -560,7 +605,7 @@ Result hidsysLegacySetButtonConfigFull(HidsysUniquePadId unique_pad_id, const Hi
/**
* @brief SetButtonConfigFull
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigFull instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigFull instead.
* @param[in] addr \ref BtdrvAddress
* @param[in] config \ref HidsysButtonConfigFull
*/
@ -568,7 +613,7 @@ Result hidsysSetButtonConfigFull(BtdrvAddress addr, const HidsysButtonConfigFull
/**
* @brief Legacy SetButtonConfigLeft.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigLeft instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysSetButtonConfigLeft instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[in] config \ref HidsysButtonConfigLeft
*/
@ -576,7 +621,7 @@ Result hidsysLegacySetButtonConfigLeft(HidsysUniquePadId unique_pad_id, const Hi
/**
* @brief SetButtonConfigLeft
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigLeft instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigLeft instead.
* @param[in] addr \ref BtdrvAddress
* @param[in] config \ref HidsysButtonConfigLeft
*/
@ -584,7 +629,7 @@ Result hidsysSetButtonConfigLeft(BtdrvAddress addr, const HidsysButtonConfigLeft
/**
* @brief Legacy SetButtonConfigRight.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigRight instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysSetButtonConfigRight instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[in] config \ref HidsysButtonConfigRight
*/
@ -592,7 +637,7 @@ Result hidsysLegacySetButtonConfigRight(HidsysUniquePadId unique_pad_id, const H
/**
* @brief SetButtonConfigRight
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigRight instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigRight instead.
* @param[in] addr \ref BtdrvAddress
* @param[in] config \ref HidsysButtonConfigRight
*/
@ -600,7 +645,7 @@ Result hidsysSetButtonConfigRight(BtdrvAddress addr, const HidsysButtonConfigRig
/**
* @brief Legacy GetButtonConfigEmbedded.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigEmbedded instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysGetButtonConfigEmbedded instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] config \ref HidsysButtonConfigEmbedded
*/
@ -608,14 +653,14 @@ Result hidsysLegacyGetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, Hids
/**
* @brief GetButtonConfigEmbedded
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigEmbedded instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigEmbedded instead.
* @param[out] config \ref HidsysButtonConfigEmbedded
*/
Result hidsysGetButtonConfigEmbedded(HidsysButtonConfigEmbedded *config);
/**
* @brief Legacy GetButtonConfigFull.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigFull instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysGetButtonConfigFull instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] config \ref HidsysButtonConfigFull
*/
@ -623,7 +668,7 @@ Result hidsysLegacyGetButtonConfigFull(HidsysUniquePadId unique_pad_id, HidsysBu
/**
* @brief GetButtonConfigFull
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigFull instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigFull instead.
* @param[in] addr \ref BtdrvAddress
* @param[out] config \ref HidsysButtonConfigFull
*/
@ -631,7 +676,7 @@ Result hidsysGetButtonConfigFull(BtdrvAddress addr, HidsysButtonConfigFull *conf
/**
* @brief Legacy GetButtonConfigLeft.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigLeft instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysGetButtonConfigLeft instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] config \ref HidsysButtonConfigLeft
*/
@ -639,7 +684,7 @@ Result hidsysLegacyGetButtonConfigLeft(HidsysUniquePadId unique_pad_id, HidsysBu
/**
* @brief GetButtonConfigLeft
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigLeft instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigLeft instead.
* @param[in] addr \ref BtdrvAddress
* @param[out] config \ref HidsysButtonConfigLeft
*/
@ -647,7 +692,7 @@ Result hidsysGetButtonConfigLeft(BtdrvAddress addr, HidsysButtonConfigLeft *conf
/**
* @brief Legacy GetButtonConfigRight.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigRight instead.
* @note Only available on [10.0.0-10.2.0]. On [11.0.0-17.0.1], use \ref hidsysGetButtonConfigRight instead.
* @param[in] unique_pad_id \ref HidsysUniquePadId
* @param[out] config \ref HidsysButtonConfigRight
*/
@ -655,7 +700,7 @@ Result hidsysLegacyGetButtonConfigRight(HidsysUniquePadId unique_pad_id, HidsysB
/**
* @brief GetButtonConfigRight
* @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigRight instead.
* @note Only available on [11.0.0-17.0.1]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigRight instead.
* @param[in] addr \ref BtdrvAddress
* @param[out] config \ref HidsysButtonConfigRight
*/

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

@ -20,7 +20,7 @@ typedef struct {
MiiCreateId create_id; ///< Mii's create ID.
u32 unk;
u16 mii_name[10+1]; ///< utf-16be, null-terminated
} PACKED MiiimgImageAttribute;
} NX_PACKED MiiimgImageAttribute;
/// Initialize miiimg.
Result miiimgInitialize(void);

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];
} 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];
} 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];
} PACKED NfpCommonInfo;
} NfpCommonInfo;
typedef struct {
u8 amiibo_id[0x8];
u8 reserved[0x38];
} 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];
} 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];
} 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];
} 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
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 register_info_crc;
u32 crc32_2; ///< CRC32 of Ver3StoreData + application_id_byte + unknown1 + StoreDataExtension + unknown2 (0x7E bytes total)
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];
} PACKED NfpData;
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;
@ -207,19 +227,19 @@ typedef struct {
u8 reserved1[0x6];
u8 sector_key[0x6];
u8 reserved2[0x2];
} PACKED NfcSectorKey;
} NX_PACKED NfcSectorKey;
typedef struct {
u8 sector_number;
u8 reserved[0x7];
NfcSectorKey sector_key;
} PACKED NfcMifareReadBlockParameter;
} NX_PACKED NfcMifareReadBlockParameter;
typedef struct {
u8 data[0x10];
u8 sector_number;
u8 reserved[0x7];
} PACKED NfcMifareReadBlockData;
} NX_PACKED NfcMifareReadBlockData;
typedef struct {
u8 data[0x10];
@ -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

@ -1339,8 +1339,8 @@ Result nsdevGetShellEventInfo(NsShellEventInfo* out); ///< [1.0.0-9.2.0]
Result nsdevTerminateApplication(void);
Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len); ///< [1.0.0-9.2.0]
Result nsdevLaunchApplicationForDevelop(u64* out_pid, u64 application_id, u32 flags); ///< [1.0.0-9.2.0]
Result nsdevLaunchApplicationFromHost(u64* out_pid, const char* path, size_t path_len, u32 flags); ///< [10.0.0+]
Result nsdevLaunchApplicationWithStorageIdForDevelop(u64* out_pid, u64 application_id, u32 flags, u8 app_storage_id, u8 patch_storage_id);
Result nsdevLaunchApplicationFromHost(u64* out_pid, const char* path, size_t path_len, u32 flags); ///< [10.0.0-17.0.1]
Result nsdevLaunchApplicationWithStorageIdForDevelop(u64* out_pid, u64 application_id, u32 flags, u8 app_storage_id, u8 patch_storage_id); ///< [1.0.0-17.0.1]
Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out); ///< [6.0.0-8.1.0]
Result nsdevGetRunningApplicationProcessIdForDevelop(u64* out_pid); ///< [6.0.0+]
Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop(bool can_be_active); ///< [6.0.0+]

View File

@ -9,6 +9,15 @@
#include "../sf/service.h"
#include "../kernel/event.h"
/// NvServiceType, for __nx_nv_service_type.
typedef enum {
NvServiceType_Auto = -1, ///< This is the default. Automatically select the type using \ref appletGetAppletType.
NvServiceType_Application = 0, ///< Initializes nvdrv.
NvServiceType_Applet = 1, ///< Initializes nvdrv:a.
NvServiceType_System = 2, ///< Initializes nvdrv:s.
NvServiceType_Factory = 3, ///< Initializes nvdrv:t.
} NvServiceType;
/// Initialize nvdrv*.
Result nvInitialize(void);

View File

@ -31,7 +31,7 @@ typedef enum {
SetSysProductModel_Iowa = 3, ///< Mariko Model
SetSysProductModel_Hoag = 4, ///< Mariko Lite Model
SetSysProductModel_Calcio = 5, ///< Mariko "Simulation" Model
SetSysProductModel_Aula = 6, ///< Mariko Pro Model(?)
SetSysProductModel_Aula = 6, ///< Mariko OLED Model
} SetSysProductModel;
/// IDs for Language.
@ -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;
@ -468,7 +465,7 @@ typedef struct {
u8 svd_index : 7;
u8 native_flag : 1;
} svd[0xC];
} PACKED video;
} NX_PACKED video;
struct {
u8 size : 5;
SetSysBlockType block_type : 3;
@ -477,7 +474,7 @@ typedef struct {
u8 padding1 : 1;
u8 sampling_rates_bitmap;
u8 bitrate;
} PACKED audio;
} NX_PACKED audio;
struct {
u8 size : 5;
SetSysBlockType block_type : 3;
@ -486,7 +483,7 @@ typedef struct {
u8 mode_bitmap;
u8 max_tmds_frequency;
u8 latency_bitmap;
} PACKED vendor_specific;
} NX_PACKED vendor_specific;
u8 padding[2];
} SetSysDataBlock;
@ -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

@ -29,7 +29,7 @@ struct usb_endpoint_descriptor {
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} PACKED;
} NX_PACKED;
/// Imported from libusb, with some adjustments.
struct usb_interface_descriptor {
@ -72,7 +72,7 @@ struct usb_config_descriptor {
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t MaxPower;
} PACKED;
} NX_PACKED;
/// Imported from libusb, with some adjustments.
struct usb_ss_endpoint_companion_descriptor {

View File

@ -60,7 +60,7 @@ typedef struct {
u8 pad_x155[0x6];
struct usb_ss_endpoint_companion_descriptor output_ss_endpoint_companion_descs[15]; ///< ?
u8 pad_x1b5[0x3];
} PACKED UsbHsInterfaceInfo;
} NX_PACKED UsbHsInterfaceInfo;
/// Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface.
typedef struct {
@ -75,7 +75,7 @@ typedef struct {
u8 pad_x21b[0x5];
u64 timestamp; ///< Unknown u64 timestamp for when the device was inserted?
} PACKED UsbHsInterface;
} NX_PACKED UsbHsInterface;
typedef struct {
u32 xferId;

View File

@ -59,26 +59,26 @@ typedef struct { float value[3]; } UtilFloat3; ///< 3 floats.
#endif
/// Packs a struct so that it won't include padding bytes.
#ifndef PACKED
#define PACKED __attribute__((packed))
#ifndef NX_PACKED
#define NX_PACKED __attribute__((packed))
#endif
/// Marks a function as not returning, for the purposes of compiler optimization.
#ifndef NORETURN
#define NORETURN __attribute__((noreturn))
#ifndef NX_NORETURN
#define NX_NORETURN __attribute__((noreturn))
#endif
/// Performs a dummy operation on the specified argument in order to silence compiler warnings about unused arguments.
#ifndef IGNORE_ARG
#define IGNORE_ARG(x) (void)(x)
#ifndef NX_IGNORE_ARG
#define NX_IGNORE_ARG(x) (void)(x)
#endif
/// Flags a function as deprecated.
#ifndef DEPRECATED
#ifndef NX_DEPRECATED
#ifndef LIBNX_NO_DEPRECATION
#define DEPRECATED __attribute__ ((deprecated))
#define NX_DEPRECATED __attribute__ ((deprecated))
#else
#define DEPRECATED
#define NX_DEPRECATED
#endif
#endif

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

@ -514,7 +514,7 @@ SVC_BEGIN svcQueryPhysicalAddress
ret
SVC_END
SVC_BEGIN svcQueryIoMapping
SVC_BEGIN svcQueryMemoryMapping
stp x0, x1, [sp, #-16]!
svc 0x55
ldp x3, x4, [sp], #16
@ -799,12 +799,12 @@ SVC_BEGIN svcCallSecureMonitor
ret
SVC_END
SVC_BEGIN svcMapInsecureMemory
SVC_BEGIN svcMapInsecurePhysicalMemory
svc 0x90
ret
SVC_END
SVC_BEGIN svcUnmapInsecureMemory
SVC_BEGIN svcUnmapInsecurePhysicalMemory
svc 0x91
ret
SVC_END

View File

@ -160,6 +160,13 @@ void virtmemSetup(void) {
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel));
}
// Account for the alias region extra size.
u64 alias_extra_size;
rc = svcGetInfo(&alias_extra_size, InfoType_AliasRegionExtraSize, CUR_PROCESS_HANDLE, 0);
if (R_SUCCEEDED(rc)) {
g_AliasRegion.end -= alias_extra_size;
}
// Retrieve memory region information for the reserved heap region.
rc = _memregionInitWithInfo(&g_HeapRegion, InfoType_HeapRegionAddress, InfoType_HeapRegionSize);
if (R_FAILED(rc)) {

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

@ -212,8 +212,7 @@ Result nvioctlChannel_Submit(u32 fd, const nvioctl_cmdbuf *cmdbufs, u32 num_cmdb
__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_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;
@ -254,15 +256,12 @@ Result nvioctlChannel_GetSyncpt(u32 fd, u32 id, u32 *syncpt) {
}
Result nvioctlChannel_GetModuleClockRate(u32 fd, u32 module_id, u32 *freq) {
struct {
__nv_out u32 rate;
__nv_in u32 module;
} data = {
.module = module_id,
nvioctl_clk_rate data = {
.moduleid = module_id,
};
u32 ioctl = _NV_IOWR(0, hosversionAtLeast(8,0,0) ? 0x14 : 0x23, data);
Result rc = nvIoctl(fd, ioctl, &data);
u32 nr = _NV_IOWR(0, hosversionBefore(8,0,0) ? 0x14 : 0x23, data);
Result rc = nvIoctl(fd, nr, &data);
if (R_SUCCEEDED(rc) && freq)
*freq = data.rate;
@ -270,6 +269,25 @@ Result nvioctlChannel_GetModuleClockRate(u32 fd, u32 module_id, u32 *freq) {
return rc;
}
Result nvioctlChannel_SetModuleClockRate(u32 fd, u32 module_id, u32 freq) {
nvioctl_clk_rate data = {
.rate = freq,
.moduleid = module_id,
};
return nvIoctl(fd, _NV_IOW(0, 0x08, data), &data);
}
Result nvioctlChannel_SetSubmitTimeout(u32 fd, u32 timeout) {
struct {
__nv_in u32 timeout;
} data = {
.timeout = timeout,
};
return nvIoctl(fd, _NV_IOW(0, 0x07, data), &data);
}
Result nvioctlChannel_MapCommandBuffer(u32 fd, nvioctl_command_buffer_map *maps, u32 num_maps, bool compressed) {
if (num_maps > 0x200)
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);

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

@ -7,7 +7,7 @@
#include "services/acc.h"
#include "runtime/diag.h"
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
void NX_NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
static bool g_isNso = false;
static const char* g_loaderInfo = NULL;

View File

@ -10,7 +10,7 @@
#include "runtime/diag.h"
#include "runtime/devices/fs_dev.h"
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
void NX_NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
void virtmemSetup(void);
void newlibSetup(void);
@ -187,12 +187,8 @@ void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread, void* sav
__libc_init_array();
}
void __attribute__((weak)) NORETURN __libnx_exit(int rc)
void __attribute__((weak)) NX_NORETURN __libnx_exit(int rc)
{
// Call destructors.
void __libc_fini_array(void);
__libc_fini_array();
// Clean up services.
__appExit();

View File

@ -28,7 +28,7 @@ struct __pthread_t
void *rc;
};
void __attribute__((weak)) NORETURN __libnx_exit(int rc);
void __attribute__((weak)) NX_NORETURN __libnx_exit(int rc);
/// TimeType passed to timeGetCurrentTime() during time initialization. If that fails and __nx_time_type isn't TimeType_Default, timeGetCurrentTime() will be called again with TimeType_Default.
__attribute__((weak)) TimeType __nx_time_type = TimeType_Default;

View File

@ -240,12 +240,12 @@ Result ringconReadId(RingCon *c, u64 *id_l, u64 *id_h) {
struct {
u32 data_x0;
u16 data_x4;
} PACKED id_l;
} NX_PACKED id_l;
struct {
u32 data_x0;
u16 data_x4;
} PACKED id_h;
} NX_PACKED id_h;
} id;
} reply;

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

@ -357,7 +357,7 @@ static void _appletInfiniteSleepLoop(void) {
while(1) svcSleepThread(86400000000000ULL);
}
static void NORETURN _appletExitProcess(int result_code) {
static void NX_NORETURN _appletExitProcess(int result_code) {
appletInitialize();
appletExit();

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);
if (hosversionAtLeast(19,0,0)) {
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
CapsApplicationId applicationId;
} in = { appletResourceUserId, *application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
}
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
}
else {
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
return serviceDispatchIn(&g_capscSrv, 2012, in);
} in = { appletResourceUserId, application_id->application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
}
}
Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid) {
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
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(CapsApplicationId *application_id, u64 aruid) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
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);
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 };
} 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

@ -53,7 +53,7 @@ static void _fatalCmd(Result err, FatalPolicy type, FatalCpuContext *ctx, u32 cm
}
}
void NORETURN fatalThrow(Result err) {
void NX_NORETURN fatalThrow(Result err) {
// By default, do not generate an error report.
fatalThrowWithPolicy(err, FatalPolicy_ErrorScreen);
svcExitProcess();

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);
}
@ -937,6 +944,13 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *
);
}
Result fsFsGetFileSystemAttribute(FsFileSystem* fs, FsFileSystemAttribute *out) {
if (hosversionBefore(15,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _fsObjectDispatchOut(&fs->s, 16, *out);
}
Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path) {
return fsFsQueryEntry(fs, NULL, 0, NULL, 0, path, FsFileSystemQueryId_SetConcatenationFileAttribute);
}
@ -1218,10 +1232,40 @@ Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle*
return _fsObjectDispatchOut(&d->s, 202, *out);
}
Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const FsGameCardHandle* handle, FsGameCardUpdatePartitionInfo* out) {
return _fsObjectDispatchInOut(&d->s, 203, *handle, *out);
}
Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out) {
return _fsObjectDispatchInOut(&d->s, 205, *handle, *out);
}
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 };
// 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) {
return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 208);
}
@ -1238,6 +1282,24 @@ Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_
return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 218);
}
Result fsDeviceOperatorChallengeCardExistence(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, void* seed, size_t seed_size, void* value, size_t value_size) {
if (hosversionBefore(8,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _fsObjectDispatchIn(&d->s, 219, *handle,
.buffer_attrs = {
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
},
.buffers = {
{ dst, dst_size },
{ seed, seed_size },
{ value, value_size },
},
);
}
void fsDeviceOperatorClose(FsDeviceOperator* d) {
_fsObjectClose(&d->s);
}

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};
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;
@ -497,14 +540,14 @@ Result hidsysLegacyIsButtonConfigSupported(HidsysUniquePadId unique_pad_id, bool
}
Result hidsysIsButtonConfigSupported(BtdrvAddress addr, bool *out) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrOutBool(addr, out, 1200);
}
Result hidsysIsButtonConfigEmbeddedSupported(bool *out) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 1201);
@ -518,14 +561,14 @@ Result hidsysLegacyDeleteButtonConfig(HidsysUniquePadId unique_pad_id) {
}
Result hidsysDeleteButtonConfig(BtdrvAddress addr) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrNoOut(addr, 1202);
}
Result hidsysDeleteButtonConfigEmbedded(void) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoIO(1203);
@ -539,14 +582,14 @@ Result hidsysLegacySetButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool
}
Result hidsysSetButtonConfigEnabled(BtdrvAddress addr, bool flag) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrInBoolNoOut(addr, flag, 1204);
}
Result hidsysSetButtonConfigEmbeddedEnabled(bool flag) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInBoolNoOut(flag, 1205);
@ -560,14 +603,14 @@ Result hidsysLegacyIsButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool *
}
Result hidsysIsButtonConfigEnabled(BtdrvAddress addr, bool *out) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrInBoolNoOut(addr, out, 1206);
}
Result hidsysIsButtonConfigEmbeddedEnabled(bool *out) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdNoInOutBool(out, 1207);
@ -581,7 +624,7 @@ Result hidsysLegacySetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, cons
}
Result hidsysSetButtonConfigEmbedded(const HidsysButtonConfigEmbedded *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatch(&g_hidsysSrv, 1208,
@ -598,7 +641,7 @@ Result hidsysLegacySetButtonConfigFull(HidsysUniquePadId unique_pad_id, const Hi
}
Result hidsysSetButtonConfigFull(BtdrvAddress addr, const HidsysButtonConfigFull *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrInBufFixedNoOut(addr, config, sizeof(*config), 1209);
@ -612,7 +655,7 @@ Result hidsysLegacySetButtonConfigLeft(HidsysUniquePadId unique_pad_id, const Hi
}
Result hidsysSetButtonConfigLeft(BtdrvAddress addr, const HidsysButtonConfigLeft *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrInBufFixedNoOut(addr, config, sizeof(*config), 12010);
@ -626,7 +669,7 @@ Result hidsysLegacySetButtonConfigRight(HidsysUniquePadId unique_pad_id, const H
}
Result hidsysSetButtonConfigRight(BtdrvAddress addr, const HidsysButtonConfigRight *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrInBufFixedNoOut(addr, config, sizeof(*config), 1211);
@ -640,7 +683,7 @@ Result hidsysLegacyGetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, Hids
}
Result hidsysGetButtonConfigEmbedded(HidsysButtonConfigEmbedded *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatch(&g_hidsysSrv, 1212,
@ -657,7 +700,7 @@ Result hidsysLegacyGetButtonConfigFull(HidsysUniquePadId unique_pad_id, HidsysBu
}
Result hidsysGetButtonConfigFull(BtdrvAddress addr, HidsysButtonConfigFull *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrOutBufFixedNoOut(addr, config, sizeof(*config), 1213);
@ -671,7 +714,7 @@ Result hidsysLegacyGetButtonConfigLeft(HidsysUniquePadId unique_pad_id, HidsysBu
}
Result hidsysGetButtonConfigLeft(BtdrvAddress addr, HidsysButtonConfigLeft *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrOutBufFixedNoOut(addr, config, sizeof(*config), 1214);
@ -685,7 +728,7 @@ Result hidsysLegacyGetButtonConfigRight(HidsysUniquePadId unique_pad_id, HidsysB
}
Result hidsysGetButtonConfigRight(BtdrvAddress addr, HidsysButtonConfigRight *config) {
if (hosversionBefore(11,0,0))
if (!hosversionBetween(11,18))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _hidsysCmdInAddrOutBufFixedNoOut(addr, config, sizeof(*config), 1215);

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,7 +79,21 @@ Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos,
);
}
Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *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;
@ -91,9 +105,37 @@ Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_
.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

@ -2367,7 +2367,7 @@ Result nsdevLaunchApplicationForDevelop(u64* out_pid, u64 application_id, u32 fl
}
Result nsdevLaunchApplicationFromHost(u64* out_pid, const char* path, size_t path_len, u32 flags) {
if (hosversionBefore(10,0,0))
if (hosversionBefore(10,0,0) || hosversionAtLeast(18,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchInOut(&g_nsdevSrv, 8, flags, *out_pid,
@ -2377,6 +2377,9 @@ Result nsdevLaunchApplicationFromHost(u64* out_pid, const char* path, size_t pat
}
Result nsdevLaunchApplicationWithStorageIdForDevelop(u64* out_pid, u64 application_id, u32 flags, u8 app_storage_id, u8 patch_storage_id) {
if (hosversionAtLeast(18,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 app_storage_id;
u8 patch_storage_id;

View File

@ -7,6 +7,7 @@
#include "services/nv.h"
#include "nvidia/ioctl.h"
__attribute__((weak)) NvServiceType __nx_nv_service_type = NvServiceType_Auto;
__attribute__((weak)) u32 __nx_nv_transfermem_size = 0x800000;
static Service g_nvSrv;
@ -27,23 +28,46 @@ NX_GENERATE_SERVICE_GUARD(nv);
Result _nvInitialize(void) {
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
if (__nx_nv_service_type == NvServiceType_Auto) {
switch (appletGetAppletType()) {
case AppletType_None:
rc = smGetService(&g_nvSrv, "nvdrv:s");
__nx_nv_service_type = NvServiceType_System;
break;
case AppletType_Default:
case AppletType_Application:
case AppletType_SystemApplication:
default:
rc = smGetService(&g_nvSrv, "nvdrv");
__nx_nv_service_type = NvServiceType_Application;
break;
case AppletType_SystemApplet:
case AppletType_LibraryApplet:
case AppletType_OverlayApplet:
__nx_nv_service_type = NvServiceType_Applet;
break;
}
}
switch (__nx_nv_service_type) {
case NvServiceType_Application:
rc = smGetService(&g_nvSrv, "nvdrv");
break;
case NvServiceType_Applet:
rc = smGetService(&g_nvSrv, "nvdrv:a");
break;
case NvServiceType_System:
rc = smGetService(&g_nvSrv, "nvdrv:s");
break;
case NvServiceType_Factory:
rc = smGetService(&g_nvSrv, "nvdrv:t");
break;
default:
break; // Leave rc at the error set above.
}
if (R_SUCCEEDED(rc)) {

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