mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dfee0c8ba2 | ||
|
0a4ac1b87c | ||
|
638624cf02 | ||
|
2f471a1c26 | ||
|
d1dbd8db51 | ||
|
de7cfeb3d9 | ||
|
2fc81d8f35 | ||
|
29f6f4fa7a | ||
|
b88afc509c | ||
|
ceb7ee1cbf | ||
|
0ba4f96bfe | ||
|
17bcd07095 | ||
|
ce6bc0c3e8 | ||
|
8f1cce6946 | ||
|
60bf943ec1 | ||
|
0ae0792770 | ||
|
953c1b7a8a | ||
|
5da574f852 | ||
|
b2d7022e1b | ||
|
29a6691b66 | ||
|
88de3cbea7 | ||
|
218e3f3a04 | ||
|
a063ceb19c | ||
|
e79dd7ac52 | ||
|
2e2b110668 | ||
|
432b4e3900 | ||
|
eef44aa5e1 | ||
|
688e4dd14e | ||
|
d4f5f4b145 | ||
|
6c430b273a | ||
|
58f1fc6561 | ||
|
65c643f149 | ||
|
73d79d4a0f | ||
|
163fdddabf | ||
|
c7c9617290 | ||
|
250a5777f7 | ||
|
5d5d13c9d6 | ||
|
2bbf49377e | ||
|
81bed00b5b | ||
|
8cff58d5af | ||
|
d66e3aa487 | ||
|
7b4e02be35 | ||
|
3c851a3443 | ||
|
df0508200b |
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
@ -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)
|
||||
|
22
nx/Makefile
22
nx/Makefile
@ -8,13 +8,6 @@ endif
|
||||
|
||||
include $(DEVKITPRO)/devkitA64/base_rules
|
||||
|
||||
export LIBNX_MAJOR := 4
|
||||
export LIBNX_MINOR := 7
|
||||
export LIBNX_PATCH := 0
|
||||
|
||||
|
||||
VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
@ -95,17 +88,14 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
#---------------------------------------------------------------------------------
|
||||
all: lib/libnx.a lib/libnxd.a
|
||||
|
||||
dist-bin: all
|
||||
@tar --exclude=*~ -cjf libnx-$(VERSION).tar.bz2 include lib default_icon.jpg switch_rules switch.ld switch.specs -C external/bsd include
|
||||
install: lib/libnx.a lib/libnxd.a
|
||||
@mkdir -p $(DESTDIR)$(DEVKITPRO)/libnx
|
||||
@cp -v default_icon.jpg switch_rules switch.ld switch.specs $(DESTDIR)$(DEVKITPRO)/libnx/
|
||||
@cp -rv include lib $(DESTDIR)$(DEVKITPRO)/libnx/
|
||||
@cp -rv external/bsd/include $(DESTDIR)$(DEVKITPRO)/libnx/
|
||||
|
||||
dist-src:
|
||||
@tar --exclude=*~ -cjf libnx-src-$(VERSION).tar.bz2 include source data external Makefile default_icon.jpg switch_rules switch.ld switch.specs
|
||||
|
||||
dist: dist-src dist-bin
|
||||
|
||||
install: dist-bin
|
||||
mkdir -p $(DESTDIR)$(DEVKITPRO)/libnx
|
||||
bzip2 -cd libnx-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/libnx
|
||||
@tar -cjf libnx-`git describe --tags | sed 's/^v//'`.tar.bz2 include source data external Makefile default_icon.jpg switch_rules switch.ld switch.specs
|
||||
|
||||
#dox:
|
||||
# @doxygen Doxyfile
|
||||
|
@ -212,6 +212,8 @@ typedef enum {
|
||||
InfoType_IoRegionHint = 27, ///< [16.0.0+] Low bits of the physical address for a KIoRegion.
|
||||
InfoType_AliasRegionExtraSize = 28, ///< [18.0.0+] Extra size added to the reserved region.
|
||||
|
||||
InfoType_TransferMemoryHint = 34, ///< [19.0.0+] Low bits of the process address for a KTransferMemory.
|
||||
|
||||
InfoType_ThreadTickCountDeprecated = 0xF0000002, ///< [1.0.0-12.1.0] Number of ticks spent on thread.
|
||||
} InfoType;
|
||||
|
||||
@ -262,9 +264,10 @@ typedef enum {
|
||||
|
||||
/// WaitForAddress behaviors.
|
||||
typedef enum {
|
||||
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the value is less than argument.
|
||||
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the value and wait if it is less than argument.
|
||||
ArbitrationType_WaitIfEqual = 2, ///< Wait if the value is equal to argument.
|
||||
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the 32-bit value is less than argument.
|
||||
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the 32-bit value and wait if it is less than argument.
|
||||
ArbitrationType_WaitIfEqual = 2, ///< Wait if the 32-bit value is equal to argument.
|
||||
ArbitrationType_WaitIfEqual64 = 3, ///< [19.0.0+] Wait if the 64-bit value is equal to argument.
|
||||
} ArbitrationType;
|
||||
|
||||
/// Context of a scheduled thread.
|
||||
@ -809,7 +812,7 @@ Result svcGetThreadContext3(ThreadContext* ctx, Handle thread);
|
||||
* @return Result code.
|
||||
* @note Syscall number 0x34.
|
||||
*/
|
||||
Result svcWaitForAddress(void *address, u32 arb_type, s32 value, s64 timeout);
|
||||
Result svcWaitForAddress(void *address, u32 arb_type, s64 value, s64 timeout);
|
||||
|
||||
/**
|
||||
* @brief Signals (and updates) an address depending on type and value. [4.0.0+]
|
||||
|
@ -10,6 +10,7 @@ typedef struct {
|
||||
|
||||
Result nvFenceInit(void);
|
||||
void nvFenceExit(void);
|
||||
u32 nvFenceGetFd(void);
|
||||
|
||||
Result nvFenceWait(NvFence* f, s32 timeout_us);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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+]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -553,6 +553,8 @@ Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id);
|
||||
/// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+], attr is ignored before [16.0.0].
|
||||
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, FsContentAttributes attr, u8* out_key_generation, FsRightsId* out_rights_id);
|
||||
|
||||
Result fsGetContentStorageInfoIndex(s32 *out); ///< [19.0.0+]
|
||||
|
||||
Result fsDisableAutoSaveDataCreation(void);
|
||||
|
||||
Result fsSetGlobalAccessLogMode(u32 mode);
|
||||
@ -683,7 +685,7 @@ Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out);
|
||||
Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out);
|
||||
Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const FsGameCardHandle* handle, FsGameCardUpdatePartitionInfo* out);
|
||||
Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out);
|
||||
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size);
|
||||
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size);
|
||||
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
|
||||
Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCardErrorReportInfo* out);
|
||||
Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
///@{
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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+]
|
||||
|
@ -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;
|
||||
|
@ -23,11 +23,6 @@ typedef enum {
|
||||
NfcServiceType_System = 1, ///< Initializes nfc:sys.
|
||||
} NfcServiceType;
|
||||
|
||||
typedef enum {
|
||||
NfpState_NonInitialized = 0,
|
||||
NfpState_Initialized = 1,
|
||||
} NfpState;
|
||||
|
||||
typedef enum {
|
||||
NfcState_NonInitialized = 0,
|
||||
NfcState_Initialized = 1,
|
||||
@ -40,7 +35,6 @@ typedef enum {
|
||||
NfpDeviceState_TagRemoved = 3,
|
||||
NfpDeviceState_TagMounted = 4,
|
||||
NfpDeviceState_Unavailable = 5,
|
||||
NfpDeviceState_Finalized = 6,
|
||||
} NfpDeviceState;
|
||||
|
||||
typedef enum {
|
||||
@ -49,16 +43,23 @@ typedef enum {
|
||||
NfcDeviceState_TagFound = 2,
|
||||
NfcDeviceState_TagRemoved = 3,
|
||||
NfcDeviceState_TagMounted = 4,
|
||||
NfcDeviceState_Unavailable = 5,
|
||||
NfcDeviceState_Finalized = 6,
|
||||
} NfcDeviceState;
|
||||
|
||||
typedef enum {
|
||||
NfpApplicationAreaVersion_3DS = 0,
|
||||
NfpApplicationAreaVersion_WiiU = 1,
|
||||
NfpApplicationAreaVersion_3DSv2 = 2,
|
||||
NfpApplicationAreaVersion_Switch = 3,
|
||||
NfpApplicationAreaVersion_NotSet = 0xFF,
|
||||
NfcMifareDeviceState_Initialized = 0,
|
||||
NfcMifareDeviceState_SearchingForTag = 1,
|
||||
NfcMifareDeviceState_TagFound = 2,
|
||||
NfcMifareDeviceState_TagRemoved = 3,
|
||||
NfcMifareDeviceState_TagMounted = 4,
|
||||
NfcMifareDeviceState_Unavailable = 5,
|
||||
} NfcMifareDeviceState;
|
||||
|
||||
typedef enum {
|
||||
NfpApplicationAreaVersion_3DS = 0, ///< Application area created by a 3DS game.
|
||||
NfpApplicationAreaVersion_WiiU = 1, ///< Application area created by a Wii U game.
|
||||
NfpApplicationAreaVersion_3DSv2 = 2, ///< Application area created by a (new?) 3DS game.
|
||||
NfpApplicationAreaVersion_Switch = 3, ///< Application area created by a Switch game.
|
||||
NfpApplicationAreaVersion_Invalid = 0xFF, ///< Invalid value (application area not created).
|
||||
} NfpApplicationAreaVersion;
|
||||
|
||||
typedef enum {
|
||||
@ -66,9 +67,9 @@ typedef enum {
|
||||
} NfpDeviceType;
|
||||
|
||||
typedef enum {
|
||||
NfpMountTarget_Rom = 1,
|
||||
NfpMountTarget_Ram = 2,
|
||||
NfpMountTarget_All = 3,
|
||||
NfpMountTarget_Rom = BIT(0),
|
||||
NfpMountTarget_Ram = BIT(1),
|
||||
NfpMountTarget_All = NfpMountTarget_Rom | NfpMountTarget_Ram,
|
||||
} NfpMountTarget;
|
||||
|
||||
typedef enum {
|
||||
@ -102,104 +103,123 @@ typedef enum {
|
||||
NfcMifareCommand_Store = 0xC2,
|
||||
} NfcMifareCommand;
|
||||
|
||||
typedef struct {
|
||||
u8 uuid[10];
|
||||
u8 uuid_length;
|
||||
u8 reserved1[0x15];
|
||||
u32 protocol;
|
||||
u32 tag_type;
|
||||
u8 reserved2[0x30];
|
||||
} NX_PACKED NfpTagInfo;
|
||||
typedef enum {
|
||||
NfpAmiiboFlag_Valid = BIT(0), ///< Initialized in system settings.
|
||||
NfpAmiiboFlag_ApplicationAreaExists = BIT(1), ///< Application area exists.
|
||||
} NfpAmiiboFlag;
|
||||
|
||||
typedef enum {
|
||||
NfpBreakType_Flush = 0,
|
||||
NfpBreakType_Break1 = 1,
|
||||
NfpBreakType_Break2 = 2,
|
||||
} NfpBreakType;
|
||||
|
||||
typedef struct {
|
||||
u8 uuid[10];
|
||||
u8 uuid_length;
|
||||
u8 reserved1[0x15];
|
||||
u32 protocol;
|
||||
u32 tag_type;
|
||||
u8 reserved2[0x30];
|
||||
} NX_PACKED NfcTagInfo;
|
||||
u16 year;
|
||||
u8 month;
|
||||
u8 day;
|
||||
} NfpDate;
|
||||
|
||||
typedef struct {
|
||||
u16 last_write_year;
|
||||
u8 last_write_month;
|
||||
u8 last_write_day;
|
||||
u8 uid[10]; ///< UUID.
|
||||
u8 uid_length; ///< UUID length.
|
||||
u8 reserved[0x15];
|
||||
} NfcTagUid;
|
||||
|
||||
typedef struct {
|
||||
NfcTagUid uid; ///< UUID.
|
||||
u32 protocol; ///< \ref NfcProtocol
|
||||
u32 tag_type; ///< \ref NfcTagType
|
||||
u8 reserved[0x30];
|
||||
} NfpTagInfo;
|
||||
|
||||
typedef struct {
|
||||
NfcTagUid uid; ///< UUID.
|
||||
u32 protocol; ///< \ref NfcProtocol
|
||||
u32 tag_type; ///< \ref NfcTagType
|
||||
u8 reserved[0x30];
|
||||
} NfcTagInfo;
|
||||
|
||||
typedef struct {
|
||||
NfpDate last_write_date;
|
||||
u16 write_counter;
|
||||
u16 version;
|
||||
u32 application_area_size;
|
||||
u8 reserved[0x34];
|
||||
} NX_PACKED NfpCommonInfo;
|
||||
} NfpCommonInfo;
|
||||
|
||||
typedef struct {
|
||||
u8 amiibo_id[0x8];
|
||||
u8 reserved[0x38];
|
||||
} NX_PACKED NfpModelInfo;
|
||||
union {
|
||||
u8 character_id[3];
|
||||
struct {
|
||||
u16 game_character_id;
|
||||
u8 character_variant;
|
||||
} NX_PACKED;
|
||||
};
|
||||
u8 series_id; ///< Series.
|
||||
u16 numbering_id; ///< Model number.
|
||||
u8 nfp_type; ///< Figure type.
|
||||
u8 reserved[0x39];
|
||||
} NfpModelInfo;
|
||||
|
||||
typedef struct {
|
||||
MiiCharInfo mii;
|
||||
u16 first_write_year;
|
||||
u8 first_write_month;
|
||||
u8 first_write_day;
|
||||
char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
|
||||
NfpDate first_write_date;
|
||||
char amiibo_name[(10*4)+1]; ///< Amiibo name (utf-8, null-terminated).
|
||||
u8 font_region;
|
||||
u8 reserved[0x7A];
|
||||
} NX_PACKED NfpRegisterInfo;
|
||||
} NfpRegisterInfo;
|
||||
|
||||
typedef struct {
|
||||
u8 mii_store_data[0x44];
|
||||
u16 first_write_year;
|
||||
u8 first_write_month;
|
||||
u8 first_write_day;
|
||||
char amiibo_name[(10*4)+1]; ///< utf-8, null-terminated
|
||||
MiiStoreData mii_store_data;
|
||||
NfpDate first_write_date;
|
||||
char amiibo_name[(10*4)+1]; ///< Amiibo name (utf-8, null-terminated).
|
||||
u8 font_region;
|
||||
u8 reserved[0x8E];
|
||||
} NX_PACKED NfpRegisterInfoPrivate;
|
||||
} NfpRegisterInfoPrivate;
|
||||
|
||||
typedef struct {
|
||||
u64 application_id;
|
||||
u32 application_area_id;
|
||||
u16 crc_change_counter;
|
||||
u32 access_id;
|
||||
u16 crc32_change_counter;
|
||||
u8 flags;
|
||||
u8 tag_type;
|
||||
u8 application_area_version;
|
||||
u8 reserved[0x2F];
|
||||
} NX_PACKED NfpAdminInfo;
|
||||
} NfpAdminInfo;
|
||||
|
||||
typedef struct {
|
||||
u8 magic;
|
||||
u8 tag_magic; ///< Tag magic (always 0xA5: https://www.3dbrew.org/wiki/Amiibo#Page_layout).
|
||||
u8 reserved1[0x1];
|
||||
u8 write_counter;
|
||||
u8 reserved2[0x1];
|
||||
u32 settings_crc;
|
||||
u8 reserved3[0x38];
|
||||
u16 last_write_year;
|
||||
u8 last_write_month;
|
||||
u8 last_write_day;
|
||||
u16 application_write_counter;
|
||||
u16 version;
|
||||
u32 application_area_size;
|
||||
u8 reserved4[0x34];
|
||||
MiiCharInfo mii;
|
||||
MiiNfpStoreDataExtension mii_store_data_extension;
|
||||
u16 first_write_year;
|
||||
u8 first_write_month;
|
||||
u8 first_write_day;
|
||||
u16 amiibo_name[10+1]; ///< utf-16, null-terminated
|
||||
u8 settings_flag; ///< bit4 = amiibo was initialized in console settings, bit5 = has application area
|
||||
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];
|
||||
} NX_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;
|
||||
@ -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);
|
||||
|
||||
|
@ -312,7 +312,7 @@ typedef struct {
|
||||
/// BluetoothDevicesSettings
|
||||
typedef struct {
|
||||
BtdrvAddress addr; ///< \ref BtdrvAddress
|
||||
BtmBdName name; ///< BdName. Unused on 13.0.0+
|
||||
BtmBdName name; ///< [1.0.0-12.1.0] BdName. On 13.0.0+ name2 is used instead.
|
||||
BtmClassOfDevice class_of_device; ///< ClassOfDevice
|
||||
u8 link_key[0x10]; ///< LinkKey
|
||||
u8 link_key_present; ///< LinkKeyPresent
|
||||
@ -328,14 +328,11 @@ typedef struct {
|
||||
u8 device_type; ///< DeviceType
|
||||
u16 brr_size; ///< BrrSize
|
||||
u8 brr[0x9]; ///< Brr
|
||||
union {
|
||||
u8 reserved[0x12B]; ///< Reserved [1.0.0-12.1.0]
|
||||
|
||||
struct {
|
||||
u8 pad; ///< Padding
|
||||
char name2[0xF9]; ///< Name
|
||||
}; ///< [13.0.0+]
|
||||
};
|
||||
u8 audio_source_volume; ///< [13.0.0+] AudioSourceVolume
|
||||
char name2[0xF9]; ///< [13.0.0+] Name
|
||||
u8 audio_sink_volume; ///< [15.0.0+] AudioSinkVolume
|
||||
u32 audio_flags; ///< [14.0.0+] AudioFlags
|
||||
u8 reserved[0x2C]; ///< Reserved
|
||||
} SetSysBluetoothDevicesSettings;
|
||||
|
||||
/// Structure returned by \ref setsysGetFirmwareVersion.
|
||||
@ -440,8 +437,8 @@ typedef struct {
|
||||
u8 vertical_active_lines_msb : 4;
|
||||
u8 horizontal_sync_offset_pixels_lsb;
|
||||
u8 horizontal_sync_pulse_width_pixels_lsb;
|
||||
u8 horizontal_sync_pulse_width_lines_lsb : 4;
|
||||
u8 horizontal_sync_offset_lines_lsb : 4;
|
||||
u8 vertical_sync_pulse_width_lines_lsb : 4;
|
||||
u8 vertical_sync_offset_lines_lsb : 4;
|
||||
u8 vertical_sync_pulse_width_lines_msb : 2;
|
||||
u8 vertical_sync_offset_lines_msb : 2;
|
||||
u8 horizontal_sync_pulse_width_pixels_msb : 2;
|
||||
@ -497,7 +494,7 @@ typedef struct {
|
||||
u16 product_code;
|
||||
u32 serial_number;
|
||||
u8 manufacture_week;
|
||||
u8 manufacture_year;
|
||||
u8 manufacture_year; ///< Real value is val - 10.
|
||||
u8 edid_version;
|
||||
u8 edid_revision;
|
||||
u8 video_input_parameters_bitmap;
|
||||
@ -560,6 +557,8 @@ typedef struct {
|
||||
SetSysModeLine extended_timing_descriptor[5];
|
||||
u8 padding[5];
|
||||
u8 extended_checksum; ///< Sum of 128 extended bytes should equal 0 mod 256.
|
||||
u8 data2[0x80]; ///< [13.0.0+]
|
||||
u8 data3[0x80]; ///< [13.0.0+]
|
||||
} SetSysEdid;
|
||||
|
||||
/// DataDeletionSettings
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "../kernel/event.h"
|
||||
#include "../sf/service.h"
|
||||
|
||||
#define SPL_RSA_BUFFER_SIZE (0x100)
|
||||
|
||||
|
@ -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)
|
||||
:
|
||||
);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -623,6 +623,13 @@ Result fsGetAndClearErrorInfo(FsFileSystemProxyErrorInfo *out) {
|
||||
return _fsObjectDispatchOut(&g_fsSrv, 800, *out);
|
||||
}
|
||||
|
||||
Result fsGetContentStorageInfoIndex(s32 *out) {
|
||||
if (hosversionBefore(19,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return _fsCmdNoInOutU32(&g_fsSrv, (u32 *)out, 820);
|
||||
}
|
||||
|
||||
Result fsDisableAutoSaveDataCreation(void) {
|
||||
return _fsCmdNoIO(&g_fsSrv, 1003);
|
||||
}
|
||||
@ -1233,15 +1240,30 @@ Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCar
|
||||
return _fsObjectDispatchInOut(&d->s, 205, *handle, *out);
|
||||
}
|
||||
|
||||
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size) {
|
||||
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size) {
|
||||
const struct {
|
||||
FsGameCardHandle handle;
|
||||
s64 buffer_size;
|
||||
} in = { *handle, size };
|
||||
|
||||
return _fsObjectDispatchIn(&d->s, 206, in,
|
||||
// Assume old gamecard certificate size on pre-19.0.0
|
||||
s64 os = 0x200;
|
||||
Result rc;
|
||||
|
||||
if (hosversionAtLeast(19,0,0)) {
|
||||
rc = _fsObjectDispatchInOut(&d->s, 206, in, os,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { dst, dst_size } });
|
||||
} else {
|
||||
rc = _fsObjectDispatchIn(&d->s, 206, in,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { dst, dst_size } });
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
*out_size = os;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) {
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) } },
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 ====
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user