diff --git a/.gitignore b/.gitignore index f72c83c..5d7a326 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +* +!*/ +!*.* + nimcache/ # Swap [._]*.s[a-v][a-z] @@ -19,7 +23,6 @@ tags build *.elf -wrapper nimcache/ nimcache*/ diff --git a/libnx.nimble b/libnx.nimble index 6724840..9206c2c 100644 --- a/libnx.nimble +++ b/libnx.nimble @@ -16,13 +16,9 @@ if detectOs(Windows): username = getEnv("USERNAME") # Deps -requires "nim >= 0.18.1", "nimgen#dc9943a22c9c8f6a5a6a92f0055e1de4dfaf87d2" +requires "nim >= 1.6.6" requires "switch_build >= 0.1.3" -task setup, "Download and generate bindings": - echo "Building libnx..." - exec prefix & "nimgen libnxGen.cfg" - task buildExamples, "Build switch examples": if detectOs(Windows): let devkitPath = getEnv("DEVKITPRO") diff --git a/libnxGen.cfg b/libnxGen.cfg deleted file mode 100644 index 4404075..0000000 --- a/libnxGen.cfg +++ /dev/null @@ -1,389 +0,0 @@ -[n.global] -output="src/libnx/wrapper" -c_compiler="aarch64-none-elf-gcc" -cpp_compiler="aarch64-none-elf-g++" -filter=lock - -[n.include] -"${output}/nx/include" -"${output}/nx/include/switch" -"${output}/nx/include/switch/arm" -"${output}/nx/include/switch/audio" -"${output}/nx/include/switch/display" -"${output}/nx/include/switch/kernel" -"${output}/nx/include/switch/nvidia" -"${output}/nx/include/switch/runtime" -"${output}/nx/include/switch/runtime/util" -"${output}/nx/include/switch/runtime/devices" -"${output}/nx/include/switch/services" -"${DEVKITPRO}/devkitA64/aarch64-none-elf/include/" - -[n.exclude] -"${output}/nim.cfg" -"${output}/config.nims" - -[svc.h] -search = "PACKED" -replace = "" - -search.noreturn = "NORETURN" -replace.noreturn = "" - -defines=true - -[result.h] -defines = true - -[thread_context.h] -preprocess = false - -[hid.h] -defines = true -search.static_assert = "static_assert" -replace.static_assert = "// static_assert" -search.touch = "touchPosition" -replace.touch = "TouchPosition" - -[ipc.h] -defines = true - -[romfs_dev.h] -search = "romfs_" -replace = "Romfs_" - -[gfx.h] -defines = true - -[ioctl.h] -defines = true -search = "_NV_" -replace = "UNV_" - -search.nv = "__nv_" -replace.nv = "DUnv_" - -[n.wildcard] -wildcard.1 = "console.h" -rename = "$replace(console=cons)" - -wildcard.2 = "*.h" - -search.u8 = "u8" -replace.u8 = "uint8" - -search.u16 = "u16" -replace.u16 = "uint16" - -search.u32 = "u32" -replace.u32 = "uint32" - -search.u64 = "u64" -replace.u64 = "uint64" - -wildcard.3 = "*.nim" - -search.bool = "_Bool" -replace.bool = "bool" - -search.lib = "src/libnx/wrapper" -replace.lib = "libnx/wrapper" - -search.kimport = "../kernel/" -replace.kimport = "libnx/wrapper/" - -search.resimport = "../result" -replace.resimport = "libnx/wrapper/result" - -search.armimport = "../arm/" -replace.armimport = "libnx/wrapper/" - -search.lock = "_LOCK" -replace.lock = "LOCK" - -search.cdecl = "stdcall" -replace.cdecl = "cdecl" - -[n.prepare] -git = "https://github.com/switchbrew/libnx" -execute-lin = """cd ${output}; make;""" -execute-mac = """cd ${output}; make;""" - -[n.post] -reset=true - -[src/libnx/wrapper/nim.cfg] -create = """ ---path:"../" ---path:"../../" -""" -noprocess=true - -[src/libnx/wrapper/config.nims] -create = """ -switch("passC", "-I" & thisDir() & "/nx/include") -switch("passL", "-specs=" & thisDir() & "/nx/switch.specs -L" & thisDir() & "/nx/lib -lnx") -""" -noprocess=true - -[switch.h] -preprocess = true -defines = true -recurse = true - - -[types.nim] -search.o = " uint8*" -prepend.o = """ - u8* = uint8 - u16* = uint16 - u32* = uint32 - u64* = uint64 - int8_t* = int8 - int16_t* = int16 - int32_t* = int32 - int64_t* = int64 - ssize_t* = int -""" - -search.s128 = " s128* = __int128_t" -replace.s128 = "" - -search.u128 = " u128* = __uint128_t" -replace.u128 = "" - -search.uint8 = "uint8* = uint8_t" -replace.uint8 = "uint8_t* = uint8" - -search.uint16 = "uint16* = uint16_t" -replace.uint16 = "uint16_t* = uint16" - -search.uint32 = "uint32* = uint32_t" -replace.uint32 = "uint32_t* = uint32" - -search.uint64 = "uint64* = uint64_t" -replace.uint64 = "uint64_t* = uint64" - -search.import = "type\n" -prepend.import = """ -import libnx/ext/integer128 -template BIT*(n): auto = (1.uint shl n) -""" - -[thread_context.nim] -search.timport = "../types" -replace.timport = "libnx/wrapper/types" - -prepend.o = """ -import libnx/ext/integer128 -""" - -search.cpuall = "RegisterGroup_CpuAll =" -comment.cpuall = 1 - -search.fpugprs = "RegisterGroup_FpuGprs =" -prepend.fpugprs = "RegisterGroup_CpuAll = BIT(0) or BIT(1), ## /< All CPU registers." - -search.fpuall = "RegisterGroup_FpuGprs or RegisterGroup_FpuSprs" -replace.fpuall = "BIT(2) or BIT(3)" - -search.groupall = "RegisterGroup_CpuAll or RegisterGroup_FpuAll" -replace.groupall = "BIT(0) or BIT(1) or BIT(2) or BIT(3)" - -[svc.nim] -search.timport = "../types" -replace.timport = "libnx/wrapper/types" - -search.permx = "Perm_X = BIT(2), ## /< Execute permission." -replace.permx = "Perm_Rw = Perm_R.int or Perm_W.int, ## /< Read/write permissions." - -search.permrw = "Perm_Rw = Perm_R or Perm_W, ## /< Read/write permissions." -replace.permrw = "Perm_X = BIT(2), ## /< Execute permission." - -search.permrx = "Perm_Rx = Perm_R or Perm_X, ## /< Read/execute permissions." -replace.permrx = "Perm_Rx = Perm_R.int or Perm_X.int, ## /< Read/execute permissions." - -[shmem.nim] -search.import = "type\n" -prepend.import = """ -import libnx/wrapper/svc -""" - -[nacp.nim] -search.t = "type" -prepend.t = """ -import libnx/wrapper/types -""" - -[lock.nim] -search.flock_t = " __lock_t" -replace.flock_t = " DUlock_t" - -search.nlock_t = "= __lock_t" -replace.nlock_t = "= DUlock_t" - -search.import = "type" -prepend.import = """ -import libnx/wrapper/types -""" - -search.proc_under = "proc __" -replace.proc_under = "proc DU" - -[ipc.nim] -search.o = "UINT32_MAX" -replace.o = "uint32.high" - -search.import = "import\n" -append.import = """ - libnx/wrapper/types, -""" - -[audin.nim] -search.o = "import " -prepend.o = """ -import libnx/wrapper/types -""" - -[audout.nim] -search.o = "import " -prepend.o = """ -import libnx/wrapper/types -""" - -[hid.nim] -search.servimport = "../services/" -replace.servimport = "libnx/wrapper/" -search.timport = "../types" -replace.timport = "libnx/wrapper/types" -search.o = """ KEY_JOYCON_RIGHT = BIT(0), KEY_JOYCON_DOWN = BIT(1), KEY_JOYCON_UP = BIT(2), KEY_JOYCON_LEFT = BIT( - 3),""" -replace.o = "" - -search.key_left = "KEY_LEFT = KEY_DLEFT or KEY_LSTICK_LEFT or KEY_RSTICK_LEFT, ## /< D-Pad Left or Sticks Left" -replace.key_left = "" -search.key_rstick_up = " KEY_RSTICK_UP" -prepend.key_rstick_up = """ - KEY_LEFT = KEY_DLEFT.int or KEY_LSTICK_LEFT.int or KEY_RSTICK_LEFT.int, ## /< D-Pad Left or Sticks Left -""" - -search.key_right = " KEY_RIGHT = KEY_DRIGHT or KEY_LSTICK_RIGHT or KEY_RSTICK_RIGHT ## /< D-Pad Right or Sticks Right" -replace.key_right = "" -search.key_rstick_down = " KEY_RSTICK_DOWN" -prepend.key_rstick_down = """ - KEY_RIGHT = KEY_DRIGHT.int or KEY_LSTICK_RIGHT.int or KEY_RSTICK_RIGHT.int, ## /< D-Pad Right or Sticks Right -""" - -search.key_up = " KEY_UP = KEY_DUP or KEY_LSTICK_UP or KEY_RSTICK_UP, ## /< D-Pad Up or Sticks Up" -replace.key_up = "" -search.key_rstick_right = " KEY_RSTICK_RIGHT" -prepend.key_rstick_right = """ - KEY_UP = KEY_DUP.int or KEY_LSTICK_UP.int or KEY_RSTICK_UP.int, ## /< D-Pad Up or Sticks Up -""" - -search.key_down = " KEY_DOWN = KEY_DDOWN or KEY_LSTICK_DOWN or KEY_RSTICK_DOWN, ## /< D-Pad Down or Sticks Down" -replace.key_down = "" -search.key_sl = " KEY_SL" -prepend.key_sl = """ - KEY_DOWN = KEY_DDOWN.int or KEY_LSTICK_DOWN.int or KEY_RSTICK_DOWN.int, ## /< D-Pad Down or Sticks Down -""" - -[nifm.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/wrapper/types -""" - -[set.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/wrapper/types -""" - -[parcel.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/wrapper/types -""" - -[fs_dev.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/wrapper/types -""" - -[buffer_producer.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/wrapper/types -import libnx/wrapper/binder -""" - -[nxlink.nim] -search.o = "var __nxlink" -replace.o = "var DUnxlink" - -[fs.nim] -search.o = "import libnx" -prepend.o = """ -import libnx/ext/integer128 -""" - -[acc.nim] -prepend.o = """ -import libnx/ext/integer128 -""" - -[fence.nim] -prepend.o = """ -import libnx/wrapper/types -""" - -[cons.nim] -search.o = "type\n" -prepend.o = """ - -template CONSOLE_ESC*(x: string): string = "\x1b[" & $x -# Colors -template CONSOLE_RESET*: string = CONSOLE_ESC("0m") -template CONSOLE_BLACK*: string = CONSOLE_ESC("30m") -template CONSOLE_RED*: string = CONSOLE_ESC("31;1m") -template CONSOLE_GREEN*: string = CONSOLE_ESC("32;1m") -template CONSOLE_YELLOW*: string = CONSOLE_ESC("33;1m") -template CONSOLE_BLUE*: string = CONSOLE_ESC("34;1m") -template CONSOLE_MAGENTA*: string = CONSOLE_ESC("35;1m") -template CONSOLE_CYAN*: string = CONSOLE_ESC("36;1m") -template CONSOLE_WHITE*: string = CONSOLE_ESC("37;1m") - -# Styles -template CONSOLE_COLOR_BOLD*: int = BIT(0).int -template CONSOLE_COLOR_FAINT*: int = BIT(1).int -template CONSOLE_ITALIC*: int = BIT(2).int -template CONSOLE_UNDERLINE*: int = BIT(3).int -template CONSOLE_BLINK_SLOW*: int = BIT(4).int -template CONSOLE_BLINK_FAST*: int = BIT(5).int -template CONSOLE_COLOR_REVERSE*: int = BIT(6).int -template CONSOLE_CONCEAL*: int = BIT(7).int -template CONSOLE_CROSSED_OUT*: int = BIT(8).int - -""" - -search.threedmoo = "debugDevice_3DMOO" -replace.threedmoo = "debugDevice_3DMOO*" - -[gfx.nim] -search.timport = "../types" -replace.timport = "libnx/wrapper/types" - -search.fimport = "../nvidia/fence" -replace.fimport = "libnx/wrapper/fence" - -[romfs_dev.nim] -search.timport = "../types" -replace.timport = "libnx/wrapper/types" -search.servimport = "../services/" -replace.servimport = "libnx/wrapper/" -search.o = "../libnx" -replace.o = "libnx" - -[n.sourcefile] -"${output}/*.nim" diff --git a/src/libnx/account.nim b/src/libnx/account.nim index aa46b36..bbada5c 100644 --- a/src/libnx/account.nim +++ b/src/libnx/account.nim @@ -1,7 +1,7 @@ import strutils -import libnx/wrapper/acc +import libnx/wrapper/switch/services/acc import libnx/results -import libnx/wrapper/types +import libnx/wrapper/switch/types import libnx/ext/integer128 import libnx/service import libnx/utils @@ -19,7 +19,7 @@ type AccountImageLoadError* = object of AccountError User* = ref object - id*: u128 + id*: AccountUid selected*: bool username*: string lastEdited*: uint64 @@ -32,24 +32,28 @@ type AccountImage* = ref object data: seq[uint8] - imageSize: int + imageSize: U32 + + +export AccountUid +export AccountServiceType var enabled = false proc getService*(): Service = - let serv = accountGetService()[] + let serv = accountGetServiceSession()[] result = newService(serv) -proc init() = +proc init(ty: AccountServiceType) = ## Initializes the account service. Should not ## be used in client code let service = getService() if service.isActive: return - let code = accountInitialize().newResult + let code = accountInitialize(ty).newResult if code.failed: raiseEx( AccountInitError, @@ -84,7 +88,7 @@ proc ensureEnabled() = proc getImageSize*(profile: AccountProfile): int = ensureEnabled() - var res = 0.csize + var res = 0.U32 result = 0 let code = accountProfileGetImageSize(profile.unsafeAddr, res.addr).newResult if code.failed: @@ -92,19 +96,19 @@ proc getImageSize*(profile: AccountProfile): int = result = res.int -proc imageSize*(user: User): int = +proc imageSize*(user: User): csize_t = ensureEnabled() var prof: AccountProfile - var size: csize + var size: U32 let res = accountProfileGetImageSize(prof.addr, size.addr).newResult if res.failed: raiseEx(AccountImageSizeError, "Error, could not get image size", res) - result = size.int + result = size.csize_t -proc getProfileHelper(userID: u128): AccountProfile = +proc getProfileHelper(userID: AccountUid): AccountProfile = let res = accountGetProfile(result.addr, userID).newResult if res.failed: @@ -115,7 +119,6 @@ proc loadImage*(user: User): AccountImage = ensureEnabled() result = new(AccountImage) let imSize = user.imageSize() - var size: csize var prof = getProfileHelper(user.id) @@ -137,7 +140,7 @@ proc userID*(user: User): string = $user.id -proc getUser*(userID: u128): User = +proc getUser*(userID: AccountUid): User = ensureEnabled() result = new(User) @@ -154,7 +157,7 @@ proc getUser*(userID: u128): User = if res.failed: raiseEx(AccountUserDataError, "Error, could not get user data", res) - result.username = profBase.username.join("") + result.username = profBase.nickname.join("") result.lastEdited = profBase.lastEditTimestamp result.iconID = userData.iconID result.iconBgColorID = userData.iconBackgroundColorID @@ -167,19 +170,15 @@ proc getActiveUser*(): User = ensureEnabled() result = new(User) var - userID: u128 = newUInt128(0,0) - selected: bool + userID: AccountUid - var res = accountGetActiveUser(userID.addr, selected.addr).newResult + var res = accountGetPreselectedUser(userID.addr).newResult if res.failed: raiseEx(AccountActiveUserError, "Error, could not get active user ID", res) - if not selected: - raiseEx(AccountUserNotSelectedError, "No user currently selected!") - result.id = userID - result.selected = selected + result.selected = true var prof: AccountProfile = getProfileHelper(userID) @@ -191,7 +190,7 @@ proc getActiveUser*(): User = if res.failed: raiseEx(AccountUserDataError, "Error, could not get user data", res) - result.username = profBase.username.join("") + result.username = profBase.nickname.join("") result.lastEdited = profBase.lastEditTimestamp result.iconID = userData.iconID result.iconBgColorID = userData.iconBackgroundColorID @@ -235,8 +234,8 @@ proc listAllUsers*(): seq[User] = result = @[] var - userIDs: array[ACC_USER_LIST_SIZE, u128] - usersReturned: csize + userIDs: array[ACC_USER_LIST_SIZE, AccountUid] + usersReturned: S32 let res = accountListAllUsers( userIDs[0].addr, diff --git a/src/libnx/results.nim b/src/libnx/results.nim index 3c1ae26..94469b3 100644 --- a/src/libnx/results.nim +++ b/src/libnx/results.nim @@ -1,7 +1,6 @@ import strutils import - libnx/wrapper/result, - libnx/wrapper/types + libnx/wrapper/switch/result type @@ -83,8 +82,8 @@ type IoctlFailed #///< Maps to Nvidia: 0x3000F -proc succeeded*(res: Result): bool = res.code.R_SUCCEEDED -proc failed*(res: Result): bool = res.code.R_FAILED +proc succeeded*(res: Result): bool {.inline.} = res.code.r_SUCCEEDED +proc failed*(res: Result): bool {.inline.} = res.code.r_FAILED proc newResult*(code: uint32): Result = ## Create a result from a libnx error code for friendlier syntax. @@ -92,12 +91,12 @@ proc newResult*(code: uint32): Result = result.code = code - let moduleCode = code.R_MODULE + let moduleCode = code.r_MODULE let module = Module(moduleCode) result.kind = module - let descCode = code.R_DESCRIPTION + let descCode = code.r_DESCRIPTION var error = "Unknown error: module: $# description: $#" % [$moduleCode, $descCode] diff --git a/src/libnx/service.nim b/src/libnx/service.nim index 8db2692..db370c9 100644 --- a/src/libnx/service.nim +++ b/src/libnx/service.nim @@ -1,17 +1,18 @@ import libnx/results, - libnx/wrapper/sm + libnx/wrapper/switch/services/sm, + libnx/wrapper/switch/sf/service, + libnx/wrapper/switch/types -from libnx/wrapper/types import Handle type Service* = ref object - serv: sm.Service + serv: service.Service -proc getSmService*(serv: Service): sm.Service = +proc getSmService*(serv: Service): service.Service = serv.serv -proc newService*(serv: sm.Service): Service = +proc newService*(serv: service.Service): Service = result = Service(serv: serv) proc isOverride*(service: Service): bool = @@ -54,24 +55,6 @@ proc objectId*(service: Service): uint32 = ## serviceGetObjectId(service.serv.addr) -proc close*(service: Service; objectId: uint32): Result = - ## * - ## @brief Closes a domain object by ID. - ## @param[in] s Service object, necessarily a domain or domain subservice. - ## @param object_id ID of the object to close. - ## @return Result code. - ## - serviceCloseObjectById(service.serv.addr, objectId).newResult - - -proc ipcDispatch*(service: Service): Result = - ## * - ## @brief Dispatches an IPC request to a service. - ## @param[in] s Service object. - ## @return Result code. - ## - serviceIpcDispatch(service.serv.addr).newResult - proc createService*(handle: Handle): Service = ## * ## @brief Creates a service object from an IPC session handle. @@ -91,7 +74,7 @@ proc createDomainSubservice*(parent: Service; objectId: uint32): Service = result = new(Service) serviceCreateDomainSubservice(result.serv.addr, parent.serv.addr, objectId) -proc convertToDomain*(service: Service): Result = +proc convertToDomain*(service: Service): results.Result = ## * ## @brief Converts a regular service to a domain. ## @param[in] s Service object. diff --git a/src/libnx/wrapper/switch.h b/src/libnx/wrapper/switch.h new file mode 100644 index 0000000..c7d648e --- /dev/null +++ b/src/libnx/wrapper/switch.h @@ -0,0 +1,197 @@ +/** + * @file switch.h + * @brief Central Switch header. Includes all others. + * @copyright libnx Authors + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "switch/types.h" +#include "switch/result.h" + +#include "switch/nro.h" +#include "switch/nacp.h" + +#include "switch/arm/tls.h" +#include "switch/arm/cache.h" +#include "switch/arm/counter.h" + +#include "switch/kernel/svc.h" +#include "switch/kernel/wait.h" +#include "switch/kernel/tmem.h" +#include "switch/kernel/shmem.h" +#include "switch/kernel/mutex.h" +#include "switch/kernel/event.h" +#include "switch/kernel/levent.h" +#include "switch/kernel/uevent.h" +#include "switch/kernel/utimer.h" +#include "switch/kernel/rwlock.h" +#include "switch/kernel/condvar.h" +#include "switch/kernel/thread.h" +#include "switch/kernel/semaphore.h" +#include "switch/kernel/virtmem.h" +#include "switch/kernel/detect.h" +#include "switch/kernel/random.h" +#include "switch/kernel/jit.h" +#include "switch/kernel/barrier.h" + +#include "switch/sf/hipc.h" +#include "switch/sf/cmif.h" +#include "switch/sf/service.h" +#include "switch/sf/sessionmgr.h" +#include "switch/sf/tipc.h" + +#include "switch/services/sm.h" +#include "switch/services/smm.h" +#include "switch/services/fs.h" +#include "switch/services/fsldr.h" +#include "switch/services/fspr.h" +#include "switch/services/acc.h" +#include "switch/services/apm.h" +#include "switch/services/applet.h" +#include "switch/services/async.h" +#include "switch/services/audctl.h" +#include "switch/services/audin.h" +#include "switch/services/audout.h" +#include "switch/services/audrec.h" +#include "switch/services/audren.h" +#include "switch/services/auddev.h" +#include "switch/services/hwopus.h" +#include "switch/services/csrng.h" +#include "switch/services/lbl.h" +#include "switch/services/i2c.h" +#include "switch/services/gpio.h" +#include "switch/services/uart.h" +#include "switch/services/bpc.h" +#include "switch/services/pcv.h" +#include "switch/services/clkrst.h" +#include "switch/services/fan.h" +#include "switch/services/pgl.h" +#include "switch/services/psm.h" +#include "switch/services/spsm.h" +//#include "switch/services/bsd.h" Use instead +//#include "switch/services/sfdnsres.h" Use instead +//#include "switch/services/htcs.h" +#include "switch/services/fatal.h" +#include "switch/services/time.h" +#include "switch/services/usb.h" +#include "switch/services/usbds.h" +#include "switch/services/usbhs.h" +#include "switch/services/hid.h" +#include "switch/services/hidbus.h" +#include "switch/services/hiddbg.h" +#include "switch/services/hidsys.h" +#include "switch/services/irs.h" +#include "switch/services/pl.h" +#include "switch/services/vi.h" +#include "switch/services/nv.h" +#include "switch/services/nifm.h" +#include "switch/services/nim.h" +#include "switch/services/ns.h" +#include "switch/services/ldr.h" +#include "switch/services/ro.h" +#include "switch/services/tc.h" +#include "switch/services/ts.h" +#include "switch/services/pm.h" +#include "switch/services/set.h" +#include "switch/services/ssl.h" +#include "switch/services/lr.h" +#include "switch/services/bt.h" +#include "switch/services/btdrv.h" +#include "switch/services/btm.h" +#include "switch/services/btmu.h" +#include "switch/services/btmsys.h" +#include "switch/services/spl.h" +#include "switch/services/ncm.h" +#include "switch/services/psc.h" +#include "switch/services/caps.h" +#include "switch/services/capsa.h" +#include "switch/services/capsc.h" +#include "switch/services/capsdc.h" +#include "switch/services/capsu.h" +#include "switch/services/capssc.h" +#include "switch/services/capssu.h" +#include "switch/services/capmtp.h" +#include "switch/services/nfc.h" +#include "switch/services/wlaninf.h" +#include "switch/services/pctl.h" +#include "switch/services/pdm.h" +#include "switch/services/grc.h" +#include "switch/services/friends.h" +#include "switch/services/notif.h" +#include "switch/services/mii.h" +#include "switch/services/miiimg.h" +#include "switch/services/ldn.h" +#include "switch/services/lp2p.h" +#include "switch/services/news.h" +#include "switch/services/ins.h" +#include "switch/services/ectx.h" +#include "switch/services/avm.h" +#include "switch/services/mm.h" + +#include "switch/display/binder.h" +#include "switch/display/parcel.h" +#include "switch/display/buffer_producer.h" +#include "switch/display/native_window.h" +#include "switch/display/framebuffer.h" + +#include "switch/nvidia/ioctl.h" +#include "switch/nvidia/graphic_buffer.h" +#include "switch/nvidia/fence.h" +#include "switch/nvidia/map.h" +#include "switch/nvidia/address_space.h" +#include "switch/nvidia/channel.h" +#include "switch/nvidia/gpu.h" +#include "switch/nvidia/gpu_channel.h" + +#include "switch/audio/driver.h" + +#include "switch/applets/libapplet.h" +#include "switch/applets/album_la.h" +#include "switch/applets/friends_la.h" +#include "switch/applets/hid_la.h" +#include "switch/applets/mii_la.h" +#include "switch/applets/nfp_la.h" +#include "switch/applets/nifm_la.h" +#include "switch/applets/pctlauth.h" +#include "switch/applets/psel.h" +#include "switch/applets/error.h" +#include "switch/applets/swkbd.h" +#include "switch/applets/web.h" + +#include "switch/runtime/env.h" +#include "switch/runtime/hosversion.h" +#include "switch/runtime/diag.h" +#include "switch/runtime/nxlink.h" +#include "switch/runtime/resolver.h" +#include "switch/runtime/pad.h" +#include "switch/runtime/ringcon.h" +#include "switch/runtime/btdev.h" + +#include "switch/runtime/util/utf.h" + +#include "switch/runtime/devices/console.h" +#include "switch/runtime/devices/usb_comms.h" +#include "switch/runtime/devices/fs_dev.h" +#include "switch/runtime/devices/romfs_dev.h" +#include "switch/runtime/devices/socket.h" + +#include "switch/crypto/aes.h" +#include "switch/crypto/aes_cbc.h" +#include "switch/crypto/aes_ctr.h" +#include "switch/crypto/aes_xts.h" +#include "switch/crypto/cmac.h" + +#include "switch/crypto/sha256.h" +#include "switch/crypto/sha1.h" +#include "switch/crypto/hmac.h" + +#include "switch/crypto/crc.h" + +#ifdef __cplusplus +} +#endif + diff --git a/src/libnx/wrapper/switch.nim b/src/libnx/wrapper/switch.nim new file mode 100644 index 0000000..331958f --- /dev/null +++ b/src/libnx/wrapper/switch.nim @@ -0,0 +1,120 @@ +## * +## @file switch.h +## @brief Central Switch header. Includes all others. +## @copyright libnx Authors +## + +import + switch/types, switch/result, switch/nro, switch/nacp, switch/arm/tls, + switch/arm/cache, switch/arm/counter, switch/kernel/svc, switch/kernel/wait, + switch/kernel/tmem, switch/kernel/shmem, switch/kernel/mutex, + switch/kernel/event, switch/kernel/levent, switch/kernel/uevent, + switch/kernel/utimer, switch/kernel/rwlock, switch/kernel/condvar, + switch/kernel/thread, switch/kernel/semaphore, switch/kernel/virtmem, + switch/kernel/detect, switch/kernel/random, switch/kernel/jit, + switch/kernel/barrier, switch/sf/hipc, switch/sf/cmif, switch/sf/service, + switch/sf/sessionmgr, switch/sf/tipc, switch/services/sm, switch/services/smm, + switch/services/fs, switch/services/fsldr, switch/services/fspr, + switch/services/acc, switch/services/apm, switch/services/applet, + switch/services/async, switch/services/audctl, switch/services/audin, + switch/services/audout, switch/services/audrec, switch/services/audren, + switch/services/auddev, switch/services/hwopus, switch/services/csrng, + switch/services/lbl, switch/services/i2c, switch/services/gpio, + switch/services/uart, switch/services/bpc, switch/services/pcv, + switch/services/clkrst, switch/services/fan, switch/services/pgl, + switch/services/psm, switch/services/spsm + +export + types, result, nro, nacp, tls, + cache, counter, svc, wait, + tmem, shmem, mutex, + event, levent, uevent, + utimer, rwlock, condvar, + thread, semaphore, virtmem, + detect, random, jit, + barrier, hipc, cmif, service, + sessionmgr, tipc, sm, smm, + fs, fsldr, fspr, + acc, apm, applet, + async, audctl, audin, + audout, audrec, audren, + auddev, hwopus, csrng, + lbl, i2c, gpio, + uart, bpc, pcv, + clkrst, fan, pgl, + psm, spsm + + +import + switch/services/fatal, switch/services/time, switch/services/usb, + switch/services/usbds, switch/services/usbhs, switch/services/hid, + switch/services/hidbus, switch/services/hiddbg, switch/services/hidsys, + switch/services/irs, switch/services/pl, switch/services/vi, switch/services/nv, + switch/services/nifm, switch/services/nim, switch/services/ns, + switch/services/ldr, switch/services/ro, switch/services/tc, switch/services/ts, + switch/services/pm, switch/services/set, switch/services/ssl, switch/services/lr, + switch/services/bt, switch/services/btdrv, switch/services/btm, + switch/services/btmu, switch/services/btmsys, switch/services/spl, + switch/services/ncm, switch/services/psc, switch/services/caps, + switch/services/capsa, switch/services/capsc, switch/services/capsdc, + switch/services/capsu, switch/services/capssc, switch/services/capssu, + switch/services/capmtp, switch/services/nfc, switch/services/wlaninf, + switch/services/pctl, switch/services/pdm, switch/services/grc, + switch/services/friends, switch/services/notif, switch/services/mii, + switch/services/miiimg, switch/services/ldn, switch/services/lp2p, + switch/services/news, switch/services/ins, switch/services/ectx, + switch/services/avm, switch/services/mm, switch/display/binder, + switch/display/parcel, switch/display/buffer_producer, + switch/display/native_window, switch/display/framebuffer, switch/nvidia/ioctl, + switch/nvidia/graphic_buffer, switch/nvidia/fence, switch/nvidia/map, + switch/nvidia/address_space, switch/nvidia/channel, switch/nvidia/gpu, + switch/nvidia/gpu_channel, switch/audio/driver, switch/applets/libapplet, + switch/applets/album_la, switch/applets/friends_la, switch/applets/hid_la, + switch/applets/mii_la, switch/applets/nfp_la, switch/applets/nifm_la, + switch/applets/pctlauth, switch/applets/psel, switch/applets/error, + switch/applets/swkbd, switch/applets/web, switch/runtime/env, + switch/runtime/hosversion, switch/runtime/diag, switch/runtime/nxlink, + switch/runtime/resolver, switch/runtime/pad, switch/runtime/ringcon, + switch/runtime/btdev, switch/runtime/util/utf, switch/runtime/devices/console, + switch/runtime/devices/usb_comms, switch/runtime/devices/fs_dev, + switch/runtime/devices/romfs_dev, switch/runtime/devices/socket, + switch/crypto/aes, switch/crypto/aes_cbc, switch/crypto/aes_ctr, + switch/crypto/aes_xts, switch/crypto/cmac, switch/crypto/sha256, + switch/crypto/sha1, switch/crypto/hmac, switch/crypto/crc + +export + fatal, time, usb, + usbds, usbhs, hid, + hidbus, hiddbg, hidsys, + irs, pl, vi, nv, + nifm, nim, ns, + ldr, ro, tc, ts, + pm, set, ssl, lr, + bt, btdrv, btm, + btmu, btmsys, spl, + ncm, psc, caps, + capsa, capsc, capsdc, + capsu, capssc, capssu, + capmtp, nfc, wlaninf, + pctl, pdm, grc, + friends, notif, mii, + miiimg, ldn, lp2p, + news, ins, ectx, + avm, mm, binder, + parcel, buffer_producer, + native_window, framebuffer, ioctl, + graphic_buffer, fence, map, + address_space, channel, gpu, + gpu_channel, driver, libapplet, + album_la, friends_la, hid_la, + mii_la, nfp_la, nifm_la, + pctlauth, psel, error, + swkbd, web, env, + hosversion, diag, nxlink, + resolver, pad, ringcon, + btdev, utf, console, + usb_comms, fs_dev, + romfs_dev, socket, + aes, aes_cbc, aes_ctr, + aes_xts, cmac, sha256, + sha1, hmac, crc diff --git a/src/libnx/wrapper/switch/applets/album_la.h b/src/libnx/wrapper/switch/applets/album_la.h new file mode 100644 index 0000000..44a5f61 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/album_la.h @@ -0,0 +1,31 @@ +/** + * @file album_la.h + * @brief Wrapper for using the Album LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Arg type values pushed for the applet input storage, stored as an u8. +typedef enum { + AlbumLaArg_ShowAlbumFiles = 0, ///< ShowAlbumFiles. Only displays AlbumFiles associated with the application which launched the Album applet, with the filter button disabled. + AlbumLaArg_ShowAllAlbumFiles = 1, ///< ShowAllAlbumFiles. Displays all AlbumFiles, with filtering allowed. + AlbumLaArg_ShowAllAlbumFilesForHomeMenu = 2, ///< ShowAllAlbumFilesForHomeMenu. Similar to ::AlbumLaArg_ShowAllAlbumFiles. +} AlbumLaArg; + +/** + * @brief Launches the applet with ::AlbumLaArg_ShowAlbumFiles and playStartupSound=false. + */ +Result albumLaShowAlbumFiles(void); + +/** + * @brief Launches the applet with ::AlbumLaArg_ShowAllAlbumFiles and playStartupSound=false. + */ +Result albumLaShowAllAlbumFiles(void); + +/** + * @brief Launches the applet with ::AlbumLaArg_ShowAllAlbumFilesForHomeMenu and playStartupSound=true. + */ +Result albumLaShowAllAlbumFilesForHomeMenu(void); + diff --git a/src/libnx/wrapper/switch/applets/album_la.nim b/src/libnx/wrapper/switch/applets/album_la.nim new file mode 100644 index 0000000..3645101 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/album_la.nim @@ -0,0 +1,36 @@ +## * +## @file album_la.h +## @brief Wrapper for using the Album LibraryApplet. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types + +## / Arg type values pushed for the applet input storage, stored as an u8. + +type + AlbumLaArg* = enum + AlbumLaArg_ShowAlbumFiles = 0, ## /< ShowAlbumFiles. Only displays AlbumFiles associated with the application which launched the Album applet, with the filter button disabled. + AlbumLaArg_ShowAllAlbumFiles = 1, ## /< ShowAllAlbumFiles. Displays all AlbumFiles, with filtering allowed. + AlbumLaArg_ShowAllAlbumFilesForHomeMenu = 2 ## /< ShowAllAlbumFilesForHomeMenu. Similar to ::AlbumLaArg_ShowAllAlbumFiles. + + +## * +## @brief Launches the applet with ::AlbumLaArg_ShowAlbumFiles and playStartupSound=false. +## + +proc albumLaShowAlbumFiles*(): Result {.cdecl, importc: "albumLaShowAlbumFiles".} +## * +## @brief Launches the applet with ::AlbumLaArg_ShowAllAlbumFiles and playStartupSound=false. +## + +proc albumLaShowAllAlbumFiles*(): Result {.cdecl, + importc: "albumLaShowAllAlbumFiles".} +## * +## @brief Launches the applet with ::AlbumLaArg_ShowAllAlbumFilesForHomeMenu and playStartupSound=true. +## + +proc albumLaShowAllAlbumFilesForHomeMenu*(): Result {.cdecl, + importc: "albumLaShowAllAlbumFilesForHomeMenu".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/applets/error.h b/src/libnx/wrapper/switch/applets/error.h new file mode 100644 index 0000000..7346b0f --- /dev/null +++ b/src/libnx/wrapper/switch/applets/error.h @@ -0,0 +1,314 @@ +/** + * @file error.h + * @brief Wrapper for using the error LibraryApplet. + * @author StuntHacks, yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/set.h" + +/// Error type for ErrorCommonHeader.type. +typedef enum { + ErrorType_Normal = 0, ///< Normal + ErrorType_System = 1, ///< System + ErrorType_Application = 2, ///< Application + ErrorType_Eula = 3, ///< EULA + ErrorType_Pctl = 4, ///< Parental Controls + ErrorType_Record = 5, ///< Record + ErrorType_SystemUpdateEula = 8, ///< SystemUpdateEula +} ErrorType; + +/// Stores error-codes which are displayed as XXXX-XXXX, low for the former and desc for the latter. +typedef struct { + u32 low; ///< The module portion of the error, normally this should be set to module + 2000. + u32 desc; ///< The error description. +} ErrorCode; + +/// Error type for ErrorContext.type +typedef enum { + ErrorContextType_None = 0, ///< None + ErrorContextType_Http = 1, ///< Http + ErrorContextType_FileSystem = 2, ///< FileSystem + ErrorContextType_WebMediaPlayer = 3, ///< WebMediaPlayer + ErrorContextType_LocalContentShare = 4, ///< LocalContentShare +} ErrorContextType; + +/// Error context. +typedef struct { + u8 type; ///< Type, see \ref ErrorContextType. + u8 pad[7]; ///< Padding + u8 data[0x1f4]; ///< Data + Result res; ///< Result +} ErrorContext; + +/// Common header for the start of the arg storage. +typedef struct { + u8 type; ///< Type, see \ref ErrorType. + u8 jumpFlag; ///< When clear, this indicates WithoutJump. + u8 unk_x2[3]; ///< Unknown + u8 contextFlag; ///< When set with ::ErrorType_Normal, indicates that an additional storage is pushed for \ref ErrorResultBacktrace. [4.0.0+] Otherwise, when set indicates that an additional storage is pushed for \ref ErrorContext. + u8 resultFlag; ///< ErrorCommonArg: When clear, errorCode is used, otherwise the applet generates the error-code from res. + u8 contextFlag2; ///< Similar to contextFlag except for ErrorCommonArg, indicating \ref ErrorContext is used. +} ErrorCommonHeader; + +/// Common error arg data. +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + ErrorCode errorCode; ///< \ref ErrorCode + Result res; ///< Result +} ErrorCommonArg; + +/// Error arg data for certain errors with module PCTL. +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + Result res; ///< Result +} ErrorPctlArg; + +/// ResultBacktrace +typedef struct { + s32 count; ///< Total entries in the backtrace array. + Result backtrace[0x20]; ///< Result backtrace. +} ErrorResultBacktrace; + +/// Error arg data for EULA. +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + SetRegion regionCode; ///< \ref SetRegion +} ErrorEulaArg; + +/// Additional input storage data for \ref errorSystemUpdateEulaShow. +typedef struct { + u8 data[0x20000]; ///< data +} ErrorEulaData; + +/// Error arg data for Record. +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + ErrorCode errorCode; ///< \ref ErrorCode + u64 timestamp; ///< POSIX timestamp. +} ErrorRecordArg; + +/// SystemErrorArg +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + ErrorCode errorCode; ///< \ref ErrorCode + u64 languageCode; ///< See set.h. + char dialogMessage[0x800]; ///< UTF-8 Dialog message. + char fullscreenMessage[0x800]; ///< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). +} ErrorSystemArg; + +/// Error system config. +typedef struct { + ErrorSystemArg arg; ///< Arg data. + ErrorContext ctx; ///< Optional error context. +} ErrorSystemConfig; + +/// ApplicationErrorArg +typedef struct { + ErrorCommonHeader hdr; ///< Common header. + u32 errorNumber; ///< Raw decimal error number which is displayed in the dialog. + u64 languageCode; ///< See set.h. + char dialogMessage[0x800]; ///< UTF-8 Dialog message. + char fullscreenMessage[0x800]; ///< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). +} PACKED ErrorApplicationArg; + +/// Error application config. +typedef struct { + ErrorApplicationArg arg; ///< Arg data. +} ErrorApplicationConfig; + +/** + * @brief Creates an \ref ErrorCode. + * @param low The module portion of the error, normally this should be set to module + 2000. + * @param desc The error description. + */ +static inline ErrorCode errorCodeCreate(u32 low, u32 desc) { + return (ErrorCode){low, desc}; +} + +/** + * @brief Creates an \ref ErrorCode with the input Result. Wrapper for \ref errorCodeCreate. + * @param res Input Result. + */ +static inline ErrorCode errorCodeCreateResult(Result res) { + return errorCodeCreate(2000 + R_MODULE(res), R_DESCRIPTION(res)); +} + +/** + * @brief Creates an invalid \ref ErrorCode. + */ +static inline ErrorCode errorCodeCreateInvalid(void) { + return (ErrorCode){0}; +} + +/** + * @brief Checks whether the input ErrorCode is valid. + * @param errorCode \ref ErrorCode + */ +static inline bool errorCodeIsValid(ErrorCode errorCode) { + return errorCode.low!=0; +} + +/** + * @brief Launches the applet for displaying the specified Result. + * @param res Result + * @param jumpFlag Jump flag, normally this is true. + * @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. + * @note Sets the following fields: jumpFlag and contextFlag2. Uses ::ErrorType_Normal normally. + * @note For module=PCTL errors with desc 100-119 this sets uses ::ErrorType_Pctl, in which case the applet will display the following special dialog: "This software is restricted by Parental Controls". + * @note If the input Result is 0xC8A2, the applet will display a special dialog regarding the current application requiring a software update, with buttons "Later" and "Restart". + * @note [3.0.0+] If the input Result is 0xCAA2, the applet will display a special dialog related to DLC version. + * @warning This applet creates an error report that is logged in the system, when not handling the above special dialogs. Proceed at your own risk! + */ +Result errorResultShow(Result res, bool jumpFlag, const ErrorContext* ctx); + +/** + * @brief Launches the applet for displaying the specified ErrorCode. + * @param errorCode \ref ErrorCode + * @param jumpFlag Jump flag, normally this is true. + * @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. + * @note Sets the following fields: jumpFlag and contextFlag2. resultFlag=1. Uses ::ErrorType_Normal. + * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! + */ +Result errorCodeShow(ErrorCode errorCode, bool jumpFlag, const ErrorContext* ctx); + +/** + * @brief Creates an ErrorResultBacktrace struct. + * @param backtrace \ref ErrorResultBacktrace struct. + * @param count Total number of entries. + * @param entries Input array of Result. + */ +Result errorResultBacktraceCreate(ErrorResultBacktrace* backtrace, s32 count, const Result* entries); + +/** + * @brief Launches the applet for \ref ErrorResultBacktrace. + * @param backtrace ErrorResultBacktrace struct. + * @param res Result + * @note Sets the following fields: jumpFlag=1, contextFlag=1, and uses ::ErrorType_Normal. + * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! + */ +Result errorResultBacktraceShow(Result res, const ErrorResultBacktrace* backtrace); + +/** + * @brief Launches the applet for displaying the EULA. + * @param RegionCode \ref SetRegion + * @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_Eula. + */ +Result errorEulaShow(SetRegion RegionCode); + +/** + * @brief Launches the applet for displaying the system-update EULA. + * @param RegionCode \ref SetRegion + * @param eula EULA data. Address must be 0x1000-byte aligned. + * @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_SystemUpdateEula. + */ +Result errorSystemUpdateEulaShow(SetRegion RegionCode, const ErrorEulaData* eula); + +/** + * @brief Launches the applet for displaying an error full-screen, using the specified ErrorCode and timestamp. + * @param errorCode \ref ErrorCode + * @param timestamp POSIX timestamp. + * @note Sets the following fields: jumpFlag=1, errorCode, timestamp, and uses ::ErrorType_Record. + * @note The applet does not log an error report for this. error*RecordShow is used by qlaunch for displaying previously logged error reports. + */ +Result errorCodeRecordShow(ErrorCode errorCode, u64 timestamp); + +/** + * @brief Launches the applet for displaying an error full-screen, using the specified Result and timestamp. + * @param res Result + * @param timestamp POSIX timestamp. + * @note Wrapper for \ref errorCodeRecordShow, see \ref errorCodeRecordShow notes. + */ +static inline Result errorResultRecordShow(Result res, u64 timestamp) { + return errorCodeRecordShow(errorCodeCreateResult(res), timestamp); +} + +/** + * @brief Creates an ErrorSystemConfig struct. + * @param c ErrorSystemConfig struct. + * @param dialog_message UTF-8 dialog message. + * @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). + * @note Sets the following fields: {strings}, and uses ::ErrorType_System. The rest are cleared. + * @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). + * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! + */ +Result errorSystemCreate(ErrorSystemConfig* c, const char* dialog_message, const char* fullscreen_message); + +/** + * @brief Launches the applet with the specified config. + * @param c ErrorSystemConfig struct. + */ +Result errorSystemShow(ErrorSystemConfig* c); + +/** + * @brief Sets the error code. + * @param c ErrorSystemConfig struct. + * @param errorCode \ref ErrorCode + */ +static inline void errorSystemSetCode(ErrorSystemConfig* c, ErrorCode errorCode) { + c->arg.errorCode = errorCode; +} + +/** + * @brief Sets the error code, using the input Result. Wrapper for \ref errorSystemSetCode. + * @param c ErrorSystemConfig struct. + * @param res The Result to set. + */ +static inline void errorSystemSetResult(ErrorSystemConfig* c, Result res) { + errorSystemSetCode(c, errorCodeCreateResult(res)); +} + +/** + * @brief Sets the LanguageCode. + * @param c ErrorSystemConfig struct. + * @param LanguageCode LanguageCode, see set.h. + */ +static inline void errorSystemSetLanguageCode(ErrorSystemConfig* c, u64 LanguageCode) { + c->arg.languageCode = LanguageCode; +} + +/** + * @brief Sets the ErrorContext. + * @note Only available on [4.0.0+], on older versions this will return without setting the context. + * @param c ErrorSystemConfig struct. + * @param ctx ErrorContext, NULL to clear it. + */ +void errorSystemSetContext(ErrorSystemConfig* c, const ErrorContext* ctx); + +/** + * @brief Creates an ErrorApplicationConfig struct. + * @param c ErrorApplicationConfig struct. + * @param dialog_message UTF-8 dialog message. + * @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). + * @note Sets the following fields: jumpFlag=1, {strings}, and uses ::ErrorType_Application. The rest are cleared. + * @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). + * @note With [10.0.0+] this must only be used when running under an Application, since otherwise the applet will trigger a fatalerr. + * @warning This applet creates an error report that is logged in the system. Proceed at your own risk! + */ +Result errorApplicationCreate(ErrorApplicationConfig* c, const char* dialog_message, const char* fullscreen_message); + +/** + * @brief Launches the applet with the specified config. + * @param c ErrorApplicationConfig struct. + */ +Result errorApplicationShow(ErrorApplicationConfig* c); + +/** + * @brief Sets the error code number. + * @param c ErrorApplicationConfig struct. + * @param errorNumber Error code number. Raw decimal error number which is displayed in the dialog. + */ +static inline void errorApplicationSetNumber(ErrorApplicationConfig* c, u32 errorNumber) { + c->arg.errorNumber = errorNumber; +} + +/** + * @brief Sets the LanguageCode. + * @param c ErrorApplicationConfig struct. + * @param LanguageCode LanguageCode, see set.h. + */ +static inline void errorApplicationSetLanguageCode(ErrorApplicationConfig* c, u64 LanguageCode) { + c->arg.languageCode = LanguageCode; +} + diff --git a/src/libnx/wrapper/switch/applets/error.nim b/src/libnx/wrapper/switch/applets/error.nim new file mode 100644 index 0000000..efab85b --- /dev/null +++ b/src/libnx/wrapper/switch/applets/error.nim @@ -0,0 +1,347 @@ +## * +## @file error.h +## @brief Wrapper for using the error LibraryApplet. +## @author StuntHacks, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/set, ../result + +## / Error type for ErrorCommonHeader.type. + +type + ErrorType* = enum + ErrorTypeNormal = 0, ## /< Normal + ErrorTypeSystem = 1, ## /< System + ErrorTypeApplication = 2, ## /< Application + ErrorTypeEula = 3, ## /< EULA + ErrorTypePctl = 4, ## /< Parental Controls + ErrorTypeRecord = 5, ## /< Record + ErrorTypeSystemUpdateEula = 8 ## /< SystemUpdateEula + + +## / Stores error-codes which are displayed as XXXX-XXXX, low for the former and desc for the latter. + +type + ErrorCode* {.bycopy.} = object + low*: U32 ## /< The module portion of the error, normally this should be set to module + 2000. + desc*: U32 ## /< The error description. + + +## / Error type for ErrorContext.type + +type + ErrorContextType* = enum + ErrorContextTypeNone = 0, ## /< None + ErrorContextTypeHttp = 1, ## /< Http + ErrorContextTypeFileSystem = 2, ## /< FileSystem + ErrorContextTypeWebMediaPlayer = 3, ## /< WebMediaPlayer + ErrorContextTypeLocalContentShare = 4 ## /< LocalContentShare + + +## / Error context. + +type + ErrorContext* {.bycopy.} = object + `type`*: U8 ## /< Type, see \ref ErrorContextType. + pad*: array[7, U8] ## /< Padding + data*: array[0x1f4, U8] ## /< Data + res*: Result ## /< Result + + +## / Common header for the start of the arg storage. + +type + ErrorCommonHeader* {.bycopy.} = object + `type`*: U8 ## /< Type, see \ref ErrorType. + jumpFlag*: U8 ## /< When clear, this indicates WithoutJump. + unkX2*: array[3, U8] ## /< Unknown + contextFlag*: U8 ## /< When set with ::ErrorType_Normal, indicates that an additional storage is pushed for \ref ErrorResultBacktrace. [4.0.0+] Otherwise, when set indicates that an additional storage is pushed for \ref ErrorContext. + resultFlag*: U8 ## /< ErrorCommonArg: When clear, errorCode is used, otherwise the applet generates the error-code from res. + contextFlag2*: U8 ## /< Similar to contextFlag except for ErrorCommonArg, indicating \ref ErrorContext is used. + + +## / Common error arg data. + +type + ErrorCommonArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + errorCode*: ErrorCode ## /< \ref ErrorCode + res*: Result ## /< Result + + +## / Error arg data for certain errors with module PCTL. + +type + ErrorPctlArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + res*: Result ## /< Result + + +## / ResultBacktrace + +type + ErrorResultBacktrace* {.bycopy.} = object + count*: S32 ## /< Total entries in the backtrace array. + backtrace*: array[0x20, Result] ## /< Result backtrace. + + +## / Error arg data for EULA. + +type + ErrorEulaArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + regionCode*: SetRegion ## /< \ref SetRegion + + +## / Additional input storage data for \ref errorSystemUpdateEulaShow. + +type + ErrorEulaData* {.bycopy.} = object + data*: array[0x20000, U8] ## /< data + + +## / Error arg data for Record. + +type + ErrorRecordArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + errorCode*: ErrorCode ## /< \ref ErrorCode + timestamp*: U64 ## /< POSIX timestamp. + + +## / SystemErrorArg + +type + ErrorSystemArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + errorCode*: ErrorCode ## /< \ref ErrorCode + languageCode*: U64 ## /< See set.h. + dialogMessage*: array[0x800, char] ## /< UTF-8 Dialog message. + fullscreenMessage*: array[0x800, char] ## /< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). + + +## / Error system config. + +type + ErrorSystemConfig* {.bycopy.} = object + arg*: ErrorSystemArg ## /< Arg data. + ctx*: ErrorContext ## /< Optional error context. + + +## / ApplicationErrorArg + +type + ErrorApplicationArg* {.bycopy.} = object + hdr*: ErrorCommonHeader ## /< Common header. + errorNumber*: U32 ## /< Raw decimal error number which is displayed in the dialog. + languageCode*: U64 ## /< See set.h. + dialogMessage*: array[0x800, char] ## /< UTF-8 Dialog message. + fullscreenMessage*: array[0x800, char] ## /< UTF-8 Fullscreen message (displayed when the user clicks on "Details"). + + +## / Error application config. + +type + ErrorApplicationConfig* {.bycopy.} = object + arg*: ErrorApplicationArg ## /< Arg data. + + + +proc errorCodeCreate*(low: U32; desc: U32): ErrorCode {.inline, cdecl.} = + ## * + ## @brief Creates an \ref ErrorCode. + ## @param low The module portion of the error, normally this should be set to module + 2000. + ## @param desc The error description. + ## + return ErrorCode(low: low, desc: desc) + + +proc errorCodeCreateResult*(res: Result): ErrorCode {.inline, cdecl.} = + ## * + ## @brief Creates an \ref ErrorCode with the input Result. Wrapper for \ref errorCodeCreate. + ## @param res Input Result. + ## + return errorCodeCreate(2000 + r_Module(res), r_Description(res)) + + +proc errorCodeCreateInvalid*(): ErrorCode {.inline, cdecl.} = + ## * + ## @brief Creates an invalid \ref ErrorCode. + ## + return ErrorCode(low: 0, desc: 0) + + +proc errorCodeIsValid*(errorCode: ErrorCode): bool {.inline, cdecl.} = + ## * + ## @brief Checks whether the input ErrorCode is valid. + ## @param errorCode \ref ErrorCode + ## + return errorCode.low != 0 + +proc errorResultShow*(res: Result; jumpFlag: bool; ctx: ptr ErrorContext): Result {. + cdecl, importc: "errorResultShow".} +## * +## @brief Launches the applet for displaying the specified Result. +## @param res Result +## @param jumpFlag Jump flag, normally this is true. +## @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. +## @note Sets the following fields: jumpFlag and contextFlag2. Uses ::ErrorType_Normal normally. +## @note For module=PCTL errors with desc 100-119 this sets uses ::ErrorType_Pctl, in which case the applet will display the following special dialog: "This software is restricted by Parental Controls". +## @note If the input Result is 0xC8A2, the applet will display a special dialog regarding the current application requiring a software update, with buttons "Later" and "Restart". +## @note [3.0.0+] If the input Result is 0xCAA2, the applet will display a special dialog related to DLC version. +## @warning This applet creates an error report that is logged in the system, when not handling the above special dialogs. Proceed at your own risk! +## +proc errorCodeShow*(errorCode: ErrorCode; jumpFlag: bool; ctx: ptr ErrorContext): Result {. + cdecl, importc: "errorCodeShow".} +## * +## @brief Launches the applet for displaying the specified ErrorCode. +## @param errorCode \ref ErrorCode +## @param jumpFlag Jump flag, normally this is true. +## @param ctx Optional \ref ErrorContext, can be NULL. Unused when jumpFlag=false. Ignored on pre-4.0.0, since it's only available for [4.0.0+]. +## @note Sets the following fields: jumpFlag and contextFlag2. resultFlag=1. Uses ::ErrorType_Normal. +## @warning This applet creates an error report that is logged in the system. Proceed at your own risk! +## +proc errorResultBacktraceCreate*(backtrace: ptr ErrorResultBacktrace; count: S32; + entries: ptr Result): Result {.cdecl, + importc: "errorResultBacktraceCreate".} +## * +## @brief Creates an ErrorResultBacktrace struct. +## @param backtrace \ref ErrorResultBacktrace struct. +## @param count Total number of entries. +## @param entries Input array of Result. +## +proc errorResultBacktraceShow*(res: Result; backtrace: ptr ErrorResultBacktrace): Result {. + cdecl, importc: "errorResultBacktraceShow".} +## * +## @brief Launches the applet for \ref ErrorResultBacktrace. +## @param backtrace ErrorResultBacktrace struct. +## @param res Result +## @note Sets the following fields: jumpFlag=1, contextFlag=1, and uses ::ErrorType_Normal. +## @warning This applet creates an error report that is logged in the system. Proceed at your own risk! +## +proc errorEulaShow*(regionCode: SetRegion): Result {.cdecl, importc: "errorEulaShow".} +## * +## @brief Launches the applet for displaying the EULA. +## @param RegionCode \ref SetRegion +## @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_Eula. +## +proc errorSystemUpdateEulaShow*(regionCode: SetRegion; eula: ptr ErrorEulaData): Result {. + cdecl, importc: "errorSystemUpdateEulaShow".} +## * +## @brief Launches the applet for displaying the system-update EULA. +## @param RegionCode \ref SetRegion +## @param eula EULA data. Address must be 0x1000-byte aligned. +## @note Sets the following fields: jumpFlag=1, regionCode, and uses ::ErrorType_SystemUpdateEula. +## +proc errorCodeRecordShow*(errorCode: ErrorCode; timestamp: U64): Result {.cdecl, + importc: "errorCodeRecordShow".} +## * +## @brief Launches the applet for displaying an error full-screen, using the specified ErrorCode and timestamp. +## @param errorCode \ref ErrorCode +## @param timestamp POSIX timestamp. +## @note Sets the following fields: jumpFlag=1, errorCode, timestamp, and uses ::ErrorType_Record. +## @note The applet does not log an error report for this. error*RecordShow is used by qlaunch for displaying previously logged error reports. +## +proc errorResultRecordShow*(res: Result; timestamp: U64): Result {.inline, cdecl.} = + ## * + ## @brief Launches the applet for displaying an error full-screen, using the specified Result and timestamp. + ## @param res Result + ## @param timestamp POSIX timestamp. + ## @note Wrapper for \ref errorCodeRecordShow, see \ref errorCodeRecordShow notes. + ## + return errorCodeRecordShow(errorCodeCreateResult(res), timestamp) + +proc errorSystemCreate*(c: ptr ErrorSystemConfig; dialogMessage: cstring; + fullscreenMessage: cstring): Result {.cdecl, + importc: "errorSystemCreate".} +## * +## @brief Creates an ErrorSystemConfig struct. +## @param c ErrorSystemConfig struct. +## @param dialog_message UTF-8 dialog message. +## @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). +## @note Sets the following fields: {strings}, and uses ::ErrorType_System. The rest are cleared. +## @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). +## @warning This applet creates an error report that is logged in the system. Proceed at your own risk! +## +proc errorSystemShow*(c: ptr ErrorSystemConfig): Result {.cdecl, + importc: "errorSystemShow".} +## * +## @brief Launches the applet with the specified config. +## @param c ErrorSystemConfig struct. +## +proc errorSystemSetCode*(c: ptr ErrorSystemConfig; errorCode: ErrorCode) {.inline, + cdecl.} = + ## * + ## @brief Sets the error code. + ## @param c ErrorSystemConfig struct. + ## @param errorCode \ref ErrorCode + ## + c.arg.errorCode = errorCode + +proc errorSystemSetResult*(c: ptr ErrorSystemConfig; res: Result) {.inline, cdecl.} = + ## * + ## @brief Sets the error code, using the input Result. Wrapper for \ref errorSystemSetCode. + ## @param c ErrorSystemConfig struct. + ## @param res The Result to set. + ## + errorSystemSetCode(c, errorCodeCreateResult(res)) + +proc errorSystemSetLanguageCode*(c: ptr ErrorSystemConfig; languageCode: U64) {. + inline, cdecl.} = + ## * + ## @brief Sets the LanguageCode. + ## @param c ErrorSystemConfig struct. + ## @param LanguageCode LanguageCode, see set.h. + ## + c.arg.languageCode = languageCode + +proc errorSystemSetContext*(c: ptr ErrorSystemConfig; ctx: ptr ErrorContext) {.cdecl, + importc: "errorSystemSetContext".} +## * +## @brief Sets the ErrorContext. +## @note Only available on [4.0.0+], on older versions this will return without setting the context. +## @param c ErrorSystemConfig struct. +## @param ctx ErrorContext, NULL to clear it. +## +proc errorApplicationCreate*(c: ptr ErrorApplicationConfig; dialogMessage: cstring; + fullscreenMessage: cstring): Result {.cdecl, + importc: "errorApplicationCreate".} +## * +## @brief Creates an ErrorApplicationConfig struct. +## @param c ErrorApplicationConfig struct. +## @param dialog_message UTF-8 dialog message. +## @param fullscreen_message UTF-8 fullscreen message, displayed when the user clicks on "Details". Optional, can be NULL (which disables displaying Details). +## @note Sets the following fields: jumpFlag=1, {strings}, and uses ::ErrorType_Application. The rest are cleared. +## @note On pre-5.0.0 this will initialize languageCode by using: setInitialize(), setMakeLanguageCode(SetLanguage_ENUS, ...), and setExit(). This is needed since an empty languageCode wasn't supported until [5.0.0+] (which would also use SetLanguage_ENUS). +## @note With [10.0.0+] this must only be used when running under an Application, since otherwise the applet will trigger a fatalerr. +## @warning This applet creates an error report that is logged in the system. Proceed at your own risk! +## + + +proc errorApplicationShow*(c: ptr ErrorApplicationConfig): Result {.cdecl, + importc: "errorApplicationShow".} +## * +## @brief Launches the applet with the specified config. +## @param c ErrorApplicationConfig struct. +## + +proc errorApplicationSetNumber*(c: ptr ErrorApplicationConfig; errorNumber: U32) {. + inline, cdecl.} = + ## * + ## @brief Sets the error code number. + ## @param c ErrorApplicationConfig struct. + ## @param errorNumber Error code number. Raw decimal error number which is displayed in the dialog. + ## + c.arg.errorNumber = errorNumber + + +proc errorApplicationSetLanguageCode*(c: ptr ErrorApplicationConfig; + languageCode: U64) {.inline, cdecl.} = + ## * + ## @brief Sets the LanguageCode. + ## @param c ErrorApplicationConfig struct. + ## @param LanguageCode LanguageCode, see set.h. + ## + c.arg.languageCode = languageCode diff --git a/src/libnx/wrapper/switch/applets/friends_la.h b/src/libnx/wrapper/switch/applets/friends_la.h new file mode 100644 index 0000000..5638f1c --- /dev/null +++ b/src/libnx/wrapper/switch/applets/friends_la.h @@ -0,0 +1,172 @@ +/** + * @file friends_la.h + * @brief Wrapper for using the MyPage (friends) LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/acc.h" +#include "../services/friends.h" + +/// Arg type values used with \ref FriendsLaArg. +typedef enum { + FriendsLaArgType_ShowFriendList = 0, ///< ShowFriendList. Launches the applet with the "Friend List" menu initially selected. + FriendsLaArgType_ShowUserDetailInfo = 1, ///< ShowUserDetailInfo + FriendsLaArgType_StartSendingFriendRequest = 2, ///< StartSendingFriendRequest + FriendsLaArgType_ShowMethodsOfSendingFriendRequest = 3, ///< ShowMethodsOfSendingFriendRequest. Launches the applet with the "Add Friend" menu initially selected. + FriendsLaArgType_StartFacedFriendRequest = 4, ///< StartFacedFriendRequest. Launches the applet where the "Search for Local Users" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowReceivedFriendRequestList = 5, ///< ShowReceivedFriendRequestList. Launches the applet where the "Received Friend Requests" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowBlockedUserList = 6, ///< ShowBlockedUserList. Launches the applet where the "Blocked-User List" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowMyProfile = 7, ///< ShowMyProfile. Launches the applet with the "Profile" menu initially selected. ShowMyProfileForHomeMenu is identical to this except for playStartupSound=true. + FriendsLaArgType_StartFriendInvitation = 8, ///< [9.0.0+] StartFriendInvitation. Launches the applet for sending online-play invites to friends, where the friends are selected via the UI. + FriendsLaArgType_StartSendingFriendInvitation = 9, ///< [9.0.0+] StartSendingFriendInvitation. + FriendsLaArgType_ShowReceivedInvitationDetail = 10, ///< [9.0.0+] ShowReceivedInvitationDetail. +} FriendsLaArgType; + +/// Header for the arg struct. +typedef struct { + u32 type; ///< \ref FriendsLaArgType + u32 pad; ///< Padding. + AccountUid uid; ///< \ref AccountUid +} FriendsLaArgHeader; + +/// Common data for the arg struct, for the pre-9.0.0 types. +/// This is only set for ::FriendsLaArgType_ShowUserDetailInfo/::FriendsLaArgType_StartSendingFriendRequest, for everything else this is cleared. +typedef struct { + AccountNetworkServiceAccountId id; ///< \ref AccountNetworkServiceAccountId for the other account. + FriendsInAppScreenName first_inAppScreenName; ///< First InAppScreenName. + FriendsInAppScreenName second_inAppScreenName; ///< Second InAppScreenName. +} FriendsLaArgCommonData; + +/// Arg struct pushed for the applet input storage, for pre-9.0.0. +typedef struct { + FriendsLaArgHeader hdr; ///< \ref FriendsLaArgHeader + FriendsLaArgCommonData data; ///< \ref FriendsLaArgCommonData +} FriendsLaArgV1; + +/// Arg struct pushed for the applet input storage, for [9.0.0+]. +typedef struct { + FriendsLaArgHeader hdr; ///< \ref FriendsLaArgHeader + + union { + u8 raw[0x1090]; ///< Raw data. + + FriendsLaArgCommonData common; ///< \ref FriendsLaArgCommonData + + struct { + s32 id_count; ///< \ref AccountNetworkServiceAccountId count, must be 1-15. + u32 pad; ///< Padding. + u64 userdata_size; ///< User-data size, must be <=0x400. + u8 userdata[0x400]; ///< Arbitrary user-data, see above size. + FriendsFriendInvitationGameModeDescription desc; ///< \ref FriendsFriendInvitationGameModeDescription + } start_friend_invitation; ///< Data for ::FriendsLaArgType_StartFriendInvitation. + + struct { + s32 id_count; ///< \ref AccountNetworkServiceAccountId count, must be 1-15. + u32 pad; ///< Padding. + AccountNetworkServiceAccountId id_list[16]; ///< \ref AccountNetworkServiceAccountId list, see above count. + u64 userdata_size; ///< User-data size, must be <=0x400. + u8 userdata[0x400]; ///< Arbitrary user-data, see above size. + FriendsFriendInvitationGameModeDescription desc; ///< \ref FriendsFriendInvitationGameModeDescription + } start_sending_friend_invitation; ///< Data for ::FriendsLaArgType_StartSendingFriendInvitation. + + struct { + FriendsFriendInvitationId invitation_id; ///< \ref FriendsFriendInvitationId + FriendsFriendInvitationGroupId invitation_group_id; ///< \ref FriendsFriendInvitationGroupId + } show_received_invitation_detail; ///< Data for ::FriendsLaArgType_ShowReceivedInvitationDetail. + } data; ///< Data for each \ref FriendsLaArgType. +} FriendsLaArg; + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowFriendList, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowFriendList(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowUserDetailInfo, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + * @param[in] id \ref AccountNetworkServiceAccountId for the user to show UserDetailInfo for. + * @param[in] first_inAppScreenName First \ref FriendsInAppScreenName. + * @param[in] second_inAppScreenName Second \ref FriendsInAppScreenName. + */ +Result friendsLaShowUserDetailInfo(AccountUid uid, AccountNetworkServiceAccountId id, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName); + +/** + * @brief Launches the applet with ::FriendsLaArgType_StartSendingFriendRequest, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. + * @param[in] uid \ref AccountUid + * @param[in] id \ref AccountNetworkServiceAccountId to send the friend request to. + * @param[in] first_inAppScreenName First \ref FriendsInAppScreenName. + * @param[in] second_inAppScreenName Second \ref FriendsInAppScreenName. + */ +Result friendsLaStartSendingFriendRequest(AccountUid uid, AccountNetworkServiceAccountId id, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowMethodsOfSendingFriendRequest, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowMethodsOfSendingFriendRequest(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_StartFacedFriendRequest, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaStartFacedFriendRequest(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowReceivedFriendRequestList, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowReceivedFriendRequestList(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowBlockedUserList, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowBlockedUserList(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowMyProfile, the specified input, and playStartupSound=false. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowMyProfile(AccountUid uid); + +/** + * @brief Same as \ref friendsLaShowMyProfile except with playStartupSound=true. + * @param[in] uid \ref AccountUid + */ +Result friendsLaShowMyProfileForHomeMenu(AccountUid uid); + +/** + * @brief Launches the applet with ::FriendsLaArgType_StartFriendInvitation, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. + * @note Only available on [9.0.0+]. + * @param[in] uid \ref AccountUid + * @param[in] id_count \ref AccountNetworkServiceAccountId count, must be 1-15. Number of friends to invite. + * @param[in] desc \ref FriendsFriendInvitationGameModeDescription + * @param[in] userdata Arbitrary user-data. Can be NULL. + * @param[in] userdata_size User-data size, must be <=0x400. Can be 0 if userdata is NULL. + */ +Result friendsLaStartFriendInvitation(AccountUid uid, s32 id_count, const FriendsFriendInvitationGameModeDescription *desc, const void* userdata, u64 userdata_size); + +/** + * @brief Launches the applet with ::FriendsLaArgType_StartSendingFriendInvitation, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. + * @note Only available on [9.0.0+]. + * @param[in] uid \ref AccountUid + * @param[in] id_list \ref AccountNetworkServiceAccountId list. + * @param[in] id_count Size of the id_list array in entries, must be 1-15. Number of friends to invite. + * @param[in] desc \ref FriendsFriendInvitationGameModeDescription + * @param[in] userdata Arbitrary user-data. Can be NULL. + * @param[in] userdata_size User-data size, must be <=0x400. Can be 0 if userdata is NULL. + */ +Result friendsLaStartSendingFriendInvitation(AccountUid uid, const AccountNetworkServiceAccountId *id_list, s32 id_count, const FriendsFriendInvitationGameModeDescription *desc, const void* userdata, u64 userdata_size); + +/** + * @brief Launches the applet with ::FriendsLaArgType_ShowReceivedInvitationDetail, the specified input, and playStartupSound=false. + * @note Only available on [9.0.0+]. + * @param[in] uid \ref AccountUid + * @param[in] invitation_id \ref FriendsFriendInvitationId + * @param[in] invitation_group_id \ref FriendsFriendInvitationGroupId + */ +Result friendsLaShowReceivedInvitationDetail(AccountUid uid, FriendsFriendInvitationId invitation_id, FriendsFriendInvitationGroupId invitation_group_id); + diff --git a/src/libnx/wrapper/switch/applets/friends_la.nim b/src/libnx/wrapper/switch/applets/friends_la.nim new file mode 100644 index 0000000..5344777 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/friends_la.nim @@ -0,0 +1,202 @@ +## * +## @file friends_la.h +## @brief Wrapper for using the MyPage (friends) LibraryApplet. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/acc, ../services/friends + +## / Arg type values used with \ref FriendsLaArg. + +type + FriendsLaArgType* = enum + FriendsLaArgType_ShowFriendList = 0, ## /< ShowFriendList. Launches the applet with the "Friend List" menu initially selected. + FriendsLaArgType_ShowUserDetailInfo = 1, ## /< ShowUserDetailInfo + FriendsLaArgType_StartSendingFriendRequest = 2, ## /< StartSendingFriendRequest + FriendsLaArgType_ShowMethodsOfSendingFriendRequest = 3, ## /< ShowMethodsOfSendingFriendRequest. Launches the applet with the "Add Friend" menu initially selected. + FriendsLaArgType_StartFacedFriendRequest = 4, ## /< StartFacedFriendRequest. Launches the applet where the "Search for Local Users" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowReceivedFriendRequestList = 5, ## /< ShowReceivedFriendRequestList. Launches the applet where the "Received Friend Requests" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowBlockedUserList = 6, ## /< ShowBlockedUserList. Launches the applet where the "Blocked-User List" menu is initially shown. Returning from this menu will exit the applet. + FriendsLaArgType_ShowMyProfile = 7, ## /< ShowMyProfile. Launches the applet with the "Profile" menu initially selected. ShowMyProfileForHomeMenu is identical to this except for playStartupSound=true. + FriendsLaArgType_StartFriendInvitation = 8, ## /< [9.0.0+] StartFriendInvitation. Launches the applet for sending online-play invites to friends, where the friends are selected via the UI. + FriendsLaArgType_StartSendingFriendInvitation = 9, ## /< [9.0.0+] StartSendingFriendInvitation. + FriendsLaArgType_ShowReceivedInvitationDetail = 10 ## /< [9.0.0+] ShowReceivedInvitationDetail. + + +## / Header for the arg struct. + +type + FriendsLaArgHeader* {.bycopy.} = object + `type`*: U32 ## /< \ref FriendsLaArgType + pad*: U32 ## /< Padding. + uid*: AccountUid ## /< \ref AccountUid + + +## / Common data for the arg struct, for the pre-9.0.0 types. +## / This is only set for +## ::FriendsLaArgType_ShowUserDetailInfo/::FriendsLaArgType_StartSendingFriendRequest, for everything else this is cleared. + +type + FriendsLaArgCommonData* {.bycopy.} = object + id*: AccountNetworkServiceAccountId ## /< \ref AccountNetworkServiceAccountId for the other account. + first_inAppScreenName*: FriendsInAppScreenName ## /< First InAppScreenName. + second_inAppScreenName*: FriendsInAppScreenName ## /< Second InAppScreenName. + + +## / Arg struct pushed for the applet input storage, for pre-9.0.0. + +type + FriendsLaArgV1* {.bycopy.} = object + hdr*: FriendsLaArgHeader ## /< \ref FriendsLaArgHeader + data*: FriendsLaArgCommonData ## /< \ref FriendsLaArgCommonData + + +## / Arg struct pushed for the applet input storage, for [9.0.0+]. + +type + INNER_C_STRUCT_friends_la_79* {.bycopy.} = object + id_count*: S32 ## /< \ref AccountNetworkServiceAccountId count, must be 1-15. + pad*: U32 ## /< Padding. + userdata_size*: U64 ## /< User-data size, must be <=0x400. + userdata*: array[0x400, U8] ## /< Arbitrary user-data, see above size. + desc*: FriendsFriendInvitationGameModeDescription ## /< \ref FriendsFriendInvitationGameModeDescription + + INNER_C_STRUCT_friends_la_80* {.bycopy.} = object + id_count*: S32 ## /< \ref AccountNetworkServiceAccountId count, must be 1-15. + pad*: U32 ## /< Padding. + id_list*: array[16, AccountNetworkServiceAccountId] ## /< \ref AccountNetworkServiceAccountId list, see above count. + userdata_size*: U64 ## /< User-data size, must be <=0x400. + userdata*: array[0x400, U8] ## /< Arbitrary user-data, see above size. + desc*: FriendsFriendInvitationGameModeDescription ## /< \ref FriendsFriendInvitationGameModeDescription + + INNER_C_STRUCT_friends_la_81* {.bycopy.} = object + invitation_id*: FriendsFriendInvitationId ## /< \ref FriendsFriendInvitationId + invitation_group_id*: FriendsFriendInvitationGroupId ## /< \ref FriendsFriendInvitationGroupId + + INNER_C_UNION_friends_la_79* {.bycopy, union.} = object + raw*: array[0x1090, U8] ## /< Raw data. + common*: FriendsLaArgCommonData ## /< \ref FriendsLaArgCommonData + start_friend_invitation*: INNER_C_STRUCT_friends_la_79 ## /< Data for ::FriendsLaArgType_StartFriendInvitation. + start_sending_friend_invitation*: INNER_C_STRUCT_friends_la_80 ## /< Data for ::FriendsLaArgType_StartSendingFriendInvitation. + show_received_invitation_detail*: INNER_C_STRUCT_friends_la_81 ## /< Data for ::FriendsLaArgType_ShowReceivedInvitationDetail. + + FriendsLaArg* {.bycopy.} = object + hdr*: FriendsLaArgHeader ## /< \ref FriendsLaArgHeader + data*: INNER_C_UNION_friends_la_79 ## /< Data for each \ref FriendsLaArgType. + +proc friendsLaShowFriendList*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowFriendList".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowFriendList, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaShowUserDetailInfo*(uid: AccountUid; + id: AccountNetworkServiceAccountId; + first_inAppScreenName: ptr FriendsInAppScreenName; second_inAppScreenName: ptr FriendsInAppScreenName): Result {. + cdecl, importc: "friendsLaShowUserDetailInfo".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowUserDetailInfo, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## @param[in] id \ref AccountNetworkServiceAccountId for the user to show UserDetailInfo for. +## @param[in] first_inAppScreenName First \ref FriendsInAppScreenName. +## @param[in] second_inAppScreenName Second \ref FriendsInAppScreenName. +## + +proc friendsLaStartSendingFriendRequest*(uid: AccountUid; + id: AccountNetworkServiceAccountId; + first_inAppScreenName: ptr FriendsInAppScreenName; second_inAppScreenName: ptr FriendsInAppScreenName): Result {. + cdecl, importc: "friendsLaStartSendingFriendRequest".} +## * +## @brief Launches the applet with ::FriendsLaArgType_StartSendingFriendRequest, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. +## @param[in] uid \ref AccountUid +## @param[in] id \ref AccountNetworkServiceAccountId to send the friend request to. +## @param[in] first_inAppScreenName First \ref FriendsInAppScreenName. +## @param[in] second_inAppScreenName Second \ref FriendsInAppScreenName. +## + +proc friendsLaShowMethodsOfSendingFriendRequest*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowMethodsOfSendingFriendRequest".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowMethodsOfSendingFriendRequest, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaStartFacedFriendRequest*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaStartFacedFriendRequest".} +## * +## @brief Launches the applet with ::FriendsLaArgType_StartFacedFriendRequest, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaShowReceivedFriendRequestList*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowReceivedFriendRequestList".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowReceivedFriendRequestList, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaShowBlockedUserList*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowBlockedUserList".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowBlockedUserList, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaShowMyProfile*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowMyProfile".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowMyProfile, the specified input, and playStartupSound=false. +## @param[in] uid \ref AccountUid +## + +proc friendsLaShowMyProfileForHomeMenu*(uid: AccountUid): Result {.cdecl, + importc: "friendsLaShowMyProfileForHomeMenu".} +## * +## @brief Same as \ref friendsLaShowMyProfile except with playStartupSound=true. +## @param[in] uid \ref AccountUid +## + +proc friendsLaStartFriendInvitation*(uid: AccountUid; id_count: S32; desc: ptr FriendsFriendInvitationGameModeDescription; + userdata: pointer; userdata_size: U64): Result {. + cdecl, importc: "friendsLaStartFriendInvitation".} +## * +## @brief Launches the applet with ::FriendsLaArgType_StartFriendInvitation, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. +## @note Only available on [9.0.0+]. +## @param[in] uid \ref AccountUid +## @param[in] id_count \ref AccountNetworkServiceAccountId count, must be 1-15. Number of friends to invite. +## @param[in] desc \ref FriendsFriendInvitationGameModeDescription +## @param[in] userdata Arbitrary user-data. Can be NULL. +## @param[in] userdata_size User-data size, must be <=0x400. Can be 0 if userdata is NULL. +## + +proc friendsLaStartSendingFriendInvitation*(uid: AccountUid; + id_list: ptr AccountNetworkServiceAccountId; id_count: S32; + desc: ptr FriendsFriendInvitationGameModeDescription; userdata: pointer; + userdata_size: U64): Result {.cdecl, + importc: "friendsLaStartSendingFriendInvitation".} +## * +## @brief Launches the applet with ::FriendsLaArgType_StartSendingFriendInvitation, the specified input, and playStartupSound=false. On success, this will load the output Result from the output storage. +## @note Only available on [9.0.0+]. +## @param[in] uid \ref AccountUid +## @param[in] id_list \ref AccountNetworkServiceAccountId list. +## @param[in] id_count Size of the id_list array in entries, must be 1-15. Number of friends to invite. +## @param[in] desc \ref FriendsFriendInvitationGameModeDescription +## @param[in] userdata Arbitrary user-data. Can be NULL. +## @param[in] userdata_size User-data size, must be <=0x400. Can be 0 if userdata is NULL. +## + +proc friendsLaShowReceivedInvitationDetail*(uid: AccountUid; + invitation_id: FriendsFriendInvitationId; + invitation_group_id: FriendsFriendInvitationGroupId): Result {.cdecl, + importc: "friendsLaShowReceivedInvitationDetail".} +## * +## @brief Launches the applet with ::FriendsLaArgType_ShowReceivedInvitationDetail, the specified input, and playStartupSound=false. +## @note Only available on [9.0.0+]. +## @param[in] uid \ref AccountUid +## @param[in] invitation_id \ref FriendsFriendInvitationId +## @param[in] invitation_group_id \ref FriendsFriendInvitationGroupId +## + diff --git a/src/libnx/wrapper/switch/applets/hid_la.h b/src/libnx/wrapper/switch/applets/hid_la.h new file mode 100644 index 0000000..4e0a982 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/hid_la.h @@ -0,0 +1,175 @@ +/** + * @file hid_la.h + * @brief Wrapper for using the controller LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/hid.h" + +/// Mode values for HidLaControllerSupportArgPrivate::mode. +typedef enum { + HidLaControllerSupportMode_ShowControllerSupport = 0, ///< ShowControllerSupport + HidLaControllerSupportMode_ShowControllerStrapGuide = 1, ///< [3.0.0+] ShowControllerStrapGuide + HidLaControllerSupportMode_ShowControllerFirmwareUpdate = 2, ///< [3.0.0+] ShowControllerFirmwareUpdate + HidLaControllerSupportMode_ShowControllerKeyRemappingForSystem = 4, ///< [11.0.0+] ShowControllerKeyRemappingForSystem +} HidLaControllerSupportMode; + +/// ControllerSupportCaller +typedef enum { + HidLaControllerSupportCaller_Application = 0, ///< Application, this is the default. + HidLaControllerSupportCaller_System = 1, ///< System. Skips the firmware-update confirmation dialog. This has the same affect as using the controller-update option from qlaunch System Settings. +} HidLaControllerSupportCaller; + +/// ControllerSupportArgPrivate +typedef struct { + u32 private_size; ///< Size of this ControllerSupportArgPrivate struct. + u32 arg_size; ///< Size of the storage following this one (\ref HidLaControllerSupportArg or \ref HidLaControllerFirmwareUpdateArg). + u8 flag0; ///< Flag0 + u8 flag1; ///< Flag1 + u8 mode; ///< \ref HidLaControllerSupportMode + u8 controller_support_caller; ///< \ref HidLaControllerSupportCaller. Always zero except with \ref hidLaShowControllerFirmwareUpdateForSystem, which sets this to the input param. + u32 npad_style_set; ///< Output from \ref hidGetSupportedNpadStyleSet. With ShowControllerSupportForSystem on pre-3.0.0 this is value 0. + u32 npad_joy_hold_type; ///< Output from \ref hidGetNpadJoyHoldType. With ShowControllerSupportForSystem on pre-3.0.0 this is value 1. +} HidLaControllerSupportArgPrivate; + +/// Common header used by HidLaControllerSupportArg*. +/// max_supported_players is 4 on pre-8.0.0, 8 on [8.0.0+]. player_count_min and player_count_max are overriden with value 4 when larger than value 4, during conversion handling for \ref HidLaControllerSupportArg on pre-8.0.0. +typedef struct { + s8 player_count_min; ///< playerCountMin. Must be >=0 and <=max_supported_players. + s8 player_count_max; ///< playerCountMax. Must be >=1 and <=max_supported_players. + u8 enable_take_over_connection; ///< enableTakeOverConnection, non-zero to enable. Disconnects the controllers when not enabled. + u8 enable_left_justify; ///< enableLeftJustify, non-zero to enable. + u8 enable_permit_joy_dual; ///< enablePermitJoyDual, non-zero to enable. + u8 enable_single_mode; ///< enableSingleMode, non-zero to enable. Enables using a single player in handheld-mode, dual-mode, or single-mode (player_count_* are overridden). Using handheld-mode is not allowed if this is not enabled. + u8 enable_identification_color; ///< When non-zero enables using identification_color. +} HidLaControllerSupportArgHeader; + +/// Identification color used by HidLaControllerSupportArg*. When HidLaControllerSupportArgHeader::enable_identification_color is set this controls the color of the UI player box outline. +typedef struct { + u8 r; ///< Red color component. + u8 g; ///< Green color component. + u8 b; ///< Blue color component. + u8 a; ///< Alpha color component. +} HidLaControllerSupportArgColor; + +/// ControllerSupportArg for [1.0.0+]. +typedef struct { + HidLaControllerSupportArgHeader hdr; ///< \ref HidLaControllerSupportArgHeader + HidLaControllerSupportArgColor identification_color[4]; ///< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color. + u8 enable_explain_text; ///< Enables using the ExplainText data when non-zero. + char explain_text[4][0x81]; ///< ExplainText for each player, NUL-terminated UTF-8 strings. +} HidLaControllerSupportArgV3; + +/// ControllerSupportArg for [8.0.0+], converted to \ref HidLaControllerSupportArgV3 on pre-8.0.0. +typedef struct { + HidLaControllerSupportArgHeader hdr; ///< \ref HidLaControllerSupportArgHeader + HidLaControllerSupportArgColor identification_color[8]; ///< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color. + u8 enable_explain_text; ///< Enables using the ExplainText data when non-zero. + char explain_text[8][0x81]; ///< ExplainText for each player, NUL-terminated UTF-8 strings. +} HidLaControllerSupportArg; + +/// ControllerFirmwareUpdateArg +typedef struct { + u8 enable_force_update; ///< enableForceUpdate, non-zero to enable. Default is 0. Forces a firmware update when enabled, without an UI option to skip it. + u8 pad[3]; ///< Padding. +} HidLaControllerFirmwareUpdateArg; + +/// ControllerKeyRemappingArg +typedef struct { + u64 unk_x0; ///< Unknown + u32 unk_x8; ///< Unknown + u8 pad[0x4]; ///< Padding +} HidLaControllerKeyRemappingArg; + +/// ControllerSupportResultInfo. First 8-bytes from the applet output storage. +typedef struct { + s8 player_count; ///< playerCount. + u8 pad[3]; ///< Padding. + u32 selected_id; ///< \ref HidNpadIdType, selectedId. +} HidLaControllerSupportResultInfo; + +/// Struct for the applet output storage. +typedef struct { + HidLaControllerSupportResultInfo info; ///< \ref HidLaControllerSupportResultInfo + u32 res; ///< Output res value. +} HidLaControllerSupportResultInfoInternal; + +/** + * @brief Initializes a \ref HidLaControllerSupportArg with the defaults. + * @note This clears the arg, then does: HidLaControllerSupportArgHeader::player_count_min = 0, HidLaControllerSupportArgHeader::player_count_max = 4, HidLaControllerSupportArgHeader::enable_take_over_connection = 1, HidLaControllerSupportArgHeader::enable_left_justify = 1, and HidLaControllerSupportArgHeader::enable_permit_joy_dual = 1. + * @note If preferred, you can also memset \ref HidLaControllerSupportArg manually and initialize it yourself. + * @param[out] arg \ref HidLaControllerSupportArg + */ +void hidLaCreateControllerSupportArg(HidLaControllerSupportArg *arg); + +/** + * @brief Initializes a \ref HidLaControllerFirmwareUpdateArg with the defaults. + * @note This just uses memset() with the arg. + * @param[out] arg \ref HidLaControllerFirmwareUpdateArg + */ +void hidLaCreateControllerFirmwareUpdateArg(HidLaControllerFirmwareUpdateArg *arg); + +/** + * @brief Initializes a \ref HidLaControllerKeyRemappingArg with the defaults. + * @note This just uses memset() with the arg. + * @param[out] arg \ref HidLaControllerKeyRemappingArg + */ +void hidLaCreateControllerKeyRemappingArg(HidLaControllerKeyRemappingArg *arg); + +/** + * @brief Sets the ExplainText for the specified player and \ref HidLaControllerSupportArg. + * @note This string is displayed in the UI box for the player. + * @note HidLaControllerSupportArg::enable_explain_text must be set, otherwise this ExplainText is ignored. + * @param arg \ref HidLaControllerSupportArg + * @param[in] str Input ExplainText UTF-8 string, max length is 0x80 excluding NUL-terminator. + + @oaram[in] id Player controller, must be <8. + */ +Result hidLaSetExplainText(HidLaControllerSupportArg *arg, const char *str, HidNpadIdType id); + +/** + * @brief Launches the applet for ControllerSupport. + * @note This seems to only display the applet UI when doing so is actually needed? This doesn't apply to \ref hidLaShowControllerSupportForSystem. + * @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL. + * @param[in] arg \ref HidLaControllerSupportArg + */ +Result hidLaShowControllerSupport(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg); + +/** + * @brief Launches the applet for ControllerStrapGuide. + * @note Only available on [3.0.0+]. + */ +Result hidLaShowControllerStrapGuide(void); + +/** + * @brief Launches the applet for ControllerFirmwareUpdate. + * @note Only available on [3.0.0+]. + * @param[in] arg \ref HidLaControllerFirmwareUpdateArg + */ +Result hidLaShowControllerFirmwareUpdate(const HidLaControllerFirmwareUpdateArg *arg); + +/** + * @brief This is the system version of \ref hidLaShowControllerSupport. + * @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL. + * @param[in] arg \ref HidLaControllerSupportArg + * @param[in] flag Input flag. When true, the applet displays the menu as if launched by qlaunch. + */ +Result hidLaShowControllerSupportForSystem(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, bool flag); + +/** + * @brief This is the system version of \ref hidLaShowControllerFirmwareUpdate. + * @note Only available on [3.0.0+]. + * @param[in] arg \ref HidLaControllerFirmwareUpdateArg + * @param[in] caller \ref HidLaControllerSupportCaller + */ +Result hidLaShowControllerFirmwareUpdateForSystem(const HidLaControllerFirmwareUpdateArg *arg, HidLaControllerSupportCaller caller); + +/** + * @brief Launches the applet for ControllerKeyRemappingForSystem. + * @note Only available on [11.0.0+]. + * @param[in] arg \ref HidLaControllerKeyRemappingArg + * @param[in] caller \ref HidLaControllerSupportCaller + */ +Result hidLaShowControllerKeyRemappingForSystem(const HidLaControllerKeyRemappingArg *arg, HidLaControllerSupportCaller caller); + diff --git a/src/libnx/wrapper/switch/applets/hid_la.nim b/src/libnx/wrapper/switch/applets/hid_la.nim new file mode 100644 index 0000000..e3985b4 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/hid_la.nim @@ -0,0 +1,214 @@ +## * +## @file hid_la.h +## @brief Wrapper for using the controller LibraryApplet. +## @author yellowS8 +## @copyright libnx Authors +## + +import + ../types, ../services/hid + +## / Mode values for HidLaControllerSupportArgPrivate::mode. + +type + HidLaControllerSupportMode* = enum + HidLaControllerSupportMode_ShowControllerSupport = 0, ## /< ShowControllerSupport + HidLaControllerSupportMode_ShowControllerStrapGuide = 1, ## /< [3.0.0+] ShowControllerStrapGuide + HidLaControllerSupportMode_ShowControllerFirmwareUpdate = 2, ## /< [3.0.0+] ShowControllerFirmwareUpdate + HidLaControllerSupportMode_ShowControllerKeyRemappingForSystem = 4 ## /< [11.0.0+] ShowControllerKeyRemappingForSystem + + +## / ControllerSupportCaller + +type + HidLaControllerSupportCaller* = enum + HidLaControllerSupportCaller_Application = 0, ## /< Application, this is the default. + HidLaControllerSupportCaller_System = 1 ## /< System. Skips the firmware-update confirmation dialog. This has the same affect as using the controller-update option from qlaunch System Settings. + + +## / ControllerSupportArgPrivate + +type + HidLaControllerSupportArgPrivate* {.bycopy.} = object + private_size*: U32 ## /< Size of this ControllerSupportArgPrivate struct. + arg_size*: U32 ## /< Size of the storage following this one (\ref HidLaControllerSupportArg or \ref HidLaControllerFirmwareUpdateArg). + flag0*: U8 ## /< Flag0 + flag1*: U8 ## /< Flag1 + mode*: U8 ## /< \ref HidLaControllerSupportMode + controller_support_caller*: U8 ## /< \ref HidLaControllerSupportCaller. Always zero except with \ref hidLaShowControllerFirmwareUpdateForSystem, which sets this to the input param. + npad_style_set*: U32 ## /< Output from \ref hidGetSupportedNpadStyleSet. With ShowControllerSupportForSystem on pre-3.0.0 this is value 0. + npad_joy_hold_type*: U32 ## /< Output from \ref hidGetNpadJoyHoldType. With ShowControllerSupportForSystem on pre-3.0.0 this is value 1. + + +## / Common header used by HidLaControllerSupportArg*. +## / max_supported_players is 4 on pre-8.0.0, 8 on [8.0.0+]. player_count_min and player_count_max are overriden with value 4 when larger than value 4, during conversion handling for \ref HidLaControllerSupportArg on pre-8.0.0. + +type + HidLaControllerSupportArgHeader* {.bycopy.} = object + player_count_min*: S8 ## /< playerCountMin. Must be >=0 and <=max_supported_players. + player_count_max*: S8 ## /< playerCountMax. Must be >=1 and <=max_supported_players. + enable_take_over_connection*: U8 ## /< enableTakeOverConnection, non-zero to enable. Disconnects the controllers when not enabled. + enable_left_justify*: U8 ## /< enableLeftJustify, non-zero to enable. + enable_permit_joy_dual*: U8 ## /< enablePermitJoyDual, non-zero to enable. + enable_single_mode*: U8 ## /< enableSingleMode, non-zero to enable. Enables using a single player in handheld-mode, dual-mode, or single-mode (player_count_* are overridden). Using handheld-mode is not allowed if this is not enabled. + enable_identification_color*: U8 ## /< When non-zero enables using identification_color. + + +## / Identification color used by HidLaControllerSupportArg*. When HidLaControllerSupportArgHeader::enable_identification_color is set this controls the color of the UI player box outline. + +type + HidLaControllerSupportArgColor* {.bycopy.} = object + r*: U8 ## /< Red color component. + g*: U8 ## /< Green color component. + b*: U8 ## /< Blue color component. + a*: U8 ## /< Alpha color component. + + +## / ControllerSupportArg for [1.0.0+]. + +type + HidLaControllerSupportArgV3* {.bycopy.} = object + hdr*: HidLaControllerSupportArgHeader ## /< \ref HidLaControllerSupportArgHeader + identification_color*: array[4, HidLaControllerSupportArgColor] ## /< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color. + enable_explain_text*: U8 ## /< Enables using the ExplainText data when non-zero. + explain_text*: array[4, array[0x81, char]] ## /< ExplainText for each player, NUL-terminated UTF-8 strings. + + +## / ControllerSupportArg for [8.0.0+], converted to \ref HidLaControllerSupportArgV3 on pre-8.0.0. + +type + HidLaControllerSupportArg* {.bycopy.} = object + hdr*: HidLaControllerSupportArgHeader ## /< \ref HidLaControllerSupportArgHeader + identification_color*: array[8, HidLaControllerSupportArgColor] ## /< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color. + enable_explain_text*: U8 ## /< Enables using the ExplainText data when non-zero. + explain_text*: array[8, array[0x81, char]] ## /< ExplainText for each player, NUL-terminated UTF-8 strings. + + +## / ControllerFirmwareUpdateArg + +type + HidLaControllerFirmwareUpdateArg* {.bycopy.} = object + enable_force_update*: U8 ## /< enableForceUpdate, non-zero to enable. Default is 0. Forces a firmware update when enabled, without an UI option to skip it. + pad*: array[3, U8] ## /< Padding. + + +## / ControllerKeyRemappingArg + +type + HidLaControllerKeyRemappingArg* {.bycopy.} = object + unk_x0*: U64 ## /< Unknown + unk_x8*: U32 ## /< Unknown + pad*: array[0x4, U8] ## /< Padding + + +## / ControllerSupportResultInfo. First 8-bytes from the applet output storage. + +type + HidLaControllerSupportResultInfo* {.bycopy.} = object + player_count*: S8 ## /< playerCount. + pad*: array[3, U8] ## /< Padding. + selected_id*: U32 ## /< \ref HidNpadIdType, selectedId. + + +## / Struct for the applet output storage. + +type + HidLaControllerSupportResultInfoInternal* {.bycopy.} = object + info*: HidLaControllerSupportResultInfo ## /< \ref HidLaControllerSupportResultInfo + res*: U32 ## /< Output res value. + +proc hidLaCreateControllerSupportArg*(arg: ptr HidLaControllerSupportArg) {.cdecl, + importc: "hidLaCreateControllerSupportArg".} +## * +## @brief Initializes a \ref HidLaControllerSupportArg with the defaults. +## @note This clears the arg, then does: HidLaControllerSupportArgHeader::player_count_min = 0, HidLaControllerSupportArgHeader::player_count_max = 4, HidLaControllerSupportArgHeader::enable_take_over_connection = 1, HidLaControllerSupportArgHeader::enable_left_justify = 1, and HidLaControllerSupportArgHeader::enable_permit_joy_dual = 1. +## @note If preferred, you can also memset \ref HidLaControllerSupportArg manually and initialize it yourself. +## @param[out] arg \ref HidLaControllerSupportArg +## + +proc hidLaCreateControllerFirmwareUpdateArg*( + arg: ptr HidLaControllerFirmwareUpdateArg) {.cdecl, + importc: "hidLaCreateControllerFirmwareUpdateArg".} +## * +## @brief Initializes a \ref HidLaControllerFirmwareUpdateArg with the defaults. +## @note This just uses memset() with the arg. +## @param[out] arg \ref HidLaControllerFirmwareUpdateArg +## + +proc hidLaCreateControllerKeyRemappingArg*( + arg: ptr HidLaControllerKeyRemappingArg) {.cdecl, + importc: "hidLaCreateControllerKeyRemappingArg".} +## * +## @brief Initializes a \ref HidLaControllerKeyRemappingArg with the defaults. +## @note This just uses memset() with the arg. +## @param[out] arg \ref HidLaControllerKeyRemappingArg +## + +proc hidLaSetExplainText*(arg: ptr HidLaControllerSupportArg; str: cstring; + id: HidNpadIdType): Result {.cdecl, + importc: "hidLaSetExplainText".} +## * +## @brief Sets the ExplainText for the specified player and \ref HidLaControllerSupportArg. +## @note This string is displayed in the UI box for the player. +## @note HidLaControllerSupportArg::enable_explain_text must be set, otherwise this ExplainText is ignored. +## @param arg \ref HidLaControllerSupportArg +## @param[in] str Input ExplainText UTF-8 string, max length is 0x80 excluding NUL-terminator. +## + @oaram[in] id Player controller, must be <8. +## + +proc hidLaShowControllerSupport*(result_info: ptr HidLaControllerSupportResultInfo; + arg: ptr HidLaControllerSupportArg): Result {.cdecl, + importc: "hidLaShowControllerSupport".} +## * +## @brief Launches the applet for ControllerSupport. +## @note This seems to only display the applet UI when doing so is actually needed? This doesn't apply to \ref hidLaShowControllerSupportForSystem. +## @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL. +## @param[in] arg \ref HidLaControllerSupportArg +## + +proc hidLaShowControllerStrapGuide*(): Result {.cdecl, + importc: "hidLaShowControllerStrapGuide".} +## * +## @brief Launches the applet for ControllerStrapGuide. +## @note Only available on [3.0.0+]. +## + +proc hidLaShowControllerFirmwareUpdate*(arg: ptr HidLaControllerFirmwareUpdateArg): Result {. + cdecl, importc: "hidLaShowControllerFirmwareUpdate".} +## * +## @brief Launches the applet for ControllerFirmwareUpdate. +## @note Only available on [3.0.0+]. +## @param[in] arg \ref HidLaControllerFirmwareUpdateArg +## + +proc hidLaShowControllerSupportForSystem*( + result_info: ptr HidLaControllerSupportResultInfo; + arg: ptr HidLaControllerSupportArg; flag: bool): Result {.cdecl, + importc: "hidLaShowControllerSupportForSystem".} +## * +## @brief This is the system version of \ref hidLaShowControllerSupport. +## @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL. +## @param[in] arg \ref HidLaControllerSupportArg +## @param[in] flag Input flag. When true, the applet displays the menu as if launched by qlaunch. +## + +proc hidLaShowControllerFirmwareUpdateForSystem*( + arg: ptr HidLaControllerFirmwareUpdateArg; caller: HidLaControllerSupportCaller): Result {. + cdecl, importc: "hidLaShowControllerFirmwareUpdateForSystem".} +## * +## @brief This is the system version of \ref hidLaShowControllerFirmwareUpdate. +## @note Only available on [3.0.0+]. +## @param[in] arg \ref HidLaControllerFirmwareUpdateArg +## @param[in] caller \ref HidLaControllerSupportCaller +## + +proc hidLaShowControllerKeyRemappingForSystem*( + arg: ptr HidLaControllerKeyRemappingArg; caller: HidLaControllerSupportCaller): Result {. + cdecl, importc: "hidLaShowControllerKeyRemappingForSystem".} +## * +## @brief Launches the applet for ControllerKeyRemappingForSystem. +## @note Only available on [11.0.0+]. +## @param[in] arg \ref HidLaControllerKeyRemappingArg +## @param[in] caller \ref HidLaControllerSupportCaller +## + diff --git a/src/libnx/wrapper/switch/applets/libapplet.h b/src/libnx/wrapper/switch/applets/libapplet.h new file mode 100644 index 0000000..0935e1a --- /dev/null +++ b/src/libnx/wrapper/switch/applets/libapplet.h @@ -0,0 +1,136 @@ +/** + * @file libapplet.h + * @brief LibraryApplet wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/applet.h" +#include "../services/acc.h" + +/// CommonArguments +typedef struct { + u32 CommonArgs_version; ///< \ref libappletArgsCreate sets this to 1, and \ref libappletArgsPop requires value 1. v0 is not supported. + u32 CommonArgs_size; ///< Size of this struct. + + u32 LaVersion; ///< LibraryApplet API version. + s32 ExpectedThemeColor; ///< Set to the output from \ref appletGetThemeColorType by \ref libappletArgsCreate. + u8 PlayStartupSound; ///< bool flag, default is false. + u8 pad[7]; ///< Padding. + u64 tick; ///< System tick. Set to the output from \ref armGetSystemTick during \ref libappletArgsPush. +} LibAppletArgs; + +/** + * @brief Creates a LibAppletArgs struct. + * @param a LibAppletArgs struct. + * @param version LaVersion for \ref LibAppletArgs. + */ +void libappletArgsCreate(LibAppletArgs* a, u32 version); + +/** + * @brief Sets the PlayStartupSound field in \ref LibAppletArgs. + * @param a LibAppletArgs struct. + * @param flag Value for \ref LibAppletArgs PlayStartupSound. + */ +void libappletArgsSetPlayStartupSound(LibAppletArgs* a, bool flag); + +/** + * @brief Creates an AppletStorage with the specified size and writes the buffer contents to that storage at offset 0. + * @param[out] s Storage object. + * @param buffer Input buffer. + * @param size Size to write. + */ +Result libappletCreateWriteStorage(AppletStorage* s, const void* buffer, size_t size); + +/** + * @brief Reads data from offset 0 from the specified storage into the buffer. If the storage-size is smaller than the size param, the storage-size is used instead. + * @param s Storage object. + * @param buffer Output buffer. + * @param size Size to read. + * @param transfer_size Optional output size field for the actual size used for the read, can be NULL. + */ +Result libappletReadStorage(AppletStorage* s, void* buffer, size_t size, size_t *transfer_size); + +/** + * @brief Sets the tick field in LibAppletArgs, then creates a storage with it which is pushed to the AppletHolder via \ref appletHolderPushInData. + * @param a LibAppletArgs struct. + * @param h AppletHolder object. + */ +Result libappletArgsPush(LibAppletArgs* a, AppletHolder *h); + +/** + * @brief Uses \ref appletPopInData and reads it to the specified LibAppletArgs. The LibAppletArgs is validated, an error is thrown when invalid. + * @param[out] a LibAppletArgs struct. + */ +Result libappletArgsPop(LibAppletArgs* a); + +/** + * @brief Creates a storage using the input buffer which is pushed to the AppletHolder via \ref appletHolderPushInData. + * @param h AppletHolder object. + * @param buffer Input data buffer. + * @param size Input data size. + */ +Result libappletPushInData(AppletHolder *h, const void* buffer, size_t size); + +/** + * @brief Pops a storage via \ref appletHolderPopOutData, uses \ref libappletReadStorage, then closes the storage. + * @param h AppletHolder object. + * @param buffer Output buffer. + * @param size Size to read. + * @param transfer_size Optional output size field for the actual size used for the read, can be NULL. + */ +Result libappletPopOutData(AppletHolder *h, void* buffer, size_t size, size_t *transfer_size); + +/** + * @brief Sets whether \ref libappletStart uses \ref appletHolderJump. + * @param flag Flag. Value true should not be used unless running as AppletType_LibraryApplet. + */ +void libappletSetJumpFlag(bool flag); + +/** + * @brief If the flag from \ref libappletSetJumpFlag is set, this just uses \ref appletHolderJump. Otherwise, starts the applet and waits for it to finish, then checks the \ref LibAppletExitReason. + * @note Uses \ref appletHolderStart and \ref appletHolderJoin. + * @param h AppletHolder object. + */ +Result libappletStart(AppletHolder *h); + +/** + * @brief Creates a LibraryApplet with the specified input storage data, uses \ref libappletStart, and reads the output storage reply data via \ref libappletPopOutData. + * @param id \ref AppletId + * @param commonargs \ref LibAppletArgs struct. + * @param arg Input storage data buffer. Optional, can be NULL. + * @param arg_size Size of the arg buffer. + * @param reply Output storage data buffer. Optional, can be NULL. + * @param reply_size Size to read for the reply buffer. + * @param out_reply_size Actual read reply data size, see \ref libappletPopOutData. + */ +Result libappletLaunch(AppletId id, LibAppletArgs *commonargs, const void* arg, size_t arg_size, void* reply, size_t reply_size, size_t *out_reply_size); + +/// Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +/// Returns to the main Home Menu, equivalent to pressing the HOME button. +Result libappletRequestHomeMenu(void); + +/// Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +/// Equivalent to entering "System Update" under System Settings. When leaving this, it returns to the main Home Menu. +Result libappletRequestJumpToSystemUpdate(void); + +/** + * @brief Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. + * @note Only available on [11.0.0+]. + * @param[in] application_id ApplicationId + * @param[in] uid \ref AccountUid + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + * @param[in] sender LaunchApplicationRequestSender + */ +Result libappletRequestToLaunchApplication(u64 application_id, AccountUid uid, const void* buffer, size_t size, u32 sender); + +/** + * @brief Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. + * @note Only available on [11.0.0+]. + * @param[in] uid \ref AccountUid + * @param[in] application_id Optional ApplicationId, can be 0. + */ +Result libappletRequestJumpToStory(AccountUid uid, u64 application_id); + diff --git a/src/libnx/wrapper/switch/applets/libapplet.nim b/src/libnx/wrapper/switch/applets/libapplet.nim new file mode 100644 index 0000000..b9c08a7 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/libapplet.nim @@ -0,0 +1,153 @@ +## * +## @file libapplet.h +## @brief LibraryApplet wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/applet, ../services/acc + +## / CommonArguments + +type + LibAppletArgs* {.bycopy.} = object + CommonArgs_version*: U32 ## /< \ref libappletArgsCreate sets this to 1, and \ref libappletArgsPop requires value 1. v0 is not supported. + CommonArgs_size*: U32 ## /< Size of this struct. + LaVersion*: U32 ## /< LibraryApplet API version. + ExpectedThemeColor*: S32 ## /< Set to the output from \ref appletGetThemeColorType by \ref libappletArgsCreate. + PlayStartupSound*: U8 ## /< bool flag, default is false. + pad*: array[7, U8] ## /< Padding. + tick*: U64 ## /< System tick. Set to the output from \ref armGetSystemTick during \ref libappletArgsPush. + +proc libappletArgsCreate*(a: ptr LibAppletArgs; version: U32) {.cdecl, + importc: "libappletArgsCreate".} +## * +## @brief Creates a LibAppletArgs struct. +## @param a LibAppletArgs struct. +## @param version LaVersion for \ref LibAppletArgs. +## + +proc libappletArgsSetPlayStartupSound*(a: ptr LibAppletArgs; flag: bool) {.cdecl, + importc: "libappletArgsSetPlayStartupSound".} +## * +## @brief Sets the PlayStartupSound field in \ref LibAppletArgs. +## @param a LibAppletArgs struct. +## @param flag Value for \ref LibAppletArgs PlayStartupSound. +## + +proc libappletCreateWriteStorage*(s: ptr AppletStorage; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "libappletCreateWriteStorage".} +## * +## @brief Creates an AppletStorage with the specified size and writes the buffer contents to that storage at offset 0. +## @param[out] s Storage object. +## @param buffer Input buffer. +## @param size Size to write. +## + +proc libappletReadStorage*(s: ptr AppletStorage; buffer: pointer; size: csize_t; + transfer_size: ptr csize_t): Result {.cdecl, + importc: "libappletReadStorage".} +## * +## @brief Reads data from offset 0 from the specified storage into the buffer. If the storage-size is smaller than the size param, the storage-size is used instead. +## @param s Storage object. +## @param buffer Output buffer. +## @param size Size to read. +## @param transfer_size Optional output size field for the actual size used for the read, can be NULL. +## + +proc libappletArgsPush*(a: ptr LibAppletArgs; h: ptr AppletHolder): Result {.cdecl, + importc: "libappletArgsPush".} +## * +## @brief Sets the tick field in LibAppletArgs, then creates a storage with it which is pushed to the AppletHolder via \ref appletHolderPushInData. +## @param a LibAppletArgs struct. +## @param h AppletHolder object. +## + +proc libappletArgsPop*(a: ptr LibAppletArgs): Result {.cdecl, + importc: "libappletArgsPop".} +## * +## @brief Uses \ref appletPopInData and reads it to the specified LibAppletArgs. The LibAppletArgs is validated, an error is thrown when invalid. +## @param[out] a LibAppletArgs struct. +## + +proc libappletPushInData*(h: ptr AppletHolder; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "libappletPushInData".} +## * +## @brief Creates a storage using the input buffer which is pushed to the AppletHolder via \ref appletHolderPushInData. +## @param h AppletHolder object. +## @param buffer Input data buffer. +## @param size Input data size. +## + +proc libappletPopOutData*(h: ptr AppletHolder; buffer: pointer; size: csize_t; + transfer_size: ptr csize_t): Result {.cdecl, + importc: "libappletPopOutData".} +## * +## @brief Pops a storage via \ref appletHolderPopOutData, uses \ref libappletReadStorage, then closes the storage. +## @param h AppletHolder object. +## @param buffer Output buffer. +## @param size Size to read. +## @param transfer_size Optional output size field for the actual size used for the read, can be NULL. +## + +proc libappletSetJumpFlag*(flag: bool) {.cdecl, importc: "libappletSetJumpFlag".} +## * +## @brief Sets whether \ref libappletStart uses \ref appletHolderJump. +## @param flag Flag. Value true should not be used unless running as AppletType_LibraryApplet. +## + +proc libappletStart*(h: ptr AppletHolder): Result {.cdecl, importc: "libappletStart".} +## * +## @brief If the flag from \ref libappletSetJumpFlag is set, this just uses \ref appletHolderJump. Otherwise, starts the applet and waits for it to finish, then checks the \ref LibAppletExitReason. +## @note Uses \ref appletHolderStart and \ref appletHolderJoin. +## @param h AppletHolder object. +## + +proc libappletLaunch*(id: AppletId; commonargs: ptr LibAppletArgs; arg: pointer; + arg_size: csize_t; reply: pointer; reply_size: csize_t; + out_reply_size: ptr csize_t): Result {.cdecl, + importc: "libappletLaunch".} +## * +## @brief Creates a LibraryApplet with the specified input storage data, uses \ref libappletStart, and reads the output storage reply data via \ref libappletPopOutData. +## @param id \ref AppletId +## @param commonargs \ref LibAppletArgs struct. +## @param arg Input storage data buffer. Optional, can be NULL. +## @param arg_size Size of the arg buffer. +## @param reply Output storage data buffer. Optional, can be NULL. +## @param reply_size Size to read for the reply buffer. +## @param out_reply_size Actual read reply data size, see \ref libappletPopOutData. +## + +proc libappletRequestHomeMenu*(): Result {.cdecl, + importc: "libappletRequestHomeMenu".} +## / Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +## / Returns to the main Home Menu, equivalent to pressing the HOME button. + +proc libappletRequestJumpToSystemUpdate*(): Result {.cdecl, + importc: "libappletRequestJumpToSystemUpdate".} +## / Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +## / Equivalent to entering "System Update" under System Settings. When leaving this, it returns to the main Home Menu. + +proc libappletRequestToLaunchApplication*(application_id: U64; uid: AccountUid; + buffer: pointer; size: csize_t; sender: U32): Result {.cdecl, + importc: "libappletRequestToLaunchApplication".} +## * +## @brief Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +## @note Only available on [11.0.0+]. +## @param[in] application_id ApplicationId +## @param[in] uid \ref AccountUid +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## @param[in] sender LaunchApplicationRequestSender +## + +proc libappletRequestJumpToStory*(uid: AccountUid; application_id: U64): Result {. + cdecl, importc: "libappletRequestJumpToStory".} +## * +## @brief Wrapper for \ref appletPushToGeneralChannel, see appletPushToGeneralChannel regarding the requirements for using this. +## @note Only available on [11.0.0+]. +## @param[in] uid \ref AccountUid +## @param[in] application_id Optional ApplicationId, can be 0. +## + diff --git a/src/libnx/wrapper/switch/applets/mii_la.h b/src/libnx/wrapper/switch/applets/mii_la.h new file mode 100644 index 0000000..14f7b3a --- /dev/null +++ b/src/libnx/wrapper/switch/applets/mii_la.h @@ -0,0 +1,101 @@ +/** + * @file mii_la.h + * @brief Wrapper for using the MiiEdit LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/mii.h" + +/// AppletMode +typedef enum { + MiiLaAppletMode_ShowMiiEdit = 0, ///< ShowMiiEdit + MiiLaAppletMode_AppendMii = 1, ///< AppendMii + MiiLaAppletMode_AppendMiiImage = 2, ///< AppendMiiImage + MiiLaAppletMode_UpdateMiiImage = 3, ///< UpdateMiiImage + MiiLaAppletMode_CreateMii = 4, ///< [10.2.0+] CreateMii + MiiLaAppletMode_EditMii = 5, ///< [10.2.0+] EditMii +} MiiLaAppletMode; + +/// AppletInput +typedef struct { + s32 version; ///< Version + u32 mode; ///< \ref MiiLaAppletMode + s32 special_key_code; ///< \ref MiiSpecialKeyCode + union { + Uuid valid_uuid_array[8]; ///< ValidUuidArray. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_AppendMiiImage / ::NfpLaMiiLaAppletMode_UpdateMiiImage. + struct { + MiiCharInfo char_info; ///< \ref MiiCharInfo + u8 unused_x64[0x28]; ///< Unused + } char_info; + }; + Uuid used_uuid; ///< UsedUuid. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_UpdateMiiImage. + u8 unk_x9C[0x64]; ///< Unused +} MiiLaAppletInput; + +/// AppletOutput +typedef struct { + u32 res; ///< Result: 0 = Success, 1 = Cancel. + s32 index; ///< Index. Only set when Result is Success, where \ref MiiLaAppletMode isn't ::NfpLaMiiLaAppletMode_ShowMiiEdit. + u8 unk_x8[0x18]; ///< Unused +} MiiLaAppletOutput; + +/// AppletOutputForCharInfoEditing +typedef struct { + u32 res; ///< MiiLaAppletOutput::res + MiiCharInfo char_info; ///< \ref MiiCharInfo + u8 unused[0x24]; ///< Unused +} MiiLaAppletOutputForCharInfoEditing; + +/** + * @brief Launches the applet for ShowMiiEdit. + * @param[in] special_key_code \ref MiiSpecialKeyCode + */ +Result miiLaShowMiiEdit(MiiSpecialKeyCode special_key_code); + +/** + * @brief Launches the applet for AppendMii. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[out] index Output Index. + */ +Result miiLaAppendMii(MiiSpecialKeyCode special_key_code, s32 *index); + +/** + * @brief Launches the applet for AppendMiiImage. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[in] valid_uuid_array Input array of Uuid. + * @param[in] count Total entries for the valid_uuid_array. Must be 0-8. + * @param[out] index Output Index. + */ +Result miiLaAppendMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, s32 *index); + +/** + * @brief Launches the applet for UpdateMiiImage. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[in] valid_uuid_array Input array of Uuid. + * @param[in] count Total entries for the valid_uuid_array. Must be 0-8. + * @param[in] used_uuid UsedUuid + * @param[out] index Output Index. + */ +Result miiLaUpdateMiiImage(MiiSpecialKeyCode special_key_code, const Uuid *valid_uuid_array, s32 count, Uuid used_uuid, s32 *index); + +/** + * @brief Launches the applet for CreateMii. + * @note This creates a Mii and returns it, without saving it in the database. + * @note Only available on [10.2.0+]. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[out] out_char \ref MiiCharInfo + */ +Result miiLaCreateMii(MiiSpecialKeyCode special_key_code, MiiCharInfo *out_char); + +/** + * @brief Launches the applet for EditMii. + * @note This edits the specified Mii and returns it, without saving it in the database. + * @note Only available on [10.2.0+]. + * @param[in] special_key_code \ref MiiSpecialKeyCode + * @param[in] in_char \ref MiiCharInfo + * @param[out] out_char \ref MiiCharInfo + */ +Result miiLaEditMii(MiiSpecialKeyCode special_key_code, const MiiCharInfo *in_char, MiiCharInfo *out_char); + diff --git a/src/libnx/wrapper/switch/applets/mii_la.nim b/src/libnx/wrapper/switch/applets/mii_la.nim new file mode 100644 index 0000000..d29bc2e --- /dev/null +++ b/src/libnx/wrapper/switch/applets/mii_la.nim @@ -0,0 +1,119 @@ +## * +## @file mii_la.h +## @brief Wrapper for using the MiiEdit LibraryApplet. +## @author yellowS8 +## @copyright libnx Authors +## + +import + ../types, ../services/mii + +## / AppletMode + +type + MiiLaAppletMode* = enum + MiiLaAppletMode_ShowMiiEdit = 0, ## /< ShowMiiEdit + MiiLaAppletMode_AppendMii = 1, ## /< AppendMii + MiiLaAppletMode_AppendMiiImage = 2, ## /< AppendMiiImage + MiiLaAppletMode_UpdateMiiImage = 3, ## /< UpdateMiiImage + MiiLaAppletMode_CreateMii = 4, ## /< [10.2.0+] CreateMii + MiiLaAppletMode_EditMii = 5 ## /< [10.2.0+] EditMii + + +## / AppletInput + +type + INNER_C_STRUCT_mii_la_35* {.bycopy.} = object + char_info*: MiiCharInfo ## /< \ref MiiCharInfo + unused_x64*: array[0x28, U8] ## /< Unused + + INNER_C_UNION_mii_la_35* {.bycopy, union.} = object + valid_uuid_array*: array[8, Uuid] ## /< ValidUuidArray. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_AppendMiiImage / ::NfpLaMiiLaAppletMode_UpdateMiiImage. + char_info*: INNER_C_STRUCT_mii_la_35 + + MiiLaAppletInput* {.bycopy.} = object + version*: S32 ## /< Version + mode*: U32 ## /< \ref MiiLaAppletMode + special_key_code*: S32 ## /< \ref MiiSpecialKeyCode + ano_mii_la_35*: INNER_C_UNION_mii_la_35 + used_uuid*: Uuid ## /< UsedUuid. Only used with \ref MiiLaAppletMode ::NfpLaMiiLaAppletMode_UpdateMiiImage. + unk_x9C*: array[0x64, U8] ## /< Unused + + +## / AppletOutput + +type + MiiLaAppletOutput* {.bycopy.} = object + res*: U32 ## /< Result: 0 = Success, 1 = Cancel. + index*: S32 ## /< Index. Only set when Result is Success, where \ref MiiLaAppletMode isn't ::NfpLaMiiLaAppletMode_ShowMiiEdit. + unk_x8*: array[0x18, U8] ## /< Unused + + +## / AppletOutputForCharInfoEditing + +type + MiiLaAppletOutputForCharInfoEditing* {.bycopy.} = object + res*: U32 ## /< MiiLaAppletOutput::res + char_info*: MiiCharInfo ## /< \ref MiiCharInfo + unused*: array[0x24, U8] ## /< Unused + +proc miiLaShowMiiEdit*(special_key_code: MiiSpecialKeyCode): Result {.cdecl, + importc: "miiLaShowMiiEdit".} +## * +## @brief Launches the applet for ShowMiiEdit. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## + +proc miiLaAppendMii*(special_key_code: MiiSpecialKeyCode; index: ptr S32): Result {. + cdecl, importc: "miiLaAppendMii".} +## * +## @brief Launches the applet for AppendMii. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## @param[out] index Output Index. +## + +proc miiLaAppendMiiImage*(special_key_code: MiiSpecialKeyCode; + valid_uuid_array: ptr Uuid; count: S32; index: ptr S32): Result {. + cdecl, importc: "miiLaAppendMiiImage".} +## * +## @brief Launches the applet for AppendMiiImage. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## @param[in] valid_uuid_array Input array of Uuid. +## @param[in] count Total entries for the valid_uuid_array. Must be 0-8. +## @param[out] index Output Index. +## + +proc miiLaUpdateMiiImage*(special_key_code: MiiSpecialKeyCode; + valid_uuid_array: ptr Uuid; count: S32; used_uuid: Uuid; + index: ptr S32): Result {.cdecl, + importc: "miiLaUpdateMiiImage".} +## * +## @brief Launches the applet for UpdateMiiImage. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## @param[in] valid_uuid_array Input array of Uuid. +## @param[in] count Total entries for the valid_uuid_array. Must be 0-8. +## @param[in] used_uuid UsedUuid +## @param[out] index Output Index. +## + +proc miiLaCreateMii*(special_key_code: MiiSpecialKeyCode; out_char: ptr MiiCharInfo): Result {. + cdecl, importc: "miiLaCreateMii".} +## * +## @brief Launches the applet for CreateMii. +## @note This creates a Mii and returns it, without saving it in the database. +## @note Only available on [10.2.0+]. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## @param[out] out_char \ref MiiCharInfo +## + +proc miiLaEditMii*(special_key_code: MiiSpecialKeyCode; in_char: ptr MiiCharInfo; + out_char: ptr MiiCharInfo): Result {.cdecl, importc: "miiLaEditMii".} +## * +## @brief Launches the applet for EditMii. +## @note This edits the specified Mii and returns it, without saving it in the database. +## @note Only available on [10.2.0+]. +## @param[in] special_key_code \ref MiiSpecialKeyCode +## @param[in] in_char \ref MiiCharInfo +## @param[out] out_char \ref MiiCharInfo +## + diff --git a/src/libnx/wrapper/switch/applets/nfp_la.h b/src/libnx/wrapper/switch/applets/nfp_la.h new file mode 100644 index 0000000..cf8e645 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/nfp_la.h @@ -0,0 +1,89 @@ +/** + * @file nfp_la.h + * @brief Wrapper for using the cabinet (amiibo) LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/nfc.h" + +/// Values for NfpLaStartParamForAmiiboSettings::type. +typedef enum { + NfpLaStartParamTypeForAmiiboSettings_NicknameAndOwnerSettings = 0, ///< NicknameAndOwnerSettings + NfpLaStartParamTypeForAmiiboSettings_GameDataEraser = 1, ///< GameDataEraser + NfpLaStartParamTypeForAmiiboSettings_Restorer = 2, ///< Restorer + NfpLaStartParamTypeForAmiiboSettings_Formatter = 3, ///< Formatter +} NfpLaStartParamTypeForAmiiboSettings; + +/// AmiiboSettingsStartParam +typedef struct { + u8 unk_x0[0x8]; ///< Unknown + u8 unk_x8[0x20]; ///< Unknown + u8 unk_x28; ///< Unknown +} NfpLaAmiiboSettingsStartParam; + +/// StartParamForAmiiboSettings +typedef struct { + u8 unk_x0; ///< Unknown + u8 type; ///< \ref NfpLaStartParamTypeForAmiiboSettings + u8 flags; ///< Flags + u8 unk_x3; ///< NfpLaAmiiboSettingsStartParam::unk_x28 + u8 unk_x4[0x8]; ///< NfpLaAmiiboSettingsStartParam::unk_x0 + NfpTagInfo tag_info; ///< \ref NfpTagInfo, only enabled when flags bit1 is set. + NfpRegisterInfo register_info; ///< \ref NfpRegisterInfo, only enabled when flags bit2 is set. + u8 unk_x164[0x20]; ///< NfpLaAmiiboSettingsStartParam::unk_x8 + u8 unk_x184[0x24]; ///< Unknown +} NfpLaStartParamForAmiiboSettings; + +/// ReturnValueForAmiiboSettings +typedef struct { + u8 flags; ///< 0 = error, non-zero = success. + u8 pad[3]; ///< Padding + NfcDeviceHandle handle; ///< \ref NfcDeviceHandle + NfpTagInfo tag_info; ///< \ref NfpTagInfo + NfpRegisterInfo register_info; ///< \ref NfpRegisterInfo, only available when flags bit2 is set. + u8 unk_x164[0x24]; ///< Unknown +} NfpLaReturnValueForAmiiboSettings; + +/** + * @brief Launches the applet for NicknameAndOwnerSettings. + * @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. + * @param[in] in_param \ref NfpLaAmiiboSettingsStartParam + * @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. + * @param[in] in_reg_info \ref NfpRegisterInfo. Optional, can be NULL. If specified, this sets the \ref NfpRegisterInfo which will be used for writing, with an option for the user to change it. + * @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. + * @param[out] handle \ref NfcDeviceHandle + * @param[out] reg_info_flag Flag indicating whether the data for out_reg_info is set. Optional, can be NULL. + * @param[out] out_reg_info \ref NfpRegisterInfo, see reg_info_flag. Optional, can be NULL. + */ +Result nfpLaStartNicknameAndOwnerSettings(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, const NfpRegisterInfo *in_reg_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle, bool *reg_info_flag, NfpRegisterInfo *out_reg_info); + +/** + * @brief Launches the applet for GameDataEraser. + * @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. + * @param[in] in_param \ref NfpLaAmiiboSettingsStartParam + * @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. + * @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. + * @param[out] handle \ref NfcDeviceHandle + */ +Result nfpLaStartGameDataEraser(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle); + +/** + * @brief Launches the applet for Restorer. + * @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. + * @param[in] in_param \ref NfpLaAmiiboSettingsStartParam + * @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. + * @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. + * @param[out] handle \ref NfcDeviceHandle + */ +Result nfpLaStartRestorer(const NfpLaAmiiboSettingsStartParam *in_param, const NfpTagInfo *in_tag_info, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle); + +/** + * @brief Launches the applet for Formatter. + * @param[in] in_param \ref NfpLaAmiiboSettingsStartParam + * @param[out] out_tag_info \ref NfpTagInfo + * @param[out] handle \ref NfcDeviceHandle + */ +Result nfpLaStartFormatter(const NfpLaAmiiboSettingsStartParam *in_param, NfpTagInfo *out_tag_info, NfcDeviceHandle *handle); + diff --git a/src/libnx/wrapper/switch/applets/nfp_la.nim b/src/libnx/wrapper/switch/applets/nfp_la.nim new file mode 100644 index 0000000..be4af6e --- /dev/null +++ b/src/libnx/wrapper/switch/applets/nfp_la.nim @@ -0,0 +1,112 @@ +## * +## @file nfp_la.h +## @brief Wrapper for using the cabinet (amiibo) LibraryApplet. +## @author yellowS8 +## @copyright libnx Authors +## + +import + ../types, ../services/nfc + +## / Values for NfpLaStartParamForAmiiboSettings::type. + +type + NfpLaStartParamTypeForAmiiboSettings* = enum + NfpLaStartParamTypeForAmiiboSettings_NicknameAndOwnerSettings = 0, ## /< NicknameAndOwnerSettings + NfpLaStartParamTypeForAmiiboSettings_GameDataEraser = 1, ## /< GameDataEraser + NfpLaStartParamTypeForAmiiboSettings_Restorer = 2, ## /< Restorer + NfpLaStartParamTypeForAmiiboSettings_Formatter = 3 ## /< Formatter + + +## / AmiiboSettingsStartParam + +type + NfpLaAmiiboSettingsStartParam* {.bycopy.} = object + unk_x0*: array[0x8, U8] ## /< Unknown + unk_x8*: array[0x20, U8] ## /< Unknown + unk_x28*: U8 ## /< Unknown + + +## / StartParamForAmiiboSettings + +type + NfpLaStartParamForAmiiboSettings* {.bycopy.} = object + unk_x0*: U8 ## /< Unknown + `type`*: U8 ## /< \ref NfpLaStartParamTypeForAmiiboSettings + flags*: U8 ## /< Flags + unk_x3*: U8 ## /< NfpLaAmiiboSettingsStartParam::unk_x28 + unk_x4*: array[0x8, U8] ## /< NfpLaAmiiboSettingsStartParam::unk_x0 + tag_info*: NfpTagInfo ## /< \ref NfpTagInfo, only enabled when flags bit1 is set. + register_info*: NfpRegisterInfo ## /< \ref NfpRegisterInfo, only enabled when flags bit2 is set. + unk_x164*: array[0x20, U8] ## /< NfpLaAmiiboSettingsStartParam::unk_x8 + unk_x184*: array[0x24, U8] ## /< Unknown + + +## / ReturnValueForAmiiboSettings + +type + NfpLaReturnValueForAmiiboSettings* {.bycopy.} = object + flags*: U8 ## /< 0 = error, non-zero = success. + pad*: array[3, U8] ## /< Padding + handle*: NfcDeviceHandle ## /< \ref NfcDeviceHandle + tag_info*: NfpTagInfo ## /< \ref NfpTagInfo + register_info*: NfpRegisterInfo ## /< \ref NfpRegisterInfo, only available when flags bit2 is set. + unk_x164*: array[0x24, U8] ## /< Unknown + +proc nfpLaStartNicknameAndOwnerSettings*(in_param: ptr NfpLaAmiiboSettingsStartParam; + in_tag_info: ptr NfpTagInfo; + in_reg_info: ptr NfpRegisterInfo; + out_tag_info: ptr NfpTagInfo; + handle: ptr NfcDeviceHandle; + reg_info_flag: ptr bool; + out_reg_info: ptr NfpRegisterInfo): Result {. + cdecl, importc: "nfpLaStartNicknameAndOwnerSettings".} +## * +## @brief Launches the applet for NicknameAndOwnerSettings. +## @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. +## @param[in] in_param \ref NfpLaAmiiboSettingsStartParam +## @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. +## @param[in] in_reg_info \ref NfpRegisterInfo. Optional, can be NULL. If specified, this sets the \ref NfpRegisterInfo which will be used for writing, with an option for the user to change it. +## @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. +## @param[out] handle \ref NfcDeviceHandle +## @param[out] reg_info_flag Flag indicating whether the data for out_reg_info is set. Optional, can be NULL. +## @param[out] out_reg_info \ref NfpRegisterInfo, see reg_info_flag. Optional, can be NULL. +## + +proc nfpLaStartGameDataEraser*(in_param: ptr NfpLaAmiiboSettingsStartParam; + in_tag_info: ptr NfpTagInfo; + out_tag_info: ptr NfpTagInfo; + handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfpLaStartGameDataEraser".} +## * +## @brief Launches the applet for GameDataEraser. +## @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. +## @param[in] in_param \ref NfpLaAmiiboSettingsStartParam +## @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. +## @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. +## @param[out] handle \ref NfcDeviceHandle +## + +proc nfpLaStartRestorer*(in_param: ptr NfpLaAmiiboSettingsStartParam; + in_tag_info: ptr NfpTagInfo; out_tag_info: ptr NfpTagInfo; + handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfpLaStartRestorer".} +## * +## @brief Launches the applet for Restorer. +## @note Official sw does not expose functionality for using input/output \ref NfpTagInfo at the same time. +## @param[in] in_param \ref NfpLaAmiiboSettingsStartParam +## @param[in] in_tag_info \ref NfpTagInfo. Optional, can be NULL. If specified, this must match the scanned amiibo. +## @param[out] out_tag_info \ref NfpTagInfo. Optional, can be NULL. +## @param[out] handle \ref NfcDeviceHandle +## + +proc nfpLaStartFormatter*(in_param: ptr NfpLaAmiiboSettingsStartParam; + out_tag_info: ptr NfpTagInfo; handle: ptr NfcDeviceHandle): Result {. + cdecl, importc: "nfpLaStartFormatter".} +## * +## @brief Launches the applet for Formatter. +## @param[in] in_param \ref NfpLaAmiiboSettingsStartParam +## @param[out] out_tag_info \ref NfpTagInfo +## @param[out] handle \ref NfcDeviceHandle +## + diff --git a/src/libnx/wrapper/switch/applets/nifm_la.h b/src/libnx/wrapper/switch/applets/nifm_la.h new file mode 100644 index 0000000..5bcf27a --- /dev/null +++ b/src/libnx/wrapper/switch/applets/nifm_la.h @@ -0,0 +1,16 @@ +/** + * @file nifm_la.h + * @brief Wrapper for using the nifm LibraryApplet (the launched applet varies). + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/nifm.h" + +/** + * @brief Uses \ref nifmGetResult, then on failure launches the applet. + * @param r \ref NifmRequest + */ +Result nifmLaHandleNetworkRequestResult(NifmRequest* r); + diff --git a/src/libnx/wrapper/switch/applets/nifm_la.nim b/src/libnx/wrapper/switch/applets/nifm_la.nim new file mode 100644 index 0000000..e7e3bf1 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/nifm_la.nim @@ -0,0 +1,17 @@ +## * +## @file nifm_la.h +## @brief Wrapper for using the nifm LibraryApplet (the launched applet varies). +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/nifm + +## * +## @brief Uses \ref nifmGetResult, then on failure launches the applet. +## @param r \ref NifmRequest +## + +proc nifmLaHandleNetworkRequestResult*(r: ptr NifmRequest): Result {.cdecl, + importc: "nifmLaHandleNetworkRequestResult".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/applets/pctlauth.h b/src/libnx/wrapper/switch/applets/pctlauth.h new file mode 100644 index 0000000..b416cf6 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/pctlauth.h @@ -0,0 +1,58 @@ +/** + * @file pctlauth.h + * @brief Wrapper for using the Parental Controls authentication LibraryApplet. This applet is used by qlaunch. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Type values for PctlAuthArg::type. +typedef enum { + PctlAuthType_Show = 0, ///< ShowParentalAuthentication + PctlAuthType_RegisterPasscode = 1, ///< RegisterParentalPasscode + PctlAuthType_ChangePasscode = 2, ///< ChangeParentalPasscode +} PctlAuthType; + +/// Input arg storage for the applet. +typedef struct { + u32 unk_x0; ///< Always set to 0 by the user-process. + PctlAuthType type; ///< \ref PctlAuthType + u8 arg0; ///< Arg0 + u8 arg1; ///< Arg1 + u8 arg2; ///< Arg2 + u8 pad; ///< Padding +} PctlAuthArg; + +/** + * @brief Launches the applet. + * @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. + * @param flag Input flag. false = temporarily disable Parental Controls. true = validate the input PIN. + */ +Result pctlauthShow(bool flag); + +/** + * @brief Launches the applet. Only available with [4.0.0+]. + * @param arg0 Value for PctlAuthArg.arg0. + * @param arg1 Value for PctlAuthArg.arg1. + * @param arg2 Value for PctlAuthArg.arg2. + */ +Result pctlauthShowEx(u8 arg0, u8 arg1, u8 arg2); + +/** + * @brief Just calls: pctlauthShowEx(1, 0, 1). Launches the applet for checking the PIN, used when changing system-settings. + * @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. + */ +Result pctlauthShowForConfiguration(void); + +/** + * @brief Launches the applet for registering the Parental Controls PIN. + */ +Result pctlauthRegisterPasscode(void); + +/** + * @brief Launches the applet for changing the Parental Controls PIN. + * @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. + */ +Result pctlauthChangePasscode(void); + diff --git a/src/libnx/wrapper/switch/applets/pctlauth.nim b/src/libnx/wrapper/switch/applets/pctlauth.nim new file mode 100644 index 0000000..75f84fc --- /dev/null +++ b/src/libnx/wrapper/switch/applets/pctlauth.nim @@ -0,0 +1,65 @@ +## * +## @file pctlauth.h +## @brief Wrapper for using the Parental Controls authentication LibraryApplet. This applet is used by qlaunch. +## @author yellowS8 +## @copyright libnx Authors +## + +import + ../types + +## / Type values for PctlAuthArg::type. + +type + PctlAuthType* = enum + PctlAuthType_Show = 0, ## /< ShowParentalAuthentication + PctlAuthType_RegisterPasscode = 1, ## /< RegisterParentalPasscode + PctlAuthType_ChangePasscode = 2 ## /< ChangeParentalPasscode + + +## / Input arg storage for the applet. + +type + PctlAuthArg* {.bycopy.} = object + unk_x0*: U32 ## /< Always set to 0 by the user-process. + `type`*: PctlAuthType ## /< \ref PctlAuthType + arg0*: U8 ## /< Arg0 + arg1*: U8 ## /< Arg1 + arg2*: U8 ## /< Arg2 + pad*: U8 ## /< Padding + +proc pctlauthShow*(flag: bool): Result {.cdecl, importc: "pctlauthShow".} +## * +## @brief Launches the applet. +## @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. +## @param flag Input flag. false = temporarily disable Parental Controls. true = validate the input PIN. +## + +proc pctlauthShowEx*(arg0: U8; arg1: U8; arg2: U8): Result {.cdecl, + importc: "pctlauthShowEx".} +## * +## @brief Launches the applet. Only available with [4.0.0+]. +## @param arg0 Value for PctlAuthArg.arg0. +## @param arg1 Value for PctlAuthArg.arg1. +## @param arg2 Value for PctlAuthArg.arg2. +## + +proc pctlauthShowForConfiguration*(): Result {.cdecl, + importc: "pctlauthShowForConfiguration".} +## * +## @brief Just calls: pctlauthShowEx(1, 0, 1). Launches the applet for checking the PIN, used when changing system-settings. +## @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. +## + +proc pctlauthRegisterPasscode*(): Result {.cdecl, + importc: "pctlauthRegisterPasscode".} +## * +## @brief Launches the applet for registering the Parental Controls PIN. +## + +proc pctlauthChangePasscode*(): Result {.cdecl, importc: "pctlauthChangePasscode".} +## * +## @brief Launches the applet for changing the Parental Controls PIN. +## @note Should not be used if a PIN is not already registered. See \ref pctlIsRestrictionEnabled. +## + diff --git a/src/libnx/wrapper/switch/applets/psel.h b/src/libnx/wrapper/switch/applets/psel.h new file mode 100644 index 0000000..4b63778 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/psel.h @@ -0,0 +1,210 @@ +/** + * @file psel.h + * @brief Wrapper for using the playerSelect (user selection) LibraryApplet. + * @author XorTroll, yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/acc.h" + +/// playerSelect UI modes. +typedef enum { + PselUiMode_UserSelector = 0, ///< UserSelector + PselUiMode_UserCreator = 1, ///< UserCreator + PselUiMode_EnsureNetworkServiceAccountAvailable = 2, ///< EnsureNetworkServiceAccountAvailable + PselUiMode_UserIconEditor = 3, ///< UserIconEditor + PselUiMode_UserNicknameEditor = 4, ///< UserNicknameEditor + PselUiMode_UserCreatorForStarter = 5, ///< UserCreatorForStarter + PselUiMode_NintendoAccountAuthorizationRequestContext = 6, ///< NintendoAccountAuthorizationRequestContext + PselUiMode_IntroduceExternalNetworkServiceAccount = 7, ///< IntroduceExternalNetworkServiceAccount + PselUiMode_IntroduceExternalNetworkServiceAccountForRegistration = 8, ///< [6.0.0+] IntroduceExternalNetworkServiceAccountForRegistration + PselUiMode_NintendoAccountNnidLinker = 9, ///< [6.0.0+] NintendoAccountNnidLinker + PselUiMode_LicenseRequirementsForNetworkService = 10, ///< [6.0.0+] LicenseRequirementsForNetworkService + PselUiMode_LicenseRequirementsForNetworkServiceWithUserContextImpl = 11, ///< [7.0.0+] LicenseRequirementsForNetworkServiceWithUserContextImpl + PselUiMode_UserCreatorForImmediateNaLoginTest = 12, ///< [7.0.0+] UserCreatorForImmediateNaLoginTest + PselUiMode_UserQualificationPromoter = 13, ///< [13.0.0+] UserQualificationPromoter +} PselUiMode; + +/// UI message text to display with ::PselUiMode_UserSelector. Invalid values are handled as ::PselUserSelectionPurpose_General. +typedef enum { + PselUserSelectionPurpose_General = 0, ///< "Select a user." + PselUserSelectionPurpose_GameCardRegistration = 1, ///< [2.0.0+] "Who will receive the points?" + PselUserSelectionPurpose_EShopLaunch = 2, ///< [2.0.0+] "Who is using Nintendo eShop?" + PselUserSelectionPurpose_EShopItemShow = 3, ///< [2.0.0+] "Who is making this purchase?" + PselUserSelectionPurpose_PicturePost = 4, ///< [2.0.0+] "Who is posting?" + PselUserSelectionPurpose_NintendoAccountLinkage = 5, ///< [2.0.0+] "Select a user to link to a Nintendo Account." + PselUserSelectionPurpose_SettingsUpdate = 6, ///< [2.0.0+] "Change settings for which user?" + PselUserSelectionPurpose_SaveDataDeletion = 7, ///< [2.0.0+] "Format data for which user?" + PselUserSelectionPurpose_UserMigration = 8, ///< [4.0.0+] "Which user will be transferred to another console?" + PselUserSelectionPurpose_SaveDataTransfer = 9, ///< [8.0.0+] "Send save data for which user?" +} PselUserSelectionPurpose; + +/// NintendoAccountStartupDialogType +typedef enum { + PselNintendoAccountStartupDialogType_LoginAndCreate = 0, ///< LoginAndCreate + PselNintendoAccountStartupDialogType_Login = 1, ///< Login + PselNintendoAccountStartupDialogType_Create = 2, ///< Create +} PselNintendoAccountStartupDialogType; + +/// Base UI settings for playerSelect. +typedef struct { + u32 mode; ///< \ref PselUiMode + u32 pad; ///< Padding. + AccountUid invalid_uid_list[ACC_USER_LIST_SIZE]; ///< List of \ref AccountUid. TODO: This is only correct for ::PselUiMode_UserSelector, for other modes this is a single uid, followed by mode-specific data (if any). + u64 application_id; ///< ApplicationId with \ref pselShowUserSelectorForLauncher. + u8 is_network_service_account_required; ///< PselUserSelectionSettings::is_network_service_account_required. + u8 is_skip_enabled; ///< PselUserSelectionSettings::is_skip_enabled + u8 unk_x92; ///< Set to value 1 by \ref pselShowUserSelectorForSystem / \ref pselShowUserSelectorForLauncher. + u8 is_permitted; ///< isPermitted. With ::PselUiMode_UserSelector: enables the option to create a new user. Set to the output from \ref accountIsUserRegistrationRequestPermitted with pselShowUserSelector*. When not set, a dialog will be displayed when the user attempts to create an user. + u8 show_skip_button; ///< PselUserSelectionSettings::show_skip_button + u8 additional_select; ///< PselUserSelectionSettings::additional_select + u8 unk_x96; ///< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::enable_user_creation_button. \ref pselShowUserSelectorForLauncher / \ref pselShowUserSelector sets this to value 1. + u8 unk_x97; ///< [6.0.0+] Set to PselUserSelectionSettings::is_unqualified_user_selectable ^ 1. +} PselUiSettingsV1; + +/// UI settings for versions starting with 0x10000. +typedef struct { + PselUiSettingsV1 settings; ///< \ref PselUiSettingsV1 + u32 unk_x98; ///< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::purpose. + u8 unk_x9c[0x4]; ///< Unknown. +} PselUiSettings; + +/// UserSelectionSettings +typedef struct { + AccountUid invalid_uid_list[ACC_USER_LIST_SIZE]; ///< invalidUidList. + u8 is_skip_enabled; ///< isSkipEnabled. When set, the first user in invalid_uid_list must not be set, and additional_select must be 0. When enabled \ref accountTrySelectUserWithoutInteraction will be used to select the user, in this case the applet will only be launched if \ref accountTrySelectUserWithoutInteraction doesn't return an user. + u8 is_network_service_account_required; ///< isNetworkServiceAccountRequired. Whether the user needs to be linked to a Nintendo account. + u8 show_skip_button; ///< showSkipButton. Enables the option to skip user selection with a button. + u8 additional_select; ///< additionalSelect. + u8 is_unqualified_user_selectable; ///< [6.0.0+] isUnqualifiedUserSelectable +} PselUserSelectionSettings; + +/// [2.0.0+] UserSelectionSettingsForSystemService +typedef struct { + u32 purpose; ///< \ref PselUserSelectionPurpose + u8 enable_user_creation_button; ///< Enables the user-creation button when set. Whether user-creation when pressing the button is actually allowed is controlled by PselUiSettingsV1::is_permitted. + u8 pad[0x3]; ///< Padding. +} PselUserSelectionSettingsForSystemService; + +/// Return data sent after execution. +typedef struct { + Result res; ///< Result. + AccountUid user_id; ///< Selected \ref AccountUid. +} PselUiReturnArg; + +/** + * @brief Creates a new UI config for the playerSelect applet with the specified mode. + * @param ui PseluiSettings struct. + * @param mode playerSelect UI mode. + */ +Result pselUiCreate(PselUiSettings *ui, PselUiMode mode); + +/** + * @brief Adds an user to the user list of the applet. + * @param ui PselUiSettings struct. + * @param[in] user_id user ID. + * @note The users will be treated as invalid users for user selection mode, and as the input user for other modes. + */ +void pselUiAddUser(PselUiSettings *ui, AccountUid user_id); + +/** + * @brief Sets whether users can be created in the applet. + * @param ui PselUiSettings struct. + * @param flag Flag value. + * @note Only used for ::PselUiMode_SelectUser. + */ +NX_CONSTEXPR void pselUiSetAllowUserCreation(PselUiSettings *ui, bool flag) { + if(ui->settings.mode == PselUiMode_UserSelector) { + ui->settings.is_permitted = flag!=0; + } +} + +/** + * @brief Sets whether users need to be linked to a Nintendo account. + * @param ui PselUiSettings struct. + * @param flag Flag value. + */ +NX_CONSTEXPR void pselUiSetNetworkServiceRequired(PselUiSettings *ui, bool flag) { + ui->settings.is_network_service_account_required = flag; +} + +/** + * @brief Sets whether selection can be skipped with a button. + * @param ui PselUiSettings struct. + * @param flag Flag value. + */ +NX_CONSTEXPR void pselUiSetSkipButtonEnabled(PselUiSettings *ui, bool flag) { + ui->settings.show_skip_button = flag!=0; +} + +/** + * @brief Shows the applet with the specified UI settings. + * @param ui PselUiSettings struct. + * @param out_user Selected user ID. + * @note If user skips (see \ref pselUiSetSkipEnabled) this will return successfully but the output ID will be 0. + */ +Result pselUiShow(PselUiSettings *ui, AccountUid *out_user); + +/** + * @brief This is the System version of \ref pselShowUserSelector. + * @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. + * @param[out] out_user Returned selected user ID. + * @param[in] settings \ref PselUserSelectionSettings + * @param[in] settings_system [2.0.0+] \ref PselUserSelectionSettingsForSystemService, ignored on prior versions. + */ +Result pselShowUserSelectorForSystem(AccountUid *out_user, const PselUserSelectionSettings *settings, const PselUserSelectionSettingsForSystemService *settings_system); + +/** + * @brief This is the Launcher version of \ref pselShowUserSelector. + * @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. + * @param[out] out_user Returned selected user ID. + * @param[in] settings \ref PselUserSelectionSettings + * @param[in] application_id ApplicationId + */ +Result pselShowUserSelectorForLauncher(AccountUid *out_user, const PselUserSelectionSettings *settings, u64 application_id); + +/** + * @brief Shows the applet to select a user. + * @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. + * @param[out] out_user Returned selected user ID. + * @param[in] settings \ref PselUserSelectionSettings + */ +Result pselShowUserSelector(AccountUid *out_user, const PselUserSelectionSettings *settings); + +/** + * @brief Shows the applet to create a user. + * @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. If the output flag is 0, an error will be thrown. + */ +Result pselShowUserCreator(void); + +/** + * @brief Shows the applet to change a user's icon. + * @param[in] user Input user ID. + */ +Result pselShowUserIconEditor(AccountUid user); + +/** + * @brief Shows the applet to change a user's nickname. + * @param[in] user Input user ID. + */ +Result pselShowUserNicknameEditor(AccountUid user); + +/** + * @brief Shows the applet to create a user. Used by the starter applet during system setup. + */ +Result pselShowUserCreatorForStarter(void); + +/** + * @brief Shows the applet for Nintendo Account Nnid linking. + * @note Only available on [6.0.0+]. + * @param[in] user Input user ID. + */ +Result pselShowNintendoAccountNnidLinker(AccountUid user); + +/** + * @brief Shows the applet for UserQualificationPromoter. + * @note Only available on [13.0.0+]. + * @param[in] user Input user ID. + */ +Result pselShowUserQualificationPromoter(AccountUid user); diff --git a/src/libnx/wrapper/switch/applets/psel.nim b/src/libnx/wrapper/switch/applets/psel.nim new file mode 100644 index 0000000..7babbb7 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/psel.nim @@ -0,0 +1,242 @@ +## * +## @file psel.h +## @brief Wrapper for using the playerSelect (user selection) LibraryApplet. +## @author XorTroll, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/acc + +## / playerSelect UI modes. + +type + PselUiMode* = enum + PselUiModeUserSelector = 0, ## /< UserSelector + PselUiModeUserCreator = 1, ## /< UserCreator + PselUiModeEnsureNetworkServiceAccountAvailable = 2, ## /< EnsureNetworkServiceAccountAvailable + PselUiModeUserIconEditor = 3, ## /< UserIconEditor + PselUiModeUserNicknameEditor = 4, ## /< UserNicknameEditor + PselUiModeUserCreatorForStarter = 5, ## /< UserCreatorForStarter + PselUiModeNintendoAccountAuthorizationRequestContext = 6, ## /< NintendoAccountAuthorizationRequestContext + PselUiModeIntroduceExternalNetworkServiceAccount = 7, ## /< IntroduceExternalNetworkServiceAccount + PselUiModeIntroduceExternalNetworkServiceAccountForRegistration = 8, ## /< [6.0.0+] IntroduceExternalNetworkServiceAccountForRegistration + PselUiModeNintendoAccountNnidLinker = 9, ## /< [6.0.0+] NintendoAccountNnidLinker + PselUiModeLicenseRequirementsForNetworkService = 10, ## /< [6.0.0+] LicenseRequirementsForNetworkService + PselUiModeLicenseRequirementsForNetworkServiceWithUserContextImpl = 11, ## /< [7.0.0+] LicenseRequirementsForNetworkServiceWithUserContextImpl + PselUiModeUserCreatorForImmediateNaLoginTest = 12, ## /< [7.0.0+] UserCreatorForImmediateNaLoginTest + PselUiModeUserQualificationPromoter = 13 ## /< [13.0.0+] UserQualificationPromoter + + +## / UI message text to display with ::PselUiMode_UserSelector. Invalid values are handled as ::PselUserSelectionPurpose_General. + +type + PselUserSelectionPurpose* = enum + PselUserSelectionPurposeGeneral = 0, ## /< "Select a user." + PselUserSelectionPurposeGameCardRegistration = 1, ## /< [2.0.0+] "Who will receive the points?" + PselUserSelectionPurposeEShopLaunch = 2, ## /< [2.0.0+] "Who is using Nintendo eShop?" + PselUserSelectionPurposeEShopItemShow = 3, ## /< [2.0.0+] "Who is making this purchase?" + PselUserSelectionPurposePicturePost = 4, ## /< [2.0.0+] "Who is posting?" + PselUserSelectionPurposeNintendoAccountLinkage = 5, ## /< [2.0.0+] "Select a user to link to a Nintendo Account." + PselUserSelectionPurposeSettingsUpdate = 6, ## /< [2.0.0+] "Change settings for which user?" + PselUserSelectionPurposeSaveDataDeletion = 7, ## /< [2.0.0+] "Format data for which user?" + PselUserSelectionPurposeUserMigration = 8, ## /< [4.0.0+] "Which user will be transferred to another console?" + PselUserSelectionPurposeSaveDataTransfer = 9 ## /< [8.0.0+] "Send save data for which user?" + + +## / NintendoAccountStartupDialogType + +type + PselNintendoAccountStartupDialogType* = enum + PselNintendoAccountStartupDialogTypeLoginAndCreate = 0, ## /< LoginAndCreate + PselNintendoAccountStartupDialogTypeLogin = 1, ## /< Login + PselNintendoAccountStartupDialogTypeCreate = 2 ## /< Create + + +## / Base UI settings for playerSelect. + +type + PselUiSettingsV1* {.bycopy.} = object + mode*: U32 ## /< \ref PselUiMode + pad*: U32 ## /< Padding. + invalidUidList*: array[Acc_User_List_Size, AccountUid] ## /< List of \ref AccountUid. TODO: This is only correct for ::PselUiMode_UserSelector, for other modes this is a single uid, followed by mode-specific data (if any). + applicationId*: U64 ## /< ApplicationId with \ref pselShowUserSelectorForLauncher. + isNetworkServiceAccountRequired*: U8 ## /< PselUserSelectionSettings::is_network_service_account_required. + isSkipEnabled*: U8 ## /< PselUserSelectionSettings::is_skip_enabled + unkX92*: U8 ## /< Set to value 1 by \ref pselShowUserSelectorForSystem / \ref pselShowUserSelectorForLauncher. + isPermitted*: U8 ## /< isPermitted. With ::PselUiMode_UserSelector: enables the option to create a new user. Set to the output from \ref accountIsUserRegistrationRequestPermitted with pselShowUserSelector*. When not set, a dialog will be displayed when the user attempts to create an user. + showSkipButton*: U8 ## /< PselUserSelectionSettings::show_skip_button + additionalSelect*: U8 ## /< PselUserSelectionSettings::additional_select + unkX96*: U8 ## /< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::enable_user_creation_button. \ref pselShowUserSelectorForLauncher / \ref pselShowUserSelector sets this to value 1. + unkX97*: U8 ## /< [6.0.0+] Set to PselUserSelectionSettings::is_unqualified_user_selectable ^ 1. + + +## / UI settings for versions starting with 0x10000. + +type + PselUiSettings* {.bycopy.} = object + settings*: PselUiSettingsV1 ## /< \ref PselUiSettingsV1 + unkX98*: U32 ## /< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::purpose. + unkX9c*: array[0x4, U8] ## /< Unknown. + + +## / UserSelectionSettings + +type + PselUserSelectionSettings* {.bycopy.} = object + invalidUidList*: array[Acc_User_List_Size, AccountUid] ## /< invalidUidList. + isSkipEnabled*: U8 ## /< isSkipEnabled. When set, the first user in invalid_uid_list must not be set, and additional_select must be 0. When enabled \ref accountTrySelectUserWithoutInteraction will be used to select the user, in this case the applet will only be launched if \ref accountTrySelectUserWithoutInteraction doesn't return an user. + isNetworkServiceAccountRequired*: U8 ## /< isNetworkServiceAccountRequired. Whether the user needs to be linked to a Nintendo account. + showSkipButton*: U8 ## /< showSkipButton. Enables the option to skip user selection with a button. + additionalSelect*: U8 ## /< additionalSelect. + isUnqualifiedUserSelectable*: U8 ## /< [6.0.0+] isUnqualifiedUserSelectable + + +## / [2.0.0+] UserSelectionSettingsForSystemService + +type + PselUserSelectionSettingsForSystemService* {.bycopy.} = object + purpose*: U32 ## /< \ref PselUserSelectionPurpose + enableUserCreationButton*: U8 ## /< Enables the user-creation button when set. Whether user-creation when pressing the button is actually allowed is controlled by PselUiSettingsV1::is_permitted. + pad*: array[0x3, U8] ## /< Padding. + + +## / Return data sent after execution. + +type + PselUiReturnArg* {.bycopy.} = object + res*: Result ## /< Result. + userId*: AccountUid ## /< Selected \ref AccountUid. + +proc pselUiCreate*(ui: ptr PselUiSettings; mode: PselUiMode): Result {.cdecl, + importc: "pselUiCreate".} +## * +## @brief Creates a new UI config for the playerSelect applet with the specified mode. +## @param ui PseluiSettings struct. +## @param mode playerSelect UI mode. +## + +proc pselUiAddUser*(ui: ptr PselUiSettings; userId: AccountUid) {.cdecl, + importc: "pselUiAddUser".} +## * +## @brief Adds an user to the user list of the applet. +## @param ui PselUiSettings struct. +## @param[in] user_id user ID. +## @note The users will be treated as invalid users for user selection mode, and as the input user for other modes. +## + +proc pselUiSetAllowUserCreation*(ui: ptr PselUiSettings; flag: bool) {.inline, cdecl.} = + ## * + ## @brief Sets whether users can be created in the applet. + ## @param ui PselUiSettings struct. + ## @param flag Flag value. + ## @note Only used for ::PselUiMode_SelectUser. + ## + + if ui.settings.mode == PselUiModeUserSelector.U32: + ui.settings.isPermitted = flag.U8 + +proc pselUiSetNetworkServiceRequired*(ui: ptr PselUiSettings; flag: bool) {.inline, + cdecl.} = + ## * + ## @brief Sets whether users need to be linked to a Nintendo account. + ## @param ui PselUiSettings struct. + ## @param flag Flag value. + ## + + ui.settings.isNetworkServiceAccountRequired = flag.U8 + +proc pselUiSetSkipButtonEnabled*(ui: ptr PselUiSettings; flag: bool) {.inline, cdecl.} = + ## * + ## @brief Sets whether selection can be skipped with a button. + ## @param ui PselUiSettings struct. + ## @param flag Flag value. + ## + + ui.settings.showSkipButton = flag.U8 + +proc pselUiShow*(ui: ptr PselUiSettings; outUser: ptr AccountUid): Result {.cdecl, + importc: "pselUiShow".} +## * +## @brief Shows the applet with the specified UI settings. +## @param ui PselUiSettings struct. +## @param out_user Selected user ID. +## @note If user skips (see \ref pselUiSetSkipEnabled) this will return successfully but the output ID will be 0. +## + +proc pselShowUserSelectorForSystem*(outUser: ptr AccountUid; + settings: ptr PselUserSelectionSettings; + settingsSystem: ptr PselUserSelectionSettingsForSystemService): Result {.cdecl, + importc: "pselShowUserSelectorForSystem".} +## * +## @brief This is the System version of \ref pselShowUserSelector. +## @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. +## @param[out] out_user Returned selected user ID. +## @param[in] settings \ref PselUserSelectionSettings +## @param[in] settings_system [2.0.0+] \ref PselUserSelectionSettingsForSystemService, ignored on prior versions. +## + +proc pselShowUserSelectorForLauncher*(outUser: ptr AccountUid; + settings: ptr PselUserSelectionSettings; + applicationId: U64): Result {.cdecl, + importc: "pselShowUserSelectorForLauncher".} +## * +## @brief This is the Launcher version of \ref pselShowUserSelector. +## @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. +## @param[out] out_user Returned selected user ID. +## @param[in] settings \ref PselUserSelectionSettings +## @param[in] application_id ApplicationId +## + +proc pselShowUserSelector*(outUser: ptr AccountUid; + settings: ptr PselUserSelectionSettings): Result {.cdecl, + importc: "pselShowUserSelector".} +## * +## @brief Shows the applet to select a user. +## @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled. +## @param[out] out_user Returned selected user ID. +## @param[in] settings \ref PselUserSelectionSettings +## + +proc pselShowUserCreator*(): Result {.cdecl, importc: "pselShowUserCreator".} +## * +## @brief Shows the applet to create a user. +## @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. If the output flag is 0, an error will be thrown. +## + +proc pselShowUserIconEditor*(user: AccountUid): Result {.cdecl, + importc: "pselShowUserIconEditor".} +## * +## @brief Shows the applet to change a user's icon. +## @param[in] user Input user ID. +## + +proc pselShowUserNicknameEditor*(user: AccountUid): Result {.cdecl, + importc: "pselShowUserNicknameEditor".} +## * +## @brief Shows the applet to change a user's nickname. +## @param[in] user Input user ID. +## + +proc pselShowUserCreatorForStarter*(): Result {.cdecl, + importc: "pselShowUserCreatorForStarter".} +## * +## @brief Shows the applet to create a user. Used by the starter applet during system setup. +## + +proc pselShowNintendoAccountNnidLinker*(user: AccountUid): Result {.cdecl, + importc: "pselShowNintendoAccountNnidLinker".} +## * +## @brief Shows the applet for Nintendo Account Nnid linking. +## @note Only available on [6.0.0+]. +## @param[in] user Input user ID. +## + +proc pselShowUserQualificationPromoter*(user: AccountUid): Result {.cdecl, + importc: "pselShowUserQualificationPromoter".} +## * +## @brief Shows the applet for UserQualificationPromoter. +## @note Only available on [13.0.0+]. +## @param[in] user Input user ID. +## + diff --git a/src/libnx/wrapper/switch/applets/swkbd.h b/src/libnx/wrapper/switch/applets/swkbd.h new file mode 100644 index 0000000..77bb3e2 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/swkbd.h @@ -0,0 +1,1027 @@ +/** + * @file swkbd.h + * @brief Wrapper for using the swkbd (software keyboard) LibraryApplet. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/applet.h" + +/// Output result returned by \ref SwkbdTextCheckCb. +typedef enum { + SwkbdTextCheckResult_OK = 0, ///< Success, valid string. + SwkbdTextCheckResult_Bad = 1, ///< Failure, invalid string. Error message is displayed in a message-box, pressing OK will return to swkbd again. + SwkbdTextCheckResult_Prompt = 2, ///< Failure, invalid string. Error message is displayed in a message-box, pressing Cancel will return to swkbd again, while pressing OK will continue as if the text was valid. + SwkbdTextCheckResult_Silent = 3, ///< Failure, invalid string. With value 3 and above, swkbd will silently not accept the string, without displaying any error. +} SwkbdTextCheckResult; + +/// Type of keyboard. +typedef enum { + SwkbdType_Normal = 0, ///< Normal keyboard. + SwkbdType_NumPad = 1, ///< Number pad. The buttons at the bottom left/right are only available when they're set by \ref swkbdConfigSetLeftOptionalSymbolKey / \ref swkbdConfigSetRightOptionalSymbolKey. + SwkbdType_QWERTY = 2, ///< QWERTY (and variants) keyboard only. + SwkbdType_Unknown3 = 3, ///< The same as SwkbdType_Normal keyboard. + SwkbdType_Latin = 4, ///< All Latin like languages keyboard only (without CJK keyboard). + SwkbdType_ZhHans = 5, ///< Chinese Simplified keyboard only. + SwkbdType_ZhHant = 6, ///< Chinese Traditional keyboard only. + SwkbdType_Korean = 7, ///< Korean keyboard only. + SwkbdType_All = 8, ///< All language keyboards. + SwkbdType_Unknown9 = 9, ///< Unknown +} SwkbdType; + +/// Bitmask for SwkbdArgCommon::keySetDisableBitmask. This disables keys on the keyboard when the corresponding bit(s) are set. +enum { + SwkbdKeyDisableBitmask_Space = BIT(1), ///< Disable space-bar. + SwkbdKeyDisableBitmask_At = BIT(2), ///< Disable '@'. + SwkbdKeyDisableBitmask_Percent = BIT(3), ///< Disable '%'. + SwkbdKeyDisableBitmask_ForwardSlash = BIT(4), ///< Disable '/'. + SwkbdKeyDisableBitmask_Backslash = BIT(5), ///< Disable '\'. + SwkbdKeyDisableBitmask_Numbers = BIT(6), ///< Disable numbers. + SwkbdKeyDisableBitmask_DownloadCode = BIT(7), ///< Used for \ref swkbdConfigMakePresetDownloadCode. + SwkbdKeyDisableBitmask_UserName = BIT(8), ///< Used for \ref swkbdConfigMakePresetUserName. Disables '@', '%', and '\'. +}; + +/// Value for SwkbdArgCommon::textDrawType. Only applies when stringLenMax is 1..32, otherwise swkbd will only use SwkbdTextDrawType_Box. +typedef enum { + SwkbdTextDrawType_Line = 0, ///< The text will be displayed on a line. Also enables displaying the Header and Sub text. + SwkbdTextDrawType_Box = 1, ///< The text will be displayed in a box. + SwkbdTextDrawType_DownloadCode = 2, ///< Used by \ref swkbdConfigMakePresetDownloadCode on [5.0.0+]. Enables using \ref SwkbdArgV7 unk_x3e0. +} SwkbdTextDrawType; + +/// SwkbdInline Interactive input storage request ID. +typedef enum { + SwkbdRequestCommand_Finalize = 0x4, + SwkbdRequestCommand_SetUserWordInfo = 0x6, + SwkbdRequestCommand_SetCustomizeDic = 0x7, + SwkbdRequestCommand_Calc = 0xA, + SwkbdRequestCommand_SetCustomizedDictionaries = 0xB, + SwkbdRequestCommand_UnsetCustomizedDictionaries = 0xC, + SwkbdRequestCommand_SetChangedStringV2Flag = 0xD, + SwkbdRequestCommand_SetMovedCursorV2Flag = 0xE, +} SwkbdRequestCommand; + +/// SwkbdInline Interactive output storage reply ID. +typedef enum { + SwkbdReplyType_FinishedInitialize = 0x0, + SwkbdReplyType_ChangedString = 0x2, + SwkbdReplyType_MovedCursor = 0x3, + SwkbdReplyType_MovedTab = 0x4, + SwkbdReplyType_DecidedEnter = 0x5, + SwkbdReplyType_DecidedCancel = 0x6, + SwkbdReplyType_ChangedStringUtf8 = 0x7, + SwkbdReplyType_MovedCursorUtf8 = 0x8, + SwkbdReplyType_DecidedEnterUtf8 = 0x9, + SwkbdReplyType_UnsetCustomizeDic = 0xA, + SwkbdReplyType_ReleasedUserWordInfo = 0xB, + SwkbdReplyType_UnsetCustomizedDictionaries = 0xC, + SwkbdReplyType_ChangedStringV2 = 0xD, + SwkbdReplyType_MovedCursorV2 = 0xE, + SwkbdReplyType_ChangedStringUtf8V2 = 0xF, + SwkbdReplyType_MovedCursorUtf8V2 = 0x10, +} SwkbdReplyType; + +/// SwkbdInline State +typedef enum { + SwkbdState_Inactive = 0x0, ///< Default state from \ref swkbdInlineCreate, before a state is set by \ref swkbdInlineUpdate when a reply is received. Also indicates that the applet is no longer running. + SwkbdState_Initialized = 0x1, ///< Applet is initialized but hidden. + SwkbdState_Appearing = 0x2, ///< Applet is appearing. + SwkbdState_Shown = 0x3, ///< Applet is fully shown and ready to accept text input. + SwkbdState_Disappearing = 0x4, ///< The user pressed the ok or cancel button, causing the applet to disappear. + SwkbdState_Unknown5 = 0x5, + SwkbdState_Unknown6 = 0x6, +} SwkbdState; + +/// Value for \ref SwkbdInitializeArg mode. Controls the LibAppletMode when launching the applet. +typedef enum { + SwkbdInlineMode_UserDisplay = 0, ///< LibAppletMode_BackgroundIndirect. This is the default. The user-process must handle displaying the swkbd gfx on the screen, by loading the image with \ref swkbdInlineGetImage. + SwkbdInlineMode_AppletDisplay = 1, ///< LibAppletMode_Background. The applet will handle displaying gfx on the screen. +} SwkbdInlineMode; + +/// TextCheck callback set by \ref swkbdConfigSetTextCheckCallback, for validating the input string when the swkbd ok-button is pressed. This buffer contains an UTF-8 string. This callback should validate the input string, then return a \ref SwkbdTextCheckResult indicating success/failure. On failure, this function must write an error message to the tmp_string buffer, which will then be displayed by swkbd. +typedef SwkbdTextCheckResult (*SwkbdTextCheckCb)(char* tmp_string, size_t tmp_string_size); + +/// User dictionary word. +typedef struct { + u8 unk_x0[0x64]; +} SwkbdDictWord; + +/// Input data for SwkbdInline request SetCustomizeDic. +typedef struct { + u8 unk_x0[0x70]; +} SwkbdCustomizeDicInfo; + +typedef struct { + void* buffer; ///< 0x1000-byte aligned buffer. + u32 buffer_size; ///< 0x1000-byte aligned buffer size. + u64 entries[0x18]; + u16 total_entries; +} PACKED SwkbdCustomizedDictionarySet; + +/// Base swkbd arg struct. +typedef struct { + SwkbdType type; ///< See \ref SwkbdType. + u16 okButtonText[18/2]; + u16 leftButtonText; + u16 rightButtonText; + u8 dicFlag; ///< Enables dictionary usage when non-zero (including the system dictionary). + u8 pad_x1b; + u32 keySetDisableBitmask; ///< See SwkbdKeyDisableBitmask_*. + u32 initialCursorPos; ///< Initial cursor position in the string: 0 = start, 1 = end. + u16 headerText[130/2]; + u16 subText[258/2]; + u16 guideText[514/2]; + u16 pad_x3aa; + u32 stringLenMax; ///< When non-zero, specifies the max string length. When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace). See also \ref SwkbdTextDrawType. + u32 stringLenMin; ///< When non-zero, specifies the min string length. When the input is too short, swkbd will display an icon and disable the ok-button. + u32 passwordFlag; ///< Use password: 0 = disable, 1 = enable. + SwkbdTextDrawType textDrawType; ///< See \ref SwkbdTextDrawType. + u16 returnButtonFlag; ///< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. + u8 blurBackground; ///< When enabled with value 1, the background is blurred. + u8 pad_x3bf; + u32 initialStringOffset; + u32 initialStringSize; + u32 userDicOffset; + s32 userDicEntries; + u8 textCheckFlag; +} SwkbdArgCommon; + +typedef struct { + SwkbdArgCommon arg; + u8 pad_x3d1[7]; + SwkbdTextCheckCb textCheckCb; ///< This really doesn't belong in a struct sent to another process, but official sw does this. +} SwkbdArgV0; + +/// Arg struct for version 0x30007+. +typedef struct { + SwkbdArgV0 arg; + u32 textGrouping[8]; ///< When set and enabled via \ref SwkbdTextDrawType, controls displayed text grouping (inserts spaces, without affecting output string). +} SwkbdArgV7; + +/// Arg struct for version 0x6000B+. +typedef struct { + SwkbdArgCommon arg; + u8 pad_x3d1[3]; + u32 textGrouping[8]; ///< Same as SwkbdArgV7::textGrouping. + u64 entries[0x18]; ///< This is SwkbdCustomizedDictionarySet::entries. + u8 total_entries; ///< This is SwkbdCustomizedDictionarySet::total_entries. + u8 unkFlag; ///< [8.0.0+] + u8 pad_x4b6[0xD]; + u8 trigger; ///< [8.0.0+] + u8 pad_x4c4[4]; +} SwkbdArgVB; + +typedef struct { + SwkbdArgV7 arg; + + u8* workbuf; + size_t workbuf_size; + s32 max_dictwords; + + SwkbdCustomizedDictionarySet customizedDictionarySet; + + u8 unkFlag; + u8 trigger; + + u32 version; +} SwkbdConfig; + +/// Rect +typedef struct { + s16 x; ///< X + s16 y; ///< Y + s16 width; ///< Width + s16 height; ///< Height +} SwkbdRect; + +/// InitializeArg for SwkbdInline. +typedef struct { + u32 unk_x0; + u8 mode; ///< See \ref SwkbdInlineMode. (u8 bool) + u8 unk_x5; ///< Only set on [5.0.0+]. + u8 pad[2]; +} SwkbdInitializeArg; + +typedef struct { + SwkbdType type; ///< See \ref SwkbdType. + u16 okButtonText[9]; + u16 leftButtonText; + u16 rightButtonText; + u8 dicFlag; ///< Enables dictionary usage when non-zero (including the system dictionary). + u8 unk_x1b; + u32 keySetDisableBitmask; ///< See SwkbdKeyDisableBitmask_*. + s32 stringLenMax; ///< When non-negative and non-zero, specifies the max string length. When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace). + s32 stringLenMin; ///< When non-negative and non-zero, specifies the min string length. When the input is too short, swkbd will display an icon and disable the ok-button. + u8 returnButtonFlag; ///< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. + u8 unk_x29; ///< [10.0.0+] When value 1-2, \ref swkbdInlineAppear / \ref swkbdInlineAppearEx will set keytopAsFloating=0 and footerScalable=1. + u8 unk_x2a; + u8 unk_x2b; + u32 flags; ///< Bitmask 0x4: unknown. + u8 unk_x30; + u8 unk_x31[0x17]; +} SwkbdAppearArg; + +typedef struct { + u32 unk_x0; + u16 size; ///< Size of this struct. + u8 unk_x6; + u8 unk_x7; + u64 flags; + SwkbdInitializeArg initArg; ///< Flags bitmask 0x1. + float volume; ///< Flags bitmask 0x2. + s32 cursorPos; ///< Flags bitmask 0x10. + SwkbdAppearArg appearArg; + u16 inputText[0x3f4/2]; ///< Flags bitmask 0x8. + u8 utf8Mode; ///< Flags bitmask 0x20. + u8 unk_x45d; + u8 enableBackspace; ///< Flags bitmask 0x8000. Only available with [5.0.0+]. + u8 unk_x45f[3]; + u8 keytopAsFloating; ///< Flags bitmask 0x200. + u8 footerScalable; ///< Flags bitmask 0x100. + u8 alphaEnabledInInputMode; ///< Flags bitmask 0x100. + u8 inputModeFadeType; ///< Flags bitmask 0x100. + u8 disableTouch; ///< Flags bitmask 0x200. + u8 disableHardwareKeyboard; ///< Flags bitmask 0x800. + u8 unk_x468[5]; + u8 unk_x46d; + u8 unk_x46e; + u8 unk_x46f; + float keytopScaleX; ///< Flags bitmask 0x200. + float keytopScaleY; ///< Flags bitmask 0x200. + float keytopTranslateX; ///< Flags bitmask 0x200. + float keytopTranslateY; ///< Flags bitmask 0x200. + float keytopBgAlpha; ///< Flags bitmask 0x100. + float footerBgAlpha; ///< Flags bitmask 0x100. + float balloonScale; ///< Flags bitmask 0x200. + float unk_x48c; + u8 unk_x490[0xc]; + u8 seGroup; ///< Flags bitmask: enable=0x2000, disable=0x4000. Only available with [5.0.0+]. + u8 triggerFlag; ///< [6.0.0+] Enables using the trigger field when set. + u8 trigger; ///< [6.0.0+] Trigger + u8 pad_x49f; +} SwkbdInlineCalcArg; + +/// Struct data for SwkbdInline Interactive reply storage ChangedString*, at the end following the string. +typedef struct { + u32 stringLen; ///< String length in characters, without NUL-terminator. + s32 dicStartCursorPos; ///< Starting cursorPos for the current dictionary word in the current text string. -1 for none. + s32 dicEndCursorPos; ///< Ending cursorPos for the current dictionary word in the current text string. -1 for none. + s32 cursorPos; ///< Cursor position. +} SwkbdChangedStringArg; + +/// Struct data for SwkbdInline Interactive reply storage MovedCursor*, at the end following the string. +typedef struct { + u32 stringLen; ///< String length in characters, without NUL-terminator. + s32 cursorPos; ///< Cursor position. +} SwkbdMovedCursorArg; + +/// Struct data for SwkbdInline Interactive reply storage MovedTab*, at the end following the string. +typedef struct { + u32 unk_x0; + u32 unk_x4; +} SwkbdMovedTabArg; + +/// Struct data for SwkbdInline Interactive reply storage DecidedEnter*, at the end following the string. +typedef struct { + u32 stringLen; ///< String length in characters, without NUL-terminator. +} SwkbdDecidedEnterArg; + +/// This callback is used by \ref swkbdInlineUpdate when handling ChangedString* replies (text changed by the user or by \ref swkbdInlineSetInputText). +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdChangedStringCb)(const char* str, SwkbdChangedStringArg* arg); + +/// This callback is used by \ref swkbdInlineUpdate when handling ChangedString*V2 replies (text changed by the user or by \ref swkbdInlineSetInputText). +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdChangedStringV2Cb)(const char* str, SwkbdChangedStringArg* arg, bool flag); + +/// This callback is used by \ref swkbdInlineUpdate when handling MovedCursor* replies. +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdMovedCursorCb)(const char* str, SwkbdMovedCursorArg* arg); + +/// This callback is used by \ref swkbdInlineUpdate when handling MovedCursor*V2 replies. +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdMovedCursorV2Cb)(const char* str, SwkbdMovedCursorArg* arg, bool flag); + +/// This callback is used by \ref swkbdInlineUpdate when handling MovedTab* replies. +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdMovedTabCb)(const char* str, SwkbdMovedTabArg* arg); + +/// This callback is used by \ref swkbdInlineUpdate when handling DecidedEnter* replies (when the final text was submitted via the button). +/// str is the UTF-8 string for the current text. +typedef void (*SwkbdDecidedEnterCb)(const char* str, SwkbdDecidedEnterArg* arg); + +/// InlineKeyboard +typedef struct { + u32 version; + AppletHolder holder; + SwkbdInlineCalcArg calcArg; + bool directionalButtonAssignFlag; + SwkbdState state; + + bool dicCustomInitialized; + bool customizedDictionariesInitialized; + AppletStorage dicStorage; + + bool wordInfoInitialized; + AppletStorage wordInfoStorage; + + u8* interactive_tmpbuf; + size_t interactive_tmpbuf_size; + char* interactive_strbuf; + size_t interactive_strbuf_size; + + VoidFn finishedInitializeCb; + VoidFn decidedCancelCb; + SwkbdChangedStringCb changedStringCb; + SwkbdChangedStringV2Cb changedStringV2Cb; + SwkbdMovedCursorCb movedCursorCb; + SwkbdMovedCursorV2Cb movedCursorV2Cb; + SwkbdMovedTabCb movedTabCb; + SwkbdDecidedEnterCb decidedEnterCb; + VoidFn releasedUserWordInfoCb; +} SwkbdInline; + +/** + * @brief Creates a SwkbdConfig struct. + * @param c SwkbdConfig struct. + * @param max_dictwords Max \ref SwkbdDictWord entries, 0 for none. + */ +Result swkbdCreate(SwkbdConfig* c, s32 max_dictwords); + +/** + * @brief Closes a SwkbdConfig struct. + * @param c SwkbdConfig struct. + */ +void swkbdClose(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the Default Preset. + * @note Do not use this before \ref swkbdCreate. + * @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_QWERTY, swkbdConfigSetInitialCursorPos() with value 1, swkbdConfigSetReturnButtonFlag() with value 1, and swkbdConfigSetBlurBackground() with value 1. Pre-5.0.0: swkbdConfigSetTextDrawType() with \ref SwkbdTextDrawType_Box. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetDefault(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the Password Preset. + * @note Do not use this before \ref swkbdCreate. + * @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_QWERTY, swkbdConfigSetInitialCursorPos() with value 1, swkbdConfigSetPasswordFlag() with value 1, and swkbdConfigSetBlurBackground() with value 1. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetPassword(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the UserName Preset. + * @note Do not use this before \ref swkbdCreate. + * @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_Normal, swkbdConfigSetKeySetDisableBitmask() with SwkbdKeyDisableBitmask_UserName, swkbdConfigSetInitialCursorPos() with value 1, and swkbdConfigSetBlurBackground() with value 1. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetUserName(SwkbdConfig* c); + +/** + * @brief Clears the args in the SwkbdConfig struct and initializes it with the DownloadCode Preset. + * @note Do not use this before \ref swkbdCreate. + * @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_Normal (\ref SwkbdType_QWERTY on [5.0.0+]), swkbdConfigSetKeySetDisableBitmask() with SwkbdKeyDisableBitmask_DownloadCode, swkbdConfigSetInitialCursorPos() with value 1, and swkbdConfigSetBlurBackground() with value 1. [5.0.0+]: swkbdConfigSetStringLenMax() with value 16, swkbdConfigSetStringLenMin() with value 1, and swkbdConfigSetTextDrawType() with SwkbdTextDrawType_DownloadCode. Uses swkbdConfigSetTextGrouping() for [0-2] with: 0x3, 0x7, and 0xb. + * @param c SwkbdConfig struct. + */ +void swkbdConfigMakePresetDownloadCode(SwkbdConfig* c); + +/** + * @brief Sets the Ok button text. The default is "". + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetOkButtonText(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the LeftOptionalSymbolKey, for \ref SwkbdType_NumPad. The default is "". + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetLeftOptionalSymbolKey(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the RightOptionalSymbolKey, for \ref SwkbdType_NumPad. The default is "". + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetRightOptionalSymbolKey(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the Header text. The default is "". + * @note See SwkbdArgCommon::stringLenMax. + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetHeaderText(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the Sub text. The default is "". + * @note See SwkbdArgCommon::stringLenMax. + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetSubText(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the Guide text. The default is "". + * @note The swkbd applet only displays this when the current displayed cursor position is 0. + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetGuideText(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the Initial text. The default is "". + * @param c SwkbdConfig struct. + * @param str UTF-8 input string. + */ +void swkbdConfigSetInitialText(SwkbdConfig* c, const char* str); + +/** + * @brief Sets the user dictionary. + * @param c SwkbdConfig struct. + * @param input Input data. + * @param entries Total entries in the buffer. + */ +void swkbdConfigSetDictionary(SwkbdConfig* c, const SwkbdDictWord *input, s32 entries); + +/** + * @brief Sets the CustomizedDictionaries. + * @note Only available on [6.0.0+]. + * @param c SwkbdConfig struct. + * @param dic Input \ref SwkbdCustomizedDictionarySet + */ +Result swkbdConfigSetCustomizedDictionaries(SwkbdConfig* c, const SwkbdCustomizedDictionarySet *dic); + +/** + * @brief Sets the TextCheck callback. + * @param c SwkbdConfig struct. + * @param cb \ref SwkbdTextCheckCb callback. + */ +void swkbdConfigSetTextCheckCallback(SwkbdConfig* c, SwkbdTextCheckCb cb); + +/** + * @brief Sets SwkbdArgCommon::SwkbdType. + * @param c SwkbdConfig struct. + * @param type \ref SwkbdType + */ +static inline void swkbdConfigSetType(SwkbdConfig* c, SwkbdType type) { + c->arg.arg.arg.type = type; +} + +/** + * @brief Sets SwkbdArgCommon::dicFlag. + * @param c SwkbdConfig struct. + * @param flag Flag + */ +static inline void swkbdConfigSetDicFlag(SwkbdConfig* c, u8 flag) { + c->arg.arg.arg.dicFlag = flag; +} + +/** + * @brief Sets SwkbdArgCommon::keySetDisableBitmask. + * @param c SwkbdConfig struct. + * @param keySetDisableBitmask keySetDisableBitmask + */ +static inline void swkbdConfigSetKeySetDisableBitmask(SwkbdConfig* c, u32 keySetDisableBitmask) { + c->arg.arg.arg.keySetDisableBitmask = keySetDisableBitmask; +} + +/** + * @brief Sets SwkbdArgCommon::initialCursorPos. + * @param c SwkbdConfig struct. + * @param initialCursorPos initialCursorPos + */ +static inline void swkbdConfigSetInitialCursorPos(SwkbdConfig* c, u32 initialCursorPos) { + c->arg.arg.arg.initialCursorPos = initialCursorPos; +} + +/** + * @brief Sets SwkbdArgCommon::stringLenMax. + * @param c SwkbdConfig struct. + * @param stringLenMax stringLenMax + */ +static inline void swkbdConfigSetStringLenMax(SwkbdConfig* c, u32 stringLenMax) { + c->arg.arg.arg.stringLenMax = stringLenMax; +} + +/** + * @brief Sets SwkbdArgCommon::stringLenMin. + * @param c SwkbdConfig struct. + * @param stringLenMin stringLenMin + */ +static inline void swkbdConfigSetStringLenMin(SwkbdConfig* c, u32 stringLenMin) { + c->arg.arg.arg.stringLenMin = stringLenMin; +} + +/** + * @brief Sets SwkbdArgCommon::passwordFlag. + * @param c SwkbdConfig struct. + * @param flag Flag + */ +static inline void swkbdConfigSetPasswordFlag(SwkbdConfig* c, u32 flag) { + c->arg.arg.arg.passwordFlag = flag; +} + +/** + * @brief Sets SwkbdArgCommon::textDrawType. + * @param c SwkbdConfig struct. + * @param textDrawType \ref SwkbdTextDrawType + */ +static inline void swkbdConfigSetTextDrawType(SwkbdConfig* c, SwkbdTextDrawType textDrawType) { + c->arg.arg.arg.textDrawType = textDrawType; +} + +/** + * @brief Sets SwkbdArgCommon::returnButtonFlag. + * @param c SwkbdConfig struct. + * @param flag Flag + */ +static inline void swkbdConfigSetReturnButtonFlag(SwkbdConfig* c, u16 flag) { + c->arg.arg.arg.returnButtonFlag = flag; +} + +/** + * @brief Sets SwkbdArgCommon::blurBackground. + * @param c SwkbdConfig struct. + * @param blurBackground blurBackground + */ +static inline void swkbdConfigSetBlurBackground(SwkbdConfig* c, u8 blurBackground) { + c->arg.arg.arg.blurBackground = blurBackground; +} + +/** + * @brief Sets SwkbdArgV7::textGrouping. + * @param index Array index. + * @param value Value to write. + */ +static inline void swkbdConfigSetTextGrouping(SwkbdConfig* c, u32 index, u32 value) { + if (index >= sizeof(c->arg.textGrouping)/sizeof(u32)) return; + c->arg.textGrouping[index] = value; +} + +/** + * @brief Sets SwkbdConfig::unkFlag, default is 0. Copied to SwkbdArgVB::unkFlag with [8.0.0+]. + * @param flag Flag + */ +static inline void swkbdConfigSetUnkFlag(SwkbdConfig* c, u8 flag) { + c->unkFlag = flag; +} + +/** + * @brief Sets SwkbdConfig::trigger, default is 0. Copied to SwkbdArgVB::trigger with [8.0.0+]. + * @param trigger Trigger + */ +static inline void swkbdConfigSetTrigger(SwkbdConfig* c, u8 trigger) { + c->trigger = trigger; +} + +/** + * @brief Launch swkbd with the specified config. This will return once swkbd is finished running. + * @note The string buffer is also used for the buffer passed to the \ref SwkbdTextCheckCb, when it's set. Hence, in that case this buffer should be large enough to handle TextCheck string input/output. The size passed to the callback is the same size passed here, -1. + * @param c SwkbdConfig struct. + * @param out_string UTF-8 Output string buffer. + * @param out_string_size UTF-8 Output string buffer size, including NUL-terminator. + */ +Result swkbdShow(SwkbdConfig* c, char* out_string, size_t out_string_size); + +/** + * @brief Creates a SwkbdInline object. Only available on [2.0.0+]. + * @note This is essentially an asynchronous version of the regular swkbd. + * @note This calls \ref swkbdInlineSetUtf8Mode internally with flag=true. + * @param s SwkbdInline object. + */ +Result swkbdInlineCreate(SwkbdInline* s); + +/** + * @brief Closes a SwkbdInline object. If the applet is running, this will tell the applet to exit, then wait for the applet to exit + applet exit handling. + * @param s SwkbdInline object. + */ +Result swkbdInlineClose(SwkbdInline* s); + +/** + * @brief Does setup for \ref SwkbdInitializeArg and launches the applet with the SwkbdInline object. + * @note The initArg is cleared, and on [5.0.0+] unk_x5 is set to 1. + * @param s SwkbdInline object. + */ +Result swkbdInlineLaunch(SwkbdInline* s); + +/** + * @brief Same as \ref swkbdInlineLaunch, except mode and unk_x5 for \ref SwkbdInitializeArg are set to the input params. + * @param s SwkbdInline object. + * @param mode Value for SwkbdInitializeArg::mode. + * @param unk_x5 Value for SwkbdInitializeArg::unk_x5. + */ +Result swkbdInlineLaunchForLibraryApplet(SwkbdInline* s, u8 mode, u8 unk_x5); + +/** + * @brief GetWindowSize + * @param[out] width Output width. + * @param[out] height Output height. + */ +NX_CONSTEXPR void swkbdInlineGetWindowSize(s32 *width, s32 *height) { + *width = 1280; + *height = 720; +} + +/** + * @brief GetImageMemoryRequirement + * @note Wrapper for \ref viGetIndirectLayerImageRequiredMemoryInfo. + * @param[out] out_size Output size. + * @param[out] out_alignment Output alignment. + */ +Result swkbdInlineGetImageMemoryRequirement(u64 *out_size, u64 *out_alignment); + +/** + * @brief GetImage + * @note Only available with ::SwkbdInlineMode_UserDisplay. + * @note For width/height, see \ref swkbdInlineGetWindowSize. + * @param s SwkbdInline object. + * @param[out] buffer Output RGBA8 image buffer, this must use the alignment from \ref swkbdInlineGetImageMemoryRequirement. + * @param[in] size Output buffer size, this must match the size from \ref swkbdInlineGetImageMemoryRequirement. + * @param[out] data_available Whether data is available. + */ +Result swkbdInlineGetImage(SwkbdInline* s, void* buffer, u64 size, bool *data_available); + +/** + * @brief Gets the image max height, relative to the bottom of the screen. + * @param s SwkbdInline object. + */ +s32 swkbdInlineGetMaxHeight(SwkbdInline* s); + +/** + * @brief Gets the MiniaturizedHeight, relative to the bottom of the screen. + * @param s SwkbdInline object. + */ +s32 swkbdInlineGetMiniaturizedHeight(SwkbdInline* s); + +/** + * @brief GetTouchRectangles. Returns number of valid Rects: 1 for only keytop, 2 for keytop/footer. + * @param s SwkbdInline object. + * @param[out] keytop \ref SwkbdRect for keytop. Optional, can be NULL. + * @param[out] footer \ref SwkbdRect for footer. Optional, can be NULL. + */ +s32 swkbdInlineGetTouchRectangles(SwkbdInline* s, SwkbdRect *keytop, SwkbdRect *footer); + +/** + * @brief Gets whether the input x/y are within the output from \ref swkbdInlineGetTouchRectangles. + * @param s SwkbdInline object. + * @param[out] x X + * @param[out] y Y + */ +bool swkbdInlineIsUsedTouchPointByKeyboard(SwkbdInline* s, s32 x, s32 y); + +/** + * @brief Handles updating SwkbdInline state, this should be called periodically. + * @note Handles applet exit if needed, and also sends the \ref SwkbdInlineCalcArg to the applet if needed. Hence, this should be called at some point after writing to \ref SwkbdInlineCalcArg. + * @note Handles applet Interactive storage output when needed. + * @param s SwkbdInline object. + * @param out_state Optional output \ref SwkbdState. + */ +Result swkbdInlineUpdate(SwkbdInline* s, SwkbdState* out_state); + +/** + * @brief Sets the FinishedInitialize callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @param s SwkbdInline object. + * @param cb Callback + */ +void swkbdInlineSetFinishedInitializeCallback(SwkbdInline* s, VoidFn cb); + +/** + * @brief Sets the DecidedCancel callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @param s SwkbdInline object. + * @param cb Callback + */ +void swkbdInlineSetDecidedCancelCallback(SwkbdInline* s, VoidFn cb); + +/** + * @brief Sets the ChangedString callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @note This clears the callback set by \ref swkbdInlineSetChangedStringV2Callback. + * @note This should be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. + * @param s SwkbdInline object. + * @param cb \ref SwkbdChangedStringCb Callback + */ +void swkbdInlineSetChangedStringCallback(SwkbdInline* s, SwkbdChangedStringCb cb); + +/** + * @brief Sets the ChangedStringV2 callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @note Only available with [8.0.0+]. + * @note This must be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. + * @param s SwkbdInline object. + * @param cb \ref SwkbdChangedStringV2Cb Callback + */ +void swkbdInlineSetChangedStringV2Callback(SwkbdInline* s, SwkbdChangedStringV2Cb cb); + +/** + * @brief Sets the MovedCursor callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @note This clears the callback set by \ref swkbdInlineSetMovedCursorV2Callback. + * @note This should be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. + * @param s SwkbdInline object. + * @param cb \ref SwkbdMovedCursorCb Callback + */ +void swkbdInlineSetMovedCursorCallback(SwkbdInline* s, SwkbdMovedCursorCb cb); + +/** + * @brief Sets the MovedCursorV2 callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @note Only available with [8.0.0+]. + * @note This must be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. + * @param s SwkbdInline object. + * @param cb \ref SwkbdMovedCursorV2Cb Callback + */ +void swkbdInlineSetMovedCursorV2Callback(SwkbdInline* s, SwkbdMovedCursorV2Cb cb); + +/** + * @brief Sets the MovedTab callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @param s SwkbdInline object. + * @param cb \ref SwkbdMovedTabCb Callback + */ +void swkbdInlineSetMovedTabCallback(SwkbdInline* s, SwkbdMovedTabCb cb); + +/** + * @brief Sets the DecidedEnter callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @param s SwkbdInline object. + * @param cb \ref SwkbdDecidedEnterCb Callback + */ +void swkbdInlineSetDecidedEnterCallback(SwkbdInline* s, SwkbdDecidedEnterCb cb); + +/** + * @brief Sets the ReleasedUserWordInfo callback, used by \ref swkbdInlineUpdate. The default is NULL for none. + * @param s SwkbdInline object. + * @param cb Callback + */ +void swkbdInlineSetReleasedUserWordInfoCallback(SwkbdInline* s, VoidFn cb); + +/** + * @brief Appear the kbd and set \ref SwkbdAppearArg. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Wrapper for \ref swkbdInlineAppearEx, with trigger=0. + * @param s SwkbdInline object. + * @param arg Input SwkbdAppearArg. + */ +void swkbdInlineAppear(SwkbdInline* s, const SwkbdAppearArg* arg); + +/** + * @brief Appear the kbd and set \ref SwkbdAppearArg. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param arg Input SwkbdAppearArg. + * @param trigger Trigger, default is 0. Requires [6.0.0+], on eariler versions this will always use value 0 internally. + */ +void swkbdInlineAppearEx(SwkbdInline* s, const SwkbdAppearArg* arg, u8 trigger); + +/** + * @brief Disappear the kbd. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + */ +void swkbdInlineDisappear(SwkbdInline* s); + +/** + * @brief Creates a \ref SwkbdAppearArg which can then be passed to \ref swkbdInlineAppear. arg is initialized with the defaults, with type being set to the input type. + * @param arg Output \ref SwkbdAppearArg. + * @param type \ref SwkbdType type + */ +void swkbdInlineMakeAppearArg(SwkbdAppearArg* arg, SwkbdType type); + +/** + * @brief Sets okButtonText for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. + * @param arg \ref SwkbdAppearArg + * @param str Input UTF-8 string for the Ok button text, this can be empty/NULL to use the default. + */ +void swkbdInlineAppearArgSetOkButtonText(SwkbdAppearArg* arg, const char* str); + +/** + * @brief Sets the LeftButtonText, for \ref SwkbdType_NumPad. The default is "". Equivalent to \ref swkbdConfigSetLeftOptionalSymbolKey. + * @param arg \ref SwkbdAppearArg, previously initialized by \ref swkbdInlineMakeAppearArg. + * @param str UTF-8 input string. + */ +void swkbdInlineAppearArgSetLeftButtonText(SwkbdAppearArg* arg, const char* str); + +/** + * @brief Sets the RightButtonText, for \ref SwkbdType_NumPad. The default is "". Equivalent to \ref swkbdConfigSetRightOptionalSymbolKey. + * @param arg \ref SwkbdAppearArg, previously initialized by \ref swkbdInlineMakeAppearArg. + * @param str UTF-8 input string. + */ +void swkbdInlineAppearArgSetRightButtonText(SwkbdAppearArg* arg, const char* str); + +/** + * @brief Sets the stringLenMax for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. + * @param arg \ref SwkbdAppearArg + * @param stringLenMax Max string length + */ +static inline void swkbdInlineAppearArgSetStringLenMax(SwkbdAppearArg* arg, s32 stringLenMax) { + arg->stringLenMax = stringLenMax; +} + +/** + * @brief Sets the stringLenMin for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. + * @param arg \ref SwkbdAppearArg + * @param stringLenMin Min string length + */ +static inline void swkbdInlineAppearArgSetStringLenMin(SwkbdAppearArg* arg, s32 stringLenMin) { + arg->stringLenMin = stringLenMin; +} + +/** + * @brief Sets the audio volume. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param volume Volume + */ +void swkbdInlineSetVolume(SwkbdInline* s, float volume); + +/** + * @brief Sets the current input text string. Overrides the entire user input string if the user previously entered any text. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note This will not affect the cursor position, see \ref swkbdInlineSetCursorPos for that. + * @param s SwkbdInline object. + * @param str UTF-8 input string. + */ +void swkbdInlineSetInputText(SwkbdInline* s, const char* str); + +/** + * @brief Sets the cursor character position in the string. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param pos Position + */ +void swkbdInlineSetCursorPos(SwkbdInline* s, s32 pos); + +/** + * @brief Sets the UserWordInfo. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this was already used previously. + * @note The specified buffer must not be used after this, until \ref swkbdInlineClose is used. + * @note \ref swkbdInlineUpdate must be called at some point afterwards. + * @note If input==NULL or total_entries==0, this will just call \ref swkbdInlineUnsetUserWordInfo internally. + * @param s SwkbdInline object. + * @param input Input data. + * @param entries Total entries in the buffer. + */ +Result swkbdInlineSetUserWordInfo(SwkbdInline* s, const SwkbdDictWord *input, s32 entries); + +/** + * @brief Request UnsetUserWordInfo. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. + * @param s SwkbdInline object. + */ +Result swkbdInlineUnsetUserWordInfo(SwkbdInline* s); + +/** + * @brief Sets the utf8Mode. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Automatically used internally by \ref swkbdInlineCreate. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetUtf8Mode(SwkbdInline* s, bool flag); + +/** + * @brief Sets the CustomizeDic. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this or \ref swkbdInlineSetCustomizedDictionaries was already used previously. + * @note The specified buffer must not be used after this, until \ref swkbdInlineClose is used. However, it will also become available once \ref swkbdInlineUpdate handles SwkbdReplyType_UnsetCustomizeDic internally. + * @param s SwkbdInline object. + * @param buffer 0x1000-byte aligned buffer. + * @param size 0x1000-byte aligned buffer size. + * @param info Input \ref SwkbdCustomizeDicInfo + */ +Result swkbdInlineSetCustomizeDic(SwkbdInline* s, void* buffer, size_t size, SwkbdCustomizeDicInfo *info); + +/** + * @brief Request UnsetCustomizeDic. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. + * @param s SwkbdInline object. + */ +void swkbdInlineUnsetCustomizeDic(SwkbdInline* s); + +/** + * @brief Sets the CustomizedDictionaries. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this or \ref swkbdInlineSetCustomizeDic was already used previously. + * @note The specified buffer in dic must not be used after this, until \ref swkbdInlineClose is used. However, it will also become available once \ref swkbdInlineUpdate handles SwkbdReplyType_UnsetCustomizedDictionaries internally. + * @note Only available on [6.0.0+]. + * @param s SwkbdInline object. + * @param dic Input \ref SwkbdCustomizedDictionarySet + */ +Result swkbdInlineSetCustomizedDictionaries(SwkbdInline* s, const SwkbdCustomizedDictionarySet *dic); + +/** + * @brief Request UnsetCustomizedDictionaries. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. + * @note Only available on [6.0.0+]. + * @param s SwkbdInline object. + */ +Result swkbdInlineUnsetCustomizedDictionaries(SwkbdInline* s); + +/** + * @brief Sets InputModeFadeType. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param type Type + */ +void swkbdInlineSetInputModeFadeType(SwkbdInline* s, u8 type); + +/** + * @brief Sets AlphaEnabledInInputMode. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetAlphaEnabledInInputMode(SwkbdInline* s, bool flag); + +/** + * @brief Sets KeytopBgAlpha. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param alpha Alpha, clamped to range 0.0f..1.0f. + */ +void swkbdInlineSetKeytopBgAlpha(SwkbdInline* s, float alpha); + +/** + * @brief Sets FooterBgAlpha. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param alpha Alpha, clamped to range 0.0f..1.0f. + */ +void swkbdInlineSetFooterBgAlpha(SwkbdInline* s, float alpha); + +/** + * @brief Sets gfx scaling. Configures KeytopScale* and BalloonScale based on the input value. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note The BalloonScale is not updated when \ref SwkbdState is above ::SwkbdState_Initialized. + * @param s SwkbdInline object. + * @param scale Scale + */ +void swkbdInlineSetKeytopScale(SwkbdInline* s, float scale); + +/** + * @brief Sets gfx translation for the displayed swkbd image position. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param x X + * @param y Y + */ +void swkbdInlineSetKeytopTranslate(SwkbdInline* s, float x, float y); + +/** + * @brief Sets KeytopAsFloating. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetKeytopAsFloating(SwkbdInline* s, bool flag); + +/** + * @brief Sets FooterScalable. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetFooterScalable(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether touch is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetTouchFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether Hardware-keyboard is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetHardwareKeyboardFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether DirectionalButtonAssign is enabled. The default is disabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Only available on [4.0.0+]. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetDirectionalButtonAssignFlag(SwkbdInline* s, bool flag); + +/** + * @brief Sets whether the specified SeGroup (sound effect) is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. If called again with a different seGroup, \ref swkbdInlineUpdate must be called prior to calling this again. + * @note Only available on [5.0.0+]. + * @param s SwkbdInline object. + * @param seGroup SeGroup + * @param flag Flag + */ +void swkbdInlineSetSeGroup(SwkbdInline* s, u8 seGroup, bool flag); + +/** + * @brief Sets whether the backspace button is enabled. The default is enabled. + * @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. + * @note Only available on [5.0.0+]. + * @param s SwkbdInline object. + * @param flag Flag + */ +void swkbdInlineSetBackspaceFlag(SwkbdInline* s, bool flag); + diff --git a/src/libnx/wrapper/switch/applets/swkbd.nim b/src/libnx/wrapper/switch/applets/swkbd.nim new file mode 100644 index 0000000..de9d943 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/swkbd.nim @@ -0,0 +1,1139 @@ +## * +## @file swkbd.h +## @brief Wrapper for using the swkbd (software keyboard) LibraryApplet. +## @author yellowS8 +## @copyright libnx Authors +## + +import + ../types, ../services/applet + +## / Output result returned by \ref SwkbdTextCheckCb. + +type + SwkbdTextCheckResult* = enum + SwkbdTextCheckResultOK = 0, ## /< Success, valid string. + SwkbdTextCheckResultBad = 1, ## /< Failure, invalid string. Error message is displayed in a message-box, pressing OK will return to swkbd again. + SwkbdTextCheckResultPrompt = 2, ## /< Failure, invalid string. Error message is displayed in a message-box, pressing Cancel will return to swkbd again, while pressing OK will continue as if the text was valid. + SwkbdTextCheckResultSilent = 3 ## /< Failure, invalid string. With value 3 and above, swkbd will silently not accept the string, without displaying any error. + + +## / Type of keyboard. + +type + SwkbdType* = enum + SwkbdTypeNormal = 0, ## /< Normal keyboard. + SwkbdTypeNumPad = 1, ## /< Number pad. The buttons at the bottom left/right are only available when they're set by \ref swkbdConfigSetLeftOptionalSymbolKey / \ref swkbdConfigSetRightOptionalSymbolKey. + SwkbdTypeQWERTY = 2, ## /< QWERTY (and variants) keyboard only. + SwkbdTypeUnknown3 = 3, ## /< The same as SwkbdType_Normal keyboard. + SwkbdTypeLatin = 4, ## /< All Latin like languages keyboard only (without CJK keyboard). + SwkbdTypeZhHans = 5, ## /< Chinese Simplified keyboard only. + SwkbdTypeZhHant = 6, ## /< Chinese Traditional keyboard only. + SwkbdTypeKorean = 7, ## /< Korean keyboard only. + SwkbdTypeAll = 8, ## /< All language keyboards. + SwkbdTypeUnknown9 = 9 ## /< Unknown + + +## / Bitmask for SwkbdArgCommon::keySetDisableBitmask. This disables keys on the keyboard when the corresponding bit(s) are set. + +const + SwkbdKeyDisableBitmaskSpace* = bit(1) ## /< Disable space-bar. + SwkbdKeyDisableBitmaskAt* = bit(2) ## /< Disable '@'. + SwkbdKeyDisableBitmaskPercent* = bit(3) ## /< Disable '%'. + SwkbdKeyDisableBitmaskForwardSlash* = bit(4) ## /< Disable '/'. + SwkbdKeyDisableBitmaskBackslash* = bit(5) ## /< Disable '\'. + SwkbdKeyDisableBitmaskNumbers* = bit(6) ## /< Disable numbers. + SwkbdKeyDisableBitmaskDownloadCode* = bit(7) ## /< Used for \ref swkbdConfigMakePresetDownloadCode. + SwkbdKeyDisableBitmaskUserName* = bit(8) ## /< Used for \ref swkbdConfigMakePresetUserName. Disables '@', '%', and '\'. + +## / Value for SwkbdArgCommon::textDrawType. Only applies when stringLenMax is 1..32, otherwise swkbd will only use SwkbdTextDrawType_Box. + +type + SwkbdTextDrawType* = enum + SwkbdTextDrawTypeLine = 0, ## /< The text will be displayed on a line. Also enables displaying the Header and Sub text. + SwkbdTextDrawTypeBox = 1, ## /< The text will be displayed in a box. + SwkbdTextDrawTypeDownloadCode = 2 ## /< Used by \ref swkbdConfigMakePresetDownloadCode on [5.0.0+]. Enables using \ref SwkbdArgV7 unk_x3e0. + + +## / SwkbdInline Interactive input storage request ID. + +type + SwkbdRequestCommand* = enum + SwkbdRequestCommandFinalize = 0x4, SwkbdRequestCommandSetUserWordInfo = 0x6, + SwkbdRequestCommandSetCustomizeDic = 0x7, SwkbdRequestCommandCalc = 0xA, + SwkbdRequestCommandSetCustomizedDictionaries = 0xB, + SwkbdRequestCommandUnsetCustomizedDictionaries = 0xC, + SwkbdRequestCommandSetChangedStringV2Flag = 0xD, + SwkbdRequestCommandSetMovedCursorV2Flag = 0xE + + +## / SwkbdInline Interactive output storage reply ID. + +type + SwkbdReplyType* = enum + SwkbdReplyTypeFinishedInitialize = 0x0, SwkbdReplyTypeChangedString = 0x2, + SwkbdReplyTypeMovedCursor = 0x3, SwkbdReplyTypeMovedTab = 0x4, + SwkbdReplyTypeDecidedEnter = 0x5, SwkbdReplyTypeDecidedCancel = 0x6, + SwkbdReplyTypeChangedStringUtf8 = 0x7, SwkbdReplyTypeMovedCursorUtf8 = 0x8, + SwkbdReplyTypeDecidedEnterUtf8 = 0x9, SwkbdReplyTypeUnsetCustomizeDic = 0xA, + SwkbdReplyTypeReleasedUserWordInfo = 0xB, + SwkbdReplyTypeUnsetCustomizedDictionaries = 0xC, + SwkbdReplyTypeChangedStringV2 = 0xD, SwkbdReplyTypeMovedCursorV2 = 0xE, + SwkbdReplyTypeChangedStringUtf8V2 = 0xF, SwkbdReplyTypeMovedCursorUtf8V2 = 0x10 + + +## / SwkbdInline State + +type + SwkbdState* = enum + SwkbdStateInactive = 0x0, ## /< Default state from \ref swkbdInlineCreate, before a state is set by \ref swkbdInlineUpdate when a reply is received. Also indicates that the applet is no longer running. + SwkbdStateInitialized = 0x1, ## /< Applet is initialized but hidden. + SwkbdStateAppearing = 0x2, ## /< Applet is appearing. + SwkbdStateShown = 0x3, ## /< Applet is fully shown and ready to accept text input. + SwkbdStateDisappearing = 0x4, ## /< The user pressed the ok or cancel button, causing the applet to disappear. + SwkbdStateUnknown5 = 0x5, SwkbdStateUnknown6 = 0x6 + + +## / Value for \ref SwkbdInitializeArg mode. Controls the LibAppletMode when launching the applet. + +type + SwkbdInlineMode* = enum + SwkbdInlineModeUserDisplay = 0, ## /< LibAppletMode_BackgroundIndirect. This is the default. The user-process must handle displaying the swkbd gfx on the screen, by loading the image with \ref swkbdInlineGetImage. + SwkbdInlineModeAppletDisplay = 1 ## /< LibAppletMode_Background. The applet will handle displaying gfx on the screen. + + +## / TextCheck callback set by \ref swkbdConfigSetTextCheckCallback, for validating the input string when the swkbd ok-button is pressed. This buffer contains an UTF-8 string. This callback should validate the input string, then return a \ref SwkbdTextCheckResult indicating success/failure. On failure, this function must write an error message to the tmp_string buffer, which will then be displayed by swkbd. + +type + SwkbdTextCheckCb* = proc (tmpString: cstring; tmpStringSize: csize_t): SwkbdTextCheckResult {. + cdecl.} + +## / User dictionary word. + +type + SwkbdDictWord* {.bycopy.} = object + unkX0*: array[0x64, U8] + + +## / Input data for SwkbdInline request SetCustomizeDic. + +type + SwkbdCustomizeDicInfo* {.bycopy.} = object + unkX0*: array[0x70, U8] + + SwkbdCustomizedDictionarySet* {.bycopy.} = object + buffer*: pointer ## /< 0x1000-byte aligned buffer. + bufferSize*: U32 ## /< 0x1000-byte aligned buffer size. + entries*: array[0x18, U64] + totalEntries*: U16 + + +## / Base swkbd arg struct. + +type + SwkbdArgCommon* {.bycopy.} = object + `type`*: SwkbdType ## /< See \ref SwkbdType. + okButtonText*: array[18 div 2, U16] + leftButtonText*: U16 + rightButtonText*: U16 + dicFlag*: U8 ## /< Enables dictionary usage when non-zero (including the system dictionary). + padX1b*: U8 + keySetDisableBitmask*: U32 ## /< See SwkbdKeyDisableBitmask_*. + initialCursorPos*: U32 ## /< Initial cursor position in the string: 0 = start, 1 = end. + headerText*: array[130 div 2, U16] + subText*: array[258 div 2, U16] + guideText*: array[514 div 2, U16] + padX3aa*: U16 + stringLenMax*: U32 ## /< When non-zero, specifies the max string length. When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace). See also \ref SwkbdTextDrawType. + stringLenMin*: U32 ## /< When non-zero, specifies the min string length. When the input is too short, swkbd will display an icon and disable the ok-button. + passwordFlag*: U32 ## /< Use password: 0 = disable, 1 = enable. + textDrawType*: SwkbdTextDrawType ## /< See \ref SwkbdTextDrawType. + returnButtonFlag*: U16 ## /< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. + blurBackground*: U8 ## /< When enabled with value 1, the background is blurred. + padX3bf*: U8 + initialStringOffset*: U32 + initialStringSize*: U32 + userDicOffset*: U32 + userDicEntries*: S32 + textCheckFlag*: U8 + + SwkbdArgV0* {.bycopy.} = object + arg*: SwkbdArgCommon + padX3d1*: array[7, U8] + textCheckCb*: SwkbdTextCheckCb ## /< This really doesn't belong in a struct sent to another process, but official sw does this. + + +## / Arg struct for version 0x30007+. + +type + SwkbdArgV7* {.bycopy.} = object + arg*: SwkbdArgV0 + textGrouping*: array[8, U32] ## /< When set and enabled via \ref SwkbdTextDrawType, controls displayed text grouping (inserts spaces, without affecting output string). + + +## / Arg struct for version 0x6000B+. + +type + SwkbdArgVB* {.bycopy.} = object + arg*: SwkbdArgCommon + padX3d1*: array[3, U8] + textGrouping*: array[8, U32] ## /< Same as SwkbdArgV7::textGrouping. + entries*: array[0x18, U64] ## /< This is SwkbdCustomizedDictionarySet::entries. + totalEntries*: U8 ## /< This is SwkbdCustomizedDictionarySet::total_entries. + unkFlag*: U8 ## /< [8.0.0+] + padX4b6*: array[0xD, U8] + trigger*: U8 ## /< [8.0.0+] + padX4c4*: array[4, U8] + + SwkbdConfig* {.bycopy.} = object + arg*: SwkbdArgV7 + workbuf*: ptr U8 + workbufSize*: csize_t + maxDictwords*: S32 + customizedDictionarySet*: SwkbdCustomizedDictionarySet + unkFlag*: U8 + trigger*: U8 + version*: U32 + + +## / Rect + +type + SwkbdRect* {.bycopy.} = object + x*: S16 ## /< X + y*: S16 ## /< Y + width*: S16 ## /< Width + height*: S16 ## /< Height + + +## / InitializeArg for SwkbdInline. + +type + SwkbdInitializeArg* {.bycopy.} = object + unkX0*: U32 + mode*: U8 ## /< See \ref SwkbdInlineMode. (U8 bool) + unkX5*: U8 ## /< Only set on [5.0.0+]. + pad*: array[2, U8] + + SwkbdAppearArg* {.bycopy.} = object + `type`*: SwkbdType ## /< See \ref SwkbdType. + okButtonText*: array[9, U16] + leftButtonText*: U16 + rightButtonText*: U16 + dicFlag*: U8 ## /< Enables dictionary usage when non-zero (including the system dictionary). + unkX1b*: U8 + keySetDisableBitmask*: U32 ## /< See SwkbdKeyDisableBitmask_*. + stringLenMax*: S32 ## /< When non-negative and non-zero, specifies the max string length. When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace). + stringLenMin*: S32 ## /< When non-negative and non-zero, specifies the min string length. When the input is too short, swkbd will display an icon and disable the ok-button. + returnButtonFlag*: U8 ## /< Controls whether the Return button is enabled, for newlines input. 0 = disabled, non-zero = enabled. + unkX29*: U8 ## /< [10.0.0+] When value 1-2, \ref swkbdInlineAppear / \ref swkbdInlineAppearEx will set keytopAsFloating=0 and footerScalable=1. + unkX2a*: U8 + unkX2b*: U8 + flags*: U32 ## /< Bitmask 0x4: unknown. + unkX30*: U8 + unkX31*: array[0x17, U8] + + SwkbdInlineCalcArg* {.bycopy.} = object + unkX0*: U32 + size*: U16 ## /< Size of this struct. + unkX6*: U8 + unkX7*: U8 + flags*: U64 + initArg*: SwkbdInitializeArg ## /< Flags bitmask 0x1. + volume*: cfloat ## /< Flags bitmask 0x2. + cursorPos*: S32 ## /< Flags bitmask 0x10. + appearArg*: SwkbdAppearArg + inputText*: array[0x3f4 div 2, U16] ## /< Flags bitmask 0x8. + utf8Mode*: U8 ## /< Flags bitmask 0x20. + unkX45d*: U8 + enableBackspace*: U8 ## /< Flags bitmask 0x8000. Only available with [5.0.0+]. + unkX45f*: array[3, U8] + keytopAsFloating*: U8 ## /< Flags bitmask 0x200. + footerScalable*: U8 ## /< Flags bitmask 0x100. + alphaEnabledInInputMode*: U8 ## /< Flags bitmask 0x100. + inputModeFadeType*: U8 ## /< Flags bitmask 0x100. + disableTouch*: U8 ## /< Flags bitmask 0x200. + disableHardwareKeyboard*: U8 ## /< Flags bitmask 0x800. + unkX468*: array[5, U8] + unkX46d*: U8 + unkX46e*: U8 + unkX46f*: U8 + keytopScaleX*: cfloat ## /< Flags bitmask 0x200. + keytopScaleY*: cfloat ## /< Flags bitmask 0x200. + keytopTranslateX*: cfloat ## /< Flags bitmask 0x200. + keytopTranslateY*: cfloat ## /< Flags bitmask 0x200. + keytopBgAlpha*: cfloat ## /< Flags bitmask 0x100. + footerBgAlpha*: cfloat ## /< Flags bitmask 0x100. + balloonScale*: cfloat ## /< Flags bitmask 0x200. + unkX48c*: cfloat + unkX490*: array[0xc, U8] + seGroup*: U8 ## /< Flags bitmask: enable=0x2000, disable=0x4000. Only available with [5.0.0+]. + triggerFlag*: U8 ## /< [6.0.0+] Enables using the trigger field when set. + trigger*: U8 ## /< [6.0.0+] Trigger + padX49f*: U8 + + +## / Struct data for SwkbdInline Interactive reply storage ChangedString*, at the end following the string. + +type + SwkbdChangedStringArg* {.bycopy.} = object + stringLen*: U32 ## /< String length in characters, without NUL-terminator. + dicStartCursorPos*: S32 ## /< Starting cursorPos for the current dictionary word in the current text string. -1 for none. + dicEndCursorPos*: S32 ## /< Ending cursorPos for the current dictionary word in the current text string. -1 for none. + cursorPos*: S32 ## /< Cursor position. + + +## / Struct data for SwkbdInline Interactive reply storage MovedCursor*, at the end following the string. + +type + SwkbdMovedCursorArg* {.bycopy.} = object + stringLen*: U32 ## /< String length in characters, without NUL-terminator. + cursorPos*: S32 ## /< Cursor position. + + +## / Struct data for SwkbdInline Interactive reply storage MovedTab*, at the end following the string. + +type + SwkbdMovedTabArg* {.bycopy.} = object + unkX0*: U32 + unkX4*: U32 + + +## / Struct data for SwkbdInline Interactive reply storage DecidedEnter*, at the end following the string. + +type + SwkbdDecidedEnterArg* {.bycopy.} = object + stringLen*: U32 ## /< String length in characters, without NUL-terminator. + + +## / This callback is used by \ref swkbdInlineUpdate when handling ChangedString* replies (text changed by the user or by \ref swkbdInlineSetInputText). +## / str is the UTF-8 string for the current text. + +type + SwkbdChangedStringCb* = proc (str: cstring; arg: ptr SwkbdChangedStringArg) {.cdecl.} + +## / This callback is used by \ref swkbdInlineUpdate when handling ChangedString*V2 replies (text changed by the user or by \ref swkbdInlineSetInputText). +## / str is the UTF-8 string for the current text. + +type + SwkbdChangedStringV2Cb* = proc (str: cstring; arg: ptr SwkbdChangedStringArg; + flag: bool) {.cdecl.} + +## / This callback is used by \ref swkbdInlineUpdate when handling MovedCursor* replies. +## / str is the UTF-8 string for the current text. + +type + SwkbdMovedCursorCb* = proc (str: cstring; arg: ptr SwkbdMovedCursorArg) {.cdecl.} + +## / This callback is used by \ref swkbdInlineUpdate when handling MovedCursor*V2 replies. +## / str is the UTF-8 string for the current text. + +type + SwkbdMovedCursorV2Cb* = proc (str: cstring; arg: ptr SwkbdMovedCursorArg; flag: bool) {. + cdecl.} + +## / This callback is used by \ref swkbdInlineUpdate when handling MovedTab* replies. +## / str is the UTF-8 string for the current text. + +type + SwkbdMovedTabCb* = proc (str: cstring; arg: ptr SwkbdMovedTabArg) {.cdecl.} + +## / This callback is used by \ref swkbdInlineUpdate when handling DecidedEnter* replies (when the final text was submitted via the button). +## / str is the UTF-8 string for the current text. + +type + SwkbdDecidedEnterCb* = proc (str: cstring; arg: ptr SwkbdDecidedEnterArg) {.cdecl.} + +## / InlineKeyboard + +type + SwkbdInline* {.bycopy.} = object + version*: U32 + holder*: AppletHolder + calcArg*: SwkbdInlineCalcArg + directionalButtonAssignFlag*: bool + state*: SwkbdState + dicCustomInitialized*: bool + customizedDictionariesInitialized*: bool + dicStorage*: AppletStorage + wordInfoInitialized*: bool + wordInfoStorage*: AppletStorage + interactiveTmpbuf*: ptr U8 + interactiveTmpbufSize*: csize_t + interactiveStrbuf*: cstring + interactiveStrbufSize*: csize_t + finishedInitializeCb*: VoidFn + decidedCancelCb*: VoidFn + changedStringCb*: SwkbdChangedStringCb + changedStringV2Cb*: SwkbdChangedStringV2Cb + movedCursorCb*: SwkbdMovedCursorCb + movedCursorV2Cb*: SwkbdMovedCursorV2Cb + movedTabCb*: SwkbdMovedTabCb + decidedEnterCb*: SwkbdDecidedEnterCb + releasedUserWordInfoCb*: VoidFn + +proc swkbdCreate*(c: ptr SwkbdConfig; maxDictwords: S32): Result {.cdecl, + importc: "swkbdCreate".} +## * +## @brief Creates a SwkbdConfig struct. +## @param c SwkbdConfig struct. +## @param max_dictwords Max \ref SwkbdDictWord entries, 0 for none. +## + +proc swkbdClose*(c: ptr SwkbdConfig) {.cdecl, importc: "swkbdClose".} +## * +## @brief Closes a SwkbdConfig struct. +## @param c SwkbdConfig struct. +## + +proc swkbdConfigMakePresetDefault*(c: ptr SwkbdConfig) {.cdecl, + importc: "swkbdConfigMakePresetDefault".} +## * +## @brief Clears the args in the SwkbdConfig struct and initializes it with the Default Preset. +## @note Do not use this before \ref swkbdCreate. +## @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_QWERTY, swkbdConfigSetInitialCursorPos() with value 1, swkbdConfigSetReturnButtonFlag() with value 1, and swkbdConfigSetBlurBackground() with value 1. Pre-5.0.0: swkbdConfigSetTextDrawType() with \ref SwkbdTextDrawType_Box. +## @param c SwkbdConfig struct. +## + +proc swkbdConfigMakePresetPassword*(c: ptr SwkbdConfig) {.cdecl, + importc: "swkbdConfigMakePresetPassword".} +## * +## @brief Clears the args in the SwkbdConfig struct and initializes it with the Password Preset. +## @note Do not use this before \ref swkbdCreate. +## @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_QWERTY, swkbdConfigSetInitialCursorPos() with value 1, swkbdConfigSetPasswordFlag() with value 1, and swkbdConfigSetBlurBackground() with value 1. +## @param c SwkbdConfig struct. +## + +proc swkbdConfigMakePresetUserName*(c: ptr SwkbdConfig) {.cdecl, + importc: "swkbdConfigMakePresetUserName".} +## * +## @brief Clears the args in the SwkbdConfig struct and initializes it with the UserName Preset. +## @note Do not use this before \ref swkbdCreate. +## @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_Normal, swkbdConfigSetKeySetDisableBitmask() with SwkbdKeyDisableBitmask_UserName, swkbdConfigSetInitialCursorPos() with value 1, and swkbdConfigSetBlurBackground() with value 1. +## @param c SwkbdConfig struct. +## + +proc swkbdConfigMakePresetDownloadCode*(c: ptr SwkbdConfig) {.cdecl, + importc: "swkbdConfigMakePresetDownloadCode".} +## * +## @brief Clears the args in the SwkbdConfig struct and initializes it with the DownloadCode Preset. +## @note Do not use this before \ref swkbdCreate. +## @note Uses the following: swkbdConfigSetType() with \ref SwkbdType_Normal (\ref SwkbdType_QWERTY on [5.0.0+]), swkbdConfigSetKeySetDisableBitmask() with SwkbdKeyDisableBitmask_DownloadCode, swkbdConfigSetInitialCursorPos() with value 1, and swkbdConfigSetBlurBackground() with value 1. [5.0.0+]: swkbdConfigSetStringLenMax() with value 16, swkbdConfigSetStringLenMin() with value 1, and swkbdConfigSetTextDrawType() with SwkbdTextDrawType_DownloadCode. Uses swkbdConfigSetTextGrouping() for [0-2] with: 0x3, 0x7, and 0xb. +## @param c SwkbdConfig struct. +## + +proc swkbdConfigSetOkButtonText*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetOkButtonText".} +## * +## @brief Sets the Ok button text. The default is "". +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetLeftOptionalSymbolKey*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetLeftOptionalSymbolKey".} +## * +## @brief Sets the LeftOptionalSymbolKey, for \ref SwkbdType_NumPad. The default is "". +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetRightOptionalSymbolKey*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetRightOptionalSymbolKey".} +## * +## @brief Sets the RightOptionalSymbolKey, for \ref SwkbdType_NumPad. The default is "". +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetHeaderText*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetHeaderText".} +## * +## @brief Sets the Header text. The default is "". +## @note See SwkbdArgCommon::stringLenMax. +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetSubText*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetSubText".} +## * +## @brief Sets the Sub text. The default is "". +## @note See SwkbdArgCommon::stringLenMax. +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetGuideText*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetGuideText".} +## * +## @brief Sets the Guide text. The default is "". +## @note The swkbd applet only displays this when the current displayed cursor position is 0. +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetInitialText*(c: ptr SwkbdConfig; str: cstring) {.cdecl, + importc: "swkbdConfigSetInitialText".} +## * +## @brief Sets the Initial text. The default is "". +## @param c SwkbdConfig struct. +## @param str UTF-8 input string. +## + +proc swkbdConfigSetDictionary*(c: ptr SwkbdConfig; input: ptr SwkbdDictWord; + entries: S32) {.cdecl, + importc: "swkbdConfigSetDictionary".} +## * +## @brief Sets the user dictionary. +## @param c SwkbdConfig struct. +## @param input Input data. +## @param entries Total entries in the buffer. +## + +proc swkbdConfigSetCustomizedDictionaries*(c: ptr SwkbdConfig; + dic: ptr SwkbdCustomizedDictionarySet): Result {.cdecl, + importc: "swkbdConfigSetCustomizedDictionaries".} +## * +## @brief Sets the CustomizedDictionaries. +## @note Only available on [6.0.0+]. +## @param c SwkbdConfig struct. +## @param dic Input \ref SwkbdCustomizedDictionarySet +## + +proc swkbdConfigSetTextCheckCallback*(c: ptr SwkbdConfig; cb: SwkbdTextCheckCb) {. + cdecl, importc: "swkbdConfigSetTextCheckCallback".} +## * +## @brief Sets the TextCheck callback. +## @param c SwkbdConfig struct. +## @param cb \ref SwkbdTextCheckCb callback. +## + +proc swkbdConfigSetType*(c: ptr SwkbdConfig; `type`: SwkbdType) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::SwkbdType. + ## @param c SwkbdConfig struct. + ## @param type \ref SwkbdType + ## + + c.arg.arg.arg.`type` = `type` + +proc swkbdConfigSetDicFlag*(c: ptr SwkbdConfig; flag: U8) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::dicFlag. + ## @param c SwkbdConfig struct. + ## @param flag Flag + ## + + c.arg.arg.arg.dicFlag = flag + +proc swkbdConfigSetKeySetDisableBitmask*(c: ptr SwkbdConfig; + keySetDisableBitmask: U32) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::keySetDisableBitmask. + ## @param c SwkbdConfig struct. + ## @param keySetDisableBitmask keySetDisableBitmask + ## + + c.arg.arg.arg.keySetDisableBitmask = keySetDisableBitmask + +proc swkbdConfigSetInitialCursorPos*(c: ptr SwkbdConfig; initialCursorPos: U32) {. + inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::initialCursorPos. + ## @param c SwkbdConfig struct. + ## @param initialCursorPos initialCursorPos + ## + + c.arg.arg.arg.initialCursorPos = initialCursorPos + +proc swkbdConfigSetStringLenMax*(c: ptr SwkbdConfig; stringLenMax: U32) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::stringLenMax. + ## @param c SwkbdConfig struct. + ## @param stringLenMax stringLenMax + ## + + c.arg.arg.arg.stringLenMax = stringLenMax + +proc swkbdConfigSetStringLenMin*(c: ptr SwkbdConfig; stringLenMin: U32) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::stringLenMin. + ## @param c SwkbdConfig struct. + ## @param stringLenMin stringLenMin + ## + + c.arg.arg.arg.stringLenMin = stringLenMin + +proc swkbdConfigSetPasswordFlag*(c: ptr SwkbdConfig; flag: U32) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::passwordFlag. + ## @param c SwkbdConfig struct. + ## @param flag Flag + ## + + c.arg.arg.arg.passwordFlag = flag + +proc swkbdConfigSetTextDrawType*(c: ptr SwkbdConfig; textDrawType: SwkbdTextDrawType) {. + inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::textDrawType. + ## @param c SwkbdConfig struct. + ## @param textDrawType \ref SwkbdTextDrawType + ## + + c.arg.arg.arg.textDrawType = textDrawType + +proc swkbdConfigSetReturnButtonFlag*(c: ptr SwkbdConfig; flag: U16) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::returnButtonFlag. + ## @param c SwkbdConfig struct. + ## @param flag Flag + ## + + c.arg.arg.arg.returnButtonFlag = flag + +proc swkbdConfigSetBlurBackground*(c: ptr SwkbdConfig; blurBackground: U8) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgCommon::blurBackground. + ## @param c SwkbdConfig struct. + ## @param blurBackground blurBackground + ## + + c.arg.arg.arg.blurBackground = blurBackground + +proc swkbdConfigSetTextGrouping*(c: ptr SwkbdConfig; index: U32; value: U32) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdArgV7::textGrouping. + ## @param index Array index. + ## @param value Value to write. + ## + + if index >= sizeof(c.arg.textGrouping) div sizeof(U32): + return + c.arg.textGrouping[index] = value + +proc swkbdConfigSetUnkFlag*(c: ptr SwkbdConfig; flag: U8) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdConfig::unkFlag, default is 0. Copied to SwkbdArgVB::unkFlag with [8.0.0+]. + ## @param flag Flag + ## + + c.unkFlag = flag + +proc swkbdConfigSetTrigger*(c: ptr SwkbdConfig; trigger: U8) {.inline, cdecl.} = + ## * + ## @brief Sets SwkbdConfig::trigger, default is 0. Copied to SwkbdArgVB::trigger with [8.0.0+]. + ## @param trigger Trigger + ## + + c.trigger = trigger + +proc swkbdShow*(c: ptr SwkbdConfig; outString: cstring; outStringSize: csize_t): Result {. + cdecl, importc: "swkbdShow".} +## * +## @brief Launch swkbd with the specified config. This will return once swkbd is finished running. +## @note The string buffer is also used for the buffer passed to the \ref SwkbdTextCheckCb, when it's set. Hence, in that case this buffer should be large enough to handle TextCheck string input/output. The size passed to the callback is the same size passed here, -1. +## @param c SwkbdConfig struct. +## @param out_string UTF-8 Output string buffer. +## @param out_string_size UTF-8 Output string buffer size, including NUL-terminator. +## + +proc swkbdInlineCreate*(s: ptr SwkbdInline): Result {.cdecl, + importc: "swkbdInlineCreate".} +## * +## @brief Creates a SwkbdInline object. Only available on [2.0.0+]. +## @note This is essentially an asynchronous version of the regular swkbd. +## @note This calls \ref swkbdInlineSetUtf8Mode internally with flag=true. +## @param s SwkbdInline object. +## + +proc swkbdInlineClose*(s: ptr SwkbdInline): Result {.cdecl, + importc: "swkbdInlineClose".} +## * +## @brief Closes a SwkbdInline object. If the applet is running, this will tell the applet to exit, then wait for the applet to exit + applet exit handling. +## @param s SwkbdInline object. +## + +proc swkbdInlineLaunch*(s: ptr SwkbdInline): Result {.cdecl, + importc: "swkbdInlineLaunch".} +## * +## @brief Does setup for \ref SwkbdInitializeArg and launches the applet with the SwkbdInline object. +## @note The initArg is cleared, and on [5.0.0+] unk_x5 is set to 1. +## @param s SwkbdInline object. +## + +proc swkbdInlineLaunchForLibraryApplet*(s: ptr SwkbdInline; mode: U8; unkX5: U8): Result {. + cdecl, importc: "swkbdInlineLaunchForLibraryApplet".} +## * +## @brief Same as \ref swkbdInlineLaunch, except mode and unk_x5 for \ref SwkbdInitializeArg are set to the input params. +## @param s SwkbdInline object. +## @param mode Value for SwkbdInitializeArg::mode. +## @param unk_x5 Value for SwkbdInitializeArg::unk_x5. +## + +proc swkbdInlineGetWindowSize*(width: ptr S32; height: ptr S32) {.inline, cdecl.} = + ## * + ## @brief GetWindowSize + ## @param[out] width Output width. + ## @param[out] height Output height. + ## + + width[] = 1280 + height[] = 720 + +proc swkbdInlineGetImageMemoryRequirement*(outSize: ptr U64; outAlignment: ptr U64): Result {. + cdecl, importc: "swkbdInlineGetImageMemoryRequirement".} +## * +## @brief GetImageMemoryRequirement +## @note Wrapper for \ref viGetIndirectLayerImageRequiredMemoryInfo. +## @param[out] out_size Output size. +## @param[out] out_alignment Output alignment. +## + +proc swkbdInlineGetImage*(s: ptr SwkbdInline; buffer: pointer; size: U64; + dataAvailable: ptr bool): Result {.cdecl, + importc: "swkbdInlineGetImage".} +## * +## @brief GetImage +## @note Only available with ::SwkbdInlineMode_UserDisplay. +## @note For width/height, see \ref swkbdInlineGetWindowSize. +## @param s SwkbdInline object. +## @param[out] buffer Output RGBA8 image buffer, this must use the alignment from \ref swkbdInlineGetImageMemoryRequirement. +## @param[in] size Output buffer size, this must match the size from \ref swkbdInlineGetImageMemoryRequirement. +## @param[out] data_available Whether data is available. +## + +proc swkbdInlineGetMaxHeight*(s: ptr SwkbdInline): S32 {.cdecl, + importc: "swkbdInlineGetMaxHeight".} +## * +## @brief Gets the image max height, relative to the bottom of the screen. +## @param s SwkbdInline object. +## + +proc swkbdInlineGetMiniaturizedHeight*(s: ptr SwkbdInline): S32 {.cdecl, + importc: "swkbdInlineGetMiniaturizedHeight".} +## * +## @brief Gets the MiniaturizedHeight, relative to the bottom of the screen. +## @param s SwkbdInline object. +## + +proc swkbdInlineGetTouchRectangles*(s: ptr SwkbdInline; keytop: ptr SwkbdRect; + footer: ptr SwkbdRect): S32 {.cdecl, + importc: "swkbdInlineGetTouchRectangles".} +## * +## @brief GetTouchRectangles. Returns number of valid Rects: 1 for only keytop, 2 for keytop/footer. +## @param s SwkbdInline object. +## @param[out] keytop \ref SwkbdRect for keytop. Optional, can be NULL. +## @param[out] footer \ref SwkbdRect for footer. Optional, can be NULL. +## + +proc swkbdInlineIsUsedTouchPointByKeyboard*(s: ptr SwkbdInline; x: S32; y: S32): bool {. + cdecl, importc: "swkbdInlineIsUsedTouchPointByKeyboard".} +## * +## @brief Gets whether the input x/y are within the output from \ref swkbdInlineGetTouchRectangles. +## @param s SwkbdInline object. +## @param[out] x X +## @param[out] y Y +## + +proc swkbdInlineUpdate*(s: ptr SwkbdInline; outState: ptr SwkbdState): Result {.cdecl, + importc: "swkbdInlineUpdate".} +## * +## @brief Handles updating SwkbdInline state, this should be called periodically. +## @note Handles applet exit if needed, and also sends the \ref SwkbdInlineCalcArg to the applet if needed. Hence, this should be called at some point after writing to \ref SwkbdInlineCalcArg. +## @note Handles applet Interactive storage output when needed. +## @param s SwkbdInline object. +## @param out_state Optional output \ref SwkbdState. +## + +proc swkbdInlineSetFinishedInitializeCallback*(s: ptr SwkbdInline; cb: VoidFn) {. + cdecl, importc: "swkbdInlineSetFinishedInitializeCallback".} +## * +## @brief Sets the FinishedInitialize callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @param s SwkbdInline object. +## @param cb Callback +## + +proc swkbdInlineSetDecidedCancelCallback*(s: ptr SwkbdInline; cb: VoidFn) {.cdecl, + importc: "swkbdInlineSetDecidedCancelCallback".} +## * +## @brief Sets the DecidedCancel callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @param s SwkbdInline object. +## @param cb Callback +## + +proc swkbdInlineSetChangedStringCallback*(s: ptr SwkbdInline; + cb: SwkbdChangedStringCb) {.cdecl, + importc: "swkbdInlineSetChangedStringCallback".} +## * +## @brief Sets the ChangedString callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @note This clears the callback set by \ref swkbdInlineSetChangedStringV2Callback. +## @note This should be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. +## @param s SwkbdInline object. +## @param cb \ref SwkbdChangedStringCb Callback +## + +proc swkbdInlineSetChangedStringV2Callback*(s: ptr SwkbdInline; + cb: SwkbdChangedStringV2Cb) {.cdecl, importc: "swkbdInlineSetChangedStringV2Callback".} +## * +## @brief Sets the ChangedStringV2 callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @note Only available with [8.0.0+]. +## @note This must be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. +## @param s SwkbdInline object. +## @param cb \ref SwkbdChangedStringV2Cb Callback +## + +proc swkbdInlineSetMovedCursorCallback*(s: ptr SwkbdInline; cb: SwkbdMovedCursorCb) {. + cdecl, importc: "swkbdInlineSetMovedCursorCallback".} +## * +## @brief Sets the MovedCursor callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @note This clears the callback set by \ref swkbdInlineSetMovedCursorV2Callback. +## @note This should be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. +## @param s SwkbdInline object. +## @param cb \ref SwkbdMovedCursorCb Callback +## + +proc swkbdInlineSetMovedCursorV2Callback*(s: ptr SwkbdInline; + cb: SwkbdMovedCursorV2Cb) {.cdecl, + importc: "swkbdInlineSetMovedCursorV2Callback".} +## * +## @brief Sets the MovedCursorV2 callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @note Only available with [8.0.0+]. +## @note This must be called after \ref swkbdInlineLaunch / \ref swkbdInlineLaunchForLibraryApplet. +## @param s SwkbdInline object. +## @param cb \ref SwkbdMovedCursorV2Cb Callback +## + +proc swkbdInlineSetMovedTabCallback*(s: ptr SwkbdInline; cb: SwkbdMovedTabCb) {.cdecl, + importc: "swkbdInlineSetMovedTabCallback".} +## * +## @brief Sets the MovedTab callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @param s SwkbdInline object. +## @param cb \ref SwkbdMovedTabCb Callback +## + +proc swkbdInlineSetDecidedEnterCallback*(s: ptr SwkbdInline; cb: SwkbdDecidedEnterCb) {. + cdecl, importc: "swkbdInlineSetDecidedEnterCallback".} +## * +## @brief Sets the DecidedEnter callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @param s SwkbdInline object. +## @param cb \ref SwkbdDecidedEnterCb Callback +## + +proc swkbdInlineSetReleasedUserWordInfoCallback*(s: ptr SwkbdInline; cb: VoidFn) {. + cdecl, importc: "swkbdInlineSetReleasedUserWordInfoCallback".} +## * +## @brief Sets the ReleasedUserWordInfo callback, used by \ref swkbdInlineUpdate. The default is NULL for none. +## @param s SwkbdInline object. +## @param cb Callback +## + +proc swkbdInlineAppear*(s: ptr SwkbdInline; arg: ptr SwkbdAppearArg) {.cdecl, + importc: "swkbdInlineAppear".} +## * +## @brief Appear the kbd and set \ref SwkbdAppearArg. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Wrapper for \ref swkbdInlineAppearEx, with trigger=0. +## @param s SwkbdInline object. +## @param arg Input SwkbdAppearArg. +## + +proc swkbdInlineAppearEx*(s: ptr SwkbdInline; arg: ptr SwkbdAppearArg; trigger: U8) {. + cdecl, importc: "swkbdInlineAppearEx".} +## * +## @brief Appear the kbd and set \ref SwkbdAppearArg. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param arg Input SwkbdAppearArg. +## @param trigger Trigger, default is 0. Requires [6.0.0+], on eariler versions this will always use value 0 internally. +## + +proc swkbdInlineDisappear*(s: ptr SwkbdInline) {.cdecl, + importc: "swkbdInlineDisappear".} +## * +## @brief Disappear the kbd. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## + +proc swkbdInlineMakeAppearArg*(arg: ptr SwkbdAppearArg; `type`: SwkbdType) {.cdecl, + importc: "swkbdInlineMakeAppearArg".} +## * +## @brief Creates a \ref SwkbdAppearArg which can then be passed to \ref swkbdInlineAppear. arg is initialized with the defaults, with type being set to the input type. +## @param arg Output \ref SwkbdAppearArg. +## @param type \ref SwkbdType type +## + +proc swkbdInlineAppearArgSetOkButtonText*(arg: ptr SwkbdAppearArg; str: cstring) {. + cdecl, importc: "swkbdInlineAppearArgSetOkButtonText".} +## * +## @brief Sets okButtonText for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. +## @param arg \ref SwkbdAppearArg +## @param str Input UTF-8 string for the Ok button text, this can be empty/NULL to use the default. +## + +proc swkbdInlineAppearArgSetLeftButtonText*(arg: ptr SwkbdAppearArg; str: cstring) {. + cdecl, importc: "swkbdInlineAppearArgSetLeftButtonText".} +## * +## @brief Sets the LeftButtonText, for \ref SwkbdType_NumPad. The default is "". Equivalent to \ref swkbdConfigSetLeftOptionalSymbolKey. +## @param arg \ref SwkbdAppearArg, previously initialized by \ref swkbdInlineMakeAppearArg. +## @param str UTF-8 input string. +## + +proc swkbdInlineAppearArgSetRightButtonText*(arg: ptr SwkbdAppearArg; str: cstring) {. + cdecl, importc: "swkbdInlineAppearArgSetRightButtonText".} +## * +## @brief Sets the RightButtonText, for \ref SwkbdType_NumPad. The default is "". Equivalent to \ref swkbdConfigSetRightOptionalSymbolKey. +## @param arg \ref SwkbdAppearArg, previously initialized by \ref swkbdInlineMakeAppearArg. +## @param str UTF-8 input string. +## + +proc swkbdInlineAppearArgSetStringLenMax*(arg: ptr SwkbdAppearArg; stringLenMax: S32) {. + inline, cdecl.} = + ## * + ## @brief Sets the stringLenMax for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. + ## @param arg \ref SwkbdAppearArg + ## @param stringLenMax Max string length + ## + + arg.stringLenMax = stringLenMax + +proc swkbdInlineAppearArgSetStringLenMin*(arg: ptr SwkbdAppearArg; stringLenMin: S32) {. + inline, cdecl.} = + ## * + ## @brief Sets the stringLenMin for the specified SwkbdAppearArg, which was previously initialized with \ref swkbdInlineMakeAppearArg. + ## @param arg \ref SwkbdAppearArg + ## @param stringLenMin Min string length + ## + + arg.stringLenMin = stringLenMin + +proc swkbdInlineSetVolume*(s: ptr SwkbdInline; volume: cfloat) {.cdecl, + importc: "swkbdInlineSetVolume".} +## * +## @brief Sets the audio volume. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param volume Volume +## + +proc swkbdInlineSetInputText*(s: ptr SwkbdInline; str: cstring) {.cdecl, + importc: "swkbdInlineSetInputText".} +## * +## @brief Sets the current input text string. Overrides the entire user input string if the user previously entered any text. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note This will not affect the cursor position, see \ref swkbdInlineSetCursorPos for that. +## @param s SwkbdInline object. +## @param str UTF-8 input string. +## + +proc swkbdInlineSetCursorPos*(s: ptr SwkbdInline; pos: S32) {.cdecl, + importc: "swkbdInlineSetCursorPos".} +## * +## @brief Sets the cursor character position in the string. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param pos Position +## + +proc swkbdInlineSetUserWordInfo*(s: ptr SwkbdInline; input: ptr SwkbdDictWord; + entries: S32): Result {.cdecl, + importc: "swkbdInlineSetUserWordInfo".} +## * +## @brief Sets the UserWordInfo. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this was already used previously. +## @note The specified buffer must not be used after this, until \ref swkbdInlineClose is used. +## @note \ref swkbdInlineUpdate must be called at some point afterwards. +## @note If input==NULL or total_entries==0, this will just call \ref swkbdInlineUnsetUserWordInfo internally. +## @param s SwkbdInline object. +## @param input Input data. +## @param entries Total entries in the buffer. +## + +proc swkbdInlineUnsetUserWordInfo*(s: ptr SwkbdInline): Result {.cdecl, + importc: "swkbdInlineUnsetUserWordInfo".} +## * +## @brief Request UnsetUserWordInfo. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. +## @param s SwkbdInline object. +## + +proc swkbdInlineSetUtf8Mode*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetUtf8Mode".} +## * +## @brief Sets the utf8Mode. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Automatically used internally by \ref swkbdInlineCreate. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetCustomizeDic*(s: ptr SwkbdInline; buffer: pointer; size: csize_t; + info: ptr SwkbdCustomizeDicInfo): Result {.cdecl, + importc: "swkbdInlineSetCustomizeDic".} +## * +## @brief Sets the CustomizeDic. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this or \ref swkbdInlineSetCustomizedDictionaries was already used previously. +## @note The specified buffer must not be used after this, until \ref swkbdInlineClose is used. However, it will also become available once \ref swkbdInlineUpdate handles SwkbdReplyType_UnsetCustomizeDic internally. +## @param s SwkbdInline object. +## @param buffer 0x1000-byte aligned buffer. +## @param size 0x1000-byte aligned buffer size. +## @param info Input \ref SwkbdCustomizeDicInfo +## + +proc swkbdInlineUnsetCustomizeDic*(s: ptr SwkbdInline) {.cdecl, + importc: "swkbdInlineUnsetCustomizeDic".} +## * +## @brief Request UnsetCustomizeDic. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. +## @param s SwkbdInline object. +## + +proc swkbdInlineSetCustomizedDictionaries*(s: ptr SwkbdInline; + dic: ptr SwkbdCustomizedDictionarySet): Result {.cdecl, + importc: "swkbdInlineSetCustomizedDictionaries".} +## * +## @brief Sets the CustomizedDictionaries. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. Can't be used if this or \ref swkbdInlineSetCustomizeDic was already used previously. +## @note The specified buffer in dic must not be used after this, until \ref swkbdInlineClose is used. However, it will also become available once \ref swkbdInlineUpdate handles SwkbdReplyType_UnsetCustomizedDictionaries internally. +## @note Only available on [6.0.0+]. +## @param s SwkbdInline object. +## @param dic Input \ref SwkbdCustomizedDictionarySet +## + +proc swkbdInlineUnsetCustomizedDictionaries*(s: ptr SwkbdInline): Result {.cdecl, + importc: "swkbdInlineUnsetCustomizedDictionaries".} +## * +## @brief Request UnsetCustomizedDictionaries. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. +## @note Only available on [6.0.0+]. +## @param s SwkbdInline object. +## + +proc swkbdInlineSetInputModeFadeType*(s: ptr SwkbdInline; `type`: U8) {.cdecl, + importc: "swkbdInlineSetInputModeFadeType".} +## * +## @brief Sets InputModeFadeType. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param type Type +## + +proc swkbdInlineSetAlphaEnabledInInputMode*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetAlphaEnabledInInputMode".} +## * +## @brief Sets AlphaEnabledInInputMode. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetKeytopBgAlpha*(s: ptr SwkbdInline; alpha: cfloat) {.cdecl, + importc: "swkbdInlineSetKeytopBgAlpha".} +## * +## @brief Sets KeytopBgAlpha. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param alpha Alpha, clamped to range 0.0f..1.0f. +## + +proc swkbdInlineSetFooterBgAlpha*(s: ptr SwkbdInline; alpha: cfloat) {.cdecl, + importc: "swkbdInlineSetFooterBgAlpha".} +## * +## @brief Sets FooterBgAlpha. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param alpha Alpha, clamped to range 0.0f..1.0f. +## + +proc swkbdInlineSetKeytopScale*(s: ptr SwkbdInline; scale: cfloat) {.cdecl, + importc: "swkbdInlineSetKeytopScale".} +## * +## @brief Sets gfx scaling. Configures KeytopScale* and BalloonScale based on the input value. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note The BalloonScale is not updated when \ref SwkbdState is above ::SwkbdState_Initialized. +## @param s SwkbdInline object. +## @param scale Scale +## + +proc swkbdInlineSetKeytopTranslate*(s: ptr SwkbdInline; x: cfloat; y: cfloat) {.cdecl, + importc: "swkbdInlineSetKeytopTranslate".} +## * +## @brief Sets gfx translation for the displayed swkbd image position. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param x X +## @param y Y +## + +proc swkbdInlineSetKeytopAsFloating*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetKeytopAsFloating".} +## * +## @brief Sets KeytopAsFloating. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Not available when \ref SwkbdState is above ::SwkbdState_Initialized. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetFooterScalable*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetFooterScalable".} +## * +## @brief Sets FooterScalable. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetTouchFlag*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetTouchFlag".} +## * +## @brief Sets whether touch is enabled. The default is enabled. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetHardwareKeyboardFlag*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetHardwareKeyboardFlag".} +## * +## @brief Sets whether Hardware-keyboard is enabled. The default is enabled. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetDirectionalButtonAssignFlag*(s: ptr SwkbdInline; flag: bool) {. + cdecl, importc: "swkbdInlineSetDirectionalButtonAssignFlag".} +## * +## @brief Sets whether DirectionalButtonAssign is enabled. The default is disabled. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Only available on [4.0.0+]. +## @param s SwkbdInline object. +## @param flag Flag +## + +proc swkbdInlineSetSeGroup*(s: ptr SwkbdInline; seGroup: U8; flag: bool) {.cdecl, + importc: "swkbdInlineSetSeGroup".} +## * +## @brief Sets whether the specified SeGroup (sound effect) is enabled. The default is enabled. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. If called again with a different seGroup, \ref swkbdInlineUpdate must be called prior to calling this again. +## @note Only available on [5.0.0+]. +## @param s SwkbdInline object. +## @param seGroup SeGroup +## @param flag Flag +## + +proc swkbdInlineSetBackspaceFlag*(s: ptr SwkbdInline; flag: bool) {.cdecl, + importc: "swkbdInlineSetBackspaceFlag".} +## * +## @brief Sets whether the backspace button is enabled. The default is enabled. +## @note \ref swkbdInlineUpdate must be called at some point afterwards for this to take affect. +## @note Only available on [5.0.0+]. +## @param s SwkbdInline object. +## @param flag Flag +## + diff --git a/src/libnx/wrapper/switch/applets/web.h b/src/libnx/wrapper/switch/applets/web.h new file mode 100644 index 0000000..fef8275 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/web.h @@ -0,0 +1,862 @@ +/** + * @file web.h + * @brief Wrapper for using the web LibraryApplets. See also: https://switchbrew.org/wiki/Internet_Browser + * @author p-sam, yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/applet.h" +#include "../services/caps.h" +#include "../services/acc.h" +#include "../kernel/mutex.h" + +/// This indicates the type of web-applet. +typedef enum { + WebShimKind_Shop = 1, + WebShimKind_Login = 2, + WebShimKind_Offline = 3, + WebShimKind_Share = 4, + WebShimKind_Web = 5, + WebShimKind_Wifi = 6, + WebShimKind_Lobby = 7, +} WebShimKind; + +/// ExitReason +typedef enum { + WebExitReason_ExitButton = 0x0, ///< User pressed the X button to exit. + WebExitReason_BackButton = 0x1, ///< User pressed the B button to exit, on the initial page. + WebExitReason_Requested = 0x2, ///< The applet exited since \ref webConfigRequestExit was used. + WebExitReason_LastUrl = 0x3, ///< The applet exited due to LastUrl handling, see \ref webReplyGetLastUrl. + WebExitReason_ErrorDialog = 0x7, ///< The applet exited after displaying an error dialog. + WebExitReason_UnknownE = 0xE, ///< Unknown +} WebExitReason; + +/// Button values for \ref webConfigSetBootFooterButtonVisible. +typedef enum { + WebFooterButtonId_None = 0, ///< None, for empty \ref WebBootFooterButtonEntry. Invalid for \ref webConfigSetBootFooterButtonVisible input. + WebFooterButtonId_Type1 = 1, ///< Unknown button Id 1. + WebFooterButtonId_Type2 = 2, ///< Unknown button Id 2. + WebFooterButtonId_Type3 = 3, ///< Unknown button Id 3. + WebFooterButtonId_Type4 = 4, ///< Unknown button Id 4. + WebFooterButtonId_Type5 = 5, ///< Unknown button Id 5. + WebFooterButtonId_Type6 = 6, ///< Unknown button Id 6. + WebFooterButtonId_Max, ///< Values starting with this are invalid. +} WebFooterButtonId; + +/// WebSessionBootMode +typedef enum { + WebSessionBootMode_AllForeground = 0, ///< AllForeground. This is the default. + WebSessionBootMode_AllForegroundInitiallyHidden = 1, ///< AllForegroundInitiallyHidden +} WebSessionBootMode; + +/// WebSessionSendMessageKind +typedef enum { + WebSessionSendMessageKind_BrowserEngineContent = 0x0, ///< BrowserEngine Content + WebSessionSendMessageKind_SystemMessageAppear = 0x100, ///< SystemMessage Appear + WebSessionSendMessageKind_Ack = 0x1000, ///< Ack +} WebSessionSendMessageKind; + +/// WebSessionReceiveMessageKind +typedef enum { + WebSessionReceiveMessageKind_BrowserEngineContent = 0x0, ///< BrowserEngine Content + WebSessionReceiveMessageKind_AckBrowserEngine = 0x1000, ///< Ack BrowserEngine + WebSessionReceiveMessageKind_AckSystemMessage = 0x1001, ///< Ack SystemMessage +} WebSessionReceiveMessageKind; + +/// Struct for the WebWifi applet input storage. +typedef struct { + u32 unk_x0; ///< Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct. + char conntest_url[0x100]; ///< Connection-test URL. + char initial_url[0x400]; ///< Initial URL navigated to by the applet. + Uuid uuid; ///< NIFM Network UUID. Only used by the applet when conntest_url is set. + u32 rev; ///< Input value for nifm cmd SetRequirementByRevision. Only used by the applet when conntest_url is set. +} WebWifiPageArg; + +/// Struct for the WebWifi applet output storage. +typedef struct { + u32 unk_x0; ///< Unknown. + Result res; ///< Result +} WebWifiReturnValue; + +/// Config for WebWifi. +typedef struct { + WebWifiPageArg arg; ///< Arg data. +} WebWifiConfig; + +/// TLV storage, starts with \ref WebArgHeader followed by \ref WebArgTLV entries. +typedef struct { + u8 data[0x2000]; ///< Raw TLV data storage. +} WebCommonTLVStorage; + +/// Common struct for the applet output storage, for non-TLV-storage. +typedef struct { + WebExitReason exitReason; ///< ExitReason + u32 pad; ///< Padding + char lastUrl[0x1000]; ///< LastUrl string + u64 lastUrlSize; ///< Size of LastUrl, including NUL-terminator. +} PACKED WebCommonReturnValue; + +/// Header struct at offset 0 in the web Arg storage (non-webWifi). +typedef struct { + u16 total_entries; ///< Total \ref WebArgTLV entries following this struct. + u16 pad; ///< Padding + WebShimKind shimKind; ///< ShimKind +} PACKED WebArgHeader; + +/// Web TLV used in the web Arg storage. +typedef struct { + u16 type; ///< Type of this arg. + u16 size; ///< Size of the arg data following this struct. + u8 pad[4]; ///< Padding +} PACKED WebArgTLV; + +/// Config struct for web applets, non-WebWifi. +typedef struct { + WebCommonTLVStorage arg; ///< TLV storage. + AppletId appletid; ///< AppletId + u32 version; ///< CommonArgs applet version. + AppletHolder holder; ///< AppletHolder +} WebCommonConfig; + +/// Common container struct for applets' reply data, from the output storage. +typedef struct { + bool type; ///< Type of reply: false = ret, true = storage. + WebShimKind shimKind; ///< ShimKind + WebCommonReturnValue ret; ///< Reply data for reply=false. + WebCommonTLVStorage storage; ///< Reply data for reply=true. +} WebCommonReply; + +/// Entry data for ::WebArgType_BootFooterButton. +typedef struct { + WebFooterButtonId id; + u8 visible; + u16 unk_x5; + u8 unk_x7; +} PACKED WebBootFooterButtonEntry; + +/// StorageHandleQueue +typedef struct { + s32 read_pos; + s32 write_pos; + s32 max_storages; + bool is_full; + AppletStorage storages[0x10]; +} WebSessionStorageHandleQueue; + +/// WebSession +typedef struct { + Mutex mutex; + WebCommonConfig *config; + struct { + u32 count; + u32 cur_size; + } queue[2]; + WebSessionStorageHandleQueue storage_queue; +} WebSession; + +/// SessionMessageHeader +typedef struct { + u32 kind; ///< Message Kind (\ref WebSessionSendMessageKind / \ref WebSessionReceiveMessageKind) + u32 size; ///< Data size following the header. + u8 reserved[0x8]; ///< Unused +} WebSessionMessageHeader; + +/// Types for \ref WebArgTLV, input storage. +typedef enum { + WebArgType_Url = 0x1, ///< [1.0.0+] String, size 0xC00. Initial URL. + WebArgType_CallbackUrl = 0x3, ///< [1.0.0+] String, size 0x400. + WebArgType_CallbackableUrl = 0x4, ///< [1.0.0+] String, size 0x400. + WebArgType_ApplicationId = 0x5, ///< [1.0.0+] Offline-applet, u64 ApplicationId + WebArgType_DocumentPath = 0x6, ///< [1.0.0+] Offline-applet, string with size 0xC00. + WebArgType_DocumentKind = 0x7, ///< [1.0.0+] Offline-applet, u32 enum \WebDocumentKind. + WebArgType_SystemDataId = 0x8, ///< [1.0.0+] Offline-applet, u64 SystemDataId + WebArgType_ShareStartPage = 0x9, ///< [1.0.0+] u32 enum \WebShareStartPage + WebArgType_Whitelist = 0xA, ///< [1.0.0+] String, size 0x1000. + WebArgType_NewsFlag = 0xB, ///< [1.0.0+] u8 bool + WebArgType_UnknownC = 0xC, ///< [1.0.0+] u8 + WebArgType_UnknownD = 0xD, ///< [1.0.0+] u8 + WebArgType_Uid = 0xE, ///< [1.0.0+] \ref AccountUid, controls which user-specific savedata to mount. + WebArgType_AlbumEntry0 = 0xF, ///< [1.0.0+] Share-applet caps AlbumEntry, entry 0. + WebArgType_ScreenShot = 0x10, ///< [1.0.0+] u8 bool + WebArgType_EcClientCert = 0x11, ///< [1.0.0+] u8 bool + WebArgType_Unknown12 = 0x12, ///< [1.0.0+] u8 + WebArgType_PlayReport = 0x13, ///< [1.0.0+] u8 bool + WebArgType_Unknown14 = 0x14, ///< [1.0.0+] u8 + WebArgType_Unknown15 = 0x15, ///< [1.0.0+] u8 + WebArgType_BootDisplayKind = 0x17, ///< [1.0.0+] u32 enum \ref WebBootDisplayKind + WebArgType_BackgroundKind = 0x18, ///< [1.0.0+] u32 enum \ref WebBackgroundKind + WebArgType_Footer = 0x19, ///< [1.0.0+] u8 bool + WebArgType_Pointer = 0x1A, ///< [1.0.0+] u8 bool + WebArgType_LeftStickMode = 0x1B, ///< [1.0.0+] u32 enum \ref WebLeftStickMode + WebArgType_KeyRepeatFrame0 = 0x1C, ///< [1.0.0+] s32 KeyRepeatFrame, first param + WebArgType_KeyRepeatFrame1 = 0x1D, ///< [1.0.0+] s32 KeyRepeatFrame, second param + WebArgType_BootAsMediaPlayerInverted = 0x1E, ///< [1.0.0+] u8 bool. With News on [3.0.0+] this is set after BootAsMediaPlayer with the value inverted. + WebArgType_DisplayUrlKind = 0x1F, ///< [1.0.0+] u8 bool, DisplayUrlKind (value = (input_enumval==0x1)). + WebArgType_BootAsMediaPlayer = 0x21, ///< [2.0.0+] u8 bool + WebArgType_ShopJump = 0x22, ///< [2.0.0+] u8 bool + WebArgType_MediaPlayerUserGestureRestriction = 0x23, ///< [2.0.0-5.1.0] u8 bool + WebArgType_MediaAutoPlay = 0x23, ///< [6.0.0+] u8 bool + WebArgType_LobbyParameter = 0x24, ///< [2.0.0+] String, size 0x100. + WebArgType_ApplicationAlbumEntry = 0x26, ///< [3.0.0+] Share-applet caps ApplicationAlbumEntry + WebArgType_JsExtension = 0x27, ///< [3.0.0+] u8 bool + WebArgType_AdditionalCommentText = 0x28, ///< [4.0.0+] String, size 0x100. Share-applet AdditionalCommentText. + WebArgType_TouchEnabledOnContents = 0x29, ///< [4.0.0+] u8 bool + WebArgType_UserAgentAdditionalString = 0x2A, ///< [4.0.0+] String, size 0x80. + WebArgType_AdditionalMediaData0 = 0x2B, ///< [4.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 0. If the user-input size is less than 0x10, the remaining data used for the TLV is cleared. + WebArgType_MediaPlayerAutoClose = 0x2C, ///< [4.0.0+] u8 bool + WebArgType_PageCache = 0x2D, ///< [4.0.0+] u8 bool + WebArgType_WebAudio = 0x2E, ///< [4.0.0+] u8 bool + WebArgType_2F = 0x2F, ///< [5.0.0+] u8 + WebArgType_YouTubeVideoFlag = 0x31, ///< [5.0.0+] u8 bool Indicates that the built-in whitelist for YouTubeVideo should be used. + WebArgType_FooterFixedKind = 0x32, ///< [5.0.0+] u32 enum \ref WebFooterFixedKind + WebArgType_PageFade = 0x33, ///< [5.0.0+] u8 bool + WebArgType_MediaCreatorApplicationRatingAge = 0x34, ///< [5.0.0+] Share-applet 0x20-byte s8 array, MediaCreatorApplicationRatingAge. + WebArgType_BootLoadingIcon = 0x35, ///< [5.0.0+] u8 bool + WebArgType_PageScrollIndicator = 0x36, ///< [5.0.0+] u8 bool + WebArgType_MediaPlayerSpeedControl = 0x37, ///< [6.0.0+] u8 bool + WebArgType_AlbumEntry1 = 0x38, ///< [6.0.0+] Share-applet caps AlbumEntry, entry 1. + WebArgType_AlbumEntry2 = 0x39, ///< [6.0.0+] Share-applet caps AlbumEntry, entry 2. + WebArgType_AlbumEntry3 = 0x3A, ///< [6.0.0+] Share-applet caps AlbumEntry, entry 3. + WebArgType_AdditionalMediaData1 = 0x3B, ///< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 1. + WebArgType_AdditionalMediaData2 = 0x3C, ///< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 2. + WebArgType_AdditionalMediaData3 = 0x3D, ///< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 3. + WebArgType_BootFooterButton = 0x3E, ///< [6.0.0+] Array of \ref WebBootFooterButtonEntry with 0x10 entries. + WebArgType_OverrideWebAudioVolume = 0x3F, ///< [6.0.0+] float + WebArgType_OverrideMediaAudioVolume = 0x40, ///< [6.0.0+] float + WebArgType_SessionBootMode = 0x41, ///< [7.0.0+] u32 enum \ref WebSessionBootMode + WebArgType_SessionFlag = 0x42, ///< [7.0.0+] u8 bool, enables using WebSession when set. + WebArgType_MediaPlayerUi = 0x43, ///< [8.0.0+] u8 bool + WebArgType_TransferMemory = 0x44, ///< [11.0.0+] u8 bool +} WebArgType; + +/// Types for \ref WebArgTLV, output storage. +typedef enum { + WebReplyType_ExitReason = 0x1, ///< [3.0.0+] u32 ExitReason + WebReplyType_LastUrl = 0x2, ///< [3.0.0+] string + WebReplyType_LastUrlSize = 0x3, ///< [3.0.0+] u64 + WebReplyType_SharePostResult = 0x4, ///< [3.0.0+] u32 SharePostResult + WebReplyType_PostServiceName = 0x5, ///< [3.0.0+] string + WebReplyType_PostServiceNameSize = 0x6, ///< [3.0.0+] u64 + WebReplyType_PostId = 0x7, ///< [3.0.0+] string + WebReplyType_PostIdSize = 0x8, ///< [3.0.0+] u64 + WebReplyType_MediaPlayerAutoClosedByCompletion = 0x9, ///< [8.0.0+] u8 bool +} WebReplyType; + +/// This controls the kind of content to mount with Offline-applet. +typedef enum { + WebDocumentKind_OfflineHtmlPage = 0x1, ///< Use the HtmlDocument NCA content from the application. + WebDocumentKind_ApplicationLegalInformation = 0x2, ///< Use the LegalInformation NCA content from the application. + WebDocumentKind_SystemDataPage = 0x3, ///< Use the Data NCA content from the specified SystemData, see also: https://switchbrew.org/wiki/Title_list#System_Data_Archives +} WebDocumentKind; + +/// This controls the initial page for ShareApplet, used by \ref webShareCreate. +typedef enum { + WebShareStartPage_Default = 0, ///< The default "/" page. + WebShareStartPage_Settings = 1, ///< The "/settings/" page. +} WebShareStartPage; + +/// Kind values for \ref webConfigSetBootDisplayKind. Controls the background color while displaying the loading screen during applet boot. Also controls the BackgroundKind when value is non-zero. +typedef enum { + WebBootDisplayKind_Default = 0, ///< Default. BackgroundKind is controlled by \ref WebBackgroundKind. + WebBootDisplayKind_White = 1, ///< White background. Used by \ref webOfflineCreate for docKind ::WebDocumentKind_ApplicationLegalInformation/::WebDocumentKind_SystemDataPage. + WebBootDisplayKind_Black = 2, ///< Black background. + WebBootDisplayKind_Unknown3 = 3, ///< Unknown. Used by \ref webShareCreate. + WebBootDisplayKind_Unknown4 = 4, ///< Unknown. Used by \ref webLobbyCreate. +} WebBootDisplayKind; + +/// Kind values for \ref webConfigSetBackgroundKind. Controls the background color while displaying the loading screen during applet boot. Only used when \ref WebBootDisplayKind is ::WebBootDisplayKind_Default. If the applet was not launched by an Application, the applet will only use WebBackgroundKind_Default. +typedef enum { + WebBackgroundKind_Default = 0, ///< Default. Same as ::WebBootDisplayKind_White/::WebBootDisplayKind_Black, determined via ::WebArgType_BootAsMediaPlayer. + WebBackgroundKind_Unknown1 = 1, ///< Unknown. Same as ::WebBootDisplayKind_Unknown3. + WebBackgroundKind_Unknown2 = 2, ///< Unknown. Same as ::WebBootDisplayKind_Unknown4. Used by \ref webLobbyCreate. +} WebBackgroundKind; + +/// Mode values for \ref webConfigSetLeftStickMode. Controls the initial mode, this can be toggled by the user via the pressing the left-stick button. If the Pointer flag is set to false (\ref webConfigSetPointer), only ::WebLeftStickMode_Cursor will be used and mode toggle by the user is disabled (input value ignored). +typedef enum { + WebLeftStickMode_Pointer = 0, ///< The user can directly control the pointer via the left-stick. + WebLeftStickMode_Cursor = 1, ///< The user can only select elements on the page via the left-stick. +} WebLeftStickMode; + +/// Kind values for \ref webConfigSetFooterFixedKind. Controls UI footer display behaviour. +typedef enum { + WebFooterFixedKind_Default = 0, ///< Default. Footer is hidden while scrolling. + WebFooterFixedKind_Always = 1, ///< Footer is always displayed regardless of scrolling. + WebFooterFixedKind_Hidden = 2, ///< Footer is hidden regardless of scrolling. +} WebFooterFixedKind; + +/** + * @brief Creates the config for WifiWebAuthApplet. This is the captive portal applet. + * @param config WebWifiConfig object. + * @param conntest_url URL used for the connection-test requests. When empty/NULL the applet will test the connection with nifm and throw an error on failure. + * @param initial_url Initial URL navigated to by the applet. + * @param uuid NIFM Network UUID, for nifm cmd SetNetworkProfileId. Value 0 can be used. Only used by the applet when conntest_url is set. + * @param rev Input value for nifm cmd SetRequirementByRevision. Value 0 can be used. Only used by the applet when conntest_url is set. + */ +void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, Uuid uuid, u32 rev); + +/** + * @brief Launches WifiWebAuthApplet with the specified config and waits for it to exit. + * @param config WebWifiConfig object. + * @param out Optional output applet reply data, can be NULL. + */ +Result webWifiShow(WebWifiConfig* config, WebWifiReturnValue *out); + +/** + * @brief Creates the config for WebApplet. This applet uses an URL whitelist loaded from the user-process host Application, which is only loaded when running under an Application. + * @note Sets ::WebArgType_UnknownD, and ::WebArgType_Unknown12 on pre-3.0.0, to value 1. + * @param config WebCommonConfig object. + * @param url Initial URL navigated to by the applet. + */ +Result webPageCreate(WebCommonConfig* config, const char* url); + +/** + * @brief Creates the config for WebApplet. This is based on \ref webPageCreate, for News. Hence other functions referencing \ref webPageCreate also apply to this. + * @note The domain from the input URL is automatically whitelisted, in addition to any already loaded whitelist. + * @note Sets ::WebArgType_UnknownD to value 1, and sets ::WebArgType_NewsFlag to true. Also uses \ref webConfigSetEcClientCert and \ref webConfigSetShopJump with flag=true. + * @param config WebCommonConfig object. + * @param url Initial URL navigated to by the applet. + */ +Result webNewsCreate(WebCommonConfig* config, const char* url); + +/** + * @brief Creates the config for WebApplet. This is based on \ref webPageCreate, for YouTubeVideo. Hence other functions referencing \ref webPageCreate also apply to this. This uses a whitelist which essentially only allows youtube embed/ URLs (without mounting content from the host Application). + * @note This is only available on [5.0.0+]. + * @note Sets ::WebArgType_UnknownD to value 1, and sets ::WebArgType_YouTubeVideoFlag to true. Also uses \ref webConfigSetBootAsMediaPlayer with flag=true. + * @param config WebCommonConfig object. + * @param url Initial URL navigated to by the applet. + */ +Result webYouTubeVideoCreate(WebCommonConfig* config, const char* url); + +/** + * @brief Creates the config for Offline-applet. This applet uses data loaded from content. + * @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor and sets ::WebArgType_BootAsMediaPlayerInverted to false. Uses \ref webConfigSetPointer with flag = docKind == ::WebDocumentKind_OfflineHtmlPage. + * @note For docKind ::WebDocumentKind_ApplicationLegalInformation / ::WebDocumentKind_SystemDataPage, uses \ref webConfigSetFooter with flag=true and \ref webConfigSetBackgroundKind with ::WebBackgroundKind_Default. + * @note For docKind ::WebDocumentKind_SystemDataPage, uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_White. + * @note Sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. With docKind ::WebDocumentKind_ApplicationLegalInformation, uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_White. + * @note Sets ::WebArgType_UnknownC to value 1. + * @note With docKind ::WebDocumentKind_ApplicationLegalInformation, uses \ref webConfigSetEcClientCert with flag=true. + * @note With docKind ::WebDocumentKind_OfflineHtmlPage on pre-3.0.0, sets ::WebArgType_Unknown12 to value 1. + * @note Lastly, sets the TLVs as needed for the input params. + * @param config WebCommonConfig object. + * @param docKind \ref WebDocumentKind + * @param id Id to load the content from. With docKind = ::WebDocumentKind_OfflineHtmlPage, id=0 should be used to specify the user-process application (non-zero is ignored with this docKind). + * @param docPath Initial document path in RomFS, without the leading '/'. For ::WebDocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other docKind values, this is relative to "/" in RomFS. This path must contain ".htdocs/". + */ +Result webOfflineCreate(WebCommonConfig* config, WebDocumentKind docKind, u64 id, const char* docPath); + +/** + * @brief Creates the config for ShareApplet. This applet is for social media posting/settings. + * @note If a non-zero uid isn't set with \ref webConfigSetUid prior to using \ref webConfigShow, the applet will launch the profile-selector applet to select an account. + * @note An error will be displayed if neither \ref webConfigSetAlbumEntry, nor \ref webConfigSetApplicationAlbumEntry, nor \ref webConfigAddAlbumEntryAndMediaData are used prior to using \ref webConfigShow, with ::WebShareStartPage_Default. + * @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor, \ref webConfigSetUid with uid=0, \ref webConfigSetDisplayUrlKind with kind=true, and sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. Uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_Unknown3. + * @param config WebCommonConfig object. + * @param page \ref WebShareStartPage + */ +Result webShareCreate(WebCommonConfig* config, WebShareStartPage page); + +/** + * @brief Creates the config for LobbyApplet. This applet is for "Nintendo Switch Online Lounge". + * @note Only available on [2.0.0+]. + * @note If a non-zero uid isn't set with \ref webConfigSetUid prior to using \ref webConfigShow, the applet will launch the profile-selector applet to select an account. + * @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor, \ref webConfigSetPointer with flag=false on [3.0.0+], \ref webConfigSetUid with uid=0, and sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. Uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_Unknown4, \ref webConfigSetBackgroundKind with ::WebBackgroundKind_Unknown2, and sets ::WebArgType_BootAsMediaPlayerInverted to false. + * @param config WebCommonConfig object. + */ +Result webLobbyCreate(WebCommonConfig* config); + +/** + * @brief Sets the CallbackUrl. See also \ref webReplyGetLastUrl. + * @note With Offline-applet for LastUrl handling, it compares the domain with "localhost" instead. + * @note Only available with config created by \ref webPageCreate or with Share-applet. + * @param config WebCommonConfig object. + * @param url URL + */ +Result webConfigSetCallbackUrl(WebCommonConfig* config, const char* url); + +/** + * @brief Sets the CallbackableUrl. + * @note Only available with config created by \ref webPageCreate. + * @param config WebCommonConfig object. + * @param url URL + */ +Result webConfigSetCallbackableUrl(WebCommonConfig* config, const char* url); + +/** + * @brief Sets the whitelist. + * @note Only available with config created by \ref webPageCreate. + * @note If the whitelist isn't formatted properly, the applet will exit briefly after the applet is launched. + * @param config WebCommonConfig object. + * @param whitelist Whitelist string, each line is a regex for each whitelisted URL. + */ +Result webConfigSetWhitelist(WebCommonConfig* config, const char* whitelist); + +/** + * @brief Sets the account uid. Controls which user-specific savedata to mount. + * @note Only available with config created by \ref webPageCreate, \ref webLobbyCreate, or with Share-applet. + * @note Used automatically by \ref webShareCreate and \ref webLobbyCreate with uid=0. + * @param config WebCommonConfig object. + * @param uid \ref AccountUid + */ +Result webConfigSetUid(WebCommonConfig* config, AccountUid uid); + +/** + * @brief Sets the Share CapsAlbumEntry. + * @note Only available with config created by \ref webShareCreate. + * @param config WebCommonConfig object. + * @param entry \ref CapsAlbumEntry + */ +Result webConfigSetAlbumEntry(WebCommonConfig* config, const CapsAlbumEntry *entry); + +/** + * @brief Sets the ScreenShot flag, which controls whether screen-shot capture is allowed. + * @note Only available with config created by \ref webPageCreate. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetScreenShot(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the EcClientCert flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate. + * @note Used automatically by \ref webOfflineCreate, depending on the docKind. + * @note Used automatically by \ref webNewsCreate with flag=true. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetEcClientCert(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether PlayReport is enabled. + * @note Only available with config created by \ref webOfflineCreate. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetPlayReport(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the BootDisplayKind. + * @note Only available with config created by \ref webOfflineCreate, \ref webShareCreate, \ref webPageCreate, or \ref webLobbyCreate.. + * @note Used automatically by \ref webOfflineCreate, depending on the docKind. + * @note Used automatically by \ref webShareCreate with kind=::WebBootDisplayKind_Unknown3. + * @note Used automatically by \ref webLobbyCreate with kind=::WebBootDisplayKind_Unknown4. + * @param config WebCommonConfig object. + * @param kind \ref WebBootDisplayKind + */ +Result webConfigSetBootDisplayKind(WebCommonConfig* config, WebBootDisplayKind kind); + +/** + * @brief Sets the BackgroundKind. + * @note Only available with config created by \ref webOfflineCreate, \ref webPageCreate, or \ref webLobbyCreate. + * @note Used automatically by \ref webOfflineCreate, depending on the docKind. + * @note Used automatically by \ref webLobbyCreate with kind=2. + * @param config WebCommonConfig object. + * @param kind \ref WebBackgroundKind + */ +Result webConfigSetBackgroundKind(WebCommonConfig* config, WebBackgroundKind kind); + +/** + * @brief Sets the whether the UI footer is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate. + * @note Used automatically by \ref webOfflineCreate, depending on the docKind. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetFooter(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the whether the Pointer is enabled. See also \ref WebLeftStickMode. + * @note Only available with config created by \ref webOfflineCreate, \ref webPageCreate, or \ref webLobbyCreate. + * @note Used automatically by \ref webOfflineCreate. + * @note Used automatically by \ref webLobbyCreate with flag=false on [3.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetPointer(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the LeftStickMode. + * @note Only available with config created by \ref webOfflineCreate, \ref webShareCreate, \ref webPageCreate, or \ref webLobbyCreate. + * @note Used automatically by \ref webOfflineCreate, \ref webShareCreate, and \ref webLobbyCreate with ::WebLeftStickMode_Cursor. + * @param config WebCommonConfig object. + * @param mode Mode, different enums for Web and Offline. + */ +Result webConfigSetLeftStickMode(WebCommonConfig* config, WebLeftStickMode mode); + +/** + * @brief Sets the KeyRepeatFrame. + * @note Only available with config created by \ref webOfflineCreate. + * @param config WebCommonConfig object. + * @param inval0 First input param. + * @param inval1 Second input param. + */ +Result webConfigSetKeyRepeatFrame(WebCommonConfig* config, s32 inval0, s32 inval1); + +/** + * @brief Sets the DisplayUrlKind. + * @note Only available with config created by \ref webShareCreate or \ref webPageCreate. + * @param config WebCommonConfig object. + * @note Used automatically by \ref webShareCreate with kind=true. + * @param kind Kind + */ +Result webConfigSetDisplayUrlKind(WebCommonConfig* config, bool kind); + +/** + * @brief Sets the BootAsMediaPlayer flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [2.0.0+]. + * @note With config created by \ref webNewsCreate on [3.0.0+], this also sets ::WebArgType_BootAsMediaPlayerInverted to !flag. + * @param config WebCommonConfig object. + * @param flag Flag. true = BootAsMediaPlayer, false = BootAsWebPage. + */ +Result webConfigSetBootAsMediaPlayer(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the ShopJump flag. + * @note Only available with config created by \ref webPageCreate on [2.0.0+]. + * @note Used automatically by \ref webNewsCreate with flag=true. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetShopJump(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the MediaPlayerUserGestureRestriction flag. + * @note Only available with config created by \ref webPageCreate on [2.0.0-5.1.0]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetMediaPlayerUserGestureRestriction(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether MediaAutoPlay is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetMediaAutoPlay(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the LobbyParameter. + * @note Only available with config created by \ref webLobbyCreate. + * @param config WebCommonConfig object. + * @param str String + */ +Result webConfigSetLobbyParameter(WebCommonConfig* config, const char* str); + +/** + * @brief Sets the Share CapsApplicationAlbumEntry. + * @note Only available with config created by \ref webShareCreate on [3.0.0+]. + * @param config WebCommonConfig object. + * @param entry \ref CapsApplicationAlbumEntry, see also capssu.h. + */ +Result webConfigSetApplicationAlbumEntry(WebCommonConfig* config, CapsApplicationAlbumEntry *entry); + +/** + * @brief Sets whether JsExtension is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [3.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetJsExtension(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the Share AdditionalCommentText. + * @note Only available with config created by \ref webShareCreate on [4.0.0+]. + * @param config WebCommonConfig object. + * @param str String + */ +Result webConfigSetAdditionalCommentText(WebCommonConfig* config, const char* str); + +/** + * @brief Sets the TouchEnabledOnContents flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetTouchEnabledOnContents(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the UserAgentAdditionalString. " " followed by this string are appended to the normal User-Agent string. + * @note Only available with config created by \ref webPageCreate on [4.0.0+]. + * @param config WebCommonConfig object. + * @param str String + */ +Result webConfigSetUserAgentAdditionalString(WebCommonConfig* config, const char* str); + +/** + * @brief Sets the Share AdditionalMediaData. + * @note Only available with config created by \ref webShareCreate on [4.0.0+]. + * @param config WebCommonConfig object. + * @param data Input data + * @param size Size of the input data, max size is 0x10. + */ +Result webConfigSetAdditionalMediaData(WebCommonConfig* config, const u8* data, size_t size); + +/** + * @brief Sets the MediaPlayerAutoClose flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetMediaPlayerAutoClose(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether PageCache is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetPageCache(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether WebAudio is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetWebAudio(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the FooterFixedKind. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. + * @param config WebCommonConfig object. + * @param kind \ref WebFooterFixedKind + */ +Result webConfigSetFooterFixedKind(WebCommonConfig* config, WebFooterFixedKind kind); + +/** + * @brief Sets the PageFade flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetPageFade(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the Share MediaCreatorApplicationRatingAge. + * @note Only available with config created by \ref webShareCreate on [5.0.0+]. + * @param config WebCommonConfig object. + * @param data 0x20-byte input data + */ +Result webConfigSetMediaCreatorApplicationRatingAge(WebCommonConfig* config, const s8 *data); + +/** + * @brief Sets the BootLoadingIcon flag. + * @note Only available with config created by \ref webOfflineCreate on [5.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetBootLoadingIcon(WebCommonConfig* config, bool flag); + +/** + * @brief Sets the PageScrollIndicator flag. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetPageScrollIndicator(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether MediaPlayerSpeedControl is enabled. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetMediaPlayerSpeedControl(WebCommonConfig* config, bool flag); + +/** + * @brief Adds a pair of Share CapsAlbumEntry + optionally AdditionalMediaData. This can be used up to 4 times, for setting multiple pairs. + * @note Only available with config created by \ref webShareCreate on [6.0.0+]. + * @param config WebCommonConfig object. + * @param entry \ref CapsAlbumEntry + * @param data Input data for AdditionalMediaData. Optional, can be NULL. + * @param size Size of the input data, max size is 0x10. Optional, can be 0. + */ +Result webConfigAddAlbumEntryAndMediaData(WebCommonConfig* config, const CapsAlbumEntry *entry, const u8* data, size_t size); + +/** + * @brief Sets whether the specified BootFooterButton is visible. + * @note Only available with config created by \ref webOfflineCreate on [6.0.0+]. + * @param config WebCommonConfig object. + * @param button \ref WebFooterButtonId + * @param visible Visible flag. + */ +Result webConfigSetBootFooterButtonVisible(WebCommonConfig* config, WebFooterButtonId button, bool visible); + +/** + * @brief Sets OverrideWebAudioVolume. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. + * @param config WebCommonConfig object. + * @param value Value + */ +Result webConfigSetOverrideWebAudioVolume(WebCommonConfig* config, float value); + +/** + * @brief Sets OverrideMediaAudioVolume. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. + * @param config WebCommonConfig object. + * @param value Value + */ +Result webConfigSetOverrideMediaAudioVolume(WebCommonConfig* config, float value); + +/** + * @brief Sets \ref WebSessionBootMode. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [7.0.0+]. + * @param config WebCommonConfig object. + * @param mode \ref WebSessionBootMode + */ +Result webConfigSetBootMode(WebCommonConfig* config, WebSessionBootMode mode); + +/** + * @brief Sets whether MediaPlayerUi is enabled. + * @note Only available with config created by \ref webOfflineCreate on [8.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetMediaPlayerUi(WebCommonConfig* config, bool flag); + +/** + * @brief Sets whether TransferMemory is enabled. + * @note Only available with config created by \ref webPageCreate on [11.0.0+]. + * @param config WebCommonConfig object. + * @param flag Flag + */ +Result webConfigSetTransferMemory(WebCommonConfig* config, bool flag); + +/** + * @brief Launches the {web applet} with the specified config and waits for it to exit. + * @param config WebCommonConfig object. + * @param out Optional output applet reply data, can be NULL. + */ +Result webConfigShow(WebCommonConfig* config, WebCommonReply *out); + +/** + * @brief Request the applet to exit after \ref webConfigShow was used, while the applet is still running. This is for use from another thread. + * @param config WebCommonConfig object. + */ +Result webConfigRequestExit(WebCommonConfig* config); + +/** + * @brief Gets the ExitReason from the specified reply. + * @param reply WebCommonReply object. + * @param exitReason Output \ref WebExitReason + */ +Result webReplyGetExitReason(WebCommonReply *reply, WebExitReason *exitReason); + +/** + * @brief Gets the LastUrl from the specified reply. When the applet loads a page where the beginning of the URL matches the URL from \ref webConfigSetCallbackUrl, the applet will exit and set LastUrl to that URL (exit doesn't occur when \ref webConfigSetCallbackableUrl was used). + * @note This is only available with ::WebExitReason_LastUrl (string is empty otherwise). + * @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. + * @param reply WebCommonReply object. + * @param outstr Output string buffer. If NULL, the string is not loaded. + * @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). + * @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. + */ +Result webReplyGetLastUrl(WebCommonReply *reply, char *outstr, size_t outstr_maxsize, size_t *out_size); + +/** + * @brief Gets the SharePostResult from the specified reply. + * @note Only available with reply data from ShareApplet on [3.0.0+]. + * @param reply WebCommonReply object. + * @param sharePostResult Output sharePostResult + */ +Result webReplyGetSharePostResult(WebCommonReply *reply, u32 *sharePostResult); + +/** + * @brief Gets the PostServiceName from the specified reply. + * @note Only available with reply data from ShareApplet on [3.0.0+]. + * @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. + * @param reply WebCommonReply object. + * @param outstr Output string buffer. If NULL, the string is not loaded. + * @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). + * @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. + */ +Result webReplyGetPostServiceName(WebCommonReply *reply, char *outstr, size_t outstr_maxsize, size_t *out_size); + +/** + * @brief Gets the PostId from the specified reply. + * @note Only available with reply data from ShareApplet on [3.0.0+]. + * @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. + * @param reply WebCommonReply object. + * @param outstr Output string buffer. If NULL, the string is not loaded. + * @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). + * @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. + */ +Result webReplyGetPostId(WebCommonReply *reply, char *outstr, size_t outstr_maxsize, size_t *out_size); + +/** + * @brief Gets the MediaPlayerAutoClosedByCompletion flag from the specified reply. + * @note Only available with reply data from Web on [8.0.0+]. + * @param reply WebCommonReply object. + * @param flag Output flag + */ +Result webReplyGetMediaPlayerAutoClosedByCompletion(WebCommonReply *reply, bool *flag); + +/** + * @brief Creates a \ref WebSession object. + * @param s \ref WebSession + * @param config WebCommonConfig object. + */ +void webSessionCreate(WebSession *s, WebCommonConfig* config); + +/** + * @brief Closes a \ref WebSession object. + * @param s \ref WebSession + */ +void webSessionClose(WebSession *s); + +/** + * @brief Launches the applet for \ref WebSession. + * @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [7.0.0+]. + * @note Do not use \ref webConfigShow when using WebSession. + * @param s \ref WebSession + * @param[out] out_event Output Event with autoclear=false, from \ref appletHolderGetExitEvent. Optional, can be NULL. + */ +Result webSessionStart(WebSession *s, Event **out_event); + +/** + * @brief Waits for the applet to exit. + * @note This must be used before \ref webSessionClose, when \ref webSessionStart was used successfully. + * @param s \ref WebSession + * @param out Optional output applet reply data, can be NULL. + */ +Result webSessionWaitForExit(WebSession *s, WebCommonReply *out); + +/** + * @brief Request the applet to exit. + * @note Use this instead of \ref webConfigRequestExit, when using WebSession. + * @param s \ref WebSession + */ +Result webSessionRequestExit(WebSession *s); + +/** + * @brief Request the applet to Appear, this is only needed with ::WebSessionBootMode_AllForegroundInitiallyHidden. + * @note This should not be used before \ref webSessionStart. + * @param s \ref WebSession + * @param[out] flag Whether the message was sent successfully. + */ +Result webSessionAppear(WebSession *s, bool *flag); + +/** + * @brief TrySendContentMessage + * @note This should not be used before \ref webSessionStart. + * @note The JS-side for this is only available when JsExtension is enabled via \ref webConfigSetJsExtension. + * @note The JS-side may ignore this if it's sent too soon after the applet launches. + * @param s \ref WebSession + * @param[in] content Input content NUL-terminated string. + * @param[in] size Size of content. + * @param[out] flag Whether the message was sent successfully. + */ +Result webSessionTrySendContentMessage(WebSession *s, const char *content, u32 size, bool *flag); + +/** + * @brief TryReceiveContentMessage + * @note This should not be used before \ref webSessionStart. + * @note The JS-side for this is only available when JsExtension is enabled via \ref webConfigSetJsExtension. + * @param s \ref WebSession + * @param[out] content Output content string, always NUL-terminated. + * @param[in] size Max size of content. + * @param[out] out_size Original content size, prior to being clamped to the specified size param. + * @param[out] flag Whether the message was received successfully. + */ +Result webSessionTryReceiveContentMessage(WebSession *s, char *content, u64 size, u64 *out_size, bool *flag); + diff --git a/src/libnx/wrapper/switch/applets/web.nim b/src/libnx/wrapper/switch/applets/web.nim new file mode 100644 index 0000000..6b73534 --- /dev/null +++ b/src/libnx/wrapper/switch/applets/web.nim @@ -0,0 +1,990 @@ +## * +## @file web.h +## @brief Wrapper for using the web LibraryApplets. See also: https://switchbrew.org/wiki/Internet_Browser +## @author p-sam, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/applet, ../services/caps, ../services/acc, ../kernel/mutex, ../kernel/event + +## / This indicates the type of web-applet. + +type + WebShimKind* = enum + WebShimKindShop = 1, WebShimKindLogin = 2, WebShimKindOffline = 3, + WebShimKindShare = 4, WebShimKindWeb = 5, WebShimKindWifi = 6, WebShimKindLobby = 7 + + +## / ExitReason + +type + WebExitReason* = enum + WebExitReasonExitButton = 0x0, ## /< User pressed the X button to exit. + WebExitReasonBackButton = 0x1, ## /< User pressed the B button to exit, on the initial page. + WebExitReasonRequested = 0x2, ## /< The applet exited since \ref webConfigRequestExit was used. + WebExitReasonLastUrl = 0x3, ## /< The applet exited due to LastUrl handling, see \ref webReplyGetLastUrl. + WebExitReasonErrorDialog = 0x7, ## /< The applet exited after displaying an error dialog. + WebExitReasonUnknownE = 0xE ## /< Unknown + + +## / Button values for \ref webConfigSetBootFooterButtonVisible. + +type + WebFooterButtonId* = enum + WebFooterButtonIdNone = 0, ## /< None, for empty \ref WebBootFooterButtonEntry. Invalid for \ref webConfigSetBootFooterButtonVisible input. + WebFooterButtonIdType1 = 1, ## /< Unknown button Id 1. + WebFooterButtonIdType2 = 2, ## /< Unknown button Id 2. + WebFooterButtonIdType3 = 3, ## /< Unknown button Id 3. + WebFooterButtonIdType4 = 4, ## /< Unknown button Id 4. + WebFooterButtonIdType5 = 5, ## /< Unknown button Id 5. + WebFooterButtonIdType6 = 6, ## /< Unknown button Id 6. + WebFooterButtonIdMax ## /< Values starting with this are invalid. + + +## / WebSessionBootMode + +type + WebSessionBootMode* = enum + WebSessionBootModeAllForeground = 0, ## /< AllForeground. This is the default. + WebSessionBootModeAllForegroundInitiallyHidden = 1 ## /< AllForegroundInitiallyHidden + + +## / WebSessionSendMessageKind + +type + WebSessionSendMessageKind* = enum + WebSessionSendMessageKindBrowserEngineContent = 0x0, ## /< BrowserEngine Content + WebSessionSendMessageKindSystemMessageAppear = 0x100, ## /< SystemMessage Appear + WebSessionSendMessageKindAck = 0x1000 ## /< Ack + + +## / WebSessionReceiveMessageKind + +type + WebSessionReceiveMessageKind* = enum + WebSessionReceiveMessageKindBrowserEngineContent = 0x0, ## /< BrowserEngine Content + WebSessionReceiveMessageKindAckBrowserEngine = 0x1000, ## /< Ack BrowserEngine + WebSessionReceiveMessageKindAckSystemMessage = 0x1001 ## /< Ack SystemMessage + + +## / Struct for the WebWifi applet input storage. + +type + WebWifiPageArg* {.bycopy.} = object + unkX0*: U32 ## /< Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct. + conntestUrl*: array[0x100, char] ## /< Connection-test URL. + initialUrl*: array[0x400, char] ## /< Initial URL navigated to by the applet. + uuid*: Uuid ## /< NIFM Network UUID. Only used by the applet when conntest_url is set. + rev*: U32 ## /< Input value for nifm cmd SetRequirementByRevision. Only used by the applet when conntest_url is set. + + +## / Struct for the WebWifi applet output storage. + +type + WebWifiReturnValue* {.bycopy.} = object + unkX0*: U32 ## /< Unknown. + res*: Result ## /< Result + + +## / Config for WebWifi. + +type + WebWifiConfig* {.bycopy.} = object + arg*: WebWifiPageArg ## /< Arg data. + + +## / TLV storage, starts with \ref WebArgHeader followed by \ref WebArgTLV entries. + +type + WebCommonTLVStorage* {.bycopy.} = object + data*: array[0x2000, U8] ## /< Raw TLV data storage. + + +## / Common struct for the applet output storage, for non-TLV-storage. + +type + WebCommonReturnValue* {.bycopy.} = object + exitReason*: WebExitReason ## /< ExitReason + pad*: U32 ## /< Padding + lastUrl*: array[0x1000, char] ## /< LastUrl string + lastUrlSize*: U64 ## /< Size of LastUrl, including NUL-terminator. + + +## / Header struct at offset 0 in the web Arg storage (non-webWifi). + +type + WebArgHeader* {.bycopy.} = object + totalEntries*: U16 ## /< Total \ref WebArgTLV entries following this struct. + pad*: U16 ## /< Padding + shimKind*: WebShimKind ## /< ShimKind + + +## / Web TLV used in the web Arg storage. + +type + WebArgTLV* {.bycopy.} = object + `type`*: U16 ## /< Type of this arg. + size*: U16 ## /< Size of the arg data following this struct. + pad*: array[4, U8] ## /< Padding + + +## / Config struct for web applets, non-WebWifi. + +type + WebCommonConfig* {.bycopy.} = object + arg*: WebCommonTLVStorage ## /< TLV storage. + appletid*: AppletId ## /< AppletId + version*: U32 ## /< CommonArgs applet version. + holder*: AppletHolder ## /< AppletHolder + + +## / Common container struct for applets' reply data, from the output storage. + +type + WebCommonReply* {.bycopy.} = object + `type`*: bool ## /< Type of reply: false = ret, true = storage. + shimKind*: WebShimKind ## /< ShimKind + ret*: WebCommonReturnValue ## /< Reply data for reply=false. + storage*: WebCommonTLVStorage ## /< Reply data for reply=true. + + +## / Entry data for ::WebArgType_BootFooterButton. + +type + WebBootFooterButtonEntry* {.bycopy.} = object + id*: WebFooterButtonId + visible*: U8 + unkX5*: U16 + unkX7*: U8 + + +## / StorageHandleQueue + +type + WebSessionStorageHandleQueue* {.bycopy.} = object + readPos*: S32 + writePos*: S32 + maxStorages*: S32 + isFull*: bool + storages*: array[0x10, AppletStorage] + + +## / WebSession + +type + INNER_C_STRUCT_web_1* {.bycopy.} = object + count*: U32 + curSize*: U32 + + WebSession* {.bycopy.} = object + mutex*: Mutex + config*: ptr WebCommonConfig + queue*: array[2, INNER_C_STRUCT_web_1] + storageQueue*: WebSessionStorageHandleQueue + + +## / SessionMessageHeader + +type + WebSessionMessageHeader* {.bycopy.} = object + kind*: U32 ## /< Message Kind (\ref WebSessionSendMessageKind / \ref WebSessionReceiveMessageKind) + size*: U32 ## /< Data size following the header. + reserved*: array[0x8, U8] ## /< Unused + + +## / Types for \ref WebArgTLV, input storage. + +type + WebArgType* = enum + WebArgTypeUrl = 0x1, ## /< [1.0.0+] String, size 0xC00. Initial URL. + WebArgTypeCallbackUrl = 0x3, ## /< [1.0.0+] String, size 0x400. + WebArgTypeCallbackableUrl = 0x4, ## /< [1.0.0+] String, size 0x400. + WebArgTypeApplicationId = 0x5, ## /< [1.0.0+] Offline-applet, u64 ApplicationId + WebArgTypeDocumentPath = 0x6, ## /< [1.0.0+] Offline-applet, string with size 0xC00. + WebArgTypeDocumentKind = 0x7, ## /< [1.0.0+] Offline-applet, u32 enum \WebDocumentKind. + WebArgTypeSystemDataId = 0x8, ## /< [1.0.0+] Offline-applet, u64 SystemDataId + WebArgTypeShareStartPage = 0x9, ## /< [1.0.0+] u32 enum \WebShareStartPage + WebArgTypeWhitelist = 0xA, ## /< [1.0.0+] String, size 0x1000. + WebArgTypeNewsFlag = 0xB, ## /< [1.0.0+] u8 bool + WebArgTypeUnknownC = 0xC, ## /< [1.0.0+] u8 + WebArgTypeUnknownD = 0xD, ## /< [1.0.0+] u8 + WebArgTypeUid = 0xE, ## /< [1.0.0+] \ref AccountUid, controls which user-specific savedata to mount. + WebArgTypeAlbumEntry0 = 0xF, ## /< [1.0.0+] Share-applet caps AlbumEntry, entry 0. + WebArgTypeScreenShot = 0x10, ## /< [1.0.0+] u8 bool + WebArgTypeEcClientCert = 0x11, ## /< [1.0.0+] u8 bool + WebArgTypeUnknown12 = 0x12, ## /< [1.0.0+] u8 + WebArgTypePlayReport = 0x13, ## /< [1.0.0+] u8 bool + WebArgTypeUnknown14 = 0x14, ## /< [1.0.0+] u8 + WebArgTypeUnknown15 = 0x15, ## /< [1.0.0+] u8 + WebArgTypeBootDisplayKind = 0x17, ## /< [1.0.0+] u32 enum \ref WebBootDisplayKind + WebArgTypeBackgroundKind = 0x18, ## /< [1.0.0+] u32 enum \ref WebBackgroundKind + WebArgTypeFooter = 0x19, ## /< [1.0.0+] u8 bool + WebArgTypePointer = 0x1A, ## /< [1.0.0+] u8 bool + WebArgTypeLeftStickMode = 0x1B, ## /< [1.0.0+] u32 enum \ref WebLeftStickMode + WebArgTypeKeyRepeatFrame0 = 0x1C, ## /< [1.0.0+] s32 KeyRepeatFrame, first param + WebArgTypeKeyRepeatFrame1 = 0x1D, ## /< [1.0.0+] s32 KeyRepeatFrame, second param + WebArgTypeBootAsMediaPlayerInverted = 0x1E, ## /< [1.0.0+] u8 bool. With News on [3.0.0+] this is set after BootAsMediaPlayer with the value inverted. + WebArgTypeDisplayUrlKind = 0x1F, ## /< [1.0.0+] u8 bool, DisplayUrlKind (value = (input_enumval==0x1)). + WebArgTypeBootAsMediaPlayer = 0x21, ## /< [2.0.0+] u8 bool + WebArgTypeShopJump = 0x22, ## /< [2.0.0+] u8 bool + WebArgTypeMediaPlayerUserGestureRestriction = 0x23, ## /< [2.0.0-5.1.0] u8 bool + WebArgTypeLobbyParameter = 0x24, ## /< [2.0.0+] String, size 0x100. + WebArgTypeApplicationAlbumEntry = 0x26, ## /< [3.0.0+] Share-applet caps ApplicationAlbumEntry + WebArgTypeJsExtension = 0x27, ## /< [3.0.0+] u8 bool + WebArgTypeAdditionalCommentText = 0x28, ## /< [4.0.0+] String, size 0x100. Share-applet AdditionalCommentText. + WebArgTypeTouchEnabledOnContents = 0x29, ## /< [4.0.0+] u8 bool + WebArgTypeUserAgentAdditionalString = 0x2A, ## /< [4.0.0+] String, size 0x80. + WebArgTypeAdditionalMediaData0 = 0x2B, ## /< [4.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 0. If the user-input size is less than 0x10, the remaining data used for the TLV is cleared. + WebArgTypeMediaPlayerAutoClose = 0x2C, ## /< [4.0.0+] u8 bool + WebArgTypePageCache = 0x2D, ## /< [4.0.0+] u8 bool + WebArgTypeWebAudio = 0x2E, ## /< [4.0.0+] u8 bool + WebArgType2F = 0x2F, ## /< [5.0.0+] u8 + WebArgTypeYouTubeVideoFlag = 0x31, ## /< [5.0.0+] u8 bool Indicates that the built-in whitelist for YouTubeVideo should be used. + WebArgTypeFooterFixedKind = 0x32, ## /< [5.0.0+] u32 enum \ref WebFooterFixedKind + WebArgTypePageFade = 0x33, ## /< [5.0.0+] u8 bool + WebArgTypeMediaCreatorApplicationRatingAge = 0x34, ## /< [5.0.0+] Share-applet 0x20-byte s8 array, MediaCreatorApplicationRatingAge. + WebArgTypeBootLoadingIcon = 0x35, ## /< [5.0.0+] u8 bool + WebArgTypePageScrollIndicator = 0x36, ## /< [5.0.0+] u8 bool + WebArgTypeMediaPlayerSpeedControl = 0x37, ## /< [6.0.0+] u8 bool + WebArgTypeAlbumEntry1 = 0x38, ## /< [6.0.0+] Share-applet caps AlbumEntry, entry 1. + WebArgTypeAlbumEntry2 = 0x39, ## /< [6.0.0+] Share-applet caps AlbumEntry, entry 2. + WebArgTypeAlbumEntry3 = 0x3A, ## /< [6.0.0+] Share-applet caps AlbumEntry, entry 3. + WebArgTypeAdditionalMediaData1 = 0x3B, ## /< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 1. + WebArgTypeAdditionalMediaData2 = 0x3C, ## /< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 2. + WebArgTypeAdditionalMediaData3 = 0x3D, ## /< [6.0.0+] Share-applet 0x10-byte u8 array, AdditionalMediaData. Entry 3. + WebArgTypeBootFooterButton = 0x3E, ## /< [6.0.0+] Array of \ref WebBootFooterButtonEntry with 0x10 entries. + WebArgTypeOverrideWebAudioVolume = 0x3F, ## /< [6.0.0+] float + WebArgTypeOverrideMediaAudioVolume = 0x40, ## /< [6.0.0+] float + WebArgTypeSessionBootMode = 0x41, ## /< [7.0.0+] u32 enum \ref WebSessionBootMode + WebArgTypeSessionFlag = 0x42, ## /< [7.0.0+] u8 bool, enables using WebSession when set. + WebArgTypeMediaPlayerUi = 0x43, ## /< [8.0.0+] u8 bool + WebArgTypeTransferMemory = 0x44 ## /< [11.0.0+] u8 bool + +const + WebArgTypeMediaAutoPlay* = WebArgTypeMediaPlayerUserGestureRestriction + +## / Types for \ref WebArgTLV, output storage. + +type + WebReplyType* = enum + WebReplyTypeExitReason = 0x1, ## /< [3.0.0+] u32 ExitReason + WebReplyTypeLastUrl = 0x2, ## /< [3.0.0+] string + WebReplyTypeLastUrlSize = 0x3, ## /< [3.0.0+] u64 + WebReplyTypeSharePostResult = 0x4, ## /< [3.0.0+] u32 SharePostResult + WebReplyTypePostServiceName = 0x5, ## /< [3.0.0+] string + WebReplyTypePostServiceNameSize = 0x6, ## /< [3.0.0+] u64 + WebReplyTypePostId = 0x7, ## /< [3.0.0+] string + WebReplyTypePostIdSize = 0x8, ## /< [3.0.0+] u64 + WebReplyTypeMediaPlayerAutoClosedByCompletion = 0x9 ## /< [8.0.0+] u8 bool + + +## / This controls the kind of content to mount with Offline-applet. + +type + WebDocumentKind* = enum + WebDocumentKindOfflineHtmlPage = 0x1, ## /< Use the HtmlDocument NCA content from the application. + WebDocumentKindApplicationLegalInformation = 0x2, ## /< Use the LegalInformation NCA content from the application. + WebDocumentKindSystemDataPage = 0x3 ## /< Use the Data NCA content from the specified SystemData, see also: https://switchbrew.org/wiki/Title_list#System_Data_Archives + + +## / This controls the initial page for ShareApplet, used by \ref webShareCreate. + +type + WebShareStartPage* = enum + WebShareStartPageDefault = 0, ## /< The default "/" page. + WebShareStartPageSettings = 1 ## /< The "/settings/" page. + + +## / Kind values for \ref webConfigSetBootDisplayKind. Controls the background color while displaying the loading screen during applet boot. Also controls the BackgroundKind when value is non-zero. + +type + WebBootDisplayKind* = enum + WebBootDisplayKindDefault = 0, ## /< Default. BackgroundKind is controlled by \ref WebBackgroundKind. + WebBootDisplayKindWhite = 1, ## /< White background. Used by \ref webOfflineCreate for docKind ::WebDocumentKind_ApplicationLegalInformation/::WebDocumentKind_SystemDataPage. + WebBootDisplayKindBlack = 2, ## /< Black background. + WebBootDisplayKindUnknown3 = 3, ## /< Unknown. Used by \ref webShareCreate. + WebBootDisplayKindUnknown4 = 4 ## /< Unknown. Used by \ref webLobbyCreate. + + +## / Kind values for \ref webConfigSetBackgroundKind. Controls the background color while displaying the loading screen during applet boot. Only used when \ref WebBootDisplayKind is ::WebBootDisplayKind_Default. If the applet was not launched by an Application, the applet will only use WebBackgroundKind_Default. + +type + WebBackgroundKind* = enum + WebBackgroundKindDefault = 0, ## /< Default. Same as ::WebBootDisplayKind_White/::WebBootDisplayKind_Black, determined via ::WebArgType_BootAsMediaPlayer. + WebBackgroundKindUnknown1 = 1, ## /< Unknown. Same as ::WebBootDisplayKind_Unknown3. + WebBackgroundKindUnknown2 = 2 ## /< Unknown. Same as ::WebBootDisplayKind_Unknown4. Used by \ref webLobbyCreate. + + +## / Mode values for \ref webConfigSetLeftStickMode. Controls the initial mode, this can be toggled by the user via the pressing the left-stick button. If the Pointer flag is set to false (\ref webConfigSetPointer), only ::WebLeftStickMode_Cursor will be used and mode toggle by the user is disabled (input value ignored). + +type + WebLeftStickMode* = enum + WebLeftStickModePointer = 0, ## /< The user can directly control the pointer via the left-stick. + WebLeftStickModeCursor = 1 ## /< The user can only select elements on the page via the left-stick. + + +## / Kind values for \ref webConfigSetFooterFixedKind. Controls UI footer display behaviour. + +type + WebFooterFixedKind* = enum + WebFooterFixedKindDefault = 0, ## /< Default. Footer is hidden while scrolling. + WebFooterFixedKindAlways = 1, ## /< Footer is always displayed regardless of scrolling. + WebFooterFixedKindHidden = 2 ## /< Footer is hidden regardless of scrolling. + +proc webWifiCreate*(config: ptr WebWifiConfig; conntestUrl: cstring; + initialUrl: cstring; uuid: Uuid; rev: U32) {.cdecl, + importc: "webWifiCreate".} +## * +## @brief Creates the config for WifiWebAuthApplet. This is the captive portal applet. +## @param config WebWifiConfig object. +## @param conntest_url URL used for the connection-test requests. When empty/NULL the applet will test the connection with nifm and throw an error on failure. +## @param initial_url Initial URL navigated to by the applet. +## @param uuid NIFM Network UUID, for nifm cmd SetNetworkProfileId. Value 0 can be used. Only used by the applet when conntest_url is set. +## @param rev Input value for nifm cmd SetRequirementByRevision. Value 0 can be used. Only used by the applet when conntest_url is set. +## + +proc webWifiShow*(config: ptr WebWifiConfig; `out`: ptr WebWifiReturnValue): Result {. + cdecl, importc: "webWifiShow".} +## * +## @brief Launches WifiWebAuthApplet with the specified config and waits for it to exit. +## @param config WebWifiConfig object. +## @param out Optional output applet reply data, can be NULL. +## + +proc webPageCreate*(config: ptr WebCommonConfig; url: cstring): Result {.cdecl, + importc: "webPageCreate".} +## * +## @brief Creates the config for WebApplet. This applet uses an URL whitelist loaded from the user-process host Application, which is only loaded when running under an Application. +## @note Sets ::WebArgType_UnknownD, and ::WebArgType_Unknown12 on pre-3.0.0, to value 1. +## @param config WebCommonConfig object. +## @param url Initial URL navigated to by the applet. +## + +proc webNewsCreate*(config: ptr WebCommonConfig; url: cstring): Result {.cdecl, + importc: "webNewsCreate".} +## * +## @brief Creates the config for WebApplet. This is based on \ref webPageCreate, for News. Hence other functions referencing \ref webPageCreate also apply to this. +## @note The domain from the input URL is automatically whitelisted, in addition to any already loaded whitelist. +## @note Sets ::WebArgType_UnknownD to value 1, and sets ::WebArgType_NewsFlag to true. Also uses \ref webConfigSetEcClientCert and \ref webConfigSetShopJump with flag=true. +## @param config WebCommonConfig object. +## @param url Initial URL navigated to by the applet. +## + +proc webYouTubeVideoCreate*(config: ptr WebCommonConfig; url: cstring): Result {.cdecl, + importc: "webYouTubeVideoCreate".} +## * +## @brief Creates the config for WebApplet. This is based on \ref webPageCreate, for YouTubeVideo. Hence other functions referencing \ref webPageCreate also apply to this. This uses a whitelist which essentially only allows youtube embed/ URLs (without mounting content from the host Application). +## @note This is only available on [5.0.0+]. +## @note Sets ::WebArgType_UnknownD to value 1, and sets ::WebArgType_YouTubeVideoFlag to true. Also uses \ref webConfigSetBootAsMediaPlayer with flag=true. +## @param config WebCommonConfig object. +## @param url Initial URL navigated to by the applet. +## + +proc webOfflineCreate*(config: ptr WebCommonConfig; docKind: WebDocumentKind; id: U64; + docPath: cstring): Result {.cdecl, importc: "webOfflineCreate".} +## * +## @brief Creates the config for Offline-applet. This applet uses data loaded from content. +## @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor and sets ::WebArgType_BootAsMediaPlayerInverted to false. Uses \ref webConfigSetPointer with flag = docKind == ::WebDocumentKind_OfflineHtmlPage. +## @note For docKind ::WebDocumentKind_ApplicationLegalInformation / ::WebDocumentKind_SystemDataPage, uses \ref webConfigSetFooter with flag=true and \ref webConfigSetBackgroundKind with ::WebBackgroundKind_Default. +## @note For docKind ::WebDocumentKind_SystemDataPage, uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_White. +## @note Sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. With docKind ::WebDocumentKind_ApplicationLegalInformation, uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_White. +## @note Sets ::WebArgType_UnknownC to value 1. +## @note With docKind ::WebDocumentKind_ApplicationLegalInformation, uses \ref webConfigSetEcClientCert with flag=true. +## @note With docKind ::WebDocumentKind_OfflineHtmlPage on pre-3.0.0, sets ::WebArgType_Unknown12 to value 1. +## @note Lastly, sets the TLVs as needed for the input params. +## @param config WebCommonConfig object. +## @param docKind \ref WebDocumentKind +## @param id Id to load the content from. With docKind = ::WebDocumentKind_OfflineHtmlPage, id=0 should be used to specify the user-process application (non-zero is ignored with this docKind). +## @param docPath Initial document path in RomFS, without the leading '/'. For ::WebDocumentKind_OfflineHtmlPage, this is relative to "html-document/" in RomFS. For the other docKind values, this is relative to "/" in RomFS. This path must contain ".htdocs/". +## + +proc webShareCreate*(config: ptr WebCommonConfig; page: WebShareStartPage): Result {. + cdecl, importc: "webShareCreate".} +## * +## @brief Creates the config for ShareApplet. This applet is for social media posting/settings. +## @note If a non-zero uid isn't set with \ref webConfigSetUid prior to using \ref webConfigShow, the applet will launch the profile-selector applet to select an account. +## @note An error will be displayed if neither \ref webConfigSetAlbumEntry, nor \ref webConfigSetApplicationAlbumEntry, nor \ref webConfigAddAlbumEntryAndMediaData are used prior to using \ref webConfigShow, with ::WebShareStartPage_Default. +## @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor, \ref webConfigSetUid with uid=0, \ref webConfigSetDisplayUrlKind with kind=true, and sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. Uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_Unknown3. +## @param config WebCommonConfig object. +## @param page \ref WebShareStartPage +## + +proc webLobbyCreate*(config: ptr WebCommonConfig): Result {.cdecl, + importc: "webLobbyCreate".} +## * +## @brief Creates the config for LobbyApplet. This applet is for "Nintendo Switch Online Lounge". +## @note Only available on [2.0.0+]. +## @note If a non-zero uid isn't set with \ref webConfigSetUid prior to using \ref webConfigShow, the applet will launch the profile-selector applet to select an account. +## @note Uses \ref webConfigSetLeftStickMode with ::WebLeftStickMode_Cursor, \ref webConfigSetPointer with flag=false on [3.0.0+], \ref webConfigSetUid with uid=0, and sets ::WebArgType_Unknown14/::WebArgType_Unknown15 to value 1. Uses \ref webConfigSetBootDisplayKind with ::WebBootDisplayKind_Unknown4, \ref webConfigSetBackgroundKind with ::WebBackgroundKind_Unknown2, and sets ::WebArgType_BootAsMediaPlayerInverted to false. +## @param config WebCommonConfig object. +## + +proc webConfigSetCallbackUrl*(config: ptr WebCommonConfig; url: cstring): Result {. + cdecl, importc: "webConfigSetCallbackUrl".} +## * +## @brief Sets the CallbackUrl. See also \ref webReplyGetLastUrl. +## @note With Offline-applet for LastUrl handling, it compares the domain with "localhost" instead. +## @note Only available with config created by \ref webPageCreate or with Share-applet. +## @param config WebCommonConfig object. +## @param url URL +## + +proc webConfigSetCallbackableUrl*(config: ptr WebCommonConfig; url: cstring): Result {. + cdecl, importc: "webConfigSetCallbackableUrl".} +## * +## @brief Sets the CallbackableUrl. +## @note Only available with config created by \ref webPageCreate. +## @param config WebCommonConfig object. +## @param url URL +## + +proc webConfigSetWhitelist*(config: ptr WebCommonConfig; whitelist: cstring): Result {. + cdecl, importc: "webConfigSetWhitelist".} +## * +## @brief Sets the whitelist. +## @note Only available with config created by \ref webPageCreate. +## @note If the whitelist isn't formatted properly, the applet will exit briefly after the applet is launched. +## @param config WebCommonConfig object. +## @param whitelist Whitelist string, each line is a regex for each whitelisted URL. +## + +proc webConfigSetUid*(config: ptr WebCommonConfig; uid: AccountUid): Result {.cdecl, + importc: "webConfigSetUid".} +## * +## @brief Sets the account uid. Controls which user-specific savedata to mount. +## @note Only available with config created by \ref webPageCreate, \ref webLobbyCreate, or with Share-applet. +## @note Used automatically by \ref webShareCreate and \ref webLobbyCreate with uid=0. +## @param config WebCommonConfig object. +## @param uid \ref AccountUid +## + +proc webConfigSetAlbumEntry*(config: ptr WebCommonConfig; entry: ptr CapsAlbumEntry): Result {. + cdecl, importc: "webConfigSetAlbumEntry".} +## * +## @brief Sets the Share CapsAlbumEntry. +## @note Only available with config created by \ref webShareCreate. +## @param config WebCommonConfig object. +## @param entry \ref CapsAlbumEntry +## + +proc webConfigSetScreenShot*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetScreenShot".} +## * +## @brief Sets the ScreenShot flag, which controls whether screen-shot capture is allowed. +## @note Only available with config created by \ref webPageCreate. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetEcClientCert*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetEcClientCert".} +## * +## @brief Sets the EcClientCert flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate. +## @note Used automatically by \ref webOfflineCreate, depending on the docKind. +## @note Used automatically by \ref webNewsCreate with flag=true. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetPlayReport*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetPlayReport".} +## * +## @brief Sets whether PlayReport is enabled. +## @note Only available with config created by \ref webOfflineCreate. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetBootDisplayKind*(config: ptr WebCommonConfig; + kind: WebBootDisplayKind): Result {.cdecl, + importc: "webConfigSetBootDisplayKind".} +## * +## @brief Sets the BootDisplayKind. +## @note Only available with config created by \ref webOfflineCreate, \ref webShareCreate, \ref webPageCreate, or \ref webLobbyCreate.. +## @note Used automatically by \ref webOfflineCreate, depending on the docKind. +## @note Used automatically by \ref webShareCreate with kind=::WebBootDisplayKind_Unknown3. +## @note Used automatically by \ref webLobbyCreate with kind=::WebBootDisplayKind_Unknown4. +## @param config WebCommonConfig object. +## @param kind \ref WebBootDisplayKind +## + +proc webConfigSetBackgroundKind*(config: ptr WebCommonConfig; + kind: WebBackgroundKind): Result {.cdecl, + importc: "webConfigSetBackgroundKind".} +## * +## @brief Sets the BackgroundKind. +## @note Only available with config created by \ref webOfflineCreate, \ref webPageCreate, or \ref webLobbyCreate. +## @note Used automatically by \ref webOfflineCreate, depending on the docKind. +## @note Used automatically by \ref webLobbyCreate with kind=2. +## @param config WebCommonConfig object. +## @param kind \ref WebBackgroundKind +## + +proc webConfigSetFooter*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetFooter".} +## * +## @brief Sets the whether the UI footer is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate. +## @note Used automatically by \ref webOfflineCreate, depending on the docKind. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetPointer*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetPointer".} +## * +## @brief Sets the whether the Pointer is enabled. See also \ref WebLeftStickMode. +## @note Only available with config created by \ref webOfflineCreate, \ref webPageCreate, or \ref webLobbyCreate. +## @note Used automatically by \ref webOfflineCreate. +## @note Used automatically by \ref webLobbyCreate with flag=false on [3.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetLeftStickMode*(config: ptr WebCommonConfig; mode: WebLeftStickMode): Result {. + cdecl, importc: "webConfigSetLeftStickMode".} +## * +## @brief Sets the LeftStickMode. +## @note Only available with config created by \ref webOfflineCreate, \ref webShareCreate, \ref webPageCreate, or \ref webLobbyCreate. +## @note Used automatically by \ref webOfflineCreate, \ref webShareCreate, and \ref webLobbyCreate with ::WebLeftStickMode_Cursor. +## @param config WebCommonConfig object. +## @param mode Mode, different enums for Web and Offline. +## + +proc webConfigSetKeyRepeatFrame*(config: ptr WebCommonConfig; inval0: S32; inval1: S32): Result {. + cdecl, importc: "webConfigSetKeyRepeatFrame".} +## * +## @brief Sets the KeyRepeatFrame. +## @note Only available with config created by \ref webOfflineCreate. +## @param config WebCommonConfig object. +## @param inval0 First input param. +## @param inval1 Second input param. +## + +proc webConfigSetDisplayUrlKind*(config: ptr WebCommonConfig; kind: bool): Result {. + cdecl, importc: "webConfigSetDisplayUrlKind".} +## * +## @brief Sets the DisplayUrlKind. +## @note Only available with config created by \ref webShareCreate or \ref webPageCreate. +## @param config WebCommonConfig object. +## @note Used automatically by \ref webShareCreate with kind=true. +## @param kind Kind +## + +proc webConfigSetBootAsMediaPlayer*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetBootAsMediaPlayer".} +## * +## @brief Sets the BootAsMediaPlayer flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [2.0.0+]. +## @note With config created by \ref webNewsCreate on [3.0.0+], this also sets ::WebArgType_BootAsMediaPlayerInverted to !flag. +## @param config WebCommonConfig object. +## @param flag Flag. true = BootAsMediaPlayer, false = BootAsWebPage. +## + +proc webConfigSetShopJump*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetShopJump".} +## * +## @brief Sets the ShopJump flag. +## @note Only available with config created by \ref webPageCreate on [2.0.0+]. +## @note Used automatically by \ref webNewsCreate with flag=true. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetMediaPlayerUserGestureRestriction*(config: ptr WebCommonConfig; + flag: bool): Result {.cdecl, + importc: "webConfigSetMediaPlayerUserGestureRestriction".} +## * +## @brief Sets the MediaPlayerUserGestureRestriction flag. +## @note Only available with config created by \ref webPageCreate on [2.0.0-5.1.0]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetMediaAutoPlay*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetMediaAutoPlay".} +## * +## @brief Sets whether MediaAutoPlay is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetLobbyParameter*(config: ptr WebCommonConfig; str: cstring): Result {. + cdecl, importc: "webConfigSetLobbyParameter".} +## * +## @brief Sets the LobbyParameter. +## @note Only available with config created by \ref webLobbyCreate. +## @param config WebCommonConfig object. +## @param str String +## + +proc webConfigSetApplicationAlbumEntry*(config: ptr WebCommonConfig; + entry: ptr CapsApplicationAlbumEntry): Result {. + cdecl, importc: "webConfigSetApplicationAlbumEntry".} +## * +## @brief Sets the Share CapsApplicationAlbumEntry. +## @note Only available with config created by \ref webShareCreate on [3.0.0+]. +## @param config WebCommonConfig object. +## @param entry \ref CapsApplicationAlbumEntry, see also capssu.h. +## + +proc webConfigSetJsExtension*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetJsExtension".} +## * +## @brief Sets whether JsExtension is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [3.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetAdditionalCommentText*(config: ptr WebCommonConfig; str: cstring): Result {. + cdecl, importc: "webConfigSetAdditionalCommentText".} +## * +## @brief Sets the Share AdditionalCommentText. +## @note Only available with config created by \ref webShareCreate on [4.0.0+]. +## @param config WebCommonConfig object. +## @param str String +## + +proc webConfigSetTouchEnabledOnContents*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetTouchEnabledOnContents".} +## * +## @brief Sets the TouchEnabledOnContents flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetUserAgentAdditionalString*(config: ptr WebCommonConfig; + str: cstring): Result {.cdecl, importc: "webConfigSetUserAgentAdditionalString".} +## * +## @brief Sets the UserAgentAdditionalString. " " followed by this string are appended to the normal User-Agent string. +## @note Only available with config created by \ref webPageCreate on [4.0.0+]. +## @param config WebCommonConfig object. +## @param str String +## + +proc webConfigSetAdditionalMediaData*(config: ptr WebCommonConfig; data: ptr U8; + size: csize_t): Result {.cdecl, + importc: "webConfigSetAdditionalMediaData".} +## * +## @brief Sets the Share AdditionalMediaData. +## @note Only available with config created by \ref webShareCreate on [4.0.0+]. +## @param config WebCommonConfig object. +## @param data Input data +## @param size Size of the input data, max size is 0x10. +## + +proc webConfigSetMediaPlayerAutoClose*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetMediaPlayerAutoClose".} +## * +## @brief Sets the MediaPlayerAutoClose flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetPageCache*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetPageCache".} +## * +## @brief Sets whether PageCache is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetWebAudio*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetWebAudio".} +## * +## @brief Sets whether WebAudio is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [4.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetFooterFixedKind*(config: ptr WebCommonConfig; + kind: WebFooterFixedKind): Result {.cdecl, + importc: "webConfigSetFooterFixedKind".} +## * +## @brief Sets the FooterFixedKind. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. +## @param config WebCommonConfig object. +## @param kind \ref WebFooterFixedKind +## + +proc webConfigSetPageFade*(config: ptr WebCommonConfig; flag: bool): Result {.cdecl, + importc: "webConfigSetPageFade".} +## * +## @brief Sets the PageFade flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetMediaCreatorApplicationRatingAge*(config: ptr WebCommonConfig; + data: ptr S8): Result {.cdecl, + importc: "webConfigSetMediaCreatorApplicationRatingAge".} +## * +## @brief Sets the Share MediaCreatorApplicationRatingAge. +## @note Only available with config created by \ref webShareCreate on [5.0.0+]. +## @param config WebCommonConfig object. +## @param data 0x20-byte input data +## + +proc webConfigSetBootLoadingIcon*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetBootLoadingIcon".} +## * +## @brief Sets the BootLoadingIcon flag. +## @note Only available with config created by \ref webOfflineCreate on [5.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetPageScrollIndicator*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetPageScrollIndicator".} +## * +## @brief Sets the PageScrollIndicator flag. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [5.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetMediaPlayerSpeedControl*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetMediaPlayerSpeedControl".} +## * +## @brief Sets whether MediaPlayerSpeedControl is enabled. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigAddAlbumEntryAndMediaData*(config: ptr WebCommonConfig; + entry: ptr CapsAlbumEntry; data: ptr U8; + size: csize_t): Result {.cdecl, + importc: "webConfigAddAlbumEntryAndMediaData".} +## * +## @brief Adds a pair of Share CapsAlbumEntry + optionally AdditionalMediaData. This can be used up to 4 times, for setting multiple pairs. +## @note Only available with config created by \ref webShareCreate on [6.0.0+]. +## @param config WebCommonConfig object. +## @param entry \ref CapsAlbumEntry +## @param data Input data for AdditionalMediaData. Optional, can be NULL. +## @param size Size of the input data, max size is 0x10. Optional, can be 0. +## + +proc webConfigSetBootFooterButtonVisible*(config: ptr WebCommonConfig; + button: WebFooterButtonId; visible: bool): Result {.cdecl, + importc: "webConfigSetBootFooterButtonVisible".} +## * +## @brief Sets whether the specified BootFooterButton is visible. +## @note Only available with config created by \ref webOfflineCreate on [6.0.0+]. +## @param config WebCommonConfig object. +## @param button \ref WebFooterButtonId +## @param visible Visible flag. +## + +proc webConfigSetOverrideWebAudioVolume*(config: ptr WebCommonConfig; value: cfloat): Result {. + cdecl, importc: "webConfigSetOverrideWebAudioVolume".} +## * +## @brief Sets OverrideWebAudioVolume. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. +## @param config WebCommonConfig object. +## @param value Value +## + +proc webConfigSetOverrideMediaAudioVolume*(config: ptr WebCommonConfig; + value: cfloat): Result {.cdecl, importc: "webConfigSetOverrideMediaAudioVolume".} +## * +## @brief Sets OverrideMediaAudioVolume. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [6.0.0+]. +## @param config WebCommonConfig object. +## @param value Value +## + +proc webConfigSetBootMode*(config: ptr WebCommonConfig; mode: WebSessionBootMode): Result {. + cdecl, importc: "webConfigSetBootMode".} +## * +## @brief Sets \ref WebSessionBootMode. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [7.0.0+]. +## @param config WebCommonConfig object. +## @param mode \ref WebSessionBootMode +## + +proc webConfigSetMediaPlayerUi*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetMediaPlayerUi".} +## * +## @brief Sets whether MediaPlayerUi is enabled. +## @note Only available with config created by \ref webOfflineCreate on [8.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigSetTransferMemory*(config: ptr WebCommonConfig; flag: bool): Result {. + cdecl, importc: "webConfigSetTransferMemory".} +## * +## @brief Sets whether TransferMemory is enabled. +## @note Only available with config created by \ref webPageCreate on [11.0.0+]. +## @param config WebCommonConfig object. +## @param flag Flag +## + +proc webConfigShow*(config: ptr WebCommonConfig; `out`: ptr WebCommonReply): Result {. + cdecl, importc: "webConfigShow".} +## * +## @brief Launches the {web applet} with the specified config and waits for it to exit. +## @param config WebCommonConfig object. +## @param out Optional output applet reply data, can be NULL. +## + +proc webConfigRequestExit*(config: ptr WebCommonConfig): Result {.cdecl, + importc: "webConfigRequestExit".} +## * +## @brief Request the applet to exit after \ref webConfigShow was used, while the applet is still running. This is for use from another thread. +## @param config WebCommonConfig object. +## + +proc webReplyGetExitReason*(reply: ptr WebCommonReply; exitReason: ptr WebExitReason): Result {. + cdecl, importc: "webReplyGetExitReason".} +## * +## @brief Gets the ExitReason from the specified reply. +## @param reply WebCommonReply object. +## @param exitReason Output \ref WebExitReason +## + +proc webReplyGetLastUrl*(reply: ptr WebCommonReply; outstr: cstring; + outstrMaxsize: csize_t; outSize: ptr csize_t): Result {.cdecl, + importc: "webReplyGetLastUrl".} +## * +## @brief Gets the LastUrl from the specified reply. When the applet loads a page where the beginning of the URL matches the URL from \ref webConfigSetCallbackUrl, the applet will exit and set LastUrl to that URL (exit doesn't occur when \ref webConfigSetCallbackableUrl was used). +## @note This is only available with ::WebExitReason_LastUrl (string is empty otherwise). +## @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. +## @param reply WebCommonReply object. +## @param outstr Output string buffer. If NULL, the string is not loaded. +## @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). +## @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. +## + +proc webReplyGetSharePostResult*(reply: ptr WebCommonReply; sharePostResult: ptr U32): Result {. + cdecl, importc: "webReplyGetSharePostResult".} +## * +## @brief Gets the SharePostResult from the specified reply. +## @note Only available with reply data from ShareApplet on [3.0.0+]. +## @param reply WebCommonReply object. +## @param sharePostResult Output sharePostResult +## + +proc webReplyGetPostServiceName*(reply: ptr WebCommonReply; outstr: cstring; + outstrMaxsize: csize_t; outSize: ptr csize_t): Result {. + cdecl, importc: "webReplyGetPostServiceName".} +## * +## @brief Gets the PostServiceName from the specified reply. +## @note Only available with reply data from ShareApplet on [3.0.0+]. +## @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. +## @param reply WebCommonReply object. +## @param outstr Output string buffer. If NULL, the string is not loaded. +## @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). +## @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. +## + +proc webReplyGetPostId*(reply: ptr WebCommonReply; outstr: cstring; + outstrMaxsize: csize_t; outSize: ptr csize_t): Result {.cdecl, + importc: "webReplyGetPostId".} +## * +## @brief Gets the PostId from the specified reply. +## @note Only available with reply data from ShareApplet on [3.0.0+]. +## @note If you want to allocate a string buffer on heap, you can call this with outstr=NULL/outstr_maxsize=0 to get the out_size, then call it again with the allocated buffer. +## @param reply WebCommonReply object. +## @param outstr Output string buffer. If NULL, the string is not loaded. +## @param outstr_maxsize Size of the buffer, including NUL-terminator. If outstr is set, this size must be >1. The size used for the actual string-copy is this size-1, to make sure the output is NUL-terminated (the entire buffer is cleared first). +## @param out_size Output string length including NUL-terminator, for the original input string in the reply loaded from a separate size field. +## + +proc webReplyGetMediaPlayerAutoClosedByCompletion*(reply: ptr WebCommonReply; + flag: ptr bool): Result {.cdecl, importc: "webReplyGetMediaPlayerAutoClosedByCompletion".} +## * +## @brief Gets the MediaPlayerAutoClosedByCompletion flag from the specified reply. +## @note Only available with reply data from Web on [8.0.0+]. +## @param reply WebCommonReply object. +## @param flag Output flag +## + +proc webSessionCreate*(s: ptr WebSession; config: ptr WebCommonConfig) {.cdecl, + importc: "webSessionCreate".} +## * +## @brief Creates a \ref WebSession object. +## @param s \ref WebSession +## @param config WebCommonConfig object. +## + +proc webSessionClose*(s: ptr WebSession) {.cdecl, importc: "webSessionClose".} +## * +## @brief Closes a \ref WebSession object. +## @param s \ref WebSession +## + +proc webSessionStart*(s: ptr WebSession; outEvent: ptr ptr Event): Result {.cdecl, + importc: "webSessionStart".} +## * +## @brief Launches the applet for \ref WebSession. +## @note Only available with config created by \ref webOfflineCreate or \ref webPageCreate, on [7.0.0+]. +## @note Do not use \ref webConfigShow when using WebSession. +## @param s \ref WebSession +## @param[out] out_event Output Event with autoclear=false, from \ref appletHolderGetExitEvent. Optional, can be NULL. +## + +proc webSessionWaitForExit*(s: ptr WebSession; `out`: ptr WebCommonReply): Result {. + cdecl, importc: "webSessionWaitForExit".} +## * +## @brief Waits for the applet to exit. +## @note This must be used before \ref webSessionClose, when \ref webSessionStart was used successfully. +## @param s \ref WebSession +## @param out Optional output applet reply data, can be NULL. +## + +proc webSessionRequestExit*(s: ptr WebSession): Result {.cdecl, + importc: "webSessionRequestExit".} +## * +## @brief Request the applet to exit. +## @note Use this instead of \ref webConfigRequestExit, when using WebSession. +## @param s \ref WebSession +## + +proc webSessionAppear*(s: ptr WebSession; flag: ptr bool): Result {.cdecl, + importc: "webSessionAppear".} +## * +## @brief Request the applet to Appear, this is only needed with ::WebSessionBootMode_AllForegroundInitiallyHidden. +## @note This should not be used before \ref webSessionStart. +## @param s \ref WebSession +## @param[out] flag Whether the message was sent successfully. +## + +proc webSessionTrySendContentMessage*(s: ptr WebSession; content: cstring; size: U32; + flag: ptr bool): Result {.cdecl, + importc: "webSessionTrySendContentMessage".} +## * +## @brief TrySendContentMessage +## @note This should not be used before \ref webSessionStart. +## @note The JS-side for this is only available when JsExtension is enabled via \ref webConfigSetJsExtension. +## @note The JS-side may ignore this if it's sent too soon after the applet launches. +## @param s \ref WebSession +## @param[in] content Input content NUL-terminated string. +## @param[in] size Size of content. +## @param[out] flag Whether the message was sent successfully. +## + +proc webSessionTryReceiveContentMessage*(s: ptr WebSession; content: cstring; + size: U64; outSize: ptr U64; flag: ptr bool): Result {. + cdecl, importc: "webSessionTryReceiveContentMessage".} +## * +## @brief TryReceiveContentMessage +## @note This should not be used before \ref webSessionStart. +## @note The JS-side for this is only available when JsExtension is enabled via \ref webConfigSetJsExtension. +## @param s \ref WebSession +## @param[out] content Output content string, always NUL-terminated. +## @param[in] size Max size of content. +## @param[out] out_size Original content size, prior to being clamped to the specified size param. +## @param[out] flag Whether the message was received successfully. +## + diff --git a/src/libnx/wrapper/switch/arm/cache.h b/src/libnx/wrapper/switch/arm/cache.h new file mode 100644 index 0000000..a97fbbe --- /dev/null +++ b/src/libnx/wrapper/switch/arm/cache.h @@ -0,0 +1,41 @@ +/** + * @file cache.h + * @brief AArch64 cache operations. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/** + * @brief Performs a data cache flush on the specified buffer. + * @param addr Address of the buffer. + * @param size Size of the buffer, in bytes. + * @remarks Cache flush is defined as Clean + Invalidate. + * @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). + */ +void armDCacheFlush(void* addr, size_t size); + +/** + * @brief Performs a data cache clean on the specified buffer. + * @param addr Address of the buffer. + * @param size Size of the buffer, in bytes. + * @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). + */ +void armDCacheClean(void* addr, size_t size); + +/** + * @brief Performs an instruction cache invalidation clean on the specified buffer. + * @param addr Address of the buffer. + * @param size Size of the buffer, in bytes. + * @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). + */ +void armICacheInvalidate(void* addr, size_t size); + +/** + * @brief Performs a data cache zeroing operation on the specified buffer. + * @param addr Address of the buffer. + * @param size Size of the buffer, in bytes. + * @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). + */ +void armDCacheZero(void* addr, size_t size); diff --git a/src/libnx/wrapper/switch/arm/cache.nim b/src/libnx/wrapper/switch/arm/cache.nim new file mode 100644 index 0000000..7b087e5 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/cache.nim @@ -0,0 +1,43 @@ +## * +## @file cache.h +## @brief AArch64 cache operations. +## @author plutoo +## @copyright libnx Authors +## + +proc armDCacheFlush*(`addr`: pointer; size: csize_t) {.cdecl, + importc: "armDCacheFlush".} +## * +## @brief Performs a data cache flush on the specified buffer. +## @param addr Address of the buffer. +## @param size Size of the buffer, in bytes. +## @remarks Cache flush is defined as Clean + Invalidate. +## @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). +## + +proc armDCacheClean*(`addr`: pointer; size: csize_t) {.cdecl, + importc: "armDCacheClean".} +## * +## @brief Performs a data cache clean on the specified buffer. +## @param addr Address of the buffer. +## @param size Size of the buffer, in bytes. +## @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). +## + +proc armICacheInvalidate*(`addr`: pointer; size: csize_t) {.cdecl, + importc: "armICacheInvalidate".} +## * +## @brief Performs an instruction cache invalidation clean on the specified buffer. +## @param addr Address of the buffer. +## @param size Size of the buffer, in bytes. +## @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). +## + +proc armDCacheZero*(`addr`: pointer; size: csize_t) {.cdecl, importc: "armDCacheZero".} +## * +## @brief Performs a data cache zeroing operation on the specified buffer. +## @param addr Address of the buffer. +## @param size Size of the buffer, in bytes. +## @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register). +## + diff --git a/src/libnx/wrapper/switch/arm/counter.h b/src/libnx/wrapper/switch/arm/counter.h new file mode 100644 index 0000000..601bc42 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/counter.h @@ -0,0 +1,46 @@ +/** + * @file counter.h + * @brief AArch64 system counter-timer. + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/** + * @brief Gets the current system tick. + * @return The current system tick. + */ +static inline u64 armGetSystemTick(void) { + u64 ret; + __asm__ __volatile__ ("mrs %x[data], cntpct_el0" : [data] "=r" (ret)); + return ret; +} + +/** + * @brief Gets the system counter-timer frequency + * @return The system counter-timer frequency, in Hz. + */ +static inline u64 armGetSystemTickFreq(void) { + u64 ret; + __asm__ ("mrs %x[data], cntfrq_el0" : [data] "=r" (ret)); + return ret; +} + +/** + * @brief Converts from nanoseconds to CPU ticks unit. + * @param ns Time in nanoseconds. + * @return Time in CPU ticks. + */ +static inline u64 armNsToTicks(u64 ns) { + return (ns * 12) / 625; +} + +/** + * @brief Converts from CPU ticks unit to nanoseconds. + * @param tick Time in ticks. + * @return Time in nanoseconds. + */ +static inline u64 armTicksToNs(u64 tick) { + return (tick * 625) / 12; +} diff --git a/src/libnx/wrapper/switch/arm/counter.nim b/src/libnx/wrapper/switch/arm/counter.nim new file mode 100644 index 0000000..e9c8d53 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/counter.nim @@ -0,0 +1,40 @@ +## * +## @file counter.h +## @brief AArch64 system counter-timer. +## @author fincs +## @copyright libnx Authors +## + +import + ../types + +proc armGetSystemTick*(): U64 {.inline, cdecl.} = + ## * + ## @brief Gets the current system tick. + ## @return The current system tick. + ## + {.emit: "__asm__ __volatile__ (\"mrs %x[data], cntpct_el0\" : [data] \"=r\" (`result`));".} + +proc armGetSystemTickFreq*(): U64 {.inline, cdecl.} = + ## * + ## @brief Gets the system counter-timer frequency + ## @return The system counter-timer frequency, in Hz. + ## + {.emit: "__asm__ (\"mrs %x[data], cntfrq_el0\" : [data] \"=r\" (`result`));".} + +proc armNsToTicks*(ns: U64): U64 {.inline, cdecl.} = + ## * + ## @brief Converts from nanoseconds to CPU ticks unit. + ## @param ns Time in nanoseconds. + ## @return Time in CPU ticks. + ## + {.emit: "return (`ns` * 12) / 625;".} + +proc armTicksToNs*(tick: U64): U64 {.inline, cdecl.} = + ## * + ## @brief Converts from CPU ticks unit to nanoseconds. + ## @param tick Time in ticks. + ## @return Time in nanoseconds. + ## + {.emit: "return (`tick` * 625) / 12;".} + diff --git a/src/libnx/wrapper/switch/arm/thread_context.h b/src/libnx/wrapper/switch/arm/thread_context.h new file mode 100644 index 0000000..b97710e --- /dev/null +++ b/src/libnx/wrapper/switch/arm/thread_context.h @@ -0,0 +1,130 @@ +/** + * @file thread_context.h + * @brief AArch64 register dump format and related definitions. + * @author TuxSH + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" + +/// Armv8 CPU register. +typedef union { + u64 x; ///< 64-bit AArch64 register view. + u32 w; ///< 32-bit AArch64 register view. + u32 r; ///< AArch32 register view. +} CpuRegister; + +/// Armv8 NEON register. +typedef union { + u128 v; ///< 128-bit vector view. + double d; ///< 64-bit double-precision view. + float s; ///< 32-bit single-precision view. +} FpuRegister; + +/// Armv8 register group. @ref svcGetThreadContext3 uses @ref RegisterGroup_All. +typedef enum { + RegisterGroup_CpuGprs = BIT(0), ///< General-purpose CPU registers (x0..x28 or r0..r10,r12). + RegisterGroup_CpuSprs = BIT(1), ///< Special-purpose CPU registers (fp, lr, sp, pc, PSTATE or cpsr, TPIDR_EL0). + RegisterGroup_FpuGprs = BIT(2), ///< General-purpose NEON registers. + RegisterGroup_FpuSprs = BIT(3), ///< Special-purpose NEON registers. + + RegisterGroup_CpuAll = RegisterGroup_CpuGprs | RegisterGroup_CpuSprs, ///< All CPU registers. + RegisterGroup_FpuAll = RegisterGroup_FpuGprs | RegisterGroup_FpuSprs, ///< All NEON registers. + RegisterGroup_All = RegisterGroup_CpuAll | RegisterGroup_FpuAll, ///< All registers. +} RegisterGroup; + +/// This is for \ref ThreadExceptionDump error_desc. +typedef enum { + ThreadExceptionDesc_InstructionAbort = 0x100, ///< Instruction abort + ThreadExceptionDesc_MisalignedPC = 0x102, ///< Misaligned PC + ThreadExceptionDesc_MisalignedSP = 0x103, ///< Misaligned SP + ThreadExceptionDesc_SError = 0x106, ///< SError [not in 1.0.0?] + ThreadExceptionDesc_BadSVC = 0x301, ///< Bad SVC + ThreadExceptionDesc_Trap = 0x104, ///< Uncategorized, CP15RTTrap, CP15RRTTrap, CP14RTTrap, CP14RRTTrap, IllegalState, SystemRegisterTrap + ThreadExceptionDesc_Other = 0x101, ///< None of the above, EC <= 0x34 and not a breakpoint +} ThreadExceptionDesc; + +/// Thread context structure (register dump) +typedef struct { + CpuRegister cpu_gprs[29]; ///< GPRs 0..28. Note: also contains AArch32 SPRs. + u64 fp; ///< Frame pointer (x29) (AArch64). For AArch32, check r11. + u64 lr; ///< Link register (x30) (AArch64). For AArch32, check r14. + u64 sp; ///< Stack pointer (AArch64). For AArch32, check r13. + CpuRegister pc; ///< Program counter. + u32 psr; ///< PSTATE or cpsr. + + FpuRegister fpu_gprs[32]; ///< 32 general-purpose NEON registers. + u32 fpcr; ///< Floating-point control register. + u32 fpsr; ///< Floating-point status register. + + u64 tpidr; ///< EL0 Read/Write Software Thread ID Register. +} ThreadContext; + +/// Thread exception dump structure. +typedef struct { + u32 error_desc; ///< See \ref ThreadExceptionDesc. + u32 pad[3]; + + CpuRegister cpu_gprs[29]; ///< GPRs 0..28. Note: also contains AArch32 registers. + CpuRegister fp; ///< Frame pointer. + CpuRegister lr; ///< Link register. + CpuRegister sp; ///< Stack pointer. + CpuRegister pc; ///< Program counter (elr_el1). + + u64 padding; + + FpuRegister fpu_gprs[32]; ///< 32 general-purpose NEON registers. + + u32 pstate; ///< pstate & 0xFF0FFE20 + u32 afsr0; + u32 afsr1; + u32 esr; + + CpuRegister far; ///< Fault Address Register. +} ThreadExceptionDump; + +typedef struct { + u64 cpu_gprs[9]; ///< GPRs 0..8. + u64 lr; + u64 sp; + u64 elr_el1; + u32 pstate; ///< pstate & 0xFF0FFE20 + u32 afsr0; + u32 afsr1; + u32 esr; + u64 far; +} ThreadExceptionFrameA64; + +typedef struct { + u32 cpu_gprs[8]; ///< GPRs 0..7. + u32 sp; + u32 lr; + u32 elr_el1; + u32 tpidr_el0; ///< tpidr_el0 = 1 + u32 cpsr; ///< cpsr & 0xFF0FFE20 + u32 afsr0; + u32 afsr1; + u32 esr; + u32 far; +} ThreadExceptionFrameA32; + +/** + * @brief Determines whether a thread context belong to an AArch64 process based on the PSR. + * @param[in] ctx Thread context to which PSTATE/cspr has been dumped to. + * @return true if and only if the thread context belongs to an AArch64 process. + */ +static inline bool threadContextIsAArch64(const ThreadContext *ctx) +{ + return (ctx->psr & 0x10) == 0; +} + +/** + * @brief Determines whether a ThreadExceptionDump belongs to an AArch64 process based on the PSTATE. + * @param[in] ctx ThreadExceptionDump. + * @return true if and only if the ThreadExceptionDump belongs to an AArch64 process. + */ +static inline bool threadExceptionIsAArch64(const ThreadExceptionDump *ctx) +{ + return (ctx->pstate & 0x10) == 0; +} diff --git a/src/libnx/wrapper/switch/arm/thread_context.nim b/src/libnx/wrapper/switch/arm/thread_context.nim new file mode 100644 index 0000000..49dc9b4 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/thread_context.nim @@ -0,0 +1,128 @@ +## * +## @file thread_context.h +## @brief AArch64 register dump format and related definitions. +## @author TuxSH +## @copyright libnx Authors +## + +import + ../types + +## / Armv8 CPU register. + +type + CpuRegister* {.bycopy, union.} = object + x*: U64 ## /< 64-bit AArch64 register view. + w*: U32 ## /< 32-bit AArch64 register view. + r*: U32 ## /< AArch32 register view. + + +## / Armv8 NEON register. + +type + FpuRegister* {.bycopy, union.} = object + v*: U128 ## /< 128-bit vector view. + d*: cdouble ## /< 64-bit double-precision view. + s*: cfloat ## /< 32-bit single-precision view. + + +## / Armv8 register group. @ref svcGetThreadContext3 uses @ref RegisterGroup_All. + +type + RegisterGroup* = enum + RegisterGroupCpuGprs = bit(0), ## /< General-purpose CPU registers (x0..x28 or r0..r10,r12). + RegisterGroupCpuSprs = bit(1), ## /< Special-purpose CPU registers (fp, lr, sp, pc, PSTATE or cpsr, TPIDR_EL0). + RegisterGroupCpuAll = RegisterGroupCpuGprs.uint or RegisterGroupCpuSprs.uint, ## /< All CPU registers. + RegisterGroupFpuGprs = bit(2), ## /< General-purpose NEON registers. + RegisterGroupFpuSprs = bit(3), ## /< Special-purpose NEON registers. + RegisterGroupFpuAll = RegisterGroupFpuGprs.uint or RegisterGroupFpuSprs.uint, ## /< All NEON registers. + RegisterGroupAll = RegisterGroupCpuAll.uint or RegisterGroupFpuAll.uint ## /< All registers. + + +## / This is for \ref ThreadExceptionDump error_desc. + +type + ThreadExceptionDesc* = enum + ThreadExceptionDescInstructionAbort = 0x100, ## /< Instruction abort + ThreadExceptionDescOther = 0x101, ## /< None of the above, EC <= 0x34 and not a breakpoint + ThreadExceptionDescMisalignedPC = 0x102, ## /< Misaligned PC + ThreadExceptionDescMisalignedSP = 0x103, ## /< Misaligned SP + ThreadExceptionDescTrap = 0x104, ## /< Uncategorized, CP15RTTrap, CP15RRTTrap, CP14RTTrap, CP14RRTTrap, IllegalState, SystemRegisterTrap + ThreadExceptionDescSError = 0x106, ## /< SError [not in 1.0.0?] + ThreadExceptionDescBadSVC = 0x301 ## /< Bad SVC + + +## / Thread context structure (register dump) + +type + ThreadContext* {.bycopy.} = object + cpuGprs*: array[29, CpuRegister] ## /< GPRs 0..28. Note: also contains AArch32 SPRs. + fp*: U64 ## /< Frame pointer (x29) (AArch64). For AArch32, check r11. + lr*: U64 ## /< Link register (x30) (AArch64). For AArch32, check r14. + sp*: U64 ## /< Stack pointer (AArch64). For AArch32, check r13. + pc*: CpuRegister ## /< Program counter. + psr*: U32 ## /< PSTATE or cpsr. + fpuGprs*: array[32, FpuRegister] ## /< 32 general-purpose NEON registers. + fpcr*: U32 ## /< Floating-point control register. + fpsr*: U32 ## /< Floating-point status register. + tpidr*: U64 ## /< EL0 Read/Write Software Thread ID Register. + + +## / Thread exception dump structure. + +type + ThreadExceptionDump* {.bycopy.} = object + errorDesc*: U32 ## /< See \ref ThreadExceptionDesc. + pad*: array[3, U32] + cpuGprs*: array[29, CpuRegister] ## /< GPRs 0..28. Note: also contains AArch32 registers. + fp*: CpuRegister ## /< Frame pointer. + lr*: CpuRegister ## /< Link register. + sp*: CpuRegister ## /< Stack pointer. + pc*: CpuRegister ## /< Program counter (elr_el1). + padding*: U64 + fpuGprs*: array[32, FpuRegister] ## /< 32 general-purpose NEON registers. + pstate*: U32 ## /< pstate & 0xFF0FFE20 + afsr0*: U32 + afsr1*: U32 + esr*: U32 + far*: CpuRegister ## /< Fault Address Register. + + ThreadExceptionFrameA64* {.bycopy.} = object + cpuGprs*: array[9, U64] ## /< GPRs 0..8. + lr*: U64 + sp*: U64 + elrEl1*: U64 + pstate*: U32 ## /< pstate & 0xFF0FFE20 + afsr0*: U32 + afsr1*: U32 + esr*: U32 + far*: U64 + + ThreadExceptionFrameA32* {.bycopy.} = object + cpuGprs*: array[8, U32] ## /< GPRs 0..7. + sp*: U32 + lr*: U32 + elrEl1*: U32 + tpidrEl0*: U32 ## /< tpidr_el0 = 1 + cpsr*: U32 ## /< cpsr & 0xFF0FFE20 + afsr0*: U32 + afsr1*: U32 + esr*: U32 + far*: U32 + +proc threadContextIsAArch64*(ctx: ptr ThreadContext): bool {.inline, cdecl.} = + ## * + ## @brief Determines whether a thread context belong to an AArch64 process based on the PSR. + ## @param[in] ctx Thread context to which PSTATE/cspr has been dumped to. + ## @return true if and only if the thread context belongs to an AArch64 process. + ## + + return (ctx.psr and 0x10) == 0 + +proc threadExceptionIsAArch64*(ctx: ptr ThreadExceptionDump): bool {.inline, cdecl.} = + ## * + ## @brief Determines whether a ThreadExceptionDump belongs to an AArch64 process based on the PSTATE. + ## @param[in] ctx ThreadExceptionDump. + ## @return true if and only if the ThreadExceptionDump belongs to an AArch64 process. + ## + return (ctx.pstate and 0x10) == 0 diff --git a/src/libnx/wrapper/switch/arm/tls.h b/src/libnx/wrapper/switch/arm/tls.h new file mode 100644 index 0000000..e24ac85 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/tls.h @@ -0,0 +1,18 @@ +/** + * @file tls.h + * @brief AArch64 thread local storage. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/** + * @brief Gets the thread local storage buffer. + * @return The thread local storage buffer. + */ +static inline void* armGetTls(void) { + void* ret; + __asm__ ("mrs %x[data], tpidrro_el0" : [data] "=r" (ret)); + return ret; +} diff --git a/src/libnx/wrapper/switch/arm/tls.nim b/src/libnx/wrapper/switch/arm/tls.nim new file mode 100644 index 0000000..01fdc97 --- /dev/null +++ b/src/libnx/wrapper/switch/arm/tls.nim @@ -0,0 +1,18 @@ +## * +## @file tls.h +## @brief AArch64 thread local storage. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types +export types + +## * +## @brief Gets the thread local storage buffer. +## @return The thread local storage buffer. +## + +proc armGetTls*(): pointer {.inline, cdecl.} = + {.emit: "__asm__ (\"mrs %x[data], tpidrro_el0\" : [data] \"=r\" (`result`));".} diff --git a/src/libnx/wrapper/switch/audio/audio.h b/src/libnx/wrapper/switch/audio/audio.h new file mode 100644 index 0000000..059f3ad --- /dev/null +++ b/src/libnx/wrapper/switch/audio/audio.h @@ -0,0 +1,25 @@ +/** + * @file audio.h + * @brief Global audio service. + * @author hexkyz + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" + +/// PcmFormat +typedef enum { + PcmFormat_Invalid = 0, + PcmFormat_Int8 = 1, + PcmFormat_Int16 = 2, + PcmFormat_Int24 = 3, + PcmFormat_Int32 = 4, + PcmFormat_Float = 5, + PcmFormat_Adpcm = 6, +} PcmFormat; + +/// AudioDeviceName +typedef struct { + char name[0x100]; +} AudioDeviceName; diff --git a/src/libnx/wrapper/switch/audio/audio.nim b/src/libnx/wrapper/switch/audio/audio.nim new file mode 100644 index 0000000..af9881a --- /dev/null +++ b/src/libnx/wrapper/switch/audio/audio.nim @@ -0,0 +1,21 @@ +## * +## @file audio.h +## @brief Global audio service. +## @author hexkyz +## @copyright libnx Authors +## + +## / PcmFormat + +type + PcmFormat* = enum + PcmFormatInvalid = 0, PcmFormatInt8 = 1, PcmFormatInt16 = 2, PcmFormatInt24 = 3, + PcmFormatInt32 = 4, PcmFormatFloat = 5, PcmFormatAdpcm = 6 + + +## / AudioDeviceName + +type + AudioDeviceName* {.bycopy.} = object + name*: array[0x100, char] + diff --git a/src/libnx/wrapper/switch/audio/driver.h b/src/libnx/wrapper/switch/audio/driver.h new file mode 100644 index 0000000..2138a16 --- /dev/null +++ b/src/libnx/wrapper/switch/audio/driver.h @@ -0,0 +1,145 @@ +/** + * @file driver.h + * @brief Audio driver (audren wrapper). + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../services/audren.h" + +typedef struct AudioDriverEtc AudioDriverEtc; + +typedef struct { + AudioDriverEtc* etc; + AudioRendererConfig config; + AudioRendererMemPoolInfoIn* in_mempools; + AudioRendererChannelInfoIn* in_channels; + AudioRendererVoiceInfoIn* in_voices; + AudioRendererMixInfoIn* in_mixes; + AudioRendererSinkInfoIn* in_sinks; +} AudioDriver; + +Result audrvCreate(AudioDriver* d, const AudioRendererConfig* config, int num_final_mix_channels); +Result audrvUpdate(AudioDriver* d); +void audrvClose(AudioDriver* d); + +//----------------------------------------------------------------------------- + +int audrvMemPoolAdd(AudioDriver* d, void* buffer, size_t size); +bool audrvMemPoolRemove(AudioDriver* d, int id); +bool audrvMemPoolAttach(AudioDriver* d, int id); +bool audrvMemPoolDetach(AudioDriver* d, int id); + +//----------------------------------------------------------------------------- + +typedef enum { + AudioDriverWaveBufState_Free, + AudioDriverWaveBufState_Waiting, + AudioDriverWaveBufState_Queued, + AudioDriverWaveBufState_Playing, + AudioDriverWaveBufState_Done, +} AudioDriverWaveBufState; + +typedef struct AudioDriverWaveBuf AudioDriverWaveBuf; + +struct AudioDriverWaveBuf { + union { + s16* data_pcm16; + u8* data_adpcm; + const void* data_raw; + }; + u64 size; + s32 start_sample_offset; + s32 end_sample_offset; + const void* context_addr; + u64 context_sz; + AudioDriverWaveBufState state : 8; + bool is_looping; + u32 sequence_id; + AudioDriverWaveBuf* next; +}; + +bool audrvVoiceInit(AudioDriver* d, int id, int num_channels, PcmFormat format, int sample_rate); +void audrvVoiceDrop(AudioDriver* d, int id); +void audrvVoiceStop(AudioDriver* d, int id); +bool audrvVoiceIsPaused(AudioDriver* d, int id); +bool audrvVoiceIsPlaying(AudioDriver* d, int id); +bool audrvVoiceAddWaveBuf(AudioDriver* d, int id, AudioDriverWaveBuf* wavebuf); +u32 audrvVoiceGetWaveBufSeq(AudioDriver* d, int id); +u32 audrvVoiceGetPlayedSampleCount(AudioDriver* d, int id); +u32 audrvVoiceGetVoiceDropsCount(AudioDriver* d, int id); +void audrvVoiceSetBiquadFilter(AudioDriver* d, int id, int biquad_id, float a0, float a1, float a2, float b0, float b1, float b2); + +static inline void audrvVoiceSetExtraParams(AudioDriver* d, int id, const void* params, size_t params_size) +{ + d->in_voices[id].extra_params_ptr = params; + d->in_voices[id].extra_params_sz = params_size; +} + +static inline void audrvVoiceSetDestinationMix(AudioDriver* d, int id, int mix_id) +{ + d->in_voices[id].dest_mix_id = mix_id; + d->in_voices[id].dest_splitter_id = AUDREN_UNUSED_SPLITTER_ID; +} + +static inline void audrvVoiceSetMixFactor(AudioDriver* d, int id, float factor, int src_channel_id, int dest_channel_id) +{ + int channel_id = d->in_voices[id].channel_ids[src_channel_id]; + d->in_channels[channel_id].mix[dest_channel_id] = factor; +} + +static inline void audrvVoiceSetVolume(AudioDriver* d, int id, float volume) +{ + d->in_voices[id].volume = volume; +} + +static inline void audrvVoiceSetPitch(AudioDriver* d, int id, float pitch) +{ + d->in_voices[id].pitch = pitch; +} + +static inline void audrvVoiceSetPriority(AudioDriver* d, int id, int priority) +{ + d->in_voices[id].priority = priority; +} + +static inline void audrvVoiceClearBiquadFilter(AudioDriver* d, int id, int biquad_id) +{ + d->in_voices[id].biquads[biquad_id].enable = false; +} + +static inline void audrvVoiceSetPaused(AudioDriver* d, int id, bool paused) +{ + d->in_voices[id].state = paused ? AudioRendererVoicePlayState_Paused : AudioRendererVoicePlayState_Started; +} + +static inline void audrvVoiceStart(AudioDriver* d, int id) +{ + audrvVoiceSetPaused(d, id, false); +} + +//----------------------------------------------------------------------------- + +int audrvMixAdd(AudioDriver* d, int sample_rate, int num_channels); +void audrvMixRemove(AudioDriver* d, int id); + +static inline void audrvMixSetDestinationMix(AudioDriver* d, int id, int mix_id) +{ + d->in_mixes[id].dest_mix_id = mix_id; + d->in_mixes[id].dest_splitter_id = AUDREN_UNUSED_SPLITTER_ID; +} + +static inline void audrvMixSetMixFactor(AudioDriver* d, int id, float factor, int src_channel_id, int dest_channel_id) +{ + d->in_mixes[id].mix[src_channel_id][dest_channel_id] = factor; +} + +static inline void audrvMixSetVolume(AudioDriver* d, int id, float volume) +{ + d->in_mixes[id].volume = volume; +} + +//----------------------------------------------------------------------------- + +int audrvDeviceSinkAdd(AudioDriver* d, const char* device_name, int num_channels, const u8* channel_ids); +void audrvSinkRemove(AudioDriver* d, int id); diff --git a/src/libnx/wrapper/switch/audio/driver.nim b/src/libnx/wrapper/switch/audio/driver.nim new file mode 100644 index 0000000..28b5a5f --- /dev/null +++ b/src/libnx/wrapper/switch/audio/driver.nim @@ -0,0 +1,140 @@ +## * +## @file driver.h +## @brief Audio driver (audren wrapper). +## @author fincs +## @copyright libnx Authors +## + +import + ../services/audren, ../result, audio + +type + AudioDriverEtc* = object + AudioDriver* {.bycopy.} = object + etc*: ptr AudioDriverEtc + config*: AudioRendererConfig + inMempools*: ptr AudioRendererMemPoolInfoIn + inChannels*: ptr AudioRendererChannelInfoIn + inVoices*: ptr AudioRendererVoiceInfoIn + inMixes*: ptr AudioRendererMixInfoIn + inSinks*: ptr AudioRendererSinkInfoIn + + +proc audrvCreate*(d: ptr AudioDriver; config: ptr AudioRendererConfig; + numFinalMixChannels: cint): Result {.cdecl, importc: "audrvCreate".} +proc audrvUpdate*(d: ptr AudioDriver): Result {.cdecl, importc: "audrvUpdate".} +proc audrvClose*(d: ptr AudioDriver) {.cdecl, importc: "audrvClose".} +## ----------------------------------------------------------------------------- + +proc audrvMemPoolAdd*(d: ptr AudioDriver; buffer: pointer; size: csize_t): cint {.cdecl, + importc: "audrvMemPoolAdd".} +proc audrvMemPoolRemove*(d: ptr AudioDriver; id: cint): bool {.cdecl, + importc: "audrvMemPoolRemove".} +proc audrvMemPoolAttach*(d: ptr AudioDriver; id: cint): bool {.cdecl, + importc: "audrvMemPoolAttach".} +proc audrvMemPoolDetach*(d: ptr AudioDriver; id: cint): bool {.cdecl, + importc: "audrvMemPoolDetach".} +## ----------------------------------------------------------------------------- + +type + AudioDriverWaveBufState* = enum + AudioDriverWaveBufStateFree, AudioDriverWaveBufStateWaiting, + AudioDriverWaveBufStateQueued, AudioDriverWaveBufStatePlaying, + AudioDriverWaveBufStateDone + + +type + INNER_C_UNION_driver_0* {.bycopy, union.} = object + dataPcm16*: ptr S16 + dataAdpcm*: ptr U8 + dataRaw*: pointer + + AudioDriverWaveBuf* {.bycopy.} = object + anoDriver1*: INNER_C_UNION_driver_0 + size*: U64 + startSampleOffset*: S32 + endSampleOffset*: S32 + contextAddr*: pointer + contextSz*: U64 + state* {.bitsize: 8.}: AudioDriverWaveBufState + isLooping*: bool + sequenceId*: U32 + next*: ptr AudioDriverWaveBuf + + +proc audrvVoiceInit*(d: ptr AudioDriver; id: cint; numChannels: cint; format: PcmFormat; + sampleRate: cint): bool {.cdecl, importc: "audrvVoiceInit".} +proc audrvVoiceDrop*(d: ptr AudioDriver; id: cint) {.cdecl, importc: "audrvVoiceDrop".} +proc audrvVoiceStop*(d: ptr AudioDriver; id: cint) {.cdecl, importc: "audrvVoiceStop".} +proc audrvVoiceIsPaused*(d: ptr AudioDriver; id: cint): bool {.cdecl, + importc: "audrvVoiceIsPaused".} +proc audrvVoiceIsPlaying*(d: ptr AudioDriver; id: cint): bool {.cdecl, + importc: "audrvVoiceIsPlaying".} +proc audrvVoiceAddWaveBuf*(d: ptr AudioDriver; id: cint; + wavebuf: ptr AudioDriverWaveBuf): bool {.cdecl, + importc: "audrvVoiceAddWaveBuf".} +proc audrvVoiceGetWaveBufSeq*(d: ptr AudioDriver; id: cint): U32 {.cdecl, + importc: "audrvVoiceGetWaveBufSeq".} +proc audrvVoiceGetPlayedSampleCount*(d: ptr AudioDriver; id: cint): U32 {.cdecl, + importc: "audrvVoiceGetPlayedSampleCount".} +proc audrvVoiceGetVoiceDropsCount*(d: ptr AudioDriver; id: cint): U32 {.cdecl, + importc: "audrvVoiceGetVoiceDropsCount".} +proc audrvVoiceSetBiquadFilter*(d: ptr AudioDriver; id: cint; biquadId: cint; + a0: cfloat; a1: cfloat; a2: cfloat; b0: cfloat; + b1: cfloat; b2: cfloat) {.cdecl, + importc: "audrvVoiceSetBiquadFilter".} +proc audrvVoiceSetExtraParams*(d: ptr AudioDriver; id: cint; params: pointer; + paramsSize: csize_t) {.inline, cdecl.} = + d.inVoices[id].extraParamsPtr = params + d.inVoices[id].extraParamsSz = paramsSize + +proc audrvVoiceSetDestinationMix*(d: ptr AudioDriver; id: cint; mixId: cint) {.inline, cdecl.} = + d.inVoices[id].destMixId = mixId.U32 + d.inVoices[id].destSplitterId = Audren_Unused_Splitter_Id.U32 + +proc audrvVoiceSetMixFactor*(d: ptr AudioDriver; id: cint; factor: cfloat; + srcChannelId: cint; destChannelId: cint) {.inline, cdecl.} = + var channelId = d.inVoices[id].channelIds[srcChannelId] + d.inChannels[channelId].mix[destChannelId] = factor + +proc audrvVoiceSetVolume*(d: ptr AudioDriver; id: cint; volume: cfloat) {.inline, cdecl.} = + d.inVoices[id].volume = volume + +proc audrvVoiceSetPitch*(d: ptr AudioDriver; id: cint; pitch: cfloat) {.inline, cdecl.} = + d.inVoices[id].pitch = pitch + +proc audrvVoiceSetPriority*(d: ptr AudioDriver; id: cint; priority: cint) {.inline, cdecl.} = + d.inVoices[id].priority = priority.U32 + +proc audrvVoiceClearBiquadFilter*(d: ptr AudioDriver; id: cint; biquadId: cint) {. + inline, cdecl.} = + d.inVoices[id].biquads[biquadId].enable = false + +proc audrvVoiceSetPaused*(d: ptr AudioDriver; id: cint; paused: bool) {.inline, cdecl.} = + d.inVoices[id].state = if paused: AudioRendererVoicePlayStatePaused else: AudioRendererVoicePlayStateStarted + +proc audrvVoiceStart*(d: ptr AudioDriver; id: cint) {.inline, cdecl.} = + audrvVoiceSetPaused(d, id, false) + +## ----------------------------------------------------------------------------- + +proc audrvMixAdd*(d: ptr AudioDriver; sampleRate: cint; numChannels: cint): cint {.cdecl, + importc: "audrvMixAdd".} +proc audrvMixRemove*(d: ptr AudioDriver; id: cint) {.cdecl, importc: "audrvMixRemove".} +proc audrvMixSetDestinationMix*(d: ptr AudioDriver; id: cint; mixId: cint) {.inline, cdecl.} = + d.inMixes[id].destMixId = mixId.U32 + d.inMixes[id].destSplitterId = Audren_Unused_Splitter_Id.U32 + +proc audrvMixSetMixFactor*(d: ptr AudioDriver; id: cint; factor: cfloat; + srcChannelId: cint; destChannelId: cint) {.inline, cdecl.} = + d.inMixes[id].mix[srcChannelId][destChannelId] = factor + +proc audrvMixSetVolume*(d: ptr AudioDriver; id: cint; volume: cfloat) {.inline, cdecl.} = + d.inMixes[id].volume = volume + +## ----------------------------------------------------------------------------- + +proc audrvDeviceSinkAdd*(d: ptr AudioDriver; deviceName: cstring; numChannels: cint; + channelIds: ptr U8): cint {.cdecl, + importc: "audrvDeviceSinkAdd".} +proc audrvSinkRemove*(d: ptr AudioDriver; id: cint) {.cdecl, importc: "audrvSinkRemove".} diff --git a/src/libnx/wrapper/switch/crypto/aes.h b/src/libnx/wrapper/switch/crypto/aes.h new file mode 100644 index 0000000..adddfb8 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes.h @@ -0,0 +1,74 @@ +/** + * @file aes.h + * @brief Hardware accelerated AES-ECB implementation. + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +#ifndef AES_BLOCK_SIZE +#define AES_BLOCK_SIZE 0x10 +#endif +#ifndef AES_128_KEY_SIZE +#define AES_128_KEY_SIZE 0x10 +#endif +#ifndef AES_128_U32_PER_KEY +#define AES_128_U32_PER_KEY (AES_128_KEY_SIZE / sizeof(u32)) +#endif +#ifndef AES_128_NUM_ROUNDS +#define AES_128_NUM_ROUNDS 10 +#endif +#ifndef AES_192_KEY_SIZE +#define AES_192_KEY_SIZE 0x18 +#endif +#ifndef AES_192_U32_PER_KEY +#define AES_192_U32_PER_KEY (AES_192_KEY_SIZE / sizeof(u32)) +#endif +#ifndef AES_192_NUM_ROUNDS +#define AES_192_NUM_ROUNDS 12 +#endif +#ifndef AES_256_KEY_SIZE +#define AES_256_KEY_SIZE 0x20 +#endif +#ifndef AES_256_U32_PER_KEY +#define AES_256_U32_PER_KEY (AES_256_KEY_SIZE / sizeof(u32)) +#endif +#ifndef AES_256_NUM_ROUNDS +#define AES_256_NUM_ROUNDS 14 +#endif + +/// Context for AES-128 operations. +typedef struct { + u8 round_keys[AES_128_NUM_ROUNDS+1][AES_BLOCK_SIZE]; +} Aes128Context; + +/// Context for AES-192 operations. +typedef struct { + u8 round_keys[AES_192_NUM_ROUNDS+1][AES_BLOCK_SIZE]; +} Aes192Context; + +/// Context for AES-256 operations. +typedef struct { + u8 round_keys[AES_256_NUM_ROUNDS+1][AES_BLOCK_SIZE]; +} Aes256Context; + +/// Initialize a 128-bit AES context. +void aes128ContextCreate(Aes128Context *out, const void *key, bool is_encryptor); +/// Encrypt using an AES context (Requires is_encryptor when initializing) +void aes128EncryptBlock(const Aes128Context *ctx, void *dst, const void *src); +/// Decrypt using an AES context (Requires !is_encryptor when initializing) +void aes128DecryptBlock(const Aes128Context *ctx, void *dst, const void *src); + +/// Initialize a 192-bit AES context. +void aes192ContextCreate(Aes192Context *out, const void *key, bool is_encryptor); +/// Encrypt using an AES context (Requires is_encryptor when initializing) +void aes192EncryptBlock(const Aes192Context *ctx, void *dst, const void *src); +/// Decrypt using an AES context (Requires !is_encryptor when initializing) +void aes192DecryptBlock(const Aes192Context *ctx, void *dst, const void *src); + +/// Initialize a 256-bit AES context. +void aes256ContextCreate(Aes256Context *out, const void *key, bool is_encryptor); +/// Encrypt using an AES context (Requires is_encryptor when initializing) +void aes256EncryptBlock(const Aes256Context *ctx, void *dst, const void *src); +/// Decrypt using an AES context (Requires !is_encryptor when initializing) +void aes256DecryptBlock(const Aes256Context *ctx, void *dst, const void *src); diff --git a/src/libnx/wrapper/switch/crypto/aes.nim b/src/libnx/wrapper/switch/crypto/aes.nim new file mode 100644 index 0000000..d0a143a --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes.nim @@ -0,0 +1,77 @@ +## * +## @file aes.h +## @brief Hardware accelerated AES-ECB implementation. +## @copyright libnx Authors +## + +import + ../types + +const + AES_BLOCK_SIZE* = 0x10 + AES_128_KEY_SIZE* = 0x10 + AES_128_U32_PER_KEY* = (Aes_128Key_Size div sizeof((U32))) + AES_128_NUM_ROUNDS* = 10 + AES_192_KEY_SIZE* = 0x18 + AES_192_U32_PER_KEY* = (Aes_192Key_Size div sizeof((U32))) + AES_192_NUM_ROUNDS* = 12 + AES_256_KEY_SIZE* = 0x20 + AES_256_U32_PER_KEY* = (Aes_256Key_Size div sizeof((U32))) + AES_256_NUM_ROUNDS* = 14 + +## / Context for AES-128 operations. + +type + Aes128Context* {.bycopy.} = object + roundKeys*: array[Aes_128Num_Rounds + 1, array[Aes_Block_Size, U8]] + + +## / Context for AES-192 operations. + +type + Aes192Context* {.bycopy.} = object + roundKeys*: array[Aes_192Num_Rounds + 1, array[Aes_Block_Size, U8]] + + +## / Context for AES-256 operations. + +type + Aes256Context* {.bycopy.} = object + roundKeys*: array[Aes_256Num_Rounds + 1, array[Aes_Block_Size, U8]] + +proc aes128ContextCreate*(`out`: ptr Aes128Context; key: pointer; isEncryptor: bool) {. + cdecl, importc: "aes128ContextCreate".} +## / Initialize a 128-bit AES context. + +proc aes128EncryptBlock*(ctx: ptr Aes128Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes128EncryptBlock".} +## / Encrypt using an AES context (Requires is_encryptor when initializing) + +proc aes128DecryptBlock*(ctx: ptr Aes128Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes128DecryptBlock".} +## / Decrypt using an AES context (Requires !is_encryptor when initializing) + +proc aes192ContextCreate*(`out`: ptr Aes192Context; key: pointer; isEncryptor: bool) {. + cdecl, importc: "aes192ContextCreate".} +## / Initialize a 192-bit AES context. + +proc aes192EncryptBlock*(ctx: ptr Aes192Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes192EncryptBlock".} +## / Encrypt using an AES context (Requires is_encryptor when initializing) + +proc aes192DecryptBlock*(ctx: ptr Aes192Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes192DecryptBlock".} +## / Decrypt using an AES context (Requires !is_encryptor when initializing) + +proc aes256ContextCreate*(`out`: ptr Aes256Context; key: pointer; isEncryptor: bool) {. + cdecl, importc: "aes256ContextCreate".} +## / Initialize a 256-bit AES context. + +proc aes256EncryptBlock*(ctx: ptr Aes256Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes256EncryptBlock".} +## / Encrypt using an AES context (Requires is_encryptor when initializing) + +proc aes256DecryptBlock*(ctx: ptr Aes256Context; dst: pointer; src: pointer) {.cdecl, + importc: "aes256DecryptBlock".} +## / Decrypt using an AES context (Requires !is_encryptor when initializing) + diff --git a/src/libnx/wrapper/switch/crypto/aes_cbc.h b/src/libnx/wrapper/switch/crypto/aes_cbc.h new file mode 100644 index 0000000..6f05773 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_cbc.h @@ -0,0 +1,49 @@ +/** + * @file aes_cbc.h + * @brief Hardware accelerated AES-CBC implementation. + * @copyright libnx Authors + */ +#pragma once +#include "aes.h" + +/// Context for AES-128 CBC. +typedef struct { + Aes128Context aes_ctx; + u8 iv[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes128CbcContext; + +/// Context for AES-192 CBC. +typedef struct { + Aes192Context aes_ctx; + u8 iv[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes192CbcContext; + +/// Context for AES-256 CBC. +typedef struct { + Aes256Context aes_ctx; + u8 iv[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes256CbcContext; + +/// 128-bit CBC API. +void aes128CbcContextCreate(Aes128CbcContext *out, const void *key, const void *iv, bool is_encryptor); +void aes128CbcContextResetIv(Aes128CbcContext *ctx, const void *iv); +size_t aes128CbcEncrypt(Aes128CbcContext *ctx, void *dst, const void *src, size_t size); +size_t aes128CbcDecrypt(Aes128CbcContext *ctx, void *dst, const void *src, size_t size); + +/// 192-bit CBC API. +void aes192CbcContextCreate(Aes192CbcContext *out, const void *key, const void *iv, bool is_encryptor); +void aes192CbcContextResetIv(Aes192CbcContext *ctx, const void *iv); +size_t aes192CbcEncrypt(Aes192CbcContext *ctx, void *dst, const void *src, size_t size); +size_t aes192CbcDecrypt(Aes192CbcContext *ctx, void *dst, const void *src, size_t size); + +/// 256-bit CBC API. +void aes256CbcContextCreate(Aes256CbcContext *out, const void *key, const void *iv, bool is_encryptor); +void aes256CbcContextResetIv(Aes256CbcContext *ctx, const void *iv); +size_t aes256CbcEncrypt(Aes256CbcContext *ctx, void *dst, const void *src, size_t size); +size_t aes256CbcDecrypt(Aes256CbcContext *ctx, void *dst, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/aes_cbc.nim b/src/libnx/wrapper/switch/crypto/aes_cbc.nim new file mode 100644 index 0000000..411a4ef --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_cbc.nim @@ -0,0 +1,74 @@ +## * +## @file AES_cbc.h +## @brief Hardware accelerated AES-CBC implementation. +## @copyright libnx Authors +## + +import + aes, ../types + +## / Context for AES-128 CBC. + +type + Aes128CbcContext* {.bycopy.} = object + aesCtx*: Aes128Context + iv*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / Context for AES-192 CBC. + +type + Aes192CbcContext* {.bycopy.} = object + aesCtx*: Aes192Context + iv*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / Context for AES-256 CBC. + +type + Aes256CbcContext* {.bycopy.} = object + aesCtx*: Aes256Context + iv*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / 128-bit CBC API. + +proc aes128CbcContextCreate*(`out`: ptr Aes128CbcContext; key: pointer; iv: pointer; + isEncryptor: bool) {.cdecl, + importc: "aes128CbcContextCreate".} +proc aes128CbcContextResetIv*(ctx: ptr Aes128CbcContext; iv: pointer) {.cdecl, + importc: "aes128CbcContextResetIv".} +proc aes128CbcEncrypt*(ctx: ptr Aes128CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes128CbcEncrypt".} +proc aes128CbcDecrypt*(ctx: ptr Aes128CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes128CbcDecrypt".} + +## / 192-bit CBC API. + +proc aes192CbcContextCreate*(`out`: ptr Aes192CbcContext; key: pointer; iv: pointer; + isEncryptor: bool) {.cdecl, + importc: "aes192CbcContextCreate".} +proc aes192CbcContextResetIv*(ctx: ptr Aes192CbcContext; iv: pointer) {.cdecl, + importc: "aes192CbcContextResetIv".} +proc aes192CbcEncrypt*(ctx: ptr Aes192CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes192CbcEncrypt".} +proc aes192CbcDecrypt*(ctx: ptr Aes192CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes192CbcDecrypt".} + +## / 256-bit CBC API. + +proc aes256CbcContextCreate*(`out`: ptr Aes256CbcContext; key: pointer; iv: pointer; + isEncryptor: bool) {.cdecl, + importc: "aes256CbcContextCreate".} +proc aes256CbcContextResetIv*(ctx: ptr Aes256CbcContext; iv: pointer) {.cdecl, + importc: "aes256CbcContextResetIv".} +proc aes256CbcEncrypt*(ctx: ptr Aes256CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes256CbcEncrypt".} +proc aes256CbcDecrypt*(ctx: ptr Aes256CbcContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes256CbcDecrypt".} diff --git a/src/libnx/wrapper/switch/crypto/aes_ctr.h b/src/libnx/wrapper/switch/crypto/aes_ctr.h new file mode 100644 index 0000000..c31a780 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_ctr.h @@ -0,0 +1,46 @@ +/** + * @file aes_ctr.h + * @brief Hardware accelerated AES-CTR implementation. + * @copyright libnx Authors + */ +#pragma once +#include "aes.h" + +/// Context for AES-128 CTR. +typedef struct { + Aes128Context aes_ctx; + u8 ctr[AES_BLOCK_SIZE]; + u8 enc_ctr_buffer[AES_BLOCK_SIZE]; + size_t buffer_offset; +} Aes128CtrContext; + +/// Context for AES-192 CTR. +typedef struct { + Aes192Context aes_ctx; + u8 ctr[AES_BLOCK_SIZE]; + u8 enc_ctr_buffer[AES_BLOCK_SIZE]; + size_t buffer_offset; +} Aes192CtrContext; + +/// Context for AES-256 CTR. +typedef struct { + Aes256Context aes_ctx; + u8 ctr[AES_BLOCK_SIZE]; + u8 enc_ctr_buffer[AES_BLOCK_SIZE]; + size_t buffer_offset; +} Aes256CtrContext; + +/// 128-bit CTR API. +void aes128CtrContextCreate(Aes128CtrContext *out, const void *key, const void *ctr); +void aes128CtrContextResetCtr(Aes128CtrContext *ctx, const void *ctr); +void aes128CtrCrypt(Aes128CtrContext *ctx, void *dst, const void *src, size_t size); + +/// 192-bit CTR API. +void aes192CtrContextCreate(Aes192CtrContext *out, const void *key, const void *ctr); +void aes192CtrContextResetCtr(Aes192CtrContext *ctx, const void *ctr); +void aes192CtrCrypt(Aes192CtrContext *ctx, void *dst, const void *src, size_t size); + +/// 256-bit CTR API. +void aes256CtrContextCreate(Aes256CtrContext *out, const void *key, const void *ctr); +void aes256CtrContextResetCtr(Aes256CtrContext *ctx, const void *ctr); +void aes256CtrCrypt(Aes256CtrContext *ctx, void *dst, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/aes_ctr.nim b/src/libnx/wrapper/switch/crypto/aes_ctr.nim new file mode 100644 index 0000000..de4d93f --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_ctr.nim @@ -0,0 +1,65 @@ +## * +## @file AES_ctr.h +## @brief Hardware accelerated AES-CTR implementation. +## @copyright libnx Authors +## + +import + aes, ../types + +## / Context for AES-128 CTR. + +type + Aes128CtrContext* {.bycopy.} = object + aesCtx*: Aes128Context + ctr*: array[AES_Block_Size, U8] + encCtrBuffer*: array[AES_Block_Size, U8] + bufferOffset*: csize_t + + +## / Context for AES-192 CTR. + +type + Aes192CtrContext* {.bycopy.} = object + aesCtx*: Aes192Context + ctr*: array[AES_Block_Size, U8] + encCtrBuffer*: array[AES_Block_Size, U8] + bufferOffset*: csize_t + + +## / Context for AES-256 CTR. + +type + Aes256CtrContext* {.bycopy.} = object + aesCtx*: Aes256Context + ctr*: array[AES_Block_Size, U8] + encCtrBuffer*: array[AES_Block_Size, U8] + bufferOffset*: csize_t + + +## / 128-bit CTR API. + +proc aes128CtrContextCreate*(`out`: ptr Aes128CtrContext; key: pointer; ctr: pointer) {. + cdecl, importc: "aes128CtrContextCreate".} +proc aes128CtrContextResetCtr*(ctx: ptr Aes128CtrContext; ctr: pointer) {.cdecl, + importc: "aes128CtrContextResetCtr".} +proc aes128CtrCrypt*(ctx: ptr Aes128CtrContext; dst: pointer; src: pointer; + size: csize_t) {.cdecl, importc: "aes128CtrCrypt".} + +## / 192-bit CTR API. + +proc aes192CtrContextCreate*(`out`: ptr Aes192CtrContext; key: pointer; ctr: pointer) {. + cdecl, importc: "aes192CtrContextCreate".} +proc aes192CtrContextResetCtr*(ctx: ptr Aes192CtrContext; ctr: pointer) {.cdecl, + importc: "aes192CtrContextResetCtr".} +proc aes192CtrCrypt*(ctx: ptr Aes192CtrContext; dst: pointer; src: pointer; + size: csize_t) {.cdecl, importc: "aes192CtrCrypt".} + +## / 256-bit CTR API. + +proc aes256CtrContextCreate*(`out`: ptr Aes256CtrContext; key: pointer; ctr: pointer) {. + cdecl, importc: "aes256CtrContextCreate".} +proc aes256CtrContextResetCtr*(ctx: ptr Aes256CtrContext; ctr: pointer) {.cdecl, + importc: "aes256CtrContextResetCtr".} +proc aes256CtrCrypt*(ctx: ptr Aes256CtrContext; dst: pointer; src: pointer; + size: csize_t) {.cdecl, importc: "aes256CtrCrypt".} diff --git a/src/libnx/wrapper/switch/crypto/aes_xts.h b/src/libnx/wrapper/switch/crypto/aes_xts.h new file mode 100644 index 0000000..357bd22 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_xts.h @@ -0,0 +1,55 @@ +/** + * @file aes_xts.h + * @brief Hardware accelerated AES-XTS implementation. + * @copyright libnx Authors + */ +#pragma once +#include "aes.h" + +/// Context for AES-128 XTS. +typedef struct { + Aes128Context aes_ctx; + Aes128Context tweak_ctx; + u8 tweak[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes128XtsContext; + +/// Context for AES-192 XTS. +typedef struct { + Aes192Context aes_ctx; + Aes192Context tweak_ctx; + u8 tweak[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes192XtsContext; + +/// Context for AES-256 XTS. +typedef struct { + Aes256Context aes_ctx; + Aes256Context tweak_ctx; + u8 tweak[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; +} Aes256XtsContext; + +/// 128-bit XTS API. +void aes128XtsContextCreate(Aes128XtsContext *out, const void *key0, const void *key1, bool is_encryptor); +void aes128XtsContextResetTweak(Aes128XtsContext *ctx, const void *tweak); +void aes128XtsContextResetSector(Aes128XtsContext *ctx, uint64_t sector, bool is_nintendo); +size_t aes128XtsEncrypt(Aes128XtsContext *ctx, void *dst, const void *src, size_t size); +size_t aes128XtsDecrypt(Aes128XtsContext *ctx, void *dst, const void *src, size_t size); + +/// 192-bit XTS API. +void aes192XtsContextCreate(Aes192XtsContext *out, const void *key0, const void *key1, bool is_encryptor); +void aes192XtsContextResetTweak(Aes192XtsContext *ctx, const void *tweak); +void aes192XtsContextResetSector(Aes192XtsContext *ctx, uint64_t sector, bool is_nintendo); +size_t aes192XtsEncrypt(Aes192XtsContext *ctx, void *dst, const void *src, size_t size); +size_t aes192XtsDecrypt(Aes192XtsContext *ctx, void *dst, const void *src, size_t size); + +/// 256-bit XTS API. +void aes256XtsContextCreate(Aes256XtsContext *out, const void *key0, const void *key1, bool is_encryptor); +void aes256XtsContextResetTweak(Aes256XtsContext *ctx, const void *tweak); +void aes256XtsContextResetSector(Aes256XtsContext *ctx, uint64_t sector, bool is_nintendo); +size_t aes256XtsEncrypt(Aes256XtsContext *ctx, void *dst, const void *src, size_t size); +size_t aes256XtsDecrypt(Aes256XtsContext *ctx, void *dst, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/aes_xts.nim b/src/libnx/wrapper/switch/crypto/aes_xts.nim new file mode 100644 index 0000000..aa42c01 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/aes_xts.nim @@ -0,0 +1,86 @@ +## * +## @file AES_xts.h +## @brief Hardware accelerated AES-XTS implementation. +## @copyright libnx Authors +## + +import + aes, ../types + +## / Context for AES-128 XTS. + +type + Aes128XtsContext* {.bycopy.} = object + aesCtx*: Aes128Context + tweakCtx*: Aes128Context + tweak*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / Context for AES-192 XTS. + +type + Aes192XtsContext* {.bycopy.} = object + aesCtx*: Aes192Context + tweakCtx*: Aes192Context + tweak*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / Context for AES-256 XTS. + +type + Aes256XtsContext* {.bycopy.} = object + aesCtx*: Aes256Context + tweakCtx*: Aes256Context + tweak*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + + +## / 128-bit XTS API. + +proc aes128XtsContextCreate*(`out`: ptr Aes128XtsContext; key0: pointer; + key1: pointer; isEncryptor: bool) {.cdecl, + importc: "aes128XtsContextCreate".} +proc aes128XtsContextResetTweak*(ctx: ptr Aes128XtsContext; tweak: pointer) {.cdecl, + importc: "aes128XtsContextResetTweak".} +proc aes128XtsContextResetSector*(ctx: ptr Aes128XtsContext; sector: uint64; + isNintendo: bool) {.cdecl, + importc: "aes128XtsContextResetSector".} +proc aes128XtsEncrypt*(ctx: ptr Aes128XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes128XtsEncrypt".} +proc aes128XtsDecrypt*(ctx: ptr Aes128XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes128XtsDecrypt".} + +## / 192-bit XTS API. + +proc aes192XtsContextCreate*(`out`: ptr Aes192XtsContext; key0: pointer; + key1: pointer; isEncryptor: bool) {.cdecl, + importc: "aes192XtsContextCreate".} +proc aes192XtsContextResetTweak*(ctx: ptr Aes192XtsContext; tweak: pointer) {.cdecl, + importc: "aes192XtsContextResetTweak".} +proc aes192XtsContextResetSector*(ctx: ptr Aes192XtsContext; sector: uint64; + isNintendo: bool) {.cdecl, + importc: "aes192XtsContextResetSector".} +proc aes192XtsEncrypt*(ctx: ptr Aes192XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes192XtsEncrypt".} +proc aes192XtsDecrypt*(ctx: ptr Aes192XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes192XtsDecrypt".} + +## / 256-bit XTS API. + +proc aes256XtsContextCreate*(`out`: ptr Aes256XtsContext; key0: pointer; + key1: pointer; isEncryptor: bool) {.cdecl, + importc: "aes256XtsContextCreate".} +proc aes256XtsContextResetTweak*(ctx: ptr Aes256XtsContext; tweak: pointer) {.cdecl, + importc: "aes256XtsContextResetTweak".} +proc aes256XtsContextResetSector*(ctx: ptr Aes256XtsContext; sector: uint64; + isNintendo: bool) {.cdecl, + importc: "aes256XtsContextResetSector".} +proc aes256XtsEncrypt*(ctx: ptr Aes256XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes256XtsEncrypt".} +proc aes256XtsDecrypt*(ctx: ptr Aes256XtsContext; dst: pointer; src: pointer; + size: csize_t): csize_t {.cdecl, importc: "aes256XtsDecrypt".} diff --git a/src/libnx/wrapper/switch/crypto/cmac.h b/src/libnx/wrapper/switch/crypto/cmac.h new file mode 100644 index 0000000..d35ae86 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/cmac.h @@ -0,0 +1,67 @@ +/** + * @file cmac.h + * @brief Hardware accelerated AES-CMAC implementation. + * @copyright libnx Authors + */ +#pragma once +#include "aes.h" + +/// Context for AES-128 CMAC. +typedef struct { + Aes128Context ctx; + u8 subkey[AES_BLOCK_SIZE]; + u8 mac[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; + bool finalized; +} Aes128CmacContext; + +/// Context for AES-192 CMAC. +typedef struct { + Aes192Context ctx; + u8 subkey[AES_BLOCK_SIZE]; + u8 mac[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; + bool finalized; +} Aes192CmacContext; + +/// Context for AES-256 CMAC. +typedef struct { + Aes256Context ctx; + u8 subkey[AES_BLOCK_SIZE]; + u8 mac[AES_BLOCK_SIZE]; + u8 buffer[AES_BLOCK_SIZE]; + size_t num_buffered; + bool finalized; +} Aes256CmacContext; + +/// Initialize an AES-128-CMAC context. +void cmacAes128ContextCreate(Aes128CmacContext *out, const void *key); +/// Updates AES-128-CMAC context with data to hash +void cmacAes128ContextUpdate(Aes128CmacContext *ctx, const void *src, size_t size); +/// Gets the context's output mac, finalizes the context. +void cmacAes128ContextGetMac(Aes128CmacContext *ctx, void *dst); + +/// Simple all-in-one AES-128-CMAC calculator. +void cmacAes128CalculateMac(void *dst, const void *key, const void *src, size_t size); + +/// Initialize an AES-192-CMAC context. +void cmacAes192ContextCreate(Aes192CmacContext *out, const void *key); +/// Updates AES-192-CMAC context with data to hash +void cmacAes192ContextUpdate(Aes192CmacContext *ctx, const void *src, size_t size); +/// Gets the context's output mac, finalizes the context. +void cmacAes192ContextGetMac(Aes192CmacContext *ctx, void *dst); + +/// Simple all-in-one AES-192-CMAC calculator. +void cmacAes192CalculateMac(void *dst, const void *key, const void *src, size_t size); + +/// Initialize an AES-256-CMAC context. +void cmacAes256ContextCreate(Aes256CmacContext *out, const void *key); +/// Updates AES-256-CMAC context with data to hash +void cmacAes256ContextUpdate(Aes256CmacContext *ctx, const void *src, size_t size); +/// Gets the context's output mac, finalizes the context. +void cmacAes256ContextGetMac(Aes256CmacContext *ctx, void *dst); + +/// Simple all-in-one AES-256-CMAC calculator. +void cmacAes256CalculateMac(void *dst, const void *key, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/cmac.nim b/src/libnx/wrapper/switch/crypto/cmac.nim new file mode 100644 index 0000000..7856d7c --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/cmac.nim @@ -0,0 +1,92 @@ +## * +## @file cmac.h +## @brief Hardware accelerated AES-CMAC implementation. +## @copyright libnx Authors +## + +import + aes, ../types + +## / Context for AES-128 CMAC. + +type + Aes128CmacContext* {.bycopy.} = object + ctx*: Aes128Context + subkey*: array[AES_Block_Size, U8] + mac*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + finalized*: bool + + +## / Context for AES-192 CMAC. + +type + Aes192CmacContext* {.bycopy.} = object + ctx*: Aes192Context + subkey*: array[AES_Block_Size, U8] + mac*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + finalized*: bool + + +## / Context for AES-256 CMAC. + +type + Aes256CmacContext* {.bycopy.} = object + ctx*: Aes256Context + subkey*: array[AES_Block_Size, U8] + mac*: array[AES_Block_Size, U8] + buffer*: array[AES_Block_Size, U8] + numBuffered*: csize_t + finalized*: bool + +proc cmacAes128ContextCreate*(`out`: ptr Aes128CmacContext; key: pointer) {.cdecl, + importc: "cmacAes128ContextCreate".} +## / Initialize an AES-128-CMAC context. + +proc cmacAes128ContextUpdate*(ctx: ptr Aes128CmacContext; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes128ContextUpdate".} +## / Updates AES-128-CMAC context with data to hash + +proc cmacAes128ContextGetMac*(ctx: ptr Aes128CmacContext; dst: pointer) {.cdecl, + importc: "cmacAes128ContextGetMac".} +## / Gets the context's output mac, finalizes the context. + +proc cmacAes128CalculateMac*(dst: pointer; key: pointer; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes128CalculateMac".} +## / Simple all-in-one AES-128-CMAC calculator. + +proc cmacAes192ContextCreate*(`out`: ptr Aes192CmacContext; key: pointer) {.cdecl, + importc: "cmacAes192ContextCreate".} +## / Initialize an AES-192-CMAC context. + +proc cmacAes192ContextUpdate*(ctx: ptr Aes192CmacContext; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes192ContextUpdate".} +## / Updates AES-192-CMAC context with data to hash + +proc cmacAes192ContextGetMac*(ctx: ptr Aes192CmacContext; dst: pointer) {.cdecl, + importc: "cmacAes192ContextGetMac".} +## / Gets the context's output mac, finalizes the context. + +proc cmacAes192CalculateMac*(dst: pointer; key: pointer; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes192CalculateMac".} +## / Simple all-in-one AES-192-CMAC calculator. + +proc cmacAes256ContextCreate*(`out`: ptr Aes256CmacContext; key: pointer) {.cdecl, + importc: "cmacAes256ContextCreate".} +## / Initialize an AES-256-CMAC context. + +proc cmacAes256ContextUpdate*(ctx: ptr Aes256CmacContext; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes256ContextUpdate".} +## / Updates AES-256-CMAC context with data to hash + +proc cmacAes256ContextGetMac*(ctx: ptr Aes256CmacContext; dst: pointer) {.cdecl, + importc: "cmacAes256ContextGetMac".} +## / Gets the context's output mac, finalizes the context. + +proc cmacAes256CalculateMac*(dst: pointer; key: pointer; src: pointer; size: csize_t) {. + cdecl, importc: "cmacAes256CalculateMac".} +## / Simple all-in-one AES-256-CMAC calculator. + diff --git a/src/libnx/wrapper/switch/crypto/crc.h b/src/libnx/wrapper/switch/crypto/crc.h new file mode 100644 index 0000000..8f55ea4 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/crc.h @@ -0,0 +1,84 @@ +/** + * @file crc.h + * @brief Hardware accelerated CRC32 implementation. + * @copyright libnx Authors + */ +#pragma once +#include +#include "../types.h" + +#define _CRC_ALIGN(sz, insn) \ +do { \ + if (((uintptr_t)src_u8 & sizeof(sz)) && (u64)len >= sizeof(sz)) { \ + crc = __crc32##insn(crc, *((const sz *)src_u8)); \ + src_u8 += sizeof(sz); \ + len -= sizeof(sz); \ + } \ +} while (0); + +#define _CRC_REMAINDER(sz, insn) \ +do { \ + if (len & sizeof(sz)) { \ + crc = __crc32##insn(crc, *((const sz *)src_u8)); \ + src_u8 += sizeof(sz); \ + } \ +} while (0) + +/// Calculate a CRC32 over data using a seed. +/// Can be used to calculate a CRC32 in chunks using an initial seed of zero for the first chunk. +static inline u32 crc32CalculateWithSeed(u32 seed, const void *src, size_t size) { + const u8 *src_u8 = (const u8 *)src; + + u32 crc = ~seed; + s64 len = size; + + _CRC_ALIGN(u8, b); + _CRC_ALIGN(u16, h); + _CRC_ALIGN(u32, w); + + while ((len -= sizeof(u64)) >= 0) { + crc = __crc32d(crc, *((const u64 *)src_u8)); + src_u8 += sizeof(u64); + } + + _CRC_REMAINDER(u32, w); + _CRC_REMAINDER(u16, h); + _CRC_REMAINDER(u8, b); + + return ~crc; +} + +/// Calculate a CRC32 over data. +static inline u32 crc32Calculate(const void *src, size_t size) { + return crc32CalculateWithSeed(0, src, size); +} + +/// Calculate a CRC32C over data using a seed. +/// Can be used to calculate a CRC32C in chunks using an initial seed of zero for the first chunk. +static inline u32 crc32cCalculateWithSeed(u32 seed, const void *src, size_t size) { + const u8 *src_u8 = (const u8 *)src; + + u32 crc = ~seed; + s64 len = size; + + _CRC_ALIGN(u8, cb); + _CRC_ALIGN(u16, ch); + _CRC_ALIGN(u32, cw); + + while ((len -= sizeof(u64)) >= 0) { + crc = __crc32cd(crc, *((const u64 *)src_u8)); + src_u8 += sizeof(u64); + } + + _CRC_REMAINDER(u32, cw); + _CRC_REMAINDER(u16, ch); + _CRC_REMAINDER(u8, cb); + + return ~crc; +} + +/// Calculate a CRC32C over data. +static inline u32 crc32cCalculate(const void *src, size_t size) { + return crc32cCalculateWithSeed(0, src, size); +} + diff --git a/src/libnx/wrapper/switch/crypto/crc.nim b/src/libnx/wrapper/switch/crypto/crc.nim new file mode 100644 index 0000000..9a3acef --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/crc.nim @@ -0,0 +1,92 @@ +## * +## @file crc.h +## @brief Hardware accelerated CRC32 implementation. +## @copyright libnx Authors +## + +import + ../types + +{.emit: """ +#include + +#define _CRC_ALIGN(sz, insn) \ +do { \ + if (((uintptr_t)src_u8 & sizeof(sz)) && (u64)len >= sizeof(sz)) { \ + crc = __crc32##insn(crc, *((const sz *)src_u8)); \ + src_u8 += sizeof(sz); \ + len -= sizeof(sz); \ + } \ +} while (0); + +#define _CRC_REMAINDER(sz, insn) \ +do { \ + if (len & sizeof(sz)) { \ + crc = __crc32##insn(crc, *((const sz *)src_u8)); \ + src_u8 += sizeof(sz); \ + } \ +} while (0) +""".} + +proc crc32CalculateWithSeed*(seed: U32; src: pointer; size: csize_t): U32 {.inline, + cdecl.} = + ## / Calculate a CRC32 over data using a seed. + ## / Can be used to calculate a CRC32 in chunks using an initial seed of zero for the first chunk. + {.emit: """ + const u8 *src_u8 = (const u8 *)src; + + u32 crc = ~seed; + s64 len = size; + + _CRC_ALIGN(u8, b); + _CRC_ALIGN(u16, h); + _CRC_ALIGN(u32, w); + + while ((len -= sizeof(u64)) >= 0) { + crc = __crc32d(crc, *((const u64 *)src_u8)); + src_u8 += sizeof(u64); + } + + _CRC_REMAINDER(u32, w); + _CRC_REMAINDER(u16, h); + _CRC_REMAINDER(u8, b); + """.} + + {.emit: "`result` = ~crc;".} + + +proc crc32Calculate*(src: pointer; size: csize_t): U32 {.inline, cdecl.} = + ## / Calculate a CRC32 over data. + return crc32CalculateWithSeed(0, src, size) + + +proc crc32cCalculateWithSeed*(seed: U32; src: pointer; size: csize_t): U32 {.inline, + cdecl.} = + ## / Calculate a CRC32C over data using a seed. + ## / Can be used to calculate a CRC32C in chunks using an initial seed of zero for the first chunk. + + {.emit: """ + const u8 *src_u8 = (const u8 *)src; + + u32 crc = ~seed; + s64 len = size; + + _CRC_ALIGN(u8, cb); + _CRC_ALIGN(u16, ch); + _CRC_ALIGN(u32, cw); + + while ((len -= sizeof(u64)) >= 0) { + crc = __crc32cd(crc, *((const u64 *)src_u8)); + src_u8 += sizeof(u64); + } + + _CRC_REMAINDER(u32, cw); + _CRC_REMAINDER(u16, ch); + _CRC_REMAINDER(u8, cb); + """.} + + {.emit: "`result` = ~crc;".} + +proc crc32cCalculate*(src: pointer; size: csize_t): U32 {.inline, cdecl.} = + ## / Calculate a CRC32C over data. + return crc32cCalculateWithSeed(0, src, size) diff --git a/src/libnx/wrapper/switch/crypto/hmac.h b/src/libnx/wrapper/switch/crypto/hmac.h new file mode 100644 index 0000000..45ee662 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/hmac.h @@ -0,0 +1,51 @@ +/** + * @file hmac.h + * @brief Hardware accelerated HMAC-SHA(1, 256) implementation. + * @copyright libnx Authors + */ +#pragma once +#include "sha1.h" +#include "sha256.h" + +/// Context for HMAC-SHA1 operations. +typedef struct { + Sha1Context sha_ctx; + u32 key[SHA1_BLOCK_SIZE / sizeof(u32)]; + u32 mac[SHA1_HASH_SIZE / sizeof(u32)]; + bool finalized; +} HmacSha1Context; + +/// Context for HMAC-SHA256 operations. +typedef struct { + Sha256Context sha_ctx; + u32 key[SHA256_BLOCK_SIZE / sizeof(u32)]; + u32 mac[SHA256_HASH_SIZE / sizeof(u32)]; + bool finalized; +} HmacSha256Context; + +#ifndef HMAC_SHA1_KEY_MAX +#define HMAC_SHA1_KEY_MAX (sizeof(((HmacSha1Context *)NULL)->key)) +#endif +#ifndef HMAC_SHA256_KEY_MAX +#define HMAC_SHA256_KEY_MAX (sizeof(((HmacSha256Context *)NULL)->key)) +#endif + +/// Initialize a HMAC-SHA256 context. +void hmacSha256ContextCreate(HmacSha256Context *out, const void *key, size_t key_size); +/// Updates HMAC-SHA256 context with data to hash +void hmacSha256ContextUpdate(HmacSha256Context *ctx, const void *src, size_t size); +/// Gets the context's output mac, finalizes the context. +void hmacSha256ContextGetMac(HmacSha256Context *ctx, void *dst); + +/// Simple all-in-one HMAC-SHA256 calculator. +void hmacSha256CalculateMac(void *dst, const void *key, size_t key_size, const void *src, size_t size); + +/// Initialize a HMAC-SHA1 context. +void hmacSha1ContextCreate(HmacSha1Context *out, const void *key, size_t key_size); +/// Updates HMAC-SHA1 context with data to hash +void hmacSha1ContextUpdate(HmacSha1Context *ctx, const void *src, size_t size); +/// Gets the context's output mac, finalizes the context. +void hmacSha1ContextGetMac(HmacSha1Context *ctx, void *dst); + +/// Simple all-in-one HMAC-SHA1 calculator. +void hmacSha1CalculateMac(void *dst, const void *key, size_t key_size, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/hmac.nim b/src/libnx/wrapper/switch/crypto/hmac.nim new file mode 100644 index 0000000..6e81c20 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/hmac.nim @@ -0,0 +1,67 @@ +## * +## @file hmac.h +## @brief Hardware accelerated HMAC-SHA(1, 256) implementation. +## @copyright libnx Authors +## + +import + sha1, sha256, ../types + +## / Context for HMAC-SHA1 operations. + +type + HmacSha1Context* {.bycopy.} = object + shaCtx*: Sha1Context + key*: array[Sha1Block_Size div sizeof(U32), U32] + mac*: array[Sha1Hash_Size div sizeof(U32), U32] + finalized*: bool + + +## / Context for HMAC-SHA256 operations. + +type + HmacSha256Context* {.bycopy.} = object + shaCtx*: Sha256Context + key*: array[Sha256Block_Size div sizeof((U32)), U32] + mac*: array[Sha256Hash_Size div sizeof((U32)), U32] + finalized*: bool + + +const + HMAC_SHA1_KEY_MAX* = (sizeof(((cast[ptr HmacSha1Context](nil)).key))) + HMAC_SHA256_KEY_MAX* = (sizeof(((cast[ptr HmacSha256Context](nil)).key))) + +proc hmacSha256ContextCreate*(`out`: ptr HmacSha256Context; key: pointer; + keySize: csize_t) {.cdecl, + importc: "hmacSha256ContextCreate".} +## / Initialize a HMAC-SHA256 context. + +proc hmacSha256ContextUpdate*(ctx: ptr HmacSha256Context; src: pointer; size: csize_t) {. + cdecl, importc: "hmacSha256ContextUpdate".} +## / Updates HMAC-SHA256 context with data to hash + +proc hmacSha256ContextGetMac*(ctx: ptr HmacSha256Context; dst: pointer) {.cdecl, + importc: "hmacSha256ContextGetMac".} +## / Gets the context's output mac, finalizes the context. + +proc hmacSha256CalculateMac*(dst: pointer; key: pointer; keySize: csize_t; + src: pointer; size: csize_t) {.cdecl, + importc: "hmacSha256CalculateMac".} +## / Simple all-in-one HMAC-SHA256 calculator. + +proc hmacSha1ContextCreate*(`out`: ptr HmacSha1Context; key: pointer; keySize: csize_t) {. + cdecl, importc: "hmacSha1ContextCreate".} +## / Initialize a HMAC-SHA1 context. + +proc hmacSha1ContextUpdate*(ctx: ptr HmacSha1Context; src: pointer; size: csize_t) {. + cdecl, importc: "hmacSha1ContextUpdate".} +## / Updates HMAC-SHA1 context with data to hash + +proc hmacSha1ContextGetMac*(ctx: ptr HmacSha1Context; dst: pointer) {.cdecl, + importc: "hmacSha1ContextGetMac".} +## / Gets the context's output mac, finalizes the context. + +proc hmacSha1CalculateMac*(dst: pointer; key: pointer; keySize: csize_t; src: pointer; + size: csize_t) {.cdecl, importc: "hmacSha1CalculateMac".} +## / Simple all-in-one HMAC-SHA1 calculator. + diff --git a/src/libnx/wrapper/switch/crypto/sha1.h b/src/libnx/wrapper/switch/crypto/sha1.h new file mode 100644 index 0000000..7bb6437 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/sha1.h @@ -0,0 +1,34 @@ +/** + * @file sha1.h + * @brief Hardware accelerated SHA1 implementation. + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +#ifndef SHA1_HASH_SIZE +#define SHA1_HASH_SIZE 0x14 +#endif + +#ifndef SHA1_BLOCK_SIZE +#define SHA1_BLOCK_SIZE 0x40 +#endif + +/// Context for SHA1 operations. +typedef struct { + u32 intermediate_hash[SHA1_HASH_SIZE / sizeof(u32)]; + u8 buffer[SHA1_BLOCK_SIZE]; + u64 bits_consumed; + size_t num_buffered; + bool finalized; +} Sha1Context; + +/// Initialize a SHA1 context. +void sha1ContextCreate(Sha1Context *out); +/// Updates SHA1 context with data to hash +void sha1ContextUpdate(Sha1Context *ctx, const void *src, size_t size); +/// Gets the context's output hash, finalizes the context. +void sha1ContextGetHash(Sha1Context *ctx, void *dst); + +/// Simple all-in-one SHA1 calculator. +void sha1CalculateHash(void *dst, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/sha1.nim b/src/libnx/wrapper/switch/crypto/sha1.nim new file mode 100644 index 0000000..aa6eac6 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/sha1.nim @@ -0,0 +1,37 @@ +## * +## @file sha1.h +## @brief Hardware accelerated SHA1 implementation. +## @copyright libnx Authors +## + +import + ../types + +const + SHA1_HASH_SIZE* = 0x14 + SHA1_BLOCK_SIZE* = 0x40 +## / Context for SHA1 operations. + +type + Sha1Context* {.bycopy.} = object + intermediateHash*: array[Sha1Hash_Size div sizeof((U32)), U32] + buffer*: array[Sha1Block_Size, U8] + bitsConsumed*: U64 + numBuffered*: csize_t + finalized*: bool + +proc sha1ContextCreate*(`out`: ptr Sha1Context) {.cdecl, importc: "sha1ContextCreate".} +## / Initialize a SHA1 context. + +proc sha1ContextUpdate*(ctx: ptr Sha1Context; src: pointer; size: csize_t) {.cdecl, + importc: "sha1ContextUpdate".} +## / Updates SHA1 context with data to hash + +proc sha1ContextGetHash*(ctx: ptr Sha1Context; dst: pointer) {.cdecl, + importc: "sha1ContextGetHash".} +## / Gets the context's output hash, finalizes the context. + +proc sha1CalculateHash*(dst: pointer; src: pointer; size: csize_t) {.cdecl, + importc: "sha1CalculateHash".} +## / Simple all-in-one SHA1 calculator. + diff --git a/src/libnx/wrapper/switch/crypto/sha256.h b/src/libnx/wrapper/switch/crypto/sha256.h new file mode 100644 index 0000000..603d221 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/sha256.h @@ -0,0 +1,35 @@ +/** + * @file sha256.h + * @brief Hardware accelerated SHA256 implementation. + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + + +#ifndef SHA256_HASH_SIZE +#define SHA256_HASH_SIZE 0x20 +#endif + +#ifndef SHA256_BLOCK_SIZE +#define SHA256_BLOCK_SIZE 0x40 +#endif + +/// Context for SHA256 operations. +typedef struct { + u32 intermediate_hash[SHA256_HASH_SIZE / sizeof(u32)]; + u8 buffer[SHA256_BLOCK_SIZE]; + u64 bits_consumed; + size_t num_buffered; + bool finalized; +} Sha256Context; + +/// Initialize a SHA256 context. +void sha256ContextCreate(Sha256Context *out); +/// Updates SHA256 context with data to hash +void sha256ContextUpdate(Sha256Context *ctx, const void *src, size_t size); +/// Gets the context's output hash, finalizes the context. +void sha256ContextGetHash(Sha256Context *ctx, void *dst); + +/// Simple all-in-one SHA256 calculator. +void sha256CalculateHash(void *dst, const void *src, size_t size); diff --git a/src/libnx/wrapper/switch/crypto/sha256.nim b/src/libnx/wrapper/switch/crypto/sha256.nim new file mode 100644 index 0000000..3020714 --- /dev/null +++ b/src/libnx/wrapper/switch/crypto/sha256.nim @@ -0,0 +1,41 @@ +## * +## @file sha256.h +## @brief Hardware accelerated SHA256 implementation. +## @copyright libnx Authors +## + +import + ../types + +when not defined(SHA256_HASH_SIZE): + const + SHA256_HASH_SIZE* = 0x20 +when not defined(SHA256_BLOCK_SIZE): + const + SHA256_BLOCK_SIZE* = 0x40 +## / Context for SHA256 operations. + +type + Sha256Context* {.bycopy.} = object + intermediateHash*: array[Sha256Hash_Size div sizeof((U32)), U32] + buffer*: array[Sha256Block_Size, U8] + bitsConsumed*: U64 + numBuffered*: csize_t + finalized*: bool + +proc sha256ContextCreate*(`out`: ptr Sha256Context) {.cdecl, + importc: "sha256ContextCreate".} +## / Initialize a SHA256 context. + +proc sha256ContextUpdate*(ctx: ptr Sha256Context; src: pointer; size: csize_t) {.cdecl, + importc: "sha256ContextUpdate".} +## / Updates SHA256 context with data to hash + +proc sha256ContextGetHash*(ctx: ptr Sha256Context; dst: pointer) {.cdecl, + importc: "sha256ContextGetHash".} +## / Gets the context's output hash, finalizes the context. + +proc sha256CalculateHash*(dst: pointer; src: pointer; size: csize_t) {.cdecl, + importc: "sha256CalculateHash".} +## / Simple all-in-one SHA256 calculator. + diff --git a/src/libnx/wrapper/switch/display/binder.h b/src/libnx/wrapper/switch/display/binder.h new file mode 100644 index 0000000..814f9b2 --- /dev/null +++ b/src/libnx/wrapper/switch/display/binder.h @@ -0,0 +1,51 @@ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +#define BINDER_FIRST_CALL_TRANSACTION 0x1 + +typedef struct { + bool created; + bool initialized; + s32 id; + size_t dummy; + Service* relay; +} Binder; + +// Note: binderClose will not close the session_handle provided to binderCreate. +void binderCreate(Binder* b, s32 id); +void binderClose(Binder* b); + +Result binderInitSession(Binder* b, Service* relay); + +Result binderTransactParcel( + Binder* b, u32 code, + void* parcel_data, size_t parcel_data_size, + void* parcel_reply, size_t parcel_reply_size, + u32 flags); + +Result binderConvertErrorCode(s32 code); + +Result binderAdjustRefcount(Binder* b, s32 addval, s32 type); +Result binderGetNativeHandle(Binder* b, u32 unk0, Event *event_out); + +static inline Result binderIncreaseWeakRef(Binder* b) +{ + return binderAdjustRefcount(b, 1, 0); +} + +static inline Result binderDecreaseWeakRef(Binder* b) +{ + return binderAdjustRefcount(b, -1, 0); +} + +static inline Result binderIncreaseStrongRef(Binder* b) +{ + return binderAdjustRefcount(b, 1, 1); +} + +static inline Result binderDecreaseStrongRef(Binder* b) +{ + return binderAdjustRefcount(b, -1, 1); +} diff --git a/src/libnx/wrapper/switch/display/binder.nim b/src/libnx/wrapper/switch/display/binder.nim new file mode 100644 index 0000000..6e7d9f6 --- /dev/null +++ b/src/libnx/wrapper/switch/display/binder.nim @@ -0,0 +1,42 @@ +import + ../types, ../kernel/event, ../sf/service + +const + BINDER_FIRST_CALL_TRANSACTION* = 0x1 + +type + Binder* {.bycopy.} = object + created*: bool + initialized*: bool + id*: S32 + dummy*: csize_t + relay*: ptr Service + + +## Note: binderClose will not close the session_handle provided to binderCreate. + +proc binderCreate*(b: ptr Binder; id: S32) {.cdecl, importc: "binderCreate".} +proc binderClose*(b: ptr Binder) {.cdecl, importc: "binderClose".} +proc binderInitSession*(b: ptr Binder; relay: ptr Service): Result {.cdecl, + importc: "binderInitSession".} +proc binderTransactParcel*(b: ptr Binder; code: U32; parcelData: pointer; + parcelDataSize: csize_t; parcelReply: pointer; + parcelReplySize: csize_t; flags: U32): Result {.cdecl, + importc: "binderTransactParcel".} +proc binderConvertErrorCode*(code: S32): Result {.cdecl, + importc: "binderConvertErrorCode".} +proc binderAdjustRefcount*(b: ptr Binder; addval: S32; `type`: S32): Result {.cdecl, + importc: "binderAdjustRefcount".} +proc binderGetNativeHandle*(b: ptr Binder; unk0: U32; eventOut: ptr Event): Result {. + cdecl, importc: "binderGetNativeHandle".} +proc binderIncreaseWeakRef*(b: ptr Binder): Result {.inline, cdecl.} = + return binderAdjustRefcount(b, 1, 0) + +proc binderDecreaseWeakRef*(b: ptr Binder): Result {.inline, cdecl.} = + return binderAdjustRefcount(b, -1, 0) + +proc binderIncreaseStrongRef*(b: ptr Binder): Result {.inline, cdecl.} = + return binderAdjustRefcount(b, 1, 1) + +proc binderDecreaseStrongRef*(b: ptr Binder): Result {.inline, cdecl.} = + return binderAdjustRefcount(b, -1, 1) diff --git a/src/libnx/wrapper/switch/display/buffer_producer.h b/src/libnx/wrapper/switch/display/buffer_producer.h new file mode 100644 index 0000000..9f81324 --- /dev/null +++ b/src/libnx/wrapper/switch/display/buffer_producer.h @@ -0,0 +1,49 @@ +#pragma once +#include "types.h" +#include "binder.h" +#include "../nvidia/fence.h" + +typedef struct { + s32 left; + s32 top; + s32 right; + s32 bottom; +} BqRect; + +typedef struct { + struct { s64 timestamp; } PACKED; + s32 isAutoTimestamp; + BqRect crop; + s32 scalingMode; + u32 transform; // See the NATIVE_WINDOW_TRANSFORM_* enums. + u32 stickyTransform; + u32 unk; + u32 swapInterval; + NvMultiFence fence; +} BqBufferInput; + +typedef struct { + u32 width; + u32 height; + u32 transformHint; + u32 numPendingBuffers; +} BqBufferOutput; + +typedef struct { + u32 width; + u32 height; + u32 stride; + u32 format; + u32 usage; + NativeHandle* native_handle; +} BqGraphicBuffer; + +Result bqRequestBuffer(Binder *b, s32 bufferIdx, BqGraphicBuffer *buf); +Result bqDequeueBuffer(Binder *b, bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, NvMultiFence *fence); +Result bqDetachBuffer(Binder *b, s32 slot); +Result bqQueueBuffer(Binder *b, s32 buf, const BqBufferInput *input, BqBufferOutput *output); +Result bqCancelBuffer(Binder *b, s32 buf, const NvMultiFence *fence); +Result bqQuery(Binder *b, s32 what, s32* value); +Result bqConnect(Binder *b, s32 api, bool producerControlledByApp, BqBufferOutput *output); +Result bqDisconnect(Binder *b, s32 api); +Result bqSetPreallocatedBuffer(Binder *b, s32 buf, const BqGraphicBuffer *input); diff --git a/src/libnx/wrapper/switch/display/buffer_producer.nim b/src/libnx/wrapper/switch/display/buffer_producer.nim new file mode 100644 index 0000000..3cfa335 --- /dev/null +++ b/src/libnx/wrapper/switch/display/buffer_producer.nim @@ -0,0 +1,57 @@ +import + types as t, binder, ../nvidia/fence, ../types + +type + INNER_C_STRUCT_buffer_producer_2* {.bycopy.} = object + timestamp*: S64 + + BqRect* {.bycopy.} = object + left*: S32 + top*: S32 + right*: S32 + bottom*: S32 + + BqBufferInput* {.bycopy.} = object + anoBufferProducer3*: INNER_C_STRUCT_buffer_producer_2 + isAutoTimestamp*: S32 + crop*: BqRect + scalingMode*: S32 + transform*: U32 ## See the NATIVE_WINDOW_TRANSFORM_* enums. + stickyTransform*: U32 + unk*: U32 + swapInterval*: U32 + fence*: NvMultiFence + + BqBufferOutput* {.bycopy.} = object + width*: U32 + height*: U32 + transformHint*: U32 + numPendingBuffers*: U32 + + BqGraphicBuffer* {.bycopy.} = object + width*: U32 + height*: U32 + stride*: U32 + format*: U32 + usage*: U32 + nativeHandle*: ptr NativeHandle + + +proc bqRequestBuffer*(b: ptr Binder; bufferIdx: S32; buf: ptr BqGraphicBuffer): Result {. + cdecl, importc: "bqRequestBuffer".} +proc bqDequeueBuffer*(b: ptr Binder; async: bool; width: U32; height: U32; format: S32; + usage: U32; buf: ptr S32; fence: ptr NvMultiFence): Result {.cdecl, + importc: "bqDequeueBuffer".} +proc bqDetachBuffer*(b: ptr Binder; slot: S32): Result {.cdecl, + importc: "bqDetachBuffer".} +proc bqQueueBuffer*(b: ptr Binder; buf: S32; input: ptr BqBufferInput; + output: ptr BqBufferOutput): Result {.cdecl, + importc: "bqQueueBuffer".} +proc bqCancelBuffer*(b: ptr Binder; buf: S32; fence: ptr NvMultiFence): Result {.cdecl, + importc: "bqCancelBuffer".} +proc bqQuery*(b: ptr Binder; what: S32; value: ptr S32): Result {.cdecl, importc: "bqQuery".} +proc bqConnect*(b: ptr Binder; api: S32; producerControlledByApp: bool; + output: ptr BqBufferOutput): Result {.cdecl, importc: "bqConnect".} +proc bqDisconnect*(b: ptr Binder; api: S32): Result {.cdecl, importc: "bqDisconnect".} +proc bqSetPreallocatedBuffer*(b: ptr Binder; buf: S32; input: ptr BqGraphicBuffer): Result {. + cdecl, importc: "bqSetPreallocatedBuffer".} diff --git a/src/libnx/wrapper/switch/display/framebuffer.h b/src/libnx/wrapper/switch/display/framebuffer.h new file mode 100644 index 0000000..384bd25 --- /dev/null +++ b/src/libnx/wrapper/switch/display/framebuffer.h @@ -0,0 +1,104 @@ +/** + * @file framebuffer.h + * @brief Framebuffer wrapper object, providing support for software rendered graphics. + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../nvidia/map.h" +#include "native_window.h" + +/// Converts red/green/blue/alpha components to packed RGBA8 (i.e. \ref PIXEL_FORMAT_RGBA_8888). +#define RGBA8(r,g,b,a) (((r)&0xff)|(((g)&0xff)<<8)|(((b)&0xff)<<16)|(((a)&0xff)<<24)) + +/// Same as \ref RGBA8 except with alpha=0xff. +#define RGBA8_MAXALPHA(r,g,b) RGBA8((r),(g),(b),0xff) + +/// Converts red/green/blue to packed RGBX8 (i.e. \ref PIXEL_FORMAT_RGBX_8888). +#define RGBX8(r,g,b) RGBA8((r),(g),(b),0) + +/// Converts red/green/blue components to packed RGB565 (i.e. \ref PIXEL_FORMAT_RGB_565) +#define RGB565(r,g,b) (((b)&0x1f)|(((g)&0x3f)<<5)|(((r)&0x1f)<<11)) + +/// Same as \ref RGB565 but accepting 8-bit components as input instead. +#define RGB565_FROM_RGB8(r,g,b) RGB565((r)>>3,(g)>>2,(b)>>3) + +/// Converts red/green/blue/alpha components to packed BGR8 (i.e. \ref PIXEL_FORMAT_BGRA_8888). +#define BGRA8(r,g,b,a) RGBA8((b),(g),(r),(a)) + +/// Same as \ref BGRA8 except with alpha=0xff. +#define BGRA8_MAXALPHA(r,g,b) RGBA8((b),(g),(r),0xff) + +/// Converts red/green/blue/alpha components to packed RGBA4 (i.e. \ref PIXEL_FORMAT_RGBA_4444). +#define RGBA4(r,g,b,a) (((r)&0xf)|(((g)&0xf)<<4)|(((b)&0xf)<<8)|(((a)&0xf)<<12)) + +/// Same as \ref RGBA4 except with alpha=0xf. +#define RGBA4_MAXALPHA(r,g,b) RGBA4((r),(g),(b),0xf) + +/// Same as \ref RGBA4 but accepting 8-bit components as input instead. +#define RGBA4_FROM_RGBA8(r,g,b,a) RGBA4((r)>>4,(g)>>4,(b)>>4,(a)>>4) + +/// Same as \ref RGBA4_MAXALPHA except with alpha=0xff. +#define RGBA4_FROM_RGBA8_MAXALPHA(r,g,b) RGBA4_MAXALPHA((r)>>4,(g)>>4,(b)>>4) + +/// Framebuffer structure. +typedef struct Framebuffer { + NWindow *win; + NvMap map; + void* buf; + void* buf_linear; + u32 stride; + u32 width_aligned; + u32 height_aligned; + u32 num_fbs; + u32 fb_size; + bool has_init; +} Framebuffer; + +/** + * @brief Creates a \ref Framebuffer object. + * @param[out] fb Output \ref Framebuffer structure. + * @param[in] win Pointer to the \ref NWindow to which the \ref Framebuffer will be registered. + * @param[in] width Desired width of the framebuffer (usually 1280). + * @param[in] height Desired height of the framebuffer (usually 720). + * @param[in] format Desired pixel format (see PIXEL_FORMAT_* enum). + * @param[in] num_fbs Number of buffers to create. Pass 1 for single-buffering, 2 for double-buffering or 3 for triple-buffering. + * @note Framebuffer images are stored in Tegra block linear format with 16Bx2 sector ordering, read TRM chapter 20.1 for more details. + * In order to use regular linear layout, consider calling \ref framebufferMakeLinear after the \ref Framebuffer object is created. + * @note Presently, only the following pixel formats are supported: + * \ref PIXEL_FORMAT_RGBA_8888 + * \ref PIXEL_FORMAT_RGBX_8888 + * \ref PIXEL_FORMAT_RGB_565 + * \ref PIXEL_FORMAT_BGRA_8888 + * \ref PIXEL_FORMAT_RGBA_4444 + */ +Result framebufferCreate(Framebuffer* fb, NWindow *win, u32 width, u32 height, u32 format, u32 num_fbs); + +/// Enables linear framebuffer mode in a \ref Framebuffer, allocating a shadow buffer in the process. +Result framebufferMakeLinear(Framebuffer* fb); + +/// Closes a \ref Framebuffer object, freeing all resources associated with it. +void framebufferClose(Framebuffer* fb); + +/** + * @brief Begins rendering a frame in a \ref Framebuffer. + * @param[in] fb Pointer to \ref Framebuffer structure. + * @param[out] out_stride Output variable containing the distance in bytes between rows of pixels in memory. + * @return Pointer to buffer to which new graphics data should be written to. + * @note When this function is called, a buffer will be dequeued from the corresponding \ref NWindow. + * @note This function will return pointers to different buffers, depending on the number of buffers it was initialized with. + * @note If \ref framebufferMakeLinear was used, this function will instead return a pointer to the shadow linear buffer. + * In this case, the offset of a pixel is \p y * \p out_stride + \p x * \p bytes_per_pixel. + * @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. + */ +void* framebufferBegin(Framebuffer* fb, u32* out_stride); + +/** + * @brief Finishes rendering a frame in a \ref Framebuffer. + * @param[in] fb Pointer to \ref Framebuffer structure. + * @note When this function is called, the written image data will be flushed and queued (presented) in the corresponding \ref NWindow. + * @note If \ref framebufferMakeLinear was used, this function will copy the image from the shadow linear buffer to the actual framebuffer, + * converting it in the process to the layout expected by the compositor. + * @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. + */ +void framebufferEnd(Framebuffer* fb); diff --git a/src/libnx/wrapper/switch/display/framebuffer.nim b/src/libnx/wrapper/switch/display/framebuffer.nim new file mode 100644 index 0000000..673d2a7 --- /dev/null +++ b/src/libnx/wrapper/switch/display/framebuffer.nim @@ -0,0 +1,133 @@ +## * +## @file framebuffer.h +## @brief Framebuffer wrapper object, providing support for software rendered graphics. +## @author fincs +## @copyright libnx Authors +## + +import + ../nvidia/map, native_window, ../types + +## / Converts red/green/blue/alpha components to packed RGBA8 (i.e. \ref PIXEL_FORMAT_RGBA_8888). + +template rgba8*(r, g, b, a: untyped): untyped = + (((r) and 0xff) or (((g) and 0xff) shl 8) or (((b) and 0xff) shl 16) or + (((a) and 0xff) shl 24)) + +## / Same as \ref RGBA8 except with alpha=0xff. + +template rgba8Maxalpha*(r, g, b: untyped): untyped = + rgba8((r), (g), (b), 0xff) + +## / Converts red/green/blue to packed RGBX8 (i.e. \ref PIXEL_FORMAT_RGBX_8888). + +template rgbx8*(r, g, b: untyped): untyped = + rgba8((r), (g), (b), 0) + +## / Converts red/green/blue components to packed RGB565 (i.e. \ref PIXEL_FORMAT_RGB_565) + +template rgb565*(r, g, b: untyped): untyped = + (((b) and 0x1f) or (((g) and 0x3f) shl 5) or (((r) and 0x1f) shl 11)) + +## / Same as \ref RGB565 but accepting 8-bit components as input instead. + +template rgb565From_Rgb8*(r, g, b: untyped): untyped = + rgb565((r) shr 3, (g) shr 2, (b) shr 3) + +## / Converts red/green/blue/alpha components to packed BGR8 (i.e. \ref PIXEL_FORMAT_BGRA_8888). + +template bgra8*(r, g, b, a: untyped): untyped = + rgba8((b), (g), (r), (a)) + +## / Same as \ref BGRA8 except with alpha=0xff. + +template bgra8Maxalpha*(r, g, b: untyped): untyped = + rgba8((b), (g), (r), 0xff) + +## / Converts red/green/blue/alpha components to packed RGBA4 (i.e. \ref PIXEL_FORMAT_RGBA_4444). + +template rgba4*(r, g, b, a: untyped): untyped = + (((r) and 0xf) or (((g) and 0xf) shl 4) or (((b) and 0xf) shl 8) or (((a) and 0xf) shl 12)) + +## / Same as \ref RGBA4 except with alpha=0xf. + +template rgba4Maxalpha*(r, g, b: untyped): untyped = + rgba4((r), (g), (b), 0xf) + +## / Same as \ref RGBA4 but accepting 8-bit components as input instead. + +template rgba4From_Rgba8*(r, g, b, a: untyped): untyped = + rgba4((r) shr 4, (g) shr 4, (b) shr 4, (a) shr 4) + +## / Same as \ref RGBA4_MAXALPHA except with alpha=0xff. + +template rgba4From_Rgba8Maxalpha*(r, g, b: untyped): untyped = + rgba4Maxalpha((r) shr 4, (g) shr 4, (b) shr 4) + +## / Framebuffer structure. + +type + Framebuffer* {.bycopy.} = object + win*: ptr NWindow + map*: NvMap + buf*: pointer + bufLinear*: pointer + stride*: U32 + widthAligned*: U32 + heightAligned*: U32 + numFbs*: U32 + fbSize*: U32 + hasInit*: bool + +proc framebufferCreate*(fb: ptr Framebuffer; win: ptr NWindow; width: U32; height: U32; + format: U32; numFbs: U32): Result {.cdecl, + importc: "framebufferCreate".} +## * +## @brief Creates a \ref Framebuffer object. +## @param[out] fb Output \ref Framebuffer structure. +## @param[in] win Pointer to the \ref NWindow to which the \ref Framebuffer will be registered. +## @param[in] width Desired width of the framebuffer (usually 1280). +## @param[in] height Desired height of the framebuffer (usually 720). +## @param[in] format Desired pixel format (see PIXEL_FORMAT_* enum). +## @param[in] num_fbs Number of buffers to create. Pass 1 for single-buffering, 2 for double-buffering or 3 for triple-buffering. +## @note Framebuffer images are stored in Tegra block linear format with 16Bx2 sector ordering, read TRM chapter 20.1 for more details. +## In order to use regular linear layout, consider calling \ref framebufferMakeLinear after the \ref Framebuffer object is created. +## @note Presently, only the following pixel formats are supported: +## \ref PIXEL_FORMAT_RGBA_8888 +## \ref PIXEL_FORMAT_RGBX_8888 +## \ref PIXEL_FORMAT_RGB_565 +## \ref PIXEL_FORMAT_BGRA_8888 +## \ref PIXEL_FORMAT_RGBA_4444 +## + +proc framebufferMakeLinear*(fb: ptr Framebuffer): Result {.cdecl, + importc: "framebufferMakeLinear".} +## / Enables linear framebuffer mode in a \ref Framebuffer, allocating a shadow buffer in the process. + +proc framebufferClose*(fb: ptr Framebuffer) {.cdecl, importc: "framebufferClose".} +## / Closes a \ref Framebuffer object, freeing all resources associated with it. + +proc framebufferBegin*(fb: ptr Framebuffer; outStride: ptr U32): pointer {.cdecl, + importc: "framebufferBegin".} +## * +## @brief Begins rendering a frame in a \ref Framebuffer. +## @param[in] fb Pointer to \ref Framebuffer structure. +## @param[out] out_stride Output variable containing the distance in bytes between rows of pixels in memory. +## @return Pointer to buffer to which new graphics data should be written to. +## @note When this function is called, a buffer will be dequeued from the corresponding \ref NWindow. +## @note This function will return pointers to different buffers, depending on the number of buffers it was initialized with. +## @note If \ref framebufferMakeLinear was used, this function will instead return a pointer to the shadow linear buffer. +## In this case, the offset of a pixel is \p y * \p out_stride + \p x * \p bytes_per_pixel. +## @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. +## + +proc framebufferEnd*(fb: ptr Framebuffer) {.cdecl, importc: "framebufferEnd".} +## * +## @brief Finishes rendering a frame in a \ref Framebuffer. +## @param[in] fb Pointer to \ref Framebuffer structure. +## @note When this function is called, the written image data will be flushed and queued (presented) in the corresponding \ref NWindow. +## @note If \ref framebufferMakeLinear was used, this function will copy the image from the shadow linear buffer to the actual framebuffer, +## converting it in the process to the layout expected by the compositor. +## @note Each call to \ref framebufferBegin must be paired with a \ref framebufferEnd call. +## + diff --git a/src/libnx/wrapper/switch/display/native_window.h b/src/libnx/wrapper/switch/display/native_window.h new file mode 100644 index 0000000..396d0d8 --- /dev/null +++ b/src/libnx/wrapper/switch/display/native_window.h @@ -0,0 +1,190 @@ +/** + * @file native_window.h + * @brief Native window (NWindow) wrapper object, used for presenting images to the display (or other sinks). + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../kernel/mutex.h" +#include "../kernel/event.h" +#include "../services/vi.h" +#include "../nvidia/graphic_buffer.h" +#include "types.h" +#include "binder.h" +#include "buffer_producer.h" + +/// Native window structure. +typedef struct NWindow { + u32 magic; + Binder bq; + Event event; + Mutex mutex; + u64 slots_configured; + u64 slots_requested; + s32 cur_slot; + u32 width; + u32 height; + u32 format; + u32 usage; + BqRect crop; + u32 scaling_mode; + u32 transform; + u32 sticky_transform; + u32 default_width; + u32 default_height; + u32 swap_interval; + bool is_connected; + bool producer_controlled_by_app; + bool consumer_running_behind; +} NWindow; + +///@name Basic functions +///@{ + +/// Checks whether a pointer refers to a valid \ref NWindow object. +bool nwindowIsValid(NWindow* nw); + +/** + * @brief Retrieves the default \ref NWindow object. + * @return Pointer to the default \ref NWindow object. + * @note When this function is used/referenced, libnx will initialize VI services + * and create a \ref NWindow object from a \ref ViLayer created on the default \ref ViDisplay; + * all of this happening automatically during application startup (i.e. before main is called). + * If creating the default \ref NWindow fails, libnx will throw a LibnxError_BadGfxInit fatal error. + * Likewise, after main returns (or exit is called) libnx will clean up all resources used by it. + */ +NWindow* nwindowGetDefault(void); + +/** + * @brief Creates a \ref NWindow. + * @param[out] nw Output \ref NWindow structure. + * @param[in] binder_session Service object for the Android IGraphicBufferProducer binder session. + * @param[in] binder_id Android IGraphicBufferProducer binder session ID. + * @param[in] producer_controlled_by_app Specifies whether the producer is controlled by the application. + */ +Result nwindowCreate(NWindow* nw, Service* binder_session, s32 binder_id, bool producer_controlled_by_app); + +/** + * @brief Creates a \ref NWindow operating on a \ref ViLayer. + * @param[out] nw Output \ref NWindow structure. + * @param[in] layer Pointer to \ref ViLayer structure (such as the one returned by \ref viCreateLayer). + */ +Result nwindowCreateFromLayer(NWindow* nw, const ViLayer* layer); + +/// Closes a \ref NWindow, freeing all resources associated with it. +void nwindowClose(NWindow* nw); + +///@} + +///@name Window configuration +///@{ + +/** + * @brief Retrieves the dimensions of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[out] out_width Output variable containing the width of the \ref NWindow. + * @param[out] out_height Output variable containing the height of the \ref NWindow. + * @note After creation, a \ref NWindow reports a default size (usually 1280x720). + * This size can be overriden by calling \ref nwindowSetDimensions. + */ +Result nwindowGetDimensions(NWindow* nw, u32* out_width, u32* out_height); + +/** + * @brief Sets the dimensions of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] width Desired width of the \ref NWindow. + * @param[in] height Desired width of the \ref NWindow. + * @note This function cannot be called when there are buffers registered with the \ref NWindow. + */ +Result nwindowSetDimensions(NWindow* nw, u32 width, u32 height); + +/** + * @brief Configures the crop applied to images presented through a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] left X coordinate of the left margin of the crop bounding box. + * @param[in] top Y coordinate of the top margin of the crop bounding box. + * @param[in] right X coordinate of the right margin of the crop bounding box. + * @param[in] bottom Y coordinate of the bottom margin of the crop bounding box. + * @note Passing zero to all parameters disables the crop functionality. This is also the default. + * @note The bounding box defined by the parameters will be adjusted to fit within the dimensions of the \ref NWindow. + * @note \p left must be less or equal than \p right. + * @note \p top must be less or equal than \p bottom. + */ +Result nwindowSetCrop(NWindow* nw, s32 left, s32 top, s32 right, s32 bottom); + +/** + * @brief Configures the transformation applied to images presented through a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] transform Android transformation mode (see NATIVE_WINDOW_TRANSFORM_* enum) + * @note The default transformation is 0 (i.e. no transformation applied) + */ +Result nwindowSetTransform(NWindow* nw, u32 transform); + +/** + * @brief Configures the swap interval of a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] swap_interval Value specifying the number of display refreshes (VBlanks) that must occur between presenting images. + * @note The default swap interval is 1. + * @note If the \ref NWindow has three or more buffers configured (with \ref nwindowConfigureBuffer), it is possible to pass 0 + * to disable the swap interval feature and present images as fast as allowed by the compositor. Otherwise, the system + * enforces a minimum of 1 as the swap interval. + */ +Result nwindowSetSwapInterval(NWindow* nw, u32 swap_interval); + +/// Checks whether the consumer of a \ref NWindow is running behind. +static inline bool nwindowIsConsumerRunningBehind(NWindow* nw) +{ + return nw->consumer_running_behind; +} + +///@} + +///@name Buffer configuration and presentation +///@{ + +/** + * @brief Registers a \ref NvGraphicBuffer with a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to configure (starting from 0). + * @param[in] buf Pointer to \ref NvGraphicBuffer structure. + * @note When a buffer is registered, it is added to the internal queue of buffers used for presenting. + * @note All buffers registered with a \ref NWindow must have the same dimensions, format and usage. + * If \ref nwindowSetDimensions has not been previously called, the \ref NWindow will automatically + * adopt the dimensions of the first buffer registered with it. Otherwise, said buffer will need + * to match the dimensions that were previously configured. + */ +Result nwindowConfigureBuffer(NWindow* nw, s32 slot, NvGraphicBuffer* buf); + +/** + * @brief Dequeues a buffer from a \ref NWindow. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[out] out_slot Output variable containing the ID of the slot that has been dequeued. + * @param[out] out_fence Output variable containing a \ref NvMultiFence that will be signalled by + * the compositor when the buffer is ready to be written to. Pass NULL to wait instead + * on this fence before this function returns. + * @note For \p out_fence=NULL to work, \ref nvFenceInit must have been previously called. + */ +Result nwindowDequeueBuffer(NWindow* nw, s32* out_slot, NvMultiFence* out_fence); + +/** + * @brief Cancels a buffer previously dequeued with \ref nwindowDequeueBuffer. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to cancel. This must match the output of the previous \ref nwindowDequeueBuffer call. + * @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before cancelling the buffer. + * Pass NULL if there is no such fence. + */ +Result nwindowCancelBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); + +/** + * @brief Queues a buffer previously dequeued with \ref nwindowDequeueBuffer, making it ready for presentation. + * @param[in] nw Pointer to \ref NWindow structure. + * @param[in] slot ID of the slot to queue. This must match the output of the previous \ref nwindowDequeueBuffer call. + * @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before queuing/presenting the buffer. + * Pass NULL if there is no such fence. + */ +Result nwindowQueueBuffer(NWindow* nw, s32 slot, const NvMultiFence* fence); + +/// Releases all buffers registered with a \ref NWindow. +Result nwindowReleaseBuffers(NWindow* nw); + +///@} diff --git a/src/libnx/wrapper/switch/display/native_window.nim b/src/libnx/wrapper/switch/display/native_window.nim new file mode 100644 index 0000000..ff43757 --- /dev/null +++ b/src/libnx/wrapper/switch/display/native_window.nim @@ -0,0 +1,194 @@ +## * +## @file native_window.h +## @brief Native window (NWindow) wrapper object, used for presenting images to the display (or other sinks). +## @author fincs +## @copyright libnx Authors +## + +import + ../kernel/mutex, ../kernel/event, ../services/vi, ../nvidia/graphic_buffer, ../types, + binder, buffer_producer, ../sf/service, ../nvidia/fence + +## / Native window structure. + +type + NWindow* {.bycopy.} = object + magic*: U32 + bq*: Binder + event*: Event + mutex*: Mutex + slotsConfigured*: U64 + slotsRequested*: U64 + curSlot*: S32 + width*: U32 + height*: U32 + format*: U32 + usage*: U32 + crop*: BqRect + scalingMode*: U32 + transform*: U32 + stickyTransform*: U32 + defaultWidth*: U32 + defaultHeight*: U32 + swapInterval*: U32 + isConnected*: bool + producerControlledByApp*: bool + consumerRunningBehind*: bool + +proc nwindowIsValid*(nw: ptr NWindow): bool {.cdecl, importc: "nwindowIsValid".} +## /@name Basic functions +## /@{ +## / Checks whether a pointer refers to a valid \ref NWindow object. + +proc nwindowGetDefault*(): ptr NWindow {.cdecl, importc: "nwindowGetDefault".} +## * +## @brief Retrieves the default \ref NWindow object. +## @return Pointer to the default \ref NWindow object. +## @note When this function is used/referenced, libnx will initialize VI services +## and create a \ref NWindow object from a \ref ViLayer created on the default \ref ViDisplay; +## all of this happening automatically during application startup (i.e. before main is called). +## If creating the default \ref NWindow fails, libnx will throw a LibnxError_BadGfxInit fatal error. +## Likewise, after main returns (or exit is called) libnx will clean up all resources used by it. +## + +proc nwindowCreate*(nw: ptr NWindow; binderSession: ptr Service; binderId: S32; + producerControlledByApp: bool): Result {.cdecl, + importc: "nwindowCreate".} +## * +## @brief Creates a \ref NWindow. +## @param[out] nw Output \ref NWindow structure. +## @param[in] binder_session Service object for the Android IGraphicBufferProducer binder session. +## @param[in] binder_id Android IGraphicBufferProducer binder session ID. +## @param[in] producer_controlled_by_app Specifies whether the producer is controlled by the application. +## + +proc nwindowCreateFromLayer*(nw: ptr NWindow; layer: ptr ViLayer): Result {.cdecl, + importc: "nwindowCreateFromLayer".} +## * +## @brief Creates a \ref NWindow operating on a \ref ViLayer. +## @param[out] nw Output \ref NWindow structure. +## @param[in] layer Pointer to \ref ViLayer structure (such as the one returned by \ref viCreateLayer). +## + +proc nwindowClose*(nw: ptr NWindow) {.cdecl, importc: "nwindowClose".} +## / Closes a \ref NWindow, freeing all resources associated with it. + +proc nwindowGetDimensions*(nw: ptr NWindow; outWidth: ptr U32; outHeight: ptr U32): Result {. + cdecl, importc: "nwindowGetDimensions".} +## /@} +## /@name Window configuration +## /@{ +## * +## @brief Retrieves the dimensions of a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[out] out_width Output variable containing the width of the \ref NWindow. +## @param[out] out_height Output variable containing the height of the \ref NWindow. +## @note After creation, a \ref NWindow reports a default size (usually 1280x720). +## This size can be overriden by calling \ref nwindowSetDimensions. +## + +proc nwindowSetDimensions*(nw: ptr NWindow; width: U32; height: U32): Result {.cdecl, + importc: "nwindowSetDimensions".} +## * +## @brief Sets the dimensions of a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] width Desired width of the \ref NWindow. +## @param[in] height Desired width of the \ref NWindow. +## @note This function cannot be called when there are buffers registered with the \ref NWindow. +## + +proc nwindowSetCrop*(nw: ptr NWindow; left: S32; top: S32; right: S32; bottom: S32): Result {. + cdecl, importc: "nwindowSetCrop".} +## * +## @brief Configures the crop applied to images presented through a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] left X coordinate of the left margin of the crop bounding box. +## @param[in] top Y coordinate of the top margin of the crop bounding box. +## @param[in] right X coordinate of the right margin of the crop bounding box. +## @param[in] bottom Y coordinate of the bottom margin of the crop bounding box. +## @note Passing zero to all parameters disables the crop functionality. This is also the default. +## @note The bounding box defined by the parameters will be adjusted to fit within the dimensions of the \ref NWindow. +## @note \p left must be less or equal than \p right. +## @note \p top must be less or equal than \p bottom. +## + +proc nwindowSetTransform*(nw: ptr NWindow; transform: U32): Result {.cdecl, + importc: "nwindowSetTransform".} +## * +## @brief Configures the transformation applied to images presented through a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] transform Android transformation mode (see NATIVE_WINDOW_TRANSFORM_* enum) +## @note The default transformation is 0 (i.e. no transformation applied) +## + +proc nwindowSetSwapInterval*(nw: ptr NWindow; swapInterval: U32): Result {.cdecl, + importc: "nwindowSetSwapInterval".} +## * +## @brief Configures the swap interval of a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] swap_interval Value specifying the number of display refreshes (VBlanks) that must occur between presenting images. +## @note The default swap interval is 1. +## @note If the \ref NWindow has three or more buffers configured (with \ref nwindowConfigureBuffer), it is possible to pass 0 +## to disable the swap interval feature and present images as fast as allowed by the compositor. Otherwise, the system +## enforces a minimum of 1 as the swap interval. +## + +proc nwindowIsConsumerRunningBehind*(nw: ptr NWindow): bool {.inline, cdecl.} = + ## / Checks whether the consumer of a \ref NWindow is running behind. + return nw.consumerRunningBehind + +proc nwindowConfigureBuffer*(nw: ptr NWindow; slot: S32; buf: ptr NvGraphicBuffer): Result {. + cdecl, importc: "nwindowConfigureBuffer".} +## /@} +## /@name Buffer configuration and presentation +## /@{ +## * +## @brief Registers a \ref NvGraphicBuffer with a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] slot ID of the slot to configure (starting from 0). +## @param[in] buf Pointer to \ref NvGraphicBuffer structure. +## @note When a buffer is registered, it is added to the internal queue of buffers used for presenting. +## @note All buffers registered with a \ref NWindow must have the same dimensions, format and usage. +## If \ref nwindowSetDimensions has not been previously called, the \ref NWindow will automatically +## adopt the dimensions of the first buffer registered with it. Otherwise, said buffer will need +## to match the dimensions that were previously configured. +## + +proc nwindowDequeueBuffer*(nw: ptr NWindow; outSlot: ptr S32; + outFence: ptr NvMultiFence): Result {.cdecl, + importc: "nwindowDequeueBuffer".} +## * +## @brief Dequeues a buffer from a \ref NWindow. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[out] out_slot Output variable containing the ID of the slot that has been dequeued. +## @param[out] out_fence Output variable containing a \ref NvMultiFence that will be signalled by +## the compositor when the buffer is ready to be written to. Pass NULL to wait instead +## on this fence before this function returns. +## @note For \p out_fence=NULL to work, \ref nvFenceInit must have been previously called. +## + +proc nwindowCancelBuffer*(nw: ptr NWindow; slot: S32; fence: ptr NvMultiFence): Result {. + cdecl, importc: "nwindowCancelBuffer".} +## * +## @brief Cancels a buffer previously dequeued with \ref nwindowDequeueBuffer. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] slot ID of the slot to cancel. This must match the output of the previous \ref nwindowDequeueBuffer call. +## @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before cancelling the buffer. +## Pass NULL if there is no such fence. +## + +proc nwindowQueueBuffer*(nw: ptr NWindow; slot: S32; fence: ptr NvMultiFence): Result {. + cdecl, importc: "nwindowQueueBuffer".} +## * +## @brief Queues a buffer previously dequeued with \ref nwindowDequeueBuffer, making it ready for presentation. +## @param[in] nw Pointer to \ref NWindow structure. +## @param[in] slot ID of the slot to queue. This must match the output of the previous \ref nwindowDequeueBuffer call. +## @param[in] fence Pointer to the \ref NvMultiFence that will be waited on by the compositor before queuing/presenting the buffer. +## Pass NULL if there is no such fence. +## + +proc nwindowReleaseBuffers*(nw: ptr NWindow): Result {.cdecl, + importc: "nwindowReleaseBuffers".} +## / Releases all buffers registered with a \ref NWindow. + +## /@} diff --git a/src/libnx/wrapper/switch/display/parcel.h b/src/libnx/wrapper/switch/display/parcel.h new file mode 100644 index 0000000..4b4f272 --- /dev/null +++ b/src/libnx/wrapper/switch/display/parcel.h @@ -0,0 +1,40 @@ +#pragma once +#include "../result.h" +#include "../display/binder.h" + +typedef struct { + u32 payload_size; + u32 payload_off; + u32 objects_size; + u32 objects_off; +} ParcelHeader; + +#define PARCEL_MAX_PAYLOAD 0x400 + +typedef struct { + u8 payload[PARCEL_MAX_PAYLOAD]; + u32 payload_size; + u8* objects; + u32 objects_size; + + u32 capacity; + u32 pos; +} Parcel; + +void parcelCreate(Parcel *ctx); +Result parcelTransact(Binder *session, u32 code, Parcel *in_parcel, Parcel *reply_parcel); + +void* parcelWriteData(Parcel *ctx, const void* data, size_t data_size); +void* parcelReadData(Parcel *ctx, void* data, size_t data_size); + +void parcelWriteInt32(Parcel *ctx, s32 val); +void parcelWriteUInt32(Parcel *ctx, u32 val); +void parcelWriteString16(Parcel *ctx, const char *str); + +s32 parcelReadInt32(Parcel *ctx); +u32 parcelReadUInt32(Parcel *ctx); +void parcelWriteInterfaceToken(Parcel *ctx, const char *str); + +void* parcelReadFlattenedObject(Parcel *ctx, size_t *size); +void* parcelWriteFlattenedObject(Parcel *ctx, const void* data, size_t size); + diff --git a/src/libnx/wrapper/switch/display/parcel.nim b/src/libnx/wrapper/switch/display/parcel.nim new file mode 100644 index 0000000..d011039 --- /dev/null +++ b/src/libnx/wrapper/switch/display/parcel.nim @@ -0,0 +1,45 @@ +import + ../result, ../display/binder + +type + ParcelHeader* {.bycopy.} = object + payloadSize*: U32 + payloadOff*: U32 + objectsSize*: U32 + objectsOff*: U32 + + +const + PARCEL_MAX_PAYLOAD* = 0x400 + +type + Parcel* {.bycopy.} = object + payload*: array[Parcel_Max_Payload, U8] + payloadSize*: U32 + objects*: ptr U8 + objectsSize*: U32 + capacity*: U32 + pos*: U32 + + +proc parcelCreate*(ctx: ptr Parcel) {.cdecl, importc: "parcelCreate".} +proc parcelTransact*(session: ptr Binder; code: U32; inParcel: ptr Parcel; + replyParcel: ptr Parcel): Result {.cdecl, + importc: "parcelTransact".} +proc parcelWriteData*(ctx: ptr Parcel; data: pointer; dataSize: csize_t): pointer {. + cdecl, importc: "parcelWriteData".} +proc parcelReadData*(ctx: ptr Parcel; data: pointer; dataSize: csize_t): pointer {.cdecl, + importc: "parcelReadData".} +proc parcelWriteInt32*(ctx: ptr Parcel; val: S32) {.cdecl, importc: "parcelWriteInt32".} +proc parcelWriteUInt32*(ctx: ptr Parcel; val: U32) {.cdecl, + importc: "parcelWriteUInt32".} +proc parcelWriteString16*(ctx: ptr Parcel; str: cstring) {.cdecl, + importc: "parcelWriteString16".} +proc parcelReadInt32*(ctx: ptr Parcel): S32 {.cdecl, importc: "parcelReadInt32".} +proc parcelReadUInt32*(ctx: ptr Parcel): U32 {.cdecl, importc: "parcelReadUInt32".} +proc parcelWriteInterfaceToken*(ctx: ptr Parcel; str: cstring) {.cdecl, + importc: "parcelWriteInterfaceToken".} +proc parcelReadFlattenedObject*(ctx: ptr Parcel; size: ptr csize_t): pointer {.cdecl, + importc: "parcelReadFlattenedObject".} +proc parcelWriteFlattenedObject*(ctx: ptr Parcel; data: pointer; size: csize_t): pointer {. + cdecl, importc: "parcelWriteFlattenedObject".} diff --git a/src/libnx/wrapper/switch/display/types.h b/src/libnx/wrapper/switch/display/types.h new file mode 100644 index 0000000..c067d3c --- /dev/null +++ b/src/libnx/wrapper/switch/display/types.h @@ -0,0 +1,147 @@ +/** + * @file display/types.h + * @brief Definitions for Android-related types and enumerations. + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +// From Android PixelFormat.h & graphics-base-v1.0.h. +enum { + PIXEL_FORMAT_RGBA_8888 = 1U, + PIXEL_FORMAT_RGBX_8888 = 2U, + PIXEL_FORMAT_RGB_888 = 3U, + PIXEL_FORMAT_RGB_565 = 4U, + PIXEL_FORMAT_BGRA_8888 = 5U, + PIXEL_FORMAT_RGBA_5551 = 6U, + PIXEL_FORMAT_RGBA_4444 = 7U, + PIXEL_FORMAT_YCRCB_420_SP = 17U, + PIXEL_FORMAT_RAW16 = 32U, + PIXEL_FORMAT_BLOB = 33U, + PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 34U, + PIXEL_FORMAT_YCBCR_420_888 = 35U, + PIXEL_FORMAT_Y8 = 0x20203859U, + PIXEL_FORMAT_Y16 = 0x20363159U, + PIXEL_FORMAT_YV12 = 0x32315659U, +}; + +// From Android gralloc.h. +enum { + /* buffer is never read in software */ + GRALLOC_USAGE_SW_READ_NEVER = 0x00000000U, + /* buffer is rarely read in software */ + GRALLOC_USAGE_SW_READ_RARELY = 0x00000002U, + /* buffer is often read in software */ + GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003U, + /* mask for the software read values */ + GRALLOC_USAGE_SW_READ_MASK = 0x0000000FU, + /* buffer is never written in software */ + GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000U, + /* buffer is rarely written in software */ + GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020U, + /* buffer is often written in software */ + GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030U, + /* mask for the software write values */ + GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0U, + /* buffer will be used as an OpenGL ES texture */ + GRALLOC_USAGE_HW_TEXTURE = 0x00000100U, + /* buffer will be used as an OpenGL ES render target */ + GRALLOC_USAGE_HW_RENDER = 0x00000200U, + /* buffer will be used by the 2D hardware blitter */ + GRALLOC_USAGE_HW_2D = 0x00000400U, + /* buffer will be used by the HWComposer HAL module */ + GRALLOC_USAGE_HW_COMPOSER = 0x00000800U, + /* buffer will be used with the framebuffer device */ + GRALLOC_USAGE_HW_FB = 0x00001000U, + /* buffer should be displayed full-screen on an external display when + * possible */ + GRALLOC_USAGE_EXTERNAL_DISP = 0x00002000U, + /* Must have a hardware-protected path to external display sink for + * this buffer. If a hardware-protected path is not available, then + * either don't composite only this buffer (preferred) to the + * external sink, or (less desirable) do not route the entire + * composition to the external sink. */ + GRALLOC_USAGE_PROTECTED = 0x00004000U, + /* buffer may be used as a cursor */ + GRALLOC_USAGE_CURSOR = 0x00008000U, + /* buffer will be used with the HW video encoder */ + GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000U, + /* buffer will be written by the HW camera pipeline */ + GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000U, + /* buffer will be read by the HW camera pipeline */ + GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000U, + /* buffer will be used as part of zero-shutter-lag queue */ + GRALLOC_USAGE_HW_CAMERA_ZSL = 0x00060000U, + /* mask for the camera access values */ + GRALLOC_USAGE_HW_CAMERA_MASK = 0x00060000U, + /* mask for the software usage bit-mask */ + GRALLOC_USAGE_HW_MASK = 0x00071F00U, + /* buffer will be used as a RenderScript Allocation */ + GRALLOC_USAGE_RENDERSCRIPT = 0x00100000U, +}; + +// From Android window.h. +/* attributes queriable with query() */ +enum { + NATIVE_WINDOW_WIDTH = 0, + NATIVE_WINDOW_HEIGHT = 1, + NATIVE_WINDOW_FORMAT = 2, +//... +// NATIVE_WINDOW_DEFAULT_WIDTH = 6, //These two return invalid data. +// NATIVE_WINDOW_DEFAULT_HEIGHT = 7, +}; + +// From Android window.h. +/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ +enum { + //... + /* Buffers will be queued after being filled using the CPU + */ + NATIVE_WINDOW_API_CPU = 2, + //... +}; + +// From Android hardware.h. + +/** + * Transformation definitions + * + * IMPORTANT NOTE: + * HAL_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER HAL_TRANSFORM_FLIP_{H|V}. + * + */ + +enum { + /* flip source image horizontally (around the vertical axis) */ + HAL_TRANSFORM_FLIP_H = 0x01, + /* flip source image vertically (around the horizontal axis)*/ + HAL_TRANSFORM_FLIP_V = 0x02, + /* rotate source image 90 degrees clockwise */ + HAL_TRANSFORM_ROT_90 = 0x04, + /* rotate source image 180 degrees */ + HAL_TRANSFORM_ROT_180 = 0x03, + /* rotate source image 270 degrees clockwise */ + HAL_TRANSFORM_ROT_270 = 0x07, +}; + +// From Android window.h. +/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ +enum { + /* flip source image horizontally */ + NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H, + /* flip source image vertically */ + NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, + /* rotate source image 90 degrees clock-wise */ + NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, + /* rotate source image 180 degrees */ + NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, + /* rotate source image 270 degrees clock-wise */ + NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, +}; + +// From Android native_handle.h. +typedef struct { + int version; + int num_fds; + int num_ints; +} NativeHandle; diff --git a/src/libnx/wrapper/switch/display/types.nim b/src/libnx/wrapper/switch/display/types.nim new file mode 100644 index 0000000..2186e4f --- /dev/null +++ b/src/libnx/wrapper/switch/display/types.nim @@ -0,0 +1,109 @@ +## * +## @file display/types.h +## @brief Definitions for Android-related types and enumerations. +## @copyright libnx Authors +## + +## From Android PixelFormat.h & graphics-base-v1.0.h. + +const + PIXEL_FORMAT_RGBA_8888* = 1'u + PIXEL_FORMAT_RGBX_8888* = 2'u + PIXEL_FORMAT_RGB_888* = 3'u + PIXEL_FORMAT_RGB_565* = 4'u + PIXEL_FORMAT_BGRA_8888* = 5'u + PIXEL_FORMAT_RGBA_5551* = 6'u + PIXEL_FORMAT_RGBA_4444* = 7'u + PIXEL_FORMAT_YCRCB_420_SP* = 17'u + PIXEL_FORMAT_RAW16* = 32'u + PIXEL_FORMAT_BLOB* = 33'u + PIXEL_FORMAT_IMPLEMENTATION_DEFINED* = 34'u + PIXEL_FORMAT_YCBCR_420_888* = 35'u + PIXEL_FORMAT_Y8* = 0x20203859 + PIXEL_FORMAT_Y16* = 0x20363159 + PIXEL_FORMAT_YV12* = 0x32315659 + +## From Android gralloc.h. + +const ## buffer is never read in software + GRALLOC_USAGE_SW_READ_NEVER* = 0x00000000 ## buffer is rarely read in software + GRALLOC_USAGE_SW_READ_RARELY* = 0x00000002 ## buffer is often read in software + GRALLOC_USAGE_SW_READ_OFTEN* = 0x00000003 ## mask for the software read values + GRALLOC_USAGE_SW_READ_MASK* = 0x0000000F ## buffer is never written in software + GRALLOC_USAGE_SW_WRITE_NEVER* = 0x00000000 ## buffer is rarely written in software + GRALLOC_USAGE_SW_WRITE_RARELY* = 0x00000020 ## buffer is often written in software + GRALLOC_USAGE_SW_WRITE_OFTEN* = 0x00000030 ## mask for the software write values + GRALLOC_USAGE_SW_WRITE_MASK* = 0x000000F0 ## buffer will be used as an OpenGL ES texture + GRALLOC_USAGE_HW_TEXTURE* = 0x00000100 ## buffer will be used as an OpenGL ES render target + GRALLOC_USAGE_HW_RENDER* = 0x00000200 ## buffer will be used by the 2D hardware blitter + GRALLOC_USAGE_HW_2D* = 0x00000400 ## buffer will be used by the HWComposer HAL module + GRALLOC_USAGE_HW_COMPOSER* = 0x00000800 ## buffer will be used with the framebuffer device + GRALLOC_USAGE_HW_FB* = 0x00001000 ## buffer should be displayed full-screen on an external display when + ## possible + GRALLOC_USAGE_EXTERNAL_DISP* = 0x00002000 ## Must have a hardware-protected path to external display sink for + ## this buffer. If a hardware-protected path is not available, then + ## either don't composite only this buffer (preferred) to the + ## external sink, or (less desirable) do not route the entire + ## composition to the external sink. + GRALLOC_USAGE_PROTECTED* = 0x00004000 ## buffer may be used as a cursor + GRALLOC_USAGE_CURSOR* = 0x00008000 ## buffer will be used with the HW video encoder + GRALLOC_USAGE_HW_VIDEO_ENCODER* = 0x00010000 ## buffer will be written by the HW camera pipeline + GRALLOC_USAGE_HW_CAMERA_WRITE* = 0x00020000 ## buffer will be read by the HW camera pipeline + GRALLOC_USAGE_HW_CAMERA_READ* = 0x00040000 ## buffer will be used as part of zero-shutter-lag queue + GRALLOC_USAGE_HW_CAMERA_ZSL* = 0x00060000 ## mask for the camera access values + GRALLOC_USAGE_HW_CAMERA_MASK* = 0x00060000 ## mask for the software usage bit-mask + GRALLOC_USAGE_HW_MASK* = 0x00071F00 ## buffer will be used as a RenderScript Allocation + GRALLOC_USAGE_RENDERSCRIPT* = 0x00100000 + +## From Android window.h. +## attributes queriable with query() + +const + NATIVE_WINDOW_WIDTH* = 0 + NATIVE_WINDOW_HEIGHT* = 1 + NATIVE_WINDOW_FORMAT* = 2 ## ... + ## NATIVE_WINDOW_DEFAULT_WIDTH = 6, //These two return invalid data. + ## NATIVE_WINDOW_DEFAULT_HEIGHT = 7, + +## From Android window.h. +## parameter for NATIVE_WINDOW_[API_][DIS]CONNECT + +const ## ... + ## Buffers will be queued after being filled using the CPU + ## + NATIVE_WINDOW_API_CPU* = 2 ## ... + +## From Android hardware.h. +## * +## Transformation definitions +## +## IMPORTANT NOTE: +## HAL_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER HAL_TRANSFORM_FLIP_{H|V}. +## +## + +const ## flip source image horizontally (around the vertical axis) + HAL_TRANSFORM_FLIP_H* = 0x01 ## flip source image vertically (around the horizontal axis) + HAL_TRANSFORM_FLIP_V* = 0x02 ## rotate source image 90 degrees clockwise + HAL_TRANSFORM_ROT_90* = 0x04 ## rotate source image 180 degrees + HAL_TRANSFORM_ROT_180* = 0x03 ## rotate source image 270 degrees clockwise + HAL_TRANSFORM_ROT_270* = 0x07 + +## From Android window.h. +## parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM + +const ## flip source image horizontally + NATIVE_WINDOW_TRANSFORM_FLIP_H* = HAL_TRANSFORM_FLIP_H ## flip source image vertically + NATIVE_WINDOW_TRANSFORM_FLIP_V* = HAL_TRANSFORM_FLIP_V ## rotate source image 90 degrees clock-wise + NATIVE_WINDOW_TRANSFORM_ROT_90* = HAL_TRANSFORM_ROT_90 ## rotate source image 180 degrees + NATIVE_WINDOW_TRANSFORM_ROT_180* = HAL_TRANSFORM_ROT_180 ## rotate source image 270 degrees clock-wise + NATIVE_WINDOW_TRANSFORM_ROT_270* = HAL_TRANSFORM_ROT_270 + +## From Android native_handle.h. + +type + NativeHandle* {.bycopy.} = object + version*: cint + numFds*: cint + numInts*: cint + diff --git a/src/libnx/wrapper/switch/integer128.nim b/src/libnx/wrapper/switch/integer128.nim new file mode 100644 index 0000000..67c4b7f --- /dev/null +++ b/src/libnx/wrapper/switch/integer128.nim @@ -0,0 +1,379 @@ +import strutils +# Capacity of 42 because it seems +# reasonable that the number will fit. +# If it doesn't, nim will just allocate +# more memory for us anyway +const STRING_CAPACITY = 42 + +type + s128* {.importc: "__int128_t".} = object + high: int64 + low: uint64 + + u128* {.importc: "__uint128_t".} = object + high, low: uint64 + + helperInt128 = object + hi: int64 + lo: uint64 + + helperUInt128 = object + hi: uint64 + lo: uint64 + +proc toHelper(val: s128): helperInt128 = + (cast[ptr helperInt128](unsafeAddr val))[] + +proc lo*(val: s128): uint64 = + val.toHelper().lo + +proc hi*(val: s128): int64 = + val.toHelper().hi + +proc toInt128(val: helperInt128): s128 = + (cast[ptr s128](unsafeAddr val))[] + +proc toHelper(val: u128): helperUInt128 = + (cast[ptr helperUInt128](unsafeAddr val))[] + +proc lo*(val: u128): uint64 = + val.toHelper().lo + +proc hi*(val: u128): uint64 = + val.toHelper().hi + +proc toUInt128(val: helperUInt128): u128 = + (cast[ptr u128](unsafeAddr val))[] + +proc newInt128*(hi: int64, lo: uint64): s128 = + let r = helperInt128(hi: hi, lo: lo) + return r.toInt128() + +proc newUInt128*(hi: uint64, lo: uint64): u128 = + let r = helperUInt128(hi: hi, lo: lo) + return r.toUInt128() + +proc toUInt128(val: s128): u128 = + newUInt128(val.hi.uint64, val.lo) + +converter intToInt128*(val: int): s128 = + newInt128(0, val.uint64) + +converter intToUInt128*(val: int): u128 = + newUInt128(0, val.uint64) + +proc `<`*(val1: u128, val2: u128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if (lhs.hi < rhs.hi): + return true + if (rhs.hi < lhs.hi): + return false + if (lhs.lo < rhs.lo): + return true + return false + +proc `<`*(val1: s128, val2: s128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if (lhs.hi < rhs.hi): + return true + if (rhs.hi < lhs.hi): + return false + if (lhs.lo < rhs.lo): + return true + return false + +proc `>=`*(val1: s128, val2: s128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if lhs.hi == rhs.hi and lhs.lo == rhs.lo: + return true + + if lhs.hi > rhs.hi: + return true + if rhs.hi > lhs.hi: + return false + + if lhs.lo > rhs.lo: + return true + return false + +proc `>=`*(val1: u128, val2: u128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if lhs.hi == rhs.hi and lhs.lo == rhs.lo: + return true + + if lhs.hi > rhs.hi: + return true + if rhs.hi > lhs.hi: + return false + + if lhs.lo > rhs.lo: + return true + return false + +proc `>`*(val1: s128, val2: s128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if (lhs.hi < rhs.hi): + return true + if (rhs.hi < lhs.hi): + return false + if (lhs.lo < rhs.lo): + return true + return false + +proc `>`*(val1: u128, val2: u128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if (lhs.hi < rhs.hi): + return true + if (rhs.hi < lhs.hi): + return false + if (lhs.lo < rhs.lo): + return true + return false + +proc `<=`*(val1: s128, val2: s128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if lhs.hi == rhs.hi and lhs.lo == rhs.lo: + return true + + if lhs.hi < rhs.hi: + return true + if rhs.hi < lhs.hi: + return false + if lhs.lo < rhs.lo: + return true + return false + +proc `<=`*(val1: u128, val2: u128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + if lhs.hi == rhs.hi and lhs.lo == rhs.lo: + return true + + if lhs.hi < rhs.hi: + return true + if rhs.hi < lhs.hi: + return false + if lhs.lo < rhs.lo: + return true + return false + +proc `!=`*(val1: s128, val2: s128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + return (lhs.hi != rhs.hi) or (lhs.lo != rhs.lo) + +proc `!=`*(val1: u128, val2: u128): bool = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + return (lhs.hi != rhs.hi) or (lhs.lo != rhs.lo) + +proc `==`*(val1: s128, val2: s128): bool = + let lhs = val1.tohelper() + let rhs = val2.tohelper() + if lhs.hi != rhs.hi: + return false + if lhs.lo != rhs.lo: + return false + return true + +proc `==`*(val1: u128, val2: u128): bool = + let lhs = val1.tohelper() + let rhs = val2.tohelper() + if lhs.hi != rhs.hi: + return false + if lhs.lo != rhs.lo: + return false + return true + +proc `+`*(val1, val2: s128): s128 = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + var res = result.toHelper() + + res.hi = lhs.hi + rhs.hi + + res.lo = lhs.lo + rhs.lo + if res.lo < rhs.lo: + res.hi.inc() + result = res.toInt128() + +proc `+`*(val1, val2: u128): u128 = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + var res = result.toHelper() + + res.hi = lhs.hi + rhs.hi + + res.lo = lhs.lo + rhs.lo + if res.lo < rhs.lo: + res.hi.inc() + result = res.toUInt128() + +proc `-`*(val: s128): s128 = + var res = val.toHelper() + res.hi = not res.hi + res.lo = not res.lo + res.lo += 1 + if res.lo == 0: + res.hi += 1 + + result = res.toInt128() + +proc `-`*(val: u128): s128 = + var res = newInt128(val.hi.int64, val.lo).toHelper() + + res.hi = not res.hi + res.lo = not res.lo + res.lo += 1 + if res.lo == 0: + res.hi += 1 + + result = res.toInt128() + +proc `-`*(val1, val2: s128): s128 = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + var res = result.toHelper() + + res.hi = lhs.hi - rhs.hi + res.lo = lhs.lo - rhs.lo + if res.lo > lhs.lo: + res.hi.dec() + + result = res.toInt128() + +proc `-`*(val1, val2: u128): s128 = + let lhs = val1.toHelper() + let rhs = val2.toHelper() + + var res = result.toHelper() + + res.hi = (lhs.hi - rhs.hi).int64 + res.lo = lhs.lo - rhs.lo + if res.lo > lhs.lo: + res.hi.dec() + + result = res.toInt128() + +proc `$`*(val: s128): string = + var v = val + + if v == 0: + return "0" + + var str = newStringOfCap(STRING_CAPACITY) + + var + p10 = 1.s128 + temp: s128 + num_digits = 0 + going = 1 + digit = 0 + + if v < 0: + str.add('-') + v = -v + + while (p10 <= v and going > 0): + p10 = p10 + p10 + if p10 < 0: + going = 0 + temp = p10 + p10 = p10 + p10 + if p10 < 0: + going = 0 + p10 = p10 + p10 + if p10 < 0: + going = 0 + p10 = p10 + temp + if p10 < 0: + going = 0 + num_digits.inc + + while num_digits > 0: + num_digits -= 1 + p10 = 1 + for i in 0..= p10): + v = v - p10 + digit.inc + str.add(char(48 + digit)) + + result = str + +proc toHex*(val: u128): string = + result = val.hi.toHex & val.lo.toHex + +proc `$`*(val: u128): string = + var v = val + + if v == 0: + return "0" + + var str = newStringOfCap(STRING_CAPACITY) + + var + p10 = 1.u128 + temp: u128 + num_digits = 0 + going = 1 + digit = 0 + + while (p10 <= v and going > 0): + p10 = p10 + p10 + if p10 < 0: + going = 0 + temp = p10 + p10 = p10 + p10 + if p10 < 0: + going = 0 + p10 = p10 + p10 + if p10 < 0: + going = 0 + p10 = p10 + temp + if p10 < 0: + going = 0 + num_digits.inc + + while num_digits > 0: + num_digits -= 1 + p10 = 1 + for i in 0..= p10): + v = (v - p10).toUInt128() + digit.inc + str.add(char(48 + digit)) + + result = str diff --git a/src/libnx/wrapper/switch/kernel/barrier.h b/src/libnx/wrapper/switch/kernel/barrier.h new file mode 100644 index 0000000..b5f3acd --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/barrier.h @@ -0,0 +1,30 @@ +/** + * @file barrier.h + * @brief Multi-threading Barrier + * @author tatehaga + * @copyright libnx Authors + */ +#pragma once +#include "mutex.h" +#include "condvar.h" + +/// Barrier structure. +typedef struct Barrier { + u64 count; ///< Number of threads to reach the barrier. + u64 total; ///< Number of threads to wait on. + Mutex mutex; + CondVar condvar; +} Barrier; + +/** + * @brief Initializes a barrier and the number of threads to wait on. + * @param b Barrier object. + * @param thread_count Initial value for the number of threads the barrier must wait for. + */ +void barrierInit(Barrier *b, u64 thread_count); + +/** + * @brief Forces threads to wait until all threads have called barrierWait. + * @param b Barrier object. + */ +void barrierWait(Barrier *b); diff --git a/src/libnx/wrapper/switch/kernel/barrier.nim b/src/libnx/wrapper/switch/kernel/barrier.nim new file mode 100644 index 0000000..224afde --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/barrier.nim @@ -0,0 +1,34 @@ +## * +## @file barrier.h +## @brief Multi-threading Barrier +## @author tatehaga +## @copyright libnx Authors +## + +import + mutex, condvar +import ../types + +## / Barrier structure. + +type + Barrier* {.bycopy.} = object + count*: U64 ## /< Number of threads to reach the barrier. + total*: U64 ## /< Number of threads to wait on. + mutex*: Mutex + condvar*: CondVar + + +## * +## @brief Initializes a barrier and the number of threads to wait on. +## @param b Barrier object. +## @param thread_count Initial value for the number of threads the barrier must wait for. +## + +proc barrierInit*(b: ptr Barrier; threadCount: U64) {.cdecl, importc: "barrierInit".} +## * +## @brief Forces threads to wait until all threads have called barrierWait. +## @param b Barrier object. +## + +proc barrierWait*(b: ptr Barrier) {.cdecl, importc: "barrierWait".} diff --git a/src/libnx/wrapper/switch/kernel/condvar.h b/src/libnx/wrapper/switch/kernel/condvar.h new file mode 100644 index 0000000..563a662 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/condvar.h @@ -0,0 +1,76 @@ +/** + * @file condvar.h + * @brief Condition variable synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/svc.h" +#include "../kernel/mutex.h" + +/// Condition variable. +typedef u32 CondVar; + +/** + * @brief Initializes a condition variable. + * @param[in] c Condition variable object. + */ +static inline void condvarInit(CondVar* c) +{ + *c = 0; +} + +/** + * @brief Waits on a condition variable with a timeout. + * @param[in] c Condition variable object. + * @param[in] m Mutex object to use inside the condition variable. + * @param[in] timeout Timeout in nanoseconds. + * @return Result code (0xEA01 on timeout). + * @remark On function return, the underlying mutex is acquired. + */ +Result condvarWaitTimeout(CondVar* c, Mutex* m, u64 timeout); + +/** + * @brief Waits on a condition variable. + * @param[in] c Condition variable object. + * @param[in] m Mutex object to use inside the condition variable. + * @return Result code. + * @remark On function return, the underlying mutex is acquired. + */ +static inline Result condvarWait(CondVar* c, Mutex* m) +{ + return condvarWaitTimeout(c, m, UINT64_MAX); +} + +/** + * @brief Wakes up up to the specified number of threads waiting on a condition variable. + * @param[in] c Condition variable object. + * @param[in] num Maximum number of threads to wake up (or -1 to wake them all up). + * @return Result code. + */ +static inline Result condvarWake(CondVar* c, int num) +{ + svcSignalProcessWideKey(c, num); + return 0; +} + +/** + * @brief Wakes up a single thread waiting on a condition variable. + * @param[in] c Condition variable object. + * @return Result code. + */ +static inline Result condvarWakeOne(CondVar* c) +{ + return condvarWake(c, 1); +} + +/** + * @brief Wakes up all thread waiting on a condition variable. + * @param[in] c Condition variable object. + * @return Result code. + */ +static inline Result condvarWakeAll(CondVar* c) +{ + return condvarWake(c, -1); +} diff --git a/src/libnx/wrapper/switch/kernel/condvar.nim b/src/libnx/wrapper/switch/kernel/condvar.nim new file mode 100644 index 0000000..1a62c1c --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/condvar.nim @@ -0,0 +1,73 @@ +## * +## @file condvar.h +## @brief Condition variable synchronization primitive. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../kernel/svc, ../kernel/mutex + +## / Condition variable. + +type + CondVar* = U32 + +## * +## @brief Initializes a condition variable. +## @param[in] c Condition variable object. +## + +proc condvarInit*(c: ptr CondVar) {.inline, cdecl.} = + c[] = 0 + +## * +## @brief Waits on a condition variable with a timeout. +## @param[in] c Condition variable object. +## @param[in] m Mutex object to use inside the condition variable. +## @param[in] timeout Timeout in nanoseconds. +## @return Result code (0xEA01 on timeout). +## @remark On function return, the underlying mutex is acquired. +## + +proc condvarWaitTimeout*(c: ptr CondVar; m: ptr Mutex; timeout: U64): Result {.cdecl, + importc: "condvarWaitTimeout".} +## * +## @brief Waits on a condition variable. +## @param[in] c Condition variable object. +## @param[in] m Mutex object to use inside the condition variable. +## @return Result code. +## @remark On function return, the underlying mutex is acquired. +## + +proc condvarWait*(c: ptr CondVar; m: ptr Mutex): Result {.inline, cdecl.} = + return condvarWaitTimeout(c, m, uint64.high) + +## * +## @brief Wakes up up to the specified number of threads waiting on a condition variable. +## @param[in] c Condition variable object. +## @param[in] num Maximum number of threads to wake up (or -1 to wake them all up). +## @return Result code. +## + +proc condvarWake*(c: ptr CondVar; num: cint): Result {.inline, cdecl.} = + svcSignalProcessWideKey(c, num) + return 0 + +## * +## @brief Wakes up a single thread waiting on a condition variable. +## @param[in] c Condition variable object. +## @return Result code. +## + +proc condvarWakeOne*(c: ptr CondVar): Result {.inline, cdecl.} = + return condvarWake(c, 1) + +## * +## @brief Wakes up all thread waiting on a condition variable. +## @param[in] c Condition variable object. +## @return Result code. +## + +proc condvarWakeAll*(c: ptr CondVar): Result {.inline, cdecl.} = + return condvarWake(c, -1) diff --git a/src/libnx/wrapper/switch/kernel/detect.h b/src/libnx/wrapper/switch/kernel/detect.h new file mode 100644 index 0000000..3fef659 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/detect.h @@ -0,0 +1,24 @@ +/** + * @file detect.h + * @brief Kernel capability detection + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../result.h" +#include "svc.h" + +/// Returns true if the process has a debugger attached. +NX_INLINE bool detectDebugger(void) { + u64 tmp = 0; + Result rc = svcGetInfo(&tmp, InfoType_DebuggerAttached, INVALID_HANDLE, 0); + return R_SUCCEEDED(rc) && tmp != 0; +} + +/// Returns true if the underlying kernel is Mesosphère. +NX_INLINE bool detectMesosphere(void) { + u64 dummy = 0; + Result rc = svcGetInfo(&dummy, 65000, INVALID_HANDLE, 0); // InfoType_MesosphereMeta + return R_SUCCEEDED(rc); +} diff --git a/src/libnx/wrapper/switch/kernel/detect.nim b/src/libnx/wrapper/switch/kernel/detect.nim new file mode 100644 index 0000000..da5b387 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/detect.nim @@ -0,0 +1,24 @@ +## * +## @file detect.h +## @brief Kernel capability detection +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../result, svc + +## / Returns true if the process has a debugger attached. + +proc detectDebugger*(): bool {.inline, cdecl.} = + var tmp: U64 = 0 + var rc: Result = svcGetInfo(addr(tmp), InfoTypeDebuggerAttached.uint32, Invalid_Handle, 0) + return r_Succeeded(rc) and tmp != 0 + +## / Returns true if the underlying kernel is Mesosphère. + +proc detectMesosphere*(): bool {.inline, cdecl.} = + var dummy: U64 = 0 + var rc: Result = svcGetInfo(addr(dummy), 65000, Invalid_Handle, 0) + ## InfoType_MesosphereMeta + return r_Succeeded(rc) diff --git a/src/libnx/wrapper/switch/kernel/event.h b/src/libnx/wrapper/switch/kernel/event.h new file mode 100644 index 0000000..99c6264 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/event.h @@ -0,0 +1,84 @@ +/** + * @file event.h + * @brief Kernel-mode event synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../result.h" +#include "wait.h" + +/// Kernel-mode event structure. +typedef struct { + Handle revent; ///< Read-only event handle + Handle wevent; ///< Write-only event handle + bool autoclear; ///< Autoclear flag +} Event; + +/// Creates a \ref Waiter for a kernel-mode event. +static inline Waiter waiterForEvent(Event* t) +{ + Waiter wait_obj; + wait_obj.type = t->autoclear ? WaiterType_HandleWithClear : WaiterType_Handle; + wait_obj.handle = t->revent; + return wait_obj; +} + +/** + * @brief Creates a kernel-mode event. + * @param[out] t Pointer to \ref Event structure. + * @param[in] autoclear Autoclear flag. + * @return Result code. + * @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. + */ +Result eventCreate(Event* t, bool autoclear); + +/** + * @brief Loads a kernel-mode event obtained from IPC. + * @param[out] t Pointer to \ref Event structure. + * @param[in] handle Read-only event handle. + * @param[in] autoclear Autoclear flag. + */ +void eventLoadRemote(Event* t, Handle handle, bool autoclear); + +/** + * @brief Closes a kernel-mode event. + * @param[in] t Pointer to \ref Event structure. + */ +void eventClose(Event* t); + +/** + * @brief Returns whether an \ref Event is initialized. + * @param[in] t Pointer to \ref Event structure. + * @return Initialization status. + */ +static inline bool eventActive(Event* t) +{ + return t->revent != INVALID_HANDLE; +} + +/** + * @brief Waits on a kernel-mode event. + * @param[in] t Pointer to \ref Event structure. + * @param[in] timeout Timeout in nanoseconds (pass UINT64_MAX to wait indefinitely). + * @return Result code. + */ +Result eventWait(Event* t, u64 timeout); + +/** + * @brief Signals a kernel-mode event. + * @param[in] t Pointer to \ref Event structure. + * @return Result code. + * @note This function only works for events initialized with \ref eventCreate, it doesn't work with events initialized with \ref eventLoadRemote. + * @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. + */ +Result eventFire(Event* t); + +/** + * @brief Clears a kernel-mode event. + * @param[in] t Pointer to \ref Event structure. + * @return Result code. + * @note This function shouldn't be used on autoclear events. + */ +Result eventClear(Event* t); diff --git a/src/libnx/wrapper/switch/kernel/event.nim b/src/libnx/wrapper/switch/kernel/event.nim new file mode 100644 index 0000000..cb565e4 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/event.nim @@ -0,0 +1,82 @@ +## * +## @file event.h +## @brief Kernel-mode event synchronization primitive. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../result, wait + +## / Kernel-mode event structure. + +type + Event* {.bycopy.} = object + revent*: Handle ## /< Read-only event handle + wevent*: Handle ## /< Write-only event handle + autoclear*: bool ## /< Autoclear flag + +proc waiterForEvent*(t: ptr Event): Waiter {.inline, cdecl.} = + ## / Creates a \ref Waiter for a kernel-mode event. + var waitObj: Waiter + waitObj.`type` = if t.autoclear: WaiterTypeHandleWithClear else: WaiterTypeHandle + waitObj.anoWait3.handle = t.revent + return waitObj + +proc eventCreate*(t: ptr Event; autoclear: bool): Result {.cdecl, importc: "eventCreate".} +## * +## @brief Creates a kernel-mode event. +## @param[out] t Pointer to \ref Event structure. +## @param[in] autoclear Autoclear flag. +## @return Result code. +## @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. +## + +proc eventLoadRemote*(t: ptr Event; handle: Handle; autoclear: bool) {.cdecl, + importc: "eventLoadRemote".} +## * +## @brief Loads a kernel-mode event obtained from IPC. +## @param[out] t Pointer to \ref Event structure. +## @param[in] handle Read-only event handle. +## @param[in] autoclear Autoclear flag. +## + +proc eventClose*(t: ptr Event) {.cdecl, importc: "eventClose".} +## * +## @brief Closes a kernel-mode event. +## @param[in] t Pointer to \ref Event structure. +## + +proc eventActive*(t: ptr Event): bool {.inline, cdecl.} = + ## * + ## @brief Returns whether an \ref Event is initialized. + ## @param[in] t Pointer to \ref Event structure. + ## @return Initialization status. + ## + return t.revent != Invalid_Handle + +proc eventWait*(t: ptr Event; timeout: U64): Result {.cdecl, importc: "eventWait".} +## * +## @brief Waits on a kernel-mode event. +## @param[in] t Pointer to \ref Event structure. +## @param[in] timeout Timeout in nanoseconds (pass UINT64_MAX to wait indefinitely). +## @return Result code. +## + +proc eventFire*(t: ptr Event): Result {.cdecl, importc: "eventFire".} +## * +## @brief Signals a kernel-mode event. +## @param[in] t Pointer to \ref Event structure. +## @return Result code. +## @note This function only works for events initialized with \ref eventCreate, it doesn't work with events initialized with \ref eventLoadRemote. +## @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. +## + +proc eventClear*(t: ptr Event): Result {.cdecl, importc: "eventClear".} +## * +## @brief Clears a kernel-mode event. +## @param[in] t Pointer to \ref Event structure. +## @return Result code. +## @note This function shouldn't be used on autoclear events. +## + diff --git a/src/libnx/wrapper/switch/kernel/jit.h b/src/libnx/wrapper/switch/kernel/jit.h new file mode 100644 index 0000000..b144f55 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/jit.h @@ -0,0 +1,76 @@ +/** + * @file jit.h + * @brief Just-in-time compilation support. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "virtmem.h" + +/// JIT implementation type. +typedef enum { + JitType_SetProcessMemoryPermission, ///< JIT supported using svcSetProcessMemoryPermission + JitType_CodeMemory, ///< JIT supported using [4.0.0+] CodeMemory syscalls +} JitType; + +/// JIT buffer object. +typedef struct { + JitType type; + size_t size; + void* src_addr; + void* rx_addr; + void* rw_addr; + bool is_executable; + union { + Handle handle; + VirtmemReservation* rv; + }; +} Jit; + +/** + * @brief Creates a JIT buffer. + * @param j JIT buffer. + * @param size Size of the JIT buffer. + * @return Result code. + */ +Result jitCreate(Jit* j, size_t size); + +/** + * @brief Transition a JIT buffer to have writable permission. + * @param j JIT buffer. + * @return Result code. + */ +Result jitTransitionToWritable(Jit* j); + +/** + * @brief Transition a JIT buffer to have executable permission. + * @param j JIT buffer. + * @return Result code. + */ +Result jitTransitionToExecutable(Jit* j); + +/** + * @brief Destroys a JIT buffer. + * @param j JIT buffer. + * @return Result code. + */ +Result jitClose(Jit* j); + +/** + * @brief Gets the address of the writable memory alias of a JIT buffer. + * @param j JIT buffer. + * @return Pointer to alias of the JIT buffer that can be written to. + */ +NX_CONSTEXPR void* jitGetRwAddr(Jit* j) { + return j->rw_addr; +} + +/** + * @brief Gets the address of the executable memory alias of a JIT buffer. + * @param j JIT buffer. + * @return Pointer to alias of the JIT buffer that can be executed. + */ +NX_CONSTEXPR void* jitGetRxAddr(Jit* j) { + return j->rx_addr; +} diff --git a/src/libnx/wrapper/switch/kernel/jit.nim b/src/libnx/wrapper/switch/kernel/jit.nim new file mode 100644 index 0000000..1b96a93 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/jit.nim @@ -0,0 +1,83 @@ +## * +## @file jit.h +## @brief Just-in-time compilation support. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, virtmem + +## / JIT implementation type. + +type + JitType* = enum + JitTypeSetProcessMemoryPermission, ## /< JIT supported using svcSetProcessMemoryPermission + JitTypeCodeMemory ## /< JIT supported using [4.0.0+] CodeMemory syscalls + + +## / JIT buffer object. + +type + INNER_C_UNION_jit_2* {.bycopy, union.} = object + handle*: Handle + rv*: ptr VirtmemReservation + + Jit* {.bycopy.} = object + `type`*: JitType + size*: csize_t + srcAddr*: pointer + rxAddr*: pointer + rwAddr*: pointer + isExecutable*: bool + anoJit3*: INNER_C_UNION_jit_2 + + +## * +## @brief Creates a JIT buffer. +## @param j JIT buffer. +## @param size Size of the JIT buffer. +## @return Result code. +## + +proc jitCreate*(j: ptr Jit; size: csize_t): Result {.cdecl, importc: "jitCreate".} +## * +## @brief Transition a JIT buffer to have writable permission. +## @param j JIT buffer. +## @return Result code. +## + +proc jitTransitionToWritable*(j: ptr Jit): Result {.cdecl, + importc: "jitTransitionToWritable".} +## * +## @brief Transition a JIT buffer to have executable permission. +## @param j JIT buffer. +## @return Result code. +## + +proc jitTransitionToExecutable*(j: ptr Jit): Result {.cdecl, + importc: "jitTransitionToExecutable".} +## * +## @brief Destroys a JIT buffer. +## @param j JIT buffer. +## @return Result code. +## + +proc jitClose*(j: ptr Jit): Result {.cdecl, importc: "jitClose".} +## * +## @brief Gets the address of the writable memory alias of a JIT buffer. +## @param j JIT buffer. +## @return Pointer to alias of the JIT buffer that can be written to. +## + +proc jitGetRwAddr*(j: ptr Jit): pointer {.inline, cdecl.} = + return j.rwAddr + +## * +## @brief Gets the address of the executable memory alias of a JIT buffer. +## @param j JIT buffer. +## @return Pointer to alias of the JIT buffer that can be executed. +## + +proc jitGetRxAddr*(j: ptr Jit): pointer {.inline, cdecl.} = + return j.rxAddr diff --git a/src/libnx/wrapper/switch/kernel/levent.h b/src/libnx/wrapper/switch/kernel/levent.h new file mode 100644 index 0000000..d83af2c --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/levent.h @@ -0,0 +1,54 @@ +/** + * @file levent.h + * @brief Light event synchronization primitive [4.0.0+] + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../result.h" +#include "svc.h" + +/// User-mode light event structure. +typedef struct LEvent { + u32 counter; + bool autoclear; +} LEvent; + +/** + * @brief Initializes a user-mode light event. + * @param[out] le Pointer to \ref LEvent structure. + * @param[in] signaled Whether the event starts off in signaled state. + * @param[in] autoclear Autoclear flag. + */ +NX_CONSTEXPR void leventInit(LEvent* le, bool signaled, bool autoclear) { + le->counter = signaled ? 2 : 0; + le->autoclear = autoclear; +} + +/** + * @brief Waits on a user-mode light event. + * @param[in] le Pointer to \ref LEvent structure. + * @param[in] timeout_ns Timeout in nanoseconds (pass UINT64_MAX to wait indefinitely). + * @return true if wait succeeded, false if wait timed out. + */ +bool leventWait(LEvent* le, u64 timeout_ns); + +/** + * @brief Polls a user-mode light event. + * @param[in] le Pointer to \ref LEvent structure. + * @return true if event is signaled, false otherwise. + */ +bool leventTryWait(LEvent* le); + +/** + * @brief Signals a user-mode light event. + * @param[in] le Pointer to \ref LEvent structure. + */ +void leventSignal(LEvent* le); + +/** + * @brief Clears a user-mode light event. + * @param[in] le Pointer to \ref LEvent structure. + */ +void leventClear(LEvent* le); diff --git a/src/libnx/wrapper/switch/kernel/levent.nim b/src/libnx/wrapper/switch/kernel/levent.nim new file mode 100644 index 0000000..23caac2 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/levent.nim @@ -0,0 +1,55 @@ +## * +## @file levent.h +## @brief Light event synchronization primitive [4.0.0+] +## @author fincs +## @copyright libnx Authors +## + +import + ../types, ../result + +## / User-mode light event structure. + +type + LEvent* {.bycopy.} = object + counter*: U32 + autoclear*: bool + +proc leventInit*(le: ptr LEvent; signaled: bool; autoclear: bool) {.inline, cdecl.} = + ## * + ## @brief Initializes a user-mode light event. + ## @param[out] le Pointer to \ref LEvent structure. + ## @param[in] signaled Whether the event starts off in signaled state. + ## @param[in] autoclear Autoclear flag. + ## + + le.counter = if signaled: 2 else: 0 + le.autoclear = autoclear + +proc leventWait*(le: ptr LEvent; timeoutNs: U64): bool {.cdecl, importc: "leventWait".} +## * +## @brief Waits on a user-mode light event. +## @param[in] le Pointer to \ref LEvent structure. +## @param[in] timeout_ns Timeout in nanoseconds (pass UINT64_MAX to wait indefinitely). +## @return true if wait succeeded, false if wait timed out. +## + +proc leventTryWait*(le: ptr LEvent): bool {.cdecl, importc: "leventTryWait".} +## * +## @brief Polls a user-mode light event. +## @param[in] le Pointer to \ref LEvent structure. +## @return true if event is signaled, false otherwise. +## + +proc leventSignal*(le: ptr LEvent) {.cdecl, importc: "leventSignal".} +## * +## @brief Signals a user-mode light event. +## @param[in] le Pointer to \ref LEvent structure. +## + +proc leventClear*(le: ptr LEvent) {.cdecl, importc: "leventClear".} +## * +## @brief Clears a user-mode light event. +## @param[in] le Pointer to \ref LEvent structure. +## + diff --git a/src/libnx/wrapper/switch/kernel/mutex.h b/src/libnx/wrapper/switch/kernel/mutex.h new file mode 100644 index 0000000..99d4020 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/mutex.h @@ -0,0 +1,81 @@ +/** + * @file mutex.h + * @brief Mutex synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include +#include "../types.h" + +/// Mutex datatype, defined in newlib. +typedef _LOCK_T Mutex; +/// Recursive mutex datatype, defined in newlib. +typedef _LOCK_RECURSIVE_T RMutex; + +/** + * @brief Initializes a mutex. + * @param m Mutex object. + * @note A mutex can also be statically initialized by assigning 0 to it. + */ +static inline void mutexInit(Mutex* m) +{ + *m = INVALID_HANDLE; +} + +/** + * @brief Locks a mutex. + * @param m Mutex object. + */ +void mutexLock(Mutex* m); + +/** + * @brief Attempts to lock a mutex without waiting. + * @param m Mutex object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool mutexTryLock(Mutex* m); + +/** + * @brief Unlocks a mutex. + * @param m Mutex object. + */ +void mutexUnlock(Mutex* m); + +/** + * @brief Gets whether the current thread owns the mutex. + * @param m Mutex object. + * @return 1 if the mutex is locked by the current thread, and 0 otherwise. + */ +bool mutexIsLockedByCurrentThread(const Mutex* m); + +/** + * @brief Initializes a recursive mutex. + * @param m Recursive mutex object. + * @note A recursive mutex can also be statically initialized by assigning {0,0,0} to it. + */ +static inline void rmutexInit(RMutex* m) +{ + m->lock = 0; + m->thread_tag = 0; + m->counter = 0; +} + +/** + * @brief Locks a recursive mutex. + * @param m Recursive mutex object. + */ +void rmutexLock(RMutex* m); + +/** + * @brief Attempts to lock a recursive mutex without waiting. + * @param m Recursive mutex object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool rmutexTryLock(RMutex* m); + +/** + * @brief Unlocks a recursive mutex. + * @param m Recursive mutex object. + */ +void rmutexUnlock(RMutex* m); diff --git a/src/libnx/wrapper/switch/kernel/mutex.nim b/src/libnx/wrapper/switch/kernel/mutex.nim new file mode 100644 index 0000000..42a36df --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/mutex.nim @@ -0,0 +1,90 @@ +## * +## @file mutex.h +## @brief Mutex synchronization primitive. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types + +## / Mutex datatype, defined in newlib. + +type + Mutex* = distinct uint32 + Lock* = distinct uint32 + +## / Recursive mutex datatype, defined in newlib. + +type + RMutex* = object + lock*: Lock + threadTag*: uint32 + counter*: uint32 + +## * +## @brief Initializes a mutex. +## @param m Mutex object. +## @note A mutex can also be statically initialized by assigning 0 to it. +## + +proc mutexInit*(m: ptr Mutex) {.inline, cdecl.} = + m[] = INVALID_HANDLE.Mutex + +## * +## @brief Locks a mutex. +## @param m Mutex object. +## + +proc mutexLock*(m: ptr Mutex) {.cdecl, importc: "mutexLock".} +## * +## @brief Attempts to lock a mutex without waiting. +## @param m Mutex object. +## @return 1 if the mutex has been acquired successfully, and 0 on contention. +## + +proc mutexTryLock*(m: ptr Mutex): bool {.cdecl, importc: "mutexTryLock".} +## * +## @brief Unlocks a mutex. +## @param m Mutex object. +## + +proc mutexUnlock*(m: ptr Mutex) {.cdecl, importc: "mutexUnlock".} +## * +## @brief Gets whether the current thread owns the mutex. +## @param m Mutex object. +## @return 1 if the mutex is locked by the current thread, and 0 otherwise. +## + +proc mutexIsLockedByCurrentThread*(m: ptr Mutex): bool {.cdecl, + importc: "mutexIsLockedByCurrentThread".} +## * +## @brief Initializes a recursive mutex. +## @param m Recursive mutex object. +## @note A recursive mutex can also be statically initialized by assigning {0,0,0} to it. +## + +proc rmutexInit*(m: ptr RMutex) {.inline, cdecl.} = + m.lock = 0.Lock + m.threadTag = 0 + m.counter = 0 + +## * +## @brief Locks a recursive mutex. +## @param m Recursive mutex object. +## + +proc rmutexLock*(m: ptr RMutex) {.cdecl, importc: "rmutexLock".} +## * +## @brief Attempts to lock a recursive mutex without waiting. +## @param m Recursive mutex object. +## @return 1 if the mutex has been acquired successfully, and 0 on contention. +## + +proc rmutexTryLock*(m: ptr RMutex): bool {.cdecl, importc: "rmutexTryLock".} +## * +## @brief Unlocks a recursive mutex. +## @param m Recursive mutex object. +## + +proc rmutexUnlock*(m: ptr RMutex) {.cdecl, importc: "rmutexUnlock".} diff --git a/src/libnx/wrapper/switch/kernel/random.h b/src/libnx/wrapper/switch/kernel/random.h new file mode 100644 index 0000000..a134865 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/random.h @@ -0,0 +1,21 @@ +/** + * @file random.h + * @brief OS-seeded pseudo-random number generation support (ChaCha algorithm). + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/** + * @brief Fills a buffer with random data. + * @param buf Pointer to the buffer. + * @param len Size of the buffer in bytes. + */ +void randomGet(void* buf, size_t len); + +/** + * @brief Returns a random 64-bit value. + * @return Random value. + */ +u64 randomGet64(void); diff --git a/src/libnx/wrapper/switch/kernel/random.nim b/src/libnx/wrapper/switch/kernel/random.nim new file mode 100644 index 0000000..272d701 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/random.nim @@ -0,0 +1,23 @@ +## * +## @file random.h +## @brief OS-seeded pseudo-random number generation support (ChaCha algorithm). +## @author plutoo +## @copyright libnx Authors +## + +import + ../types + +## * +## @brief Fills a buffer with random data. +## @param buf Pointer to the buffer. +## @param len Size of the buffer in bytes. +## + +proc randomGet*(buf: pointer; len: csize_t) {.cdecl, importc: "randomGet".} +## * +## @brief Returns a random 64-bit value. +## @return Random value. +## + +proc randomGet64*(): U64 {.cdecl, importc: "randomGet64".} diff --git a/src/libnx/wrapper/switch/kernel/rwlock.h b/src/libnx/wrapper/switch/kernel/rwlock.h new file mode 100644 index 0000000..731e95c --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/rwlock.h @@ -0,0 +1,80 @@ +/** + * @file rwlock.h + * @brief Read/write lock synchronization primitive. + * @author plutoo, SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../kernel/mutex.h" +#include "../kernel/condvar.h" + +/// Read/write lock structure. +typedef struct { + Mutex mutex; + CondVar condvar_reader_wait; + CondVar condvar_writer_wait; + u32 read_lock_count; + u32 read_waiter_count; + u32 write_lock_count; + u32 write_waiter_count; + u32 write_owner_tag; +} RwLock; + +/** + * @brief Initializes the read/write lock. + * @param r Read/write lock object. + */ +void rwlockInit(RwLock* r); + +/** + * @brief Locks the read/write lock for reading. + * @param r Read/write lock object. + */ +void rwlockReadLock(RwLock* r); + +/** + * @brief Attempts to lock the read/write lock for reading without waiting. + * @param r Read/write lock object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool rwlockTryReadLock(RwLock* r); + +/** + * @brief Unlocks the read/write lock for reading. + * @param r Read/write lock object. + */ +void rwlockReadUnlock(RwLock* r); + +/** + * @brief Locks the read/write lock for writing. + * @param r Read/write lock object. + */ +void rwlockWriteLock(RwLock* r); + +/** + * @brief Attempts to lock the read/write lock for writing without waiting. + * @param r Read/write lock object. + * @return 1 if the mutex has been acquired successfully, and 0 on contention. + */ +bool rwlockTryWriteLock(RwLock* r); + +/** + * @brief Unlocks the read/write lock for writing. + * @param r Read/write lock object. + */ +void rwlockWriteUnlock(RwLock* r); + +/** + * @brief Checks if the write lock is held by the current thread. + * @param r Read/write lock object. + * @return 1 if the current hold holds the write lock, and 0 if it does not. + */ +bool rwlockIsWriteLockHeldByCurrentThread(RwLock* r); + +/** + * @brief Checks if the read/write lock is owned by the current thread. + * @param r Read/write lock object. + * @return 1 if the current hold holds the write lock or if it holds read locks acquired + * while it held the write lock, and 0 if it does not. + */ +bool rwlockIsOwnedByCurrentThread(RwLock* r); diff --git a/src/libnx/wrapper/switch/kernel/rwlock.nim b/src/libnx/wrapper/switch/kernel/rwlock.nim new file mode 100644 index 0000000..bcf9602 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/rwlock.nim @@ -0,0 +1,84 @@ +## * +## @file rwlock.h +## @brief Read/write lock synchronization primitive. +## @author plutoo, SciresM +## @copyright libnx Authors +## + +import + ../kernel/mutex, ../kernel/condvar, ../types + +## / Read/write lock structure. + +type + RwLock* {.bycopy.} = object + mutex*: Mutex + condvarReaderWait*: CondVar + condvarWriterWait*: CondVar + readLockCount*: U32 + readWaiterCount*: U32 + writeLockCount*: U32 + writeWaiterCount*: U32 + writeOwnerTag*: U32 + +proc rwlockInit*(r: ptr RwLock) {.cdecl, importc: "rwlockInit".} +## * +## @brief Initializes the read/write lock. +## @param r Read/write lock object. +## + +proc rwlockReadLock*(r: ptr RwLock) {.cdecl, importc: "rwlockReadLock".} +## * +## @brief Locks the read/write lock for reading. +## @param r Read/write lock object. +## + +proc rwlockTryReadLock*(r: ptr RwLock): bool {.cdecl, importc: "rwlockTryReadLock".} +## * +## @brief Attempts to lock the read/write lock for reading without waiting. +## @param r Read/write lock object. +## @return 1 if the mutex has been acquired successfully, and 0 on contention. +## + +proc rwlockReadUnlock*(r: ptr RwLock) {.cdecl, importc: "rwlockReadUnlock".} +## * +## @brief Unlocks the read/write lock for reading. +## @param r Read/write lock object. +## + +proc rwlockWriteLock*(r: ptr RwLock) {.cdecl, importc: "rwlockWriteLock".} +## * +## @brief Locks the read/write lock for writing. +## @param r Read/write lock object. +## + +proc rwlockTryWriteLock*(r: ptr RwLock): bool {.cdecl, importc: "rwlockTryWriteLock".} +## * +## @brief Attempts to lock the read/write lock for writing without waiting. +## @param r Read/write lock object. +## @return 1 if the mutex has been acquired successfully, and 0 on contention. +## + +proc rwlockWriteUnlock*(r: ptr RwLock) {.cdecl, importc: "rwlockWriteUnlock".} +## * +## @brief Unlocks the read/write lock for writing. +## @param r Read/write lock object. +## + +proc rwlockIsWriteLockHeldByCurrentThread*(r: ptr RwLock): bool {.cdecl, + importc: "rwlockIsWriteLockHeldByCurrentThread".} +## * +## @brief Checks if the write lock is held by the current thread. +## @param r Read/write lock object. +## @return 1 if the current hold holds the write lock, and 0 if it does not. +## + +proc rwlockIsOwnedByCurrentThread*(r: ptr RwLock): bool {.cdecl, + importc: "rwlockIsOwnedByCurrentThread".} +## * +## @brief Checks if the read/write lock is owned by the current thread. +## @param r Read/write lock object. +## @return 1 if the current hold holds the write lock or if it holds read locks acquired +## while it held the write lock, and 0 if it does not. +## + diff --git a/src/libnx/wrapper/switch/kernel/semaphore.h b/src/libnx/wrapper/switch/kernel/semaphore.h new file mode 100644 index 0000000..12f4c5b --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/semaphore.h @@ -0,0 +1,44 @@ +/** + * @file semaphore.h + * @brief Thread synchronization based on Mutex. + * @author SciresM & Kevoot + * @copyright libnx Authors + */ +#pragma once + +#include "mutex.h" +#include "condvar.h" + +/// Semaphore structure. +typedef struct Semaphore +{ + CondVar condvar; ///< Condition variable object. + Mutex mutex; ///< Mutex object. + u64 count; ///< Internal counter. +} Semaphore; + +/** + * @brief Initializes a semaphore and its internal counter. + * @param s Semaphore object. + * @param initial_count initial value for internal counter (typically the # of free resources). + */ +void semaphoreInit(Semaphore *s, u64 initial_count); + +/** + * @brief Increments the Semaphore to allow other threads to continue. + * @param s Semaphore object. + */ +void semaphoreSignal(Semaphore *s); + +/** + * @brief Decrements Semaphore and waits if 0. + * @param s Semaphore object. + */ +void semaphoreWait(Semaphore *s); + +/** + * @brief Attempts to get lock without waiting. + * @param s Semaphore object. + * @return true if no wait and successful lock, false otherwise. + */ +bool semaphoreTryWait(Semaphore *s); diff --git a/src/libnx/wrapper/switch/kernel/semaphore.nim b/src/libnx/wrapper/switch/kernel/semaphore.nim new file mode 100644 index 0000000..c6a9705 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/semaphore.nim @@ -0,0 +1,45 @@ +## * +## @file semaphore.h +## @brief Thread synchronization based on Mutex. +## @author SciresM & Kevoot +## @copyright libnx Authors +## + +import + mutex, condvar, ../types + +## / Semaphore structure. + +type + Semaphore* {.bycopy.} = object + condvar*: CondVar ## /< Condition variable object. + mutex*: Mutex ## /< Mutex object. + count*: U64 ## /< Internal counter. + +proc semaphoreInit*(s: ptr Semaphore; initialCount: U64) {.cdecl, + importc: "semaphoreInit".} +## * +## @brief Initializes a semaphore and its internal counter. +## @param s Semaphore object. +## @param initial_count initial value for internal counter (typically the # of free resources). +## + +proc semaphoreSignal*(s: ptr Semaphore) {.cdecl, importc: "semaphoreSignal".} +## * +## @brief Increments the Semaphore to allow other threads to continue. +## @param s Semaphore object. +## + +proc semaphoreWait*(s: ptr Semaphore) {.cdecl, importc: "semaphoreWait".} +## * +## @brief Decrements Semaphore and waits if 0. +## @param s Semaphore object. +## + +proc semaphoreTryWait*(s: ptr Semaphore): bool {.cdecl, importc: "semaphoreTryWait".} +## * +## @brief Attempts to get lock without waiting. +## @param s Semaphore object. +## @return true if no wait and successful lock, false otherwise. +## + diff --git a/src/libnx/wrapper/switch/kernel/shmem.h b/src/libnx/wrapper/switch/kernel/shmem.h new file mode 100644 index 0000000..b40af1b --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/shmem.h @@ -0,0 +1,67 @@ +/** + * @file shmem.h + * @brief Shared memory object handling + * @author plutoo + * @copyright libnx Authors + * @remark Shared memory differs from transfer memory in the fact that the kernel (as opposed to the user process) allocates and owns its backing memory. + */ +#pragma once +#include "../types.h" + +/// Shared memory information structure. +typedef struct { + Handle handle; ///< Kernel object handle. + size_t size; ///< Size of the shared memory object. + Permission perm; ///< Permissions. + void* map_addr; ///< Address to which the shared memory object is mapped. +} SharedMemory; + +/** + * @brief Creates a shared memory object. + * @param s Shared memory information structure which will be filled in. + * @param size Size of the shared memory object to create. + * @param local_perm Permissions with which the shared memory object will be mapped in the local process. + * @param remote_perm Permissions with which the shared memory object will be mapped in the remote process (can be Perm_DontCare). + * @return Result code. + * @warning This is a privileged operation; in normal circumstances applications cannot use this function. + */ +Result shmemCreate(SharedMemory* s, size_t size, Permission local_perm, Permission remote_perm); + +/** + * @brief Loads a shared memory object coming from a remote process. + * @param s Shared memory information structure which will be filled in. + * @param handle Handle of the shared memory object. + * @param size Size of the shared memory object that is being loaded. + * @param perm Permissions with which the shared memory object will be mapped in the local process. + */ +void shmemLoadRemote(SharedMemory* s, Handle handle, size_t size, Permission perm); + +/** + * @brief Maps a shared memory object. + * @param s Shared memory information structure. + * @return Result code. + */ +Result shmemMap(SharedMemory* s); + +/** + * @brief Unmaps a shared memory object. + * @param s Shared memory information structure. + * @return Result code. + */ +Result shmemUnmap(SharedMemory* s); + +/** + * @brief Retrieves the mapped address of a shared memory object. + * @param s Shared memory information structure. + * @return Mapped address of the shared memory object. + */ +static inline void* shmemGetAddr(SharedMemory* s) { + return s->map_addr; +} + +/** + * @brief Frees up resources used by a shared memory object, unmapping and closing handles, etc. + * @param s Shared memory information structure. + * @return Result code. + */ +Result shmemClose(SharedMemory* s); diff --git a/src/libnx/wrapper/switch/kernel/shmem.nim b/src/libnx/wrapper/switch/kernel/shmem.nim new file mode 100644 index 0000000..e6c7a56 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/shmem.nim @@ -0,0 +1,71 @@ +## * +## @file shmem.h +## @brief Shared memory object handling +## @author plutoo +## @copyright libnx Authors +## @remark Shared memory differs from transfer memory in the fact that the kernel (as opposed to the user process) allocates and owns its backing memory. +## + +import + ../types, svc + +## / Shared memory information structure. + +type + SharedMemory* {.bycopy.} = object + handle*: Handle ## /< Kernel object handle. + size*: csize_t ## /< Size of the shared memory object. + perm*: Permission ## /< Permissions. + mapAddr*: pointer ## /< Address to which the shared memory object is mapped. + +proc shmemCreate*(s: ptr SharedMemory; size: csize_t; localPerm: Permission; + remotePerm: Permission): Result {.cdecl, importc: "shmemCreate".} +## * +## @brief Creates a shared memory object. +## @param s Shared memory information structure which will be filled in. +## @param size Size of the shared memory object to create. +## @param local_perm Permissions with which the shared memory object will be mapped in the local process. +## @param remote_perm Permissions with which the shared memory object will be mapped in the remote process (can be Perm_DontCare). +## @return Result code. +## @warning This is a privileged operation; in normal circumstances applications cannot use this function. +## + +proc shmemLoadRemote*(s: ptr SharedMemory; handle: Handle; size: csize_t; + perm: Permission) {.cdecl, importc: "shmemLoadRemote".} +## * +## @brief Loads a shared memory object coming from a remote process. +## @param s Shared memory information structure which will be filled in. +## @param handle Handle of the shared memory object. +## @param size Size of the shared memory object that is being loaded. +## @param perm Permissions with which the shared memory object will be mapped in the local process. +## + +proc shmemMap*(s: ptr SharedMemory): Result {.cdecl, importc: "shmemMap".} +## * +## @brief Maps a shared memory object. +## @param s Shared memory information structure. +## @return Result code. +## + +proc shmemUnmap*(s: ptr SharedMemory): Result {.cdecl, importc: "shmemUnmap".} +## * +## @brief Unmaps a shared memory object. +## @param s Shared memory information structure. +## @return Result code. +## + +proc shmemGetAddr*(s: ptr SharedMemory): pointer {.inline, cdecl.} = + ## * + ## @brief Retrieves the mapped address of a shared memory object. + ## @param s Shared memory information structure. + ## @return Mapped address of the shared memory object. + ## + return s.mapAddr + +proc shmemClose*(s: ptr SharedMemory): Result {.cdecl, importc: "shmemClose".} +## * +## @brief Frees up resources used by a shared memory object, unmapping and closing handles, etc. +## @param s Shared memory information structure. +## @return Result code. +## + diff --git a/src/libnx/wrapper/switch/kernel/svc.h b/src/libnx/wrapper/switch/kernel/svc.h new file mode 100644 index 0000000..d054381 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/svc.h @@ -0,0 +1,1591 @@ +/** + * @file svc.h + * @brief Wrappers for kernel syscalls. + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../arm/thread_context.h" + +/// Pseudo handle for the current process. +#define CUR_PROCESS_HANDLE 0xFFFF8001 + +/// Pseudo handle for the current thread. +#define CUR_THREAD_HANDLE 0xFFFF8000 + +/// Maximum number of objects that can be waited on by \ref svcWaitSynchronization (Horizon kernel limitation). +#define MAX_WAIT_OBJECTS 0x40 + +/// Memory type enumeration (lower 8 bits of \ref MemoryState) +typedef enum { + MemType_Unmapped=0x00, ///< Unmapped memory. + MemType_Io=0x01, ///< Mapped by kernel capability parsing in \ref svcCreateProcess. + MemType_Normal=0x02, ///< Mapped by kernel capability parsing in \ref svcCreateProcess. + MemType_CodeStatic=0x03, ///< Mapped during \ref svcCreateProcess. + MemType_CodeMutable=0x04, ///< Transition from MemType_CodeStatic performed by \ref svcSetProcessMemoryPermission. + MemType_Heap=0x05, ///< Mapped using \ref svcSetHeapSize. + MemType_SharedMem=0x06, ///< Mapped using \ref svcMapSharedMemory. + MemType_WeirdMappedMem=0x07, ///< Mapped using \ref svcMapMemory. + MemType_ModuleCodeStatic=0x08, ///< Mapped using \ref svcMapProcessCodeMemory. + MemType_ModuleCodeMutable=0x09, ///< Transition from \ref MemType_ModuleCodeStatic performed by \ref svcSetProcessMemoryPermission. + MemType_IpcBuffer0=0x0A, ///< IPC buffers with descriptor flags=0. + MemType_MappedMemory=0x0B, ///< Mapped using \ref svcMapMemory. + MemType_ThreadLocal=0x0C, ///< Mapped during \ref svcCreateThread. + MemType_TransferMemIsolated=0x0D, ///< Mapped using \ref svcMapTransferMemory when the owning process has perm=0. + MemType_TransferMem=0x0E, ///< Mapped using \ref svcMapTransferMemory when the owning process has perm!=0. + MemType_ProcessMem=0x0F, ///< Mapped using \ref svcMapProcessMemory. + MemType_Reserved=0x10, ///< Reserved. + MemType_IpcBuffer1=0x11, ///< IPC buffers with descriptor flags=1. + MemType_IpcBuffer3=0x12, ///< IPC buffers with descriptor flags=3. + MemType_KernelStack=0x13, ///< Mapped in kernel during \ref svcCreateThread. + MemType_CodeReadOnly=0x14, ///< Mapped in kernel during \ref svcControlCodeMemory. + MemType_CodeWritable=0x15, ///< Mapped in kernel during \ref svcControlCodeMemory. + MemType_Coverage=0x16, ///< Not available. + MemType_Insecure=0x17, ///< Mapped in kernel during \ref svcMapInsecureMemory. +} MemoryType; + +/// Memory state bitmasks. +typedef enum { + MemState_Type=0xFF, ///< Type field (see \ref MemoryType). + MemState_PermChangeAllowed=BIT(8), ///< Permission change allowed. + MemState_ForceRwByDebugSyscalls=BIT(9), ///< Force read/writable by debug syscalls. + MemState_IpcSendAllowed_Type0=BIT(10), ///< IPC type 0 send allowed. + MemState_IpcSendAllowed_Type3=BIT(11), ///< IPC type 3 send allowed. + MemState_IpcSendAllowed_Type1=BIT(12), ///< IPC type 1 send allowed. + MemState_ProcessPermChangeAllowed=BIT(14), ///< Process permission change allowed. + MemState_MapAllowed=BIT(15), ///< Map allowed. + MemState_UnmapProcessCodeMemAllowed=BIT(16), ///< Unmap process code memory allowed. + MemState_TransferMemAllowed=BIT(17), ///< Transfer memory allowed. + MemState_QueryPAddrAllowed=BIT(18), ///< Query physical address allowed. + MemState_MapDeviceAllowed=BIT(19), ///< Map device allowed (\ref svcMapDeviceAddressSpace and \ref svcMapDeviceAddressSpaceByForce). + MemState_MapDeviceAlignedAllowed=BIT(20), ///< Map device aligned allowed. + MemState_IpcBufferAllowed=BIT(21), ///< IPC buffer allowed. + MemState_IsPoolAllocated=BIT(22), ///< Is pool allocated. + MemState_IsRefCounted=MemState_IsPoolAllocated, ///< Alias for \ref MemState_IsPoolAllocated. + MemState_MapProcessAllowed=BIT(23), ///< Map process allowed. + MemState_AttrChangeAllowed=BIT(24), ///< Attribute change allowed. + MemState_CodeMemAllowed=BIT(25), ///< Code memory allowed. +} MemoryState; + +/// Memory attribute bitmasks. +typedef enum { + MemAttr_IsBorrowed=BIT(0), ///< Is borrowed memory. + MemAttr_IsIpcMapped=BIT(1), ///< Is IPC mapped (when IpcRefCount > 0). + MemAttr_IsDeviceMapped=BIT(2), ///< Is device mapped (when DeviceRefCount > 0). + MemAttr_IsUncached=BIT(3), ///< Is uncached. +} MemoryAttribute; + +/// Memory permission bitmasks. +typedef enum { + Perm_None = 0, ///< No permissions. + Perm_R = BIT(0), ///< Read permission. + Perm_W = BIT(1), ///< Write permission. + Perm_X = BIT(2), ///< Execute permission. + Perm_Rw = Perm_R | Perm_W, ///< Read/write permissions. + Perm_Rx = Perm_R | Perm_X, ///< Read/execute permissions. + Perm_DontCare = BIT(28), ///< Don't care +} Permission; + +/// Memory information structure. +typedef struct { + u64 addr; ///< Base address. + u64 size; ///< Size. + u32 type; ///< Memory type (see lower 8 bits of \ref MemoryState). + u32 attr; ///< Memory attributes (see \ref MemoryAttribute). + u32 perm; ///< Memory permissions (see \ref Permission). + u32 ipc_refcount; ///< IPC reference count. + u32 device_refcount; ///< Device reference count. + u32 padding; ///< Padding. +} MemoryInfo; + +/// Physical memory information structure. +typedef struct { + u64 physical_address; ///< Physical address. + u64 virtual_address; ///< Virtual address. + u64 size; ///< Size. +} PhysicalMemoryInfo; + +/// Secure monitor arguments. +typedef struct { + u64 X[8]; ///< Values of X0 through X7. +} PACKED SecmonArgs; + +/// Break reasons +typedef enum { + BreakReason_Panic = 0, + BreakReason_Assert = 1, + BreakReason_User = 2, + BreakReason_PreLoadDll = 3, + BreakReason_PostLoadDll = 4, + BreakReason_PreUnloadDll = 5, + BreakReason_PostUnloadDll = 6, + BreakReason_CppException = 7, + + BreakReason_NotificationOnlyFlag = 0x80000000, +} BreakReason; + +/// Code memory mapping operations +typedef enum { + CodeMapOperation_MapOwner=0, ///< Map owner. + CodeMapOperation_MapSlave=1, ///< Map slave. + CodeMapOperation_UnmapOwner=2, ///< Unmap owner. + CodeMapOperation_UnmapSlave=3, ///< Unmap slave. +} CodeMapOperation; + +/// Limitable Resources. +typedef enum { + LimitableResource_Memory=0, ///switchbrew.org Wiki for more details. + * @note Syscall number 0x03. + */ +Result svcSetMemoryAttribute(void* addr, u64 size, u32 val0, u32 val1); + +/** + * @brief Maps a memory range into a different range. Mainly used for adding guard pages around stack. + * Source range gets reprotected to Perm_None (it can no longer be accessed), and \ref MemAttr_IsBorrowed is set in the source \ref MemoryAttribute. + * @param[in] dst_addr Destination address. + * @param[in] src_addr Source address. + * @param[in] size Size of the range. + * @return Result code. + * @note Syscall number 0x04. + */ +Result svcMapMemory(void* dst_addr, void* src_addr, u64 size); + +/** + * @brief Unmaps a region that was previously mapped with \ref svcMapMemory. + * @param[in] dst_addr Destination address. + * @param[in] src_addr Source address. + * @param[in] size Size of the range. + * @return Result code. + * @note Syscall number 0x05. + */ +Result svcUnmapMemory(void* dst_addr, void* src_addr, u64 size); + +/** + * @brief Query information about an address. Will always fetch the lowest page-aligned mapping that contains the provided address. + * @param[out] meminfo_ptr \ref MemoryInfo structure which will be filled in. + * @param[out] pageinfo Page information which will be filled in. + * @param[in] addr Address to query. + * @return Result code. + * @note Syscall number 0x06. + */ +Result svcQueryMemory(MemoryInfo* meminfo_ptr, u32 *pageinfo, u64 addr); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Exits the current process. + * @note Syscall number 0x07. + */ + +void NORETURN svcExitProcess(void); + +/** + * @brief Creates a thread. + * @return Result code. + * @note Syscall number 0x08. + */ +Result svcCreateThread(Handle* out, void* entry, void* arg, void* stack_top, int prio, int cpuid); + +/** + * @brief Starts a freshly created thread. + * @return Result code. + * @note Syscall number 0x09. + */ +Result svcStartThread(Handle handle); + +/** + * @brief Exits the current thread. + * @note Syscall number 0x0A. + */ +void NORETURN svcExitThread(void); + +/** + * @brief Sleeps the current thread for the specified amount of time. + * @param[in] nano Number of nanoseconds to sleep, or \ref YieldType for yield. + * @note Syscall number 0x0B. + */ +void svcSleepThread(s64 nano); + +/** + * @brief Gets a thread's priority. + * @return Result code. + * @note Syscall number 0x0C. + */ +Result svcGetThreadPriority(s32* priority, Handle handle); + +/** + * @brief Sets a thread's priority. + * @return Result code. + * @note Syscall number 0x0D. + */ +Result svcSetThreadPriority(Handle handle, u32 priority); + +/** + * @brief Gets a thread's core mask. + * @return Result code. + * @note Syscall number 0x0E. + */ +Result svcGetThreadCoreMask(s32* preferred_core, u64* affinity_mask, Handle handle); + +/** + * @brief Sets a thread's core mask. + * @return Result code. + * @note Syscall number 0x0F. + */ +Result svcSetThreadCoreMask(Handle handle, s32 preferred_core, u32 affinity_mask); + +/** + * @brief Gets the current processor's number. + * @return The current processor's number. + * @note Syscall number 0x10. + */ +u32 svcGetCurrentProcessorNumber(void); + +///@} + +///@name Synchronization +///@{ + +/** + * @brief Sets an event's signalled status. + * @return Result code. + * @note Syscall number 0x11. + */ +Result svcSignalEvent(Handle handle); + +/** + * @brief Clears an event's signalled status. + * @return Result code. + * @note Syscall number 0x12. + */ +Result svcClearEvent(Handle handle); + +///@} + +///@name Inter-process memory sharing +///@{ + +/** + * @brief Maps a block of shared memory. + * @return Result code. + * @note Syscall number 0x13. + */ +Result svcMapSharedMemory(Handle handle, void* addr, size_t size, u32 perm); + +/** + * @brief Unmaps a block of shared memory. + * @return Result code. + * @note Syscall number 0x14. + */ +Result svcUnmapSharedMemory(Handle handle, void* addr, size_t size); + +/** + * @brief Creates a block of transfer memory. + * @return Result code. + * @note Syscall number 0x15. + */ +Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Closes a handle, decrementing the reference count of the corresponding kernel object. + * This might result in the kernel freeing the object. + * @param handle Handle to close. + * @return Result code. + * @note Syscall number 0x16. + */ +Result svcCloseHandle(Handle handle); + +///@} + +///@name Synchronization +///@{ + +/** + * @brief Resets a signal. + * @return Result code. + * @note Syscall number 0x17. + */ +Result svcResetSignal(Handle handle); + +///@} + +///@name Synchronization +///@{ + +/** + * @brief Waits on one or more synchronization objects, optionally with a timeout. + * @return Result code. + * @note Syscall number 0x18. + * @note \p handleCount must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. + * @note This is the raw syscall, which can be cancelled by \ref svcCancelSynchronization or other means. \ref waitHandles or \ref waitMultiHandle should normally be used instead. + */ +Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout); + +/** + * @brief Waits on a single synchronization object, optionally with a timeout. + * @return Result code. + * @note Wrapper for \ref svcWaitSynchronization. + * @note This is the raw syscall, which can be cancelled by \ref svcCancelSynchronization or other means. \ref waitSingleHandle should normally be used instead. + */ +static inline Result svcWaitSynchronizationSingle(Handle handle, u64 timeout) { + s32 tmp; + return svcWaitSynchronization(&tmp, &handle, 1, timeout); +} + +/** + * @brief Waits a \ref svcWaitSynchronization operation being done on a synchronization object in another thread. + * @return Result code. + * @note Syscall number 0x19. + */ +Result svcCancelSynchronization(Handle thread); + +/** + * @brief Arbitrates a mutex lock operation in userspace. + * @return Result code. + * @note Syscall number 0x1A. + */ +Result svcArbitrateLock(u32 wait_tag, u32* tag_location, u32 self_tag); + +/** + * @brief Arbitrates a mutex unlock operation in userspace. + * @return Result code. + * @note Syscall number 0x1B. + */ +Result svcArbitrateUnlock(u32* tag_location); + +/** + * @brief Performs a condition variable wait operation in userspace. + * @return Result code. + * @note Syscall number 0x1C. + */ +Result svcWaitProcessWideKeyAtomic(u32* key, u32* tag_location, u32 self_tag, u64 timeout); + +/** + * @brief Performs a condition variable wake-up operation in userspace. + * @note Syscall number 0x1D. + */ +void svcSignalProcessWideKey(u32* key, s32 num); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Gets the current system tick. + * @return The current system tick. + * @note Syscall number 0x1E. + */ +u64 svcGetSystemTick(void); + +///@} + +///@name Inter-process communication (IPC) +///@{ + +/** + * @brief Connects to a registered named port. + * @return Result code. + * @note Syscall number 0x1F. + */ +Result svcConnectToNamedPort(Handle* session, const char* name); + +/** + * @brief Sends a light IPC synchronization request to a session. + * @return Result code. + * @note Syscall number 0x20. + */ +Result svcSendSyncRequestLight(Handle session); + +/** + * @brief Sends an IPC synchronization request to a session. + * @return Result code. + * @note Syscall number 0x21. + */ +Result svcSendSyncRequest(Handle session); + +/** + * @brief Sends an IPC synchronization request to a session from an user allocated buffer. + * @return Result code. + * @remark size must be allocated to 0x1000 bytes. + * @note Syscall number 0x22. + */ +Result svcSendSyncRequestWithUserBuffer(void* usrBuffer, u64 size, Handle session); + +/** + * @brief Sends an IPC synchronization request to a session from an user allocated buffer (asynchronous version). + * @return Result code. + * @remark size must be allocated to 0x1000 bytes. + * @note Syscall number 0x23. + */ +Result svcSendAsyncRequestWithUserBuffer(Handle* handle, void* usrBuffer, u64 size, Handle session); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Gets the PID associated with a process. + * @return Result code. + * @note Syscall number 0x24. + */ +Result svcGetProcessId(u64 *processID, Handle handle); + +/** + * @brief Gets the TID associated with a process. + * @return Result code. + * @note Syscall number 0x25. + */ +Result svcGetThreadId(u64 *threadID, Handle handle); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Breaks execution. + * @param[in] breakReason Break reason (see \ref BreakReason). + * @param[in] address Address of the buffer to pass to the debugger. + * @param[in] size Size of the buffer to pass to the debugger. + * @return Result code. + * @note Syscall number 0x26. + */ +Result svcBreak(u32 breakReason, uintptr_t address, uintptr_t size); + +///@} + +///@name Debugging +///@{ + +/** + * @brief Outputs debug text, if used during debugging. + * @param[in] str Text to output. + * @param[in] size Size of the text in bytes. + * @return Result code. + * @note Syscall number 0x27. + */ +Result svcOutputDebugString(const char *str, u64 size); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Returns from an exception. + * @param[in] res Result code. + * @note Syscall number 0x28. + */ +void NORETURN svcReturnFromException(Result res); + +/** + * @brief Retrieves information about the system, or a certain kernel object. + * @param[out] out Variable to which store the information. + * @param[in] id0 First ID of the property to retrieve. + * @param[in] handle Handle of the object to retrieve information from, or \ref INVALID_HANDLE to retrieve information about the system. + * @param[in] id1 Second ID of the property to retrieve. + * @return Result code. + * @remark The full list of property IDs can be found on the switchbrew.org wiki. + * @note Syscall number 0x29. + */ +Result svcGetInfo(u64* out, u32 id0, Handle handle, u64 id1); + +///@} + +///@name Cache Management +///@{ + +/** + * @brief Flushes the entire data cache (by set/way). + * @note Syscall number 0x2A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning This syscall is dangerous, and should not be used. + */ +void svcFlushEntireDataCache(void); + +/** + * @brief Flushes data cache for a virtual address range. + * @param[in] address Address of region to flush. + * @param[in] size Size of region to flush. + * @remark armDCacheFlush should be used instead of this syscall whenever possible. + * @note Syscall number 0x2B. + */ +Result svcFlushDataCache(void *address, size_t size); + +///@} + +///@name Memory management +///@{ + +/** + * @brief Maps new heap memory at the desired address. [3.0.0+] + * @return Result code. + * @note Syscall number 0x2C. + */ +Result svcMapPhysicalMemory(void *address, u64 size); + +/** + * @brief Undoes the effects of \ref svcMapPhysicalMemory. [3.0.0+] + * @return Result code. + * @note Syscall number 0x2D. + */ +Result svcUnmapPhysicalMemory(void *address, u64 size); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Gets information about a thread that will be scheduled in the future. [5.0.0+] + * @param[out] out_context Output \ref LastThreadContext for the thread that will be scheduled. + * @param[out] out_thread_id Output thread id for the thread that will be scheduled. + * @param[in] debug Debug handle. + * @param[in] ns Nanoseconds in the future to get scheduled thread at. + * @return Result code. + * @note Syscall number 0x2E. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetDebugFutureThreadInfo(LastThreadContext *out_context, u64 *out_thread_id, Handle debug, s64 ns); + +/** + * @brief Gets information about the previously-scheduled thread. + * @param[out] out_context Output \ref LastThreadContext for the previously scheduled thread. + * @param[out] out_tls_address Output tls address for the previously scheduled thread. + * @param[out] out_flags Output flags for the previously scheduled thread. + * @return Result code. + * @note Syscall number 0x2F. + */ +Result svcGetLastThreadInfo(LastThreadContext *out_context, u64 *out_tls_address, u32 *out_flags); + +///@} + +///@name Resource Limit Management +///@{ + +/** + * @brief Gets the maximum value a LimitableResource can have, for a Resource Limit handle. + * @return Result code. + * @note Syscall number 0x30. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetResourceLimitLimitValue(s64 *out, Handle reslimit_h, LimitableResource which); + +/** + * @brief Gets the maximum value a LimitableResource can have, for a Resource Limit handle. + * @return Result code. + * @note Syscall number 0x31. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetResourceLimitCurrentValue(s64 *out, Handle reslimit_h, LimitableResource which); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Configures the pause/unpause status of a thread. + * @return Result code. + * @note Syscall number 0x32. + */ +Result svcSetThreadActivity(Handle thread, ThreadActivity paused); + +/** + * @brief Dumps the registers of a thread paused by @ref svcSetThreadActivity (register groups: all). + * @param[out] ctx Output thread context (register dump). + * @param[in] thread Thread handle. + * @return Result code. + * @note Syscall number 0x33. + * @warning Official kernel will not dump x0..x18 if the thread is currently executing a system call, and prior to 6.0.0 doesn't dump TPIDR_EL0. + */ +Result svcGetThreadContext3(ThreadContext* ctx, Handle thread); + +///@} + +///@name Synchronization +///@{ + +/** + * @brief Arbitrates an address depending on type and value. [4.0.0+] + * @param[in] address Address to arbitrate. + * @param[in] arb_type \ref ArbitrationType to use. + * @param[in] value Value to arbitrate on. + * @param[in] timeout Maximum time in nanoseconds to wait. + * @return Result code. + * @note Syscall number 0x34. + */ +Result svcWaitForAddress(void *address, u32 arb_type, s32 value, s64 timeout); + +/** + * @brief Signals (and updates) an address depending on type and value. [4.0.0+] + * @param[in] address Address to arbitrate. + * @param[in] signal_type \ref SignalType to use. + * @param[in] value Value to arbitrate on. + * @param[in] count Number of waiting threads to signal. + * @return Result code. + * @note Syscall number 0x35. + */ +Result svcSignalToAddress(void *address, u32 signal_type, s32 value, s32 count); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Sets thread preemption state (used during abort/panic). [8.0.0+] + * @note Syscall number 0x36. + */ +void svcSynchronizePreemptionState(void); + +///@} + +///@name Resource Limit Management +///@{ + +/** + * @brief Gets the peak value a LimitableResource has had, for a Resource Limit handle. [11.0.0+] + * @return Result code. + * @note Syscall number 0x37. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetResourceLimitPeakValue(s64 *out, Handle reslimit_h, LimitableResource which); + +///@} + +///@name Memory Management +///@{ + +/** + * @brief Creates an IO Pool. [13.0.0+] + * @return Result code. + * @note Syscall number 0x39. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateIoPool(Handle *out_handle, u32 pool_type); + +/** + * @brief Creates an IO Region. [13.0.0+] + * @return Result code. + * @note Syscall number 0x3A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateIoRegion(Handle *out_handle, Handle io_pool_h, u64 physical_address, u64 size, u32 memory_mapping, u32 perm); + +///@} + +///@name Debugging +///@{ +/** + * @brief Causes the kernel to dump debug information. [1.0.0-3.0.2] + * @param[in] dump_info_type Type of information to dump. + * @param[in] arg0 Argument to the debugging operation. + * @note Syscall number 0x3C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +void svcDumpInfo(u32 dump_info_type, u64 arg0); + +/** + * @brief Performs a debugging operation on the kernel. [4.0.0+] + * @param[in] kern_debug_type Type of debugging operation to perform. + * @param[in] arg0 First argument to the debugging operation. + * @param[in] arg1 Second argument to the debugging operation. + * @param[in] arg2 Third argument to the debugging operation. + * @note Syscall number 0x3C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +void svcKernelDebug(u32 kern_debug_type, u64 arg0, u64 arg1, u64 arg2); + +/** + * @brief Performs a debugging operation on the kernel. [4.0.0+] + * @param[in] kern_trace_state Type of tracing the kernel should perform. + * @note Syscall number 0x3D. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +void svcChangeKernelTraceState(u32 kern_trace_state); + +///@} + \ +///@name Inter-process communication (IPC) +///@{ + +/** + * @brief Creates an IPC session. + * @return Result code. + * @note Syscall number 0x40. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateSession(Handle *server_handle, Handle *client_handle, u32 unk0, u64 unk1);//unk* are normally 0? + +/** + * @brief Accepts an IPC session. + * @return Result code. + * @note Syscall number 0x41. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcAcceptSession(Handle *session_handle, Handle port_handle); + +/** + * @brief Performs light IPC input/output. + * @return Result code. + * @param[in] handle Server or port handle to act on. + * @note Syscall number 0x42. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcReplyAndReceiveLight(Handle handle); + +/** + * @brief Performs IPC input/output. + * @return Result code. + * @note Syscall number 0x43. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcReplyAndReceive(s32* index, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout); + +/** + * @brief Performs IPC input/output from an user allocated buffer. + * @return Result code. + * @note Syscall number 0x44. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcReplyAndReceiveWithUserBuffer(s32* index, void* usrBuffer, u64 size, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout); + +///@} + +///@name Synchronization +///@{ + +/** + * @brief Creates a system event. + * @return Result code. + * @note Syscall number 0x45. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateEvent(Handle* server_handle, Handle* client_handle); + +///@} + +///@name Memory management +///@{ + +/** + * @brief Maps an IO Region. [13.0.0+] + * @return Result code. + * @note Syscall number 0x46. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapIoRegion(Handle io_region_h, void *address, u64 size, u32 perm); + +/** + * @brief Undoes the effects of \ref svcMapIoRegion. [13.0.0+] + * @return Result code. + * @note Syscall number 0x47. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapIoRegion(Handle io_region_h, void *address, u64 size); + +/** + * @brief Maps unsafe memory (usable for GPU DMA) for a system module at the desired address. [5.0.0+] + * @return Result code. + * @note Syscall number 0x48. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapPhysicalMemoryUnsafe(void *address, u64 size); + +/** + * @brief Undoes the effects of \ref svcMapPhysicalMemoryUnsafe. [5.0.0+] + * @return Result code. + * @note Syscall number 0x49. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapPhysicalMemoryUnsafe(void *address, u64 size); + +/** + * @brief Sets the system-wide limit for unsafe memory mappable using \ref svcMapPhysicalMemoryUnsafe. [5.0.0+] + * @return Result code. + * @note Syscall number 0x4A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetUnsafeLimit(u64 size); + +///@} + + +///@name Code memory / Just-in-time (JIT) compilation support +///@{ + +/** + * @brief Creates code memory in the caller's address space [4.0.0+]. + * @return Result code. + * @note Syscall number 0x4B. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateCodeMemory(Handle* code_handle, void* src_addr, u64 size); + +/** + * @brief Maps code memory in the caller's address space [4.0.0+]. + * @return Result code. + * @note Syscall number 0x4C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcControlCodeMemory(Handle code_handle, CodeMapOperation op, void* dst_addr, u64 size, u64 perm); + +///@} + +///@name Power Management +///@{ + +/** + * @brief Causes the system to enter deep sleep. + * @note Syscall number 0x4D. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +void svcSleepSystem(void); + +///@} + +///@name Device memory-mapped I/O (MMIO) +///@{ + +/** + * @brief Reads/writes a protected MMIO register. + * @return Result code. + * @note Syscall number 0x4E. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcReadWriteRegister(u32* outVal, u64 regAddr, u32 rwMask, u32 inVal); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Configures the pause/unpause status of a process. + * @return Result code. + * @note Syscall number 0x4F. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetProcessActivity(Handle process, ProcessActivity paused); + +///@} + +///@name Inter-process memory sharing +///@{ + +/** + * @brief Creates a block of shared memory. + * @return Result code. + * @note Syscall number 0x50. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateSharedMemory(Handle* out, size_t size, u32 local_perm, u32 other_perm); + +/** + * @brief Maps a block of transfer memory. + * @return Result code. + * @note Syscall number 0x51. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapTransferMemory(Handle tmem_handle, void* addr, size_t size, u32 perm); + +/** + * @brief Unmaps a block of transfer memory. + * @return Result code. + * @note Syscall number 0x52. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapTransferMemory(Handle tmem_handle, void* addr, size_t size); + +///@} + +///@name Device memory-mapped I/O (MMIO) +///@{ + +/** + * @brief Creates an event and binds it to a specific hardware interrupt. + * @return Result code. + * @note Syscall number 0x53. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateInterruptEvent(Handle* handle, u64 irqNum, u32 flag); + +/** + * @brief Queries information about a certain virtual address, including its physical address. + * @return Result code. + * @note Syscall number 0x54. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcQueryPhysicalAddress(PhysicalMemoryInfo *out, u64 virtaddr); + +/** + * @brief Returns a virtual address mapped to a given IO range. + * @return Result code. + * @note Syscall number 0x55. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping. + */ +Result svcQueryIoMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size); + +/** + * @brief Returns a virtual address mapped to a given IO range. + * @return Result code. + * @note Syscall number 0x55. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping. + */ +Result svcLegacyQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size); + +///@} + +///@name I/O memory management unit (IOMMU) +///@{ + +/** + * @brief Creates a virtual address space for binding device address spaces. + * @return Result code. + * @note Syscall number 0x56. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateDeviceAddressSpace(Handle *handle, u64 dev_addr, u64 dev_size); + +/** + * @brief Attaches a device address space to a device. + * @return Result code. + * @note Syscall number 0x57. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcAttachDeviceAddressSpace(u64 device, Handle handle); + +/** + * @brief Detaches a device address space from a device. + * @return Result code. + * @note Syscall number 0x58. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcDetachDeviceAddressSpace(u64 device, Handle handle); + +/** + * @brief Maps an attached device address space to an userspace address. + * @return Result code. + * @remark The userspace destination address must have the \ref MemState_MapDeviceAllowed bit set. + * @note Syscall number 0x59. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapDeviceAddressSpaceByForce(Handle handle, Handle proc_handle, u64 map_addr, u64 dev_size, u64 dev_addr, u32 option); + +/** + * @brief Maps an attached device address space to an userspace address. + * @return Result code. + * @remark The userspace destination address must have the \ref MemState_MapDeviceAlignedAllowed bit set. + * @note Syscall number 0x5A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapDeviceAddressSpaceAligned(Handle handle, Handle proc_handle, u64 map_addr, u64 dev_size, u64 dev_addr, u32 option); + +/** + * @brief Maps an attached device address space to an userspace address. [1.0.0-12.1.0] + * @return Result code. + * @remark The userspace destination address must have the \ref MemState_MapDeviceAlignedAllowed bit set. + * @note Syscall number 0x5B. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapDeviceAddressSpace(u64 *out_mapped_size, Handle handle, Handle proc_handle, u64 map_addr, u64 dev_size, u64 dev_addr, u32 perm); + +/** + * @brief Unmaps an attached device address space from an userspace address. + * @return Result code. + * @note Syscall number 0x5C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapDeviceAddressSpace(Handle handle, Handle proc_handle, u64 map_addr, u64 map_size, u64 dev_addr); + +///@} + +///@name Cache Management +///@{ + +/** + * @brief Invalidates data cache for a virtual address range within a process. + * @param[in] address Address of region to invalidate. + * @param[in] size Size of region to invalidate. + * @note Syscall number 0x5D. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcInvalidateProcessDataCache(Handle process, uintptr_t address, size_t size); + +/** + * @brief Stores data cache for a virtual address range within a process. + * @param[in] address Address of region to store. + * @param[in] size Size of region to store. + * @note Syscall number 0x5E. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcStoreProcessDataCache(Handle process, uintptr_t address, size_t size); + +/** + * @brief Flushes data cache for a virtual address range within a process. + * @param[in] address Address of region to flush. + * @param[in] size Size of region to flush. + * @note Syscall number 0x5F. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcFlushProcessDataCache(Handle process, uintptr_t address, size_t size); + +///@} + +///@name Debugging +///@{ + +/** + * @brief Debugs an active process. + * @return Result code. + * @note Syscall number 0x60. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcDebugActiveProcess(Handle* debug, u64 processID); + +/** + * @brief Breaks an active debugging session. + * @return Result code. + * @note Syscall number 0x61. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcBreakDebugProcess(Handle debug); + +/** + * @brief Terminates the process of an active debugging session. + * @return Result code. + * @note Syscall number 0x62. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcTerminateDebugProcess(Handle debug); + +/** + * @brief Gets an incoming debug event from a debugging session. + * @return Result code. + * @note Syscall number 0x63. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetDebugEvent(void* event_out, Handle debug); + +/** + * @brief Continues a debugging session. + * @return Result code. + * @note Syscall number 0x64. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [3.0.0+]. For older versions use \ref svcLegacyContinueDebugEvent. + */ +Result svcContinueDebugEvent(Handle debug, u32 flags, u64* tid_list, u32 num_tids); + +/** + * @brief Continues a debugging session. + * @return Result code. + * @note Syscall number 0x64. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [1.0.0-2.3.0]. For newer versions use \ref svcContinueDebugEvent. + */ +Result svcLegacyContinueDebugEvent(Handle debug, u32 flags, u64 threadID); + +/** + * @brief Gets the context (dump the registers) of a thread in a debugging session. + * @return Result code. + * @param[out] ctx Output thread context (register dump). + * @param[in] debug Debug handle. + * @param[in] threadID ID of the thread to dump the context of. + * @param[in] flags Register groups to select, combination of @ref RegisterGroup flags. + * @note Syscall number 0x67. + * @warning Official kernel will not dump any CPU GPR if the thread is currently executing a system call (except @ref svcBreak and @ref svcReturnFromException). + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetDebugThreadContext(ThreadContext* ctx, Handle debug, u64 threadID, u32 flags); + +/** + * @brief Gets the context (dump the registers) of a thread in a debugging session. + * @return Result code. + * @param[in] debug Debug handle. + * @param[in] threadID ID of the thread to set the context of. + * @param[in] ctx Input thread context (register dump). + * @param[in] flags Register groups to select, combination of @ref RegisterGroup flags. + * @note Syscall number 0x68. + * @warning Official kernel will return an error if the thread is currently executing a system call (except @ref svcBreak and @ref svcReturnFromException). + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetDebugThreadContext(Handle debug, u64 threadID, const ThreadContext* ctx, u32 flags); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Retrieves a list of all running processes. + * @return Result code. + * @note Syscall number 0x65. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetProcessList(s32 *num_out, u64 *pids_out, u32 max_pids); + +/** + * @brief Retrieves a list of all threads for a debug handle (or zero). + * @return Result code. + * @note Syscall number 0x66. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetThreadList(s32 *num_out, u64 *tids_out, u32 max_tids, Handle debug); + +///@} + +///@name Debugging +///@{ + +/** + * @brief Queries memory information from a process that is being debugged. + * @return Result code. + * @note Syscall number 0x69. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcQueryDebugProcessMemory(MemoryInfo* meminfo_ptr, u32* pageinfo, Handle debug, u64 addr); + +/** + * @brief Reads memory from a process that is being debugged. + * @return Result code. + * @note Syscall number 0x6A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcReadDebugProcessMemory(void* buffer, Handle debug, u64 addr, u64 size); + +/** + * @brief Writes to memory in a process that is being debugged. + * @return Result code. + * @note Syscall number 0x6B. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcWriteDebugProcessMemory(Handle debug, const void* buffer, u64 addr, u64 size); + +/** + * @brief Sets one of the hardware breakpoints. + * @return Result code. + * @note Syscall number 0x6C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetHardwareBreakPoint(u32 which, u64 flags, u64 value); + +/** + * @brief Gets parameters from a thread in a debugging session. + * @return Result code. + * @note Syscall number 0x6D. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetDebugThreadParam(u64* out_64, u32* out_32, Handle debug, u64 threadID, DebugThreadParam param); + +///@} + +///@name Miscellaneous +///@{ + +/** + * @brief Retrieves privileged information about the system, or a certain kernel object. + * @param[out] out Variable to which store the information. + * @param[in] id0 First ID of the property to retrieve. + * @param[in] handle Handle of the object to retrieve information from, or \ref INVALID_HANDLE to retrieve information about the system. + * @param[in] id1 Second ID of the property to retrieve. + * @return Result code. + * @remark The full list of property IDs can be found on the switchbrew.org wiki. + * @note Syscall number 0x6F. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetSystemInfo(u64* out, u64 id0, Handle handle, u64 id1); + +///@} + +///@name Inter-process communication (IPC) +///@{ + +/** + * @brief Creates a port. + * @return Result code. + * @note Syscall number 0x70. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreatePort(Handle* portServer, Handle *portClient, s32 max_sessions, bool is_light, const char* name); + +/** + * @brief Manages a named port. + * @return Result code. + * @note Syscall number 0x71. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcManageNamedPort(Handle* portServer, const char* name, s32 maxSessions); + +/** + * @brief Manages a named port. + * @return Result code. + * @note Syscall number 0x72. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcConnectToPort(Handle* session, Handle port); + +///@} + +///@name Memory management +///@{ + +/** + * @brief Sets the memory permissions for the specified memory with the supplied process handle. + * @param[in] proc Process handle. + * @param[in] addr Address of the memory. + * @param[in] size Size of the memory. + * @param[in] perm Permissions (see \ref Permission). + * @return Result code. + * @remark This returns an error (0xD801) when \p perm is >0x5, hence -WX and RWX are not allowed. + * @note Syscall number 0x73. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetProcessMemoryPermission(Handle proc, u64 addr, u64 size, u32 perm); + +/** + * @brief Maps the src address from the supplied process handle into the current process. + * @param[in] dst Address to which map the memory in the current process. + * @param[in] proc Process handle. + * @param[in] src Source mapping address. + * @param[in] size Size of the memory. + * @return Result code. + * @remark This allows mapping code and rodata with RW- permission. + * @note Syscall number 0x74. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapProcessMemory(void* dst, Handle proc, u64 src, u64 size); + +/** + * @brief Undoes the effects of \ref svcMapProcessMemory. + * @param[in] dst Destination mapping address + * @param[in] proc Process handle. + * @param[in] src Address of the memory in the process. + * @param[in] size Size of the memory. + * @return Result code. + * @remark This allows mapping code and rodata with RW- permission. + * @note Syscall number 0x75. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapProcessMemory(void* dst, Handle proc, u64 src, u64 size); + +/** + * @brief Equivalent to \ref svcQueryMemory, for another process. + * @param[out] meminfo_ptr \ref MemoryInfo structure which will be filled in. + * @param[out] pageinfo Page information which will be filled in. + * @param[in] proc Process handle. + * @param[in] addr Address to query. + * @return Result code. + * @note Syscall number 0x76. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcQueryProcessMemory(MemoryInfo* meminfo_ptr, u32 *pageinfo, Handle proc, u64 addr); + +/** + * @brief Maps normal heap in a certain process as executable code (used when loading NROs). + * @param[in] proc Process handle (cannot be \ref CUR_PROCESS_HANDLE). + * @param[in] dst Destination mapping address. + * @param[in] src Source mapping address. + * @param[in] size Size of the mapping. + * @return Result code. + * @note Syscall number 0x77. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcMapProcessCodeMemory(Handle proc, u64 dst, u64 src, u64 size); + +/** + * @brief Undoes the effects of \ref svcMapProcessCodeMemory. + * @param[in] proc Process handle (cannot be \ref CUR_PROCESS_HANDLE). + * @param[in] dst Destination mapping address. + * @param[in] src Source mapping address. + * @param[in] size Size of the mapping. + * @return Result code. + * @note Syscall number 0x78. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcUnmapProcessCodeMemory(Handle proc, u64 dst, u64 src, u64 size); + +///@} + +///@name Process and thread management +///@{ + +/** + * @brief Creates a new process. + * @return Result code. + * @note Syscall number 0x79. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateProcess(Handle* out, const void* proc_info, const u32* caps, u64 cap_num); + +/** + * @brief Starts executing a freshly created process. + * @return Result code. + * @note Syscall number 0x7A. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcStartProcess(Handle proc, s32 main_prio, s32 default_cpu, u32 stack_size); + +/** + * @brief Terminates a running process. + * @return Result code. + * @note Syscall number 0x7B. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcTerminateProcess(Handle proc); + +/** + * @brief Gets a \ref ProcessInfoType for a process. + * @return Result code. + * @note Syscall number 0x7C. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcGetProcessInfo(s64 *out, Handle proc, ProcessInfoType which); + +///@} + +///@name Resource Limit Management +///@{ + +/** + * @brief Creates a new Resource Limit handle. + * @return Result code. + * @note Syscall number 0x7D. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcCreateResourceLimit(Handle* out); + +/** + * @brief Sets the value for a \ref LimitableResource for a Resource Limit handle. + * @return Result code. + * @note Syscall number 0x7E. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +Result svcSetResourceLimitLimitValue(Handle reslimit, LimitableResource which, u64 value); + +///@} + +///@name ( ͡° ͜ʖ ͡°) +///@{ + +/** + * @brief Calls a secure monitor function (TrustZone, EL3). + * @param regs Arguments to pass to the secure monitor. + * @note Syscall number 0x7F. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + */ +void svcCallSecureMonitor(SecmonArgs* regs); + +///@} + +///@name Memory management +///@{ + +/** + * @brief Maps new insecure memory at the desired address. [15.0.0+] + * @return Result code. + * @note Syscall number 0x90. + */ +Result svcMapInsecureMemory(void *address, u64 size); + +/** + * @brief Undoes the effects of \ref svcMapInsecureMemory. [15.0.0+] + * @return Result code. + * @note Syscall number 0x91. + */ +Result svcUnmapInsecureMemory(void *address, u64 size); + +///@} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/kernel/svc.nim b/src/libnx/wrapper/switch/kernel/svc.nim new file mode 100644 index 0000000..5eabe04 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/svc.nim @@ -0,0 +1,1693 @@ +## * +## @file svc.h +## @brief Wrappers for kernel syscalls. +## @copyright libnx Authors +## + +import + ../types, ../arm/thread_context + +## / Pseudo handle for the current process. + +const + CUR_PROCESS_HANDLE* = 0xFFFF8001 + +## / Pseudo handle for the current thread. + +const + CUR_THREAD_HANDLE* = 0xFFFF8000 + +## / Maximum number of objects that can be waited on by \ref svcWaitSynchronization (Horizon kernel limitation). + +const + MAX_WAIT_OBJECTS* = 0x40 + +## / Memory type enumeration (lower 8 bits of \ref MemoryState) + +type + MemoryType* = enum + MemTypeUnmapped = 0x00, ## /< Unmapped memory. + MemTypeIo = 0x01, ## /< Mapped by kernel capability parsing in \ref svcCreateProcess. + MemTypeNormal = 0x02, ## /< Mapped by kernel capability parsing in \ref svcCreateProcess. + MemTypeCodeStatic = 0x03, ## /< Mapped during \ref svcCreateProcess. + MemTypeCodeMutable = 0x04, ## /< Transition from MemType_CodeStatic performed by \ref svcSetProcessMemoryPermission. + MemTypeHeap = 0x05, ## /< Mapped using \ref svcSetHeapSize. + MemTypeSharedMem = 0x06, ## /< Mapped using \ref svcMapSharedMemory. + MemTypeWeirdMappedMem = 0x07, ## /< Mapped using \ref svcMapMemory. + MemTypeModuleCodeStatic = 0x08, ## /< Mapped using \ref svcMapProcessCodeMemory. + MemTypeModuleCodeMutable = 0x09, ## /< Transition from \ref MemType_ModuleCodeStatic performed by \ref svcSetProcessMemoryPermission. + MemTypeIpcBuffer0 = 0x0A, ## /< IPC buffers with descriptor flags=0. + MemTypeMappedMemory = 0x0B, ## /< Mapped using \ref svcMapMemory. + MemTypeThreadLocal = 0x0C, ## /< Mapped during \ref svcCreateThread. + MemTypeTransferMemIsolated = 0x0D, ## /< Mapped using \ref svcMapTransferMemory when the owning process has perm=0. + MemTypeTransferMem = 0x0E, ## /< Mapped using \ref svcMapTransferMemory when the owning process has perm!=0. + MemTypeProcessMem = 0x0F, ## /< Mapped using \ref svcMapProcessMemory. + MemTypeReserved = 0x10, ## /< Reserved. + MemTypeIpcBuffer1 = 0x11, ## /< IPC buffers with descriptor flags=1. + MemTypeIpcBuffer3 = 0x12, ## /< IPC buffers with descriptor flags=3. + MemTypeKernelStack = 0x13, ## /< Mapped in kernel during \ref svcCreateThread. + MemTypeCodeReadOnly = 0x14, ## /< Mapped in kernel during \ref svcControlCodeMemory. + MemTypeCodeWritable = 0x15, ## /< Mapped in kernel during \ref svcControlCodeMemory. + MemTypeCoverage = 0x16, ## /< Not available. + MemTypeInsecure = 0x17 ## /< Mapped in kernel during \ref svcMapInsecureMemory. + + +## / Memory state bitmasks. + +type + MemoryState* = enum + MemStateType = 0xFF, ## /< Type field (see \ref MemoryType). + MemStatePermChangeAllowed = bit(8), ## /< Permission change allowed. + MemStateForceRwByDebugSyscalls = bit(9), ## /< Force read/writable by debug syscalls. + MemStateIpcSendAllowedType0 = bit(10), ## /< IPC type 0 send allowed. + MemStateIpcSendAllowedType3 = bit(11), ## /< IPC type 3 send allowed. + MemStateIpcSendAllowedType1 = bit(12), ## /< IPC type 1 send allowed. + MemStateProcessPermChangeAllowed = bit(14), ## /< Process permission change allowed. + MemStateMapAllowed = bit(15), ## /< Map allowed. + MemStateUnmapProcessCodeMemAllowed = bit(16), ## /< Unmap process code memory allowed. + MemStateTransferMemAllowed = bit(17), ## /< Transfer memory allowed. + MemStateQueryPAddrAllowed = bit(18), ## /< Query physical address allowed. + MemStateMapDeviceAllowed = bit(19), ## /< Map device allowed (\ref svcMapDeviceAddressSpace and \ref svcMapDeviceAddressSpaceByForce). + MemStateMapDeviceAlignedAllowed = bit(20), ## /< Map device aligned allowed. + MemStateIpcBufferAllowed = bit(21), ## /< IPC buffer allowed. + MemStateIsPoolAllocated = bit(22), ## /< Is pool allocated. + MemStateMapProcessAllowed = bit(23), ## /< Map process allowed. + MemStateAttrChangeAllowed = bit(24), ## /< Attribute change allowed. + MemStateCodeMemAllowed = bit(25) ## /< Code memory allowed. + +const + MemStateIsRefCounted* = MemStateIsPoolAllocated ## /< Alias for \ref MemState_IsPoolAllocated. + +## / Memory attribute bitmasks. + +type + MemoryAttribute* = enum + MemAttrIsBorrowed = bit(0), ## /< Is borrowed memory. + MemAttrIsIpcMapped = bit(1), ## /< Is IPC mapped (when IpcRefCount > 0). + MemAttrIsDeviceMapped = bit(2), ## /< Is device mapped (when DeviceRefCount > 0). + MemAttrIsUncached = bit(3) ## /< Is uncached. + + +## / Memory permission bitmasks. + +type + Permission* = enum + PermNone = 0, ## /< No permissions. + PermR = bit(0), ## /< Read permission. + PermW = bit(1), ## /< Write permission. + PermRw = PermR.uint or PermW.uint, ## /< Read/write permissions. + PermX = bit(2), ## /< Execute permission. + PermRx = PermR.uint or PermX.uint, ## /< Read/execute permissions. + PermDontCare = bit(28) ## /< Don't care + + +## / Memory information structure. + +type + MemoryInfo* {.bycopy.} = object + `addr`*: U64 ## /< Base address. + size*: U64 ## /< Size. + `type`*: U32 ## /< Memory type (see lower 8 bits of \ref MemoryState). + attr*: U32 ## /< Memory attributes (see \ref MemoryAttribute). + perm*: U32 ## /< Memory permissions (see \ref Permission). + ipcRefcount*: U32 ## /< IPC reference count. + deviceRefcount*: U32 ## /< Device reference count. + padding*: U32 ## /< Padding. + + +## / Physical memory information structure. + +type + PhysicalMemoryInfo* {.bycopy.} = object + physicalAddress*: U64 ## /< Physical address. + virtualAddress*: U64 ## /< Virtual address. + size*: U64 ## /< Size. + + +## / Secure monitor arguments. + +type + SecmonArgs* {.bycopy.} = object + x*: array[8, U64] ## /< Values of X0 through X7. + + +## / Break reasons + +type + BreakReason* = enum + BreakReasonPanic = 0, BreakReasonAssert = 1, BreakReasonUser = 2, + BreakReasonPreLoadDll = 3, BreakReasonPostLoadDll = 4, + BreakReasonPreUnloadDll = 5, BreakReasonPostUnloadDll = 6, + BreakReasonCppException = 7, BreakReasonNotificationOnlyFlag = 0x80000000 + + +## / Code memory mapping operations + +type + CodeMapOperation* = enum + CodeMapOperationMapOwner = 0, ## /< Map owner. + CodeMapOperationMapSlave = 1, ## /< Map slave. + CodeMapOperationUnmapOwner = 2, ## /< Unmap owner. + CodeMapOperationUnmapSlave = 3 ## /< Unmap slave. + + +## / Limitable Resources. + +type + LimitableResource* = enum + LimitableResourceMemory = 0, ## /switchbrew.org Wiki for more details. +## @note Syscall number 0x03. +## + +proc svcMapMemory*(dstAddr: pointer; srcAddr: pointer; size: U64): Result {.cdecl, + importc: "svcMapMemory".} +## * +## @brief Maps a memory range into a different range. Mainly used for adding guard pages around stack. +## Source range gets reprotected to Perm_None (it can no longer be accessed), and \ref MemAttr_IsBorrowed is set in the source \ref MemoryAttribute. +## @param[in] dst_addr Destination address. +## @param[in] src_addr Source address. +## @param[in] size Size of the range. +## @return Result code. +## @note Syscall number 0x04. +## + +proc svcUnmapMemory*(dstAddr: pointer; srcAddr: pointer; size: U64): Result {.cdecl, + importc: "svcUnmapMemory".} +## * +## @brief Unmaps a region that was previously mapped with \ref svcMapMemory. +## @param[in] dst_addr Destination address. +## @param[in] src_addr Source address. +## @param[in] size Size of the range. +## @return Result code. +## @note Syscall number 0x05. +## + +proc svcQueryMemory*(meminfoPtr: ptr MemoryInfo; pageinfo: ptr U32; `addr`: U64): Result {. + cdecl, importc: "svcQueryMemory".} +## * +## @brief Query information about an address. Will always fetch the lowest page-aligned mapping that contains the provided address. +## @param[out] meminfo_ptr \ref MemoryInfo structure which will be filled in. +## @param[out] pageinfo Page information which will be filled in. +## @param[in] addr Address to query. +## @return Result code. +## @note Syscall number 0x06. +## + +proc svcExitProcess*() {.cdecl, importc: "svcExitProcess".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Exits the current process. +## @note Syscall number 0x07. +## + +proc svcCreateThread*(`out`: ptr Handle; entry: pointer; arg: pointer; + stackTop: pointer; prio: cint; cpuid: cint): Result {.cdecl, + importc: "svcCreateThread".} +## * +## @brief Creates a thread. +## @return Result code. +## @note Syscall number 0x08. +## + +proc svcStartThread*(handle: Handle): Result {.cdecl, importc: "svcStartThread".} +## * +## @brief Starts a freshly created thread. +## @return Result code. +## @note Syscall number 0x09. +## + +proc svcExitThread*() {.cdecl, importc: "svcExitThread".} +## * +## @brief Exits the current thread. +## @note Syscall number 0x0A. +## + +proc svcSleepThread*(nano: S64) {.cdecl, importc: "svcSleepThread".} +## * +## @brief Sleeps the current thread for the specified amount of time. +## @param[in] nano Number of nanoseconds to sleep, or \ref YieldType for yield. +## @note Syscall number 0x0B. +## + +proc svcGetThreadPriority*(priority: ptr S32; handle: Handle): Result {.cdecl, + importc: "svcGetThreadPriority".} +## * +## @brief Gets a thread's priority. +## @return Result code. +## @note Syscall number 0x0C. +## + +proc svcSetThreadPriority*(handle: Handle; priority: U32): Result {.cdecl, + importc: "svcSetThreadPriority".} +## * +## @brief Sets a thread's priority. +## @return Result code. +## @note Syscall number 0x0D. +## + +proc svcGetThreadCoreMask*(preferredCore: ptr S32; affinityMask: ptr U64; + handle: Handle): Result {.cdecl, + importc: "svcGetThreadCoreMask".} +## * +## @brief Gets a thread's core mask. +## @return Result code. +## @note Syscall number 0x0E. +## + +proc svcSetThreadCoreMask*(handle: Handle; preferredCore: S32; affinityMask: U32): Result {. + cdecl, importc: "svcSetThreadCoreMask".} +## * +## @brief Sets a thread's core mask. +## @return Result code. +## @note Syscall number 0x0F. +## + +proc svcGetCurrentProcessorNumber*(): U32 {.cdecl, + importc: "svcGetCurrentProcessorNumber".} +## * +## @brief Gets the current processor's number. +## @return The current processor's number. +## @note Syscall number 0x10. +## + +proc svcSignalEvent*(handle: Handle): Result {.cdecl, importc: "svcSignalEvent".} +## /@} +## /@name Synchronization +## /@{ +## * +## @brief Sets an event's signalled status. +## @return Result code. +## @note Syscall number 0x11. +## + +proc svcClearEvent*(handle: Handle): Result {.cdecl, importc: "svcClearEvent".} +## * +## @brief Clears an event's signalled status. +## @return Result code. +## @note Syscall number 0x12. +## + +proc svcMapSharedMemory*(handle: Handle; `addr`: pointer; size: csize_t; perm: U32): Result {. + cdecl, importc: "svcMapSharedMemory".} +## /@} +## /@name Inter-process memory sharing +## /@{ +## * +## @brief Maps a block of shared memory. +## @return Result code. +## @note Syscall number 0x13. +## + +proc svcUnmapSharedMemory*(handle: Handle; `addr`: pointer; size: csize_t): Result {. + cdecl, importc: "svcUnmapSharedMemory".} +## * +## @brief Unmaps a block of shared memory. +## @return Result code. +## @note Syscall number 0x14. +## + +proc svcCreateTransferMemory*(`out`: ptr Handle; `addr`: pointer; size: csize_t; + perm: U32): Result {.cdecl, + importc: "svcCreateTransferMemory".} +## * +## @brief Creates a block of transfer memory. +## @return Result code. +## @note Syscall number 0x15. +## + +proc svcCloseHandle*(handle: Handle): Result {.cdecl, importc: "svcCloseHandle".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Closes a handle, decrementing the reference count of the corresponding kernel object. +## This might result in the kernel freeing the object. +## @param handle Handle to close. +## @return Result code. +## @note Syscall number 0x16. +## + +proc svcResetSignal*(handle: Handle): Result {.cdecl, importc: "svcResetSignal".} +## /@} +## /@name Synchronization +## /@{ +## * +## @brief Resets a signal. +## @return Result code. +## @note Syscall number 0x17. +## + +proc svcWaitSynchronization*(index: ptr S32; handles: ptr Handle; handleCount: S32; + timeout: U64): Result {.cdecl, + importc: "svcWaitSynchronization".} +## /@} +## /@name Synchronization +## /@{ +## * +## @brief Waits on one or more synchronization objects, optionally with a timeout. +## @return Result code. +## @note Syscall number 0x18. +## @note \p handleCount must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. +## @note This is the raw syscall, which can be cancelled by \ref svcCancelSynchronization or other means. \ref waitHandles or \ref waitMultiHandle should normally be used instead. +## + +proc svcWaitSynchronizationSingle*(handle: Handle; timeout: U64): Result {.inline, cdecl.} = + ## * + ## @brief Waits on a single synchronization object, optionally with a timeout. + ## @return Result code. + ## @note Wrapper for \ref svcWaitSynchronization. + ## @note This is the raw syscall, which can be cancelled by \ref svcCancelSynchronization or other means. \ref waitSingleHandle should normally be used instead. + ## + var tmp: S32 + return svcWaitSynchronization(addr(tmp), addr(handle), 1, timeout) + +proc svcCancelSynchronization*(thread: Handle): Result {.cdecl, + importc: "svcCancelSynchronization".} +## * +## @brief Waits a \ref svcWaitSynchronization operation being done on a synchronization object in another thread. +## @return Result code. +## @note Syscall number 0x19. +## + +proc svcArbitrateLock*(waitTag: U32; tagLocation: ptr U32; selfTag: U32): Result {.cdecl, + importc: "svcArbitrateLock".} +## * +## @brief Arbitrates a mutex lock operation in userspace. +## @return Result code. +## @note Syscall number 0x1A. +## + +proc svcArbitrateUnlock*(tagLocation: ptr U32): Result {.cdecl, + importc: "svcArbitrateUnlock".} +## * +## @brief Arbitrates a mutex unlock operation in userspace. +## @return Result code. +## @note Syscall number 0x1B. +## + +proc svcWaitProcessWideKeyAtomic*(key: ptr U32; tagLocation: ptr U32; selfTag: U32; + timeout: U64): Result {.cdecl, + importc: "svcWaitProcessWideKeyAtomic".} +## * +## @brief Performs a condition variable wait operation in userspace. +## @return Result code. +## @note Syscall number 0x1C. +## + +proc svcSignalProcessWideKey*(key: ptr U32; num: S32) {.cdecl, + importc: "svcSignalProcessWideKey".} +## * +## @brief Performs a condition variable wake-up operation in userspace. +## @note Syscall number 0x1D. +## + +proc svcGetSystemTick*(): U64 {.cdecl, importc: "svcGetSystemTick".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Gets the current system tick. +## @return The current system tick. +## @note Syscall number 0x1E. +## + +proc svcConnectToNamedPort*(session: ptr Handle; name: cstring): Result {.cdecl, + importc: "svcConnectToNamedPort".} +## /@} +## /@name Inter-process communication (IPC) +## /@{ +## * +## @brief Connects to a registered named port. +## @return Result code. +## @note Syscall number 0x1F. +## + +proc svcSendSyncRequestLight*(session: Handle): Result {.cdecl, + importc: "svcSendSyncRequestLight".} +## * +## @brief Sends a light IPC synchronization request to a session. +## @return Result code. +## @note Syscall number 0x20. +## + +proc svcSendSyncRequest*(session: Handle): Result {.cdecl, + importc: "svcSendSyncRequest".} +## * +## @brief Sends an IPC synchronization request to a session. +## @return Result code. +## @note Syscall number 0x21. +## + +proc svcSendSyncRequestWithUserBuffer*(usrBuffer: pointer; size: U64; session: Handle): Result {. + cdecl, importc: "svcSendSyncRequestWithUserBuffer".} +## * +## @brief Sends an IPC synchronization request to a session from an user allocated buffer. +## @return Result code. +## @remark size must be allocated to 0x1000 bytes. +## @note Syscall number 0x22. +## + +proc svcSendAsyncRequestWithUserBuffer*(handle: ptr Handle; usrBuffer: pointer; + size: U64; session: Handle): Result {.cdecl, + importc: "svcSendAsyncRequestWithUserBuffer".} +## * +## @brief Sends an IPC synchronization request to a session from an user allocated buffer (asynchronous version). +## @return Result code. +## @remark size must be allocated to 0x1000 bytes. +## @note Syscall number 0x23. +## + +proc svcGetProcessId*(processID: ptr U64; handle: Handle): Result {.cdecl, + importc: "svcGetProcessId".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Gets the PID associated with a process. +## @return Result code. +## @note Syscall number 0x24. +## + +proc svcGetThreadId*(threadID: ptr U64; handle: Handle): Result {.cdecl, + importc: "svcGetThreadId".} +## * +## @brief Gets the TID associated with a process. +## @return Result code. +## @note Syscall number 0x25. + +proc svcBreak*(breakReason: U32; address: uintptrT; size: uintptrT): Result {.cdecl, + importc: "svcBreak".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Breaks execution. +## @param[in] breakReason Break reason (see \ref BreakReason). +## @param[in] address Address of the buffer to pass to the debugger. +## @param[in] size Size of the buffer to pass to the debugger. +## @return Result code. +## @note Syscall number 0x26. +## + +proc svcOutputDebugString*(str: cstring; size: U64): Result {.cdecl, + importc: "svcOutputDebugString".} +## /@} +## /@name Debugging +## /@{ +## * +## @brief Outputs debug text, if used during debugging. +## @param[in] str Text to output. +## @param[in] size Size of the text in bytes. +## @return Result code. +## @note Syscall number 0x27. +## + +proc svcReturnFromException*(res: Result) {.cdecl, importc: "svcReturnFromException".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Returns from an exception. +## @param[in] res Result code. +## @note Syscall number 0x28. +## + +proc svcGetInfo*(`out`: ptr U64; id0: U32; handle: Handle; id1: U64): Result {.cdecl, + importc: "svcGetInfo".} +## * +## @brief Retrieves information about the system, or a certain kernel object. +## @param[out] out Variable to which store the information. +## @param[in] id0 First ID of the property to retrieve. +## @param[in] handle Handle of the object to retrieve information from, or \ref INVALID_HANDLE to retrieve information about the system. +## @param[in] id1 Second ID of the property to retrieve. +## @return Result code. +## @remark The full list of property IDs can be found on the switchbrew.org wiki. +## @note Syscall number 0x29. +## + +proc svcFlushEntireDataCache*() {.cdecl, importc: "svcFlushEntireDataCache".} +## /@} +## /@name Cache Management +## /@{ +## * +## @brief Flushes the entire data cache (by set/way). +## @note Syscall number 0x2A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## @warning This syscall is dangerous, and should not be used. +## + +proc svcFlushDataCache*(address: pointer; size: csize_t): Result {.cdecl, + importc: "svcFlushDataCache".} +## * +## @brief Flushes data cache for a virtual address range. +## @param[in] address Address of region to flush. +## @param[in] size Size of region to flush. +## @remark armDCacheFlush should be used instead of this syscall whenever possible. +## @note Syscall number 0x2B. +## + +proc svcMapPhysicalMemory*(address: pointer; size: U64): Result {.cdecl, + importc: "svcMapPhysicalMemory".} +## /@} +## /@name Memory management +## /@{ +## * +## @brief Maps new heap memory at the desired address. [3.0.0+] +## @return Result code. +## @note Syscall number 0x2C. +## + +proc svcUnmapPhysicalMemory*(address: pointer; size: U64): Result {.cdecl, + importc: "svcUnmapPhysicalMemory".} +## * +## @brief Undoes the effects of \ref svcMapPhysicalMemory. [3.0.0+] +## @return Result code. +## @note Syscall number 0x2D. +## + +proc svcGetDebugFutureThreadInfo*(outContext: ptr LastThreadContext; + outThreadId: ptr U64; debug: Handle; ns: S64): Result {. + cdecl, importc: "svcGetDebugFutureThreadInfo".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Gets information about a thread that will be scheduled in the future. [5.0.0+] +## @param[out] out_context Output \ref LastThreadContext for the thread that will be scheduled. +## @param[out] out_thread_id Output thread id for the thread that will be scheduled. +## @param[in] debug Debug handle. +## @param[in] ns Nanoseconds in the future to get scheduled thread at. +## @return Result code. +## @note Syscall number 0x2E. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetLastThreadInfo*(outContext: ptr LastThreadContext; + outTlsAddress: ptr U64; outFlags: ptr U32): Result {.cdecl, + importc: "svcGetLastThreadInfo".} +## * +## @brief Gets information about the previously-scheduled thread. +## @param[out] out_context Output \ref LastThreadContext for the previously scheduled thread. +## @param[out] out_tls_address Output tls address for the previously scheduled thread. +## @param[out] out_flags Output flags for the previously scheduled thread. +## @return Result code. +## @note Syscall number 0x2F. +## + +proc svcGetResourceLimitLimitValue*(`out`: ptr S64; reslimitH: Handle; + which: LimitableResource): Result {.cdecl, + importc: "svcGetResourceLimitLimitValue".} +## /@} +## /@name Resource Limit Management +## /@{ +## * +## @brief Gets the maximum value a LimitableResource can have, for a Resource Limit handle. +## @return Result code. +## @note Syscall number 0x30. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetResourceLimitCurrentValue*(`out`: ptr S64; reslimitH: Handle; + which: LimitableResource): Result {.cdecl, + importc: "svcGetResourceLimitCurrentValue".} +## * +## @brief Gets the maximum value a LimitableResource can have, for a Resource Limit handle. +## @return Result code. +## @note Syscall number 0x31. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetThreadActivity*(thread: Handle; paused: ThreadActivity): Result {.cdecl, + importc: "svcSetThreadActivity".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Configures the pause/unpause status of a thread. +## @return Result code. +## @note Syscall number 0x32. +## + +proc svcGetThreadContext3*(ctx: ptr ThreadContext; thread: Handle): Result {.cdecl, + importc: "svcGetThreadContext3".} +## * +## @brief Dumps the registers of a thread paused by @ref svcSetThreadActivity (register groups: all). +## @param[out] ctx Output thread context (register dump). +## @param[in] thread Thread handle. +## @return Result code. +## @note Syscall number 0x33. +## @warning Official kernel will not dump x0..x18 if the thread is currently executing a system call, and prior to 6.0.0 doesn't dump TPIDR_EL0. +## + +proc svcWaitForAddress*(address: pointer; arbType: U32; value: S32; timeout: S64): Result {. + cdecl, importc: "svcWaitForAddress".} +## /@} +## /@name Synchronization +## /@{ +## * +## @brief Arbitrates an address depending on type and value. [4.0.0+] +## @param[in] address Address to arbitrate. +## @param[in] arb_type \ref ArbitrationType to use. +## @param[in] value Value to arbitrate on. +## @param[in] timeout Maximum time in nanoseconds to wait. +## @return Result code. +## @note Syscall number 0x34. +## + +proc svcSignalToAddress*(address: pointer; signalType: U32; value: S32; count: S32): Result {. + cdecl, importc: "svcSignalToAddress".} +## * +## @brief Signals (and updates) an address depending on type and value. [4.0.0+] +## @param[in] address Address to arbitrate. +## @param[in] signal_type \ref SignalType to use. +## @param[in] value Value to arbitrate on. +## @param[in] count Number of waiting threads to signal. +## @return Result code. +## @note Syscall number 0x35. +## + +proc svcSynchronizePreemptionState*() {.cdecl, + importc: "svcSynchronizePreemptionState".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Sets thread preemption state (used during abort/panic). [8.0.0+] +## @note Syscall number 0x36. +## + +proc svcGetResourceLimitPeakValue*(`out`: ptr S64; reslimitH: Handle; + which: LimitableResource): Result {.cdecl, + importc: "svcGetResourceLimitPeakValue".} +## /@} +## /@name Resource Limit Management +## /@{ +## * +## @brief Gets the peak value a LimitableResource has had, for a Resource Limit handle. [11.0.0+] +## @return Result code. +## @note Syscall number 0x37. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateIoPool*(outHandle: ptr Handle; poolType: U32): Result {.cdecl, + importc: "svcCreateIoPool".} +## /@} +## /@name Memory Management +## /@{ +## * +## @brief Creates an IO Pool. [13.0.0+] +## @return Result code. +## @note Syscall number 0x39. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateIoRegion*(outHandle: ptr Handle; ioPoolH: Handle; physicalAddress: U64; + size: U64; memoryMapping: U32; perm: U32): Result {.cdecl, + importc: "svcCreateIoRegion".} +## * +## @brief Creates an IO Region. [13.0.0+] +## @return Result code. +## @note Syscall number 0x3A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcDumpInfo*(dumpInfoType: U32; arg0: U64) {.cdecl, importc: "svcDumpInfo".} +## /@} +## /@name Debugging +## /@{ +## * +## @brief Causes the kernel to dump debug information. [1.0.0-3.0.2] +## @param[in] dump_info_type Type of information to dump. +## @param[in] arg0 Argument to the debugging operation. +## @note Syscall number 0x3C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcKernelDebug*(kernDebugType: U32; arg0: U64; arg1: U64; arg2: U64) {.cdecl, + importc: "svcKernelDebug".} +## * +## @brief Performs a debugging operation on the kernel. [4.0.0+] +## @param[in] kern_debug_type Type of debugging operation to perform. +## @param[in] arg0 First argument to the debugging operation. +## @param[in] arg1 Second argument to the debugging operation. +## @param[in] arg2 Third argument to the debugging operation. +## @note Syscall number 0x3C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcChangeKernelTraceState*(kernTraceState: U32) {.cdecl, + importc: "svcChangeKernelTraceState".} +## * +## @brief Performs a debugging operation on the kernel. [4.0.0+] +## @param[in] kern_trace_state Type of tracing the kernel should perform. +## @note Syscall number 0x3D. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateSession*(serverHandle: ptr Handle; clientHandle: ptr Handle; unk0: U32; + unk1: U64): Result {.cdecl, importc: "svcCreateSession".} +## /@} +## /@name Inter-process communication (IPC) +## /@{ +## * +## @brief Creates an IPC session. +## @return Result code. +## @note Syscall number 0x40. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcAcceptSession*(sessionHandle: ptr Handle; portHandle: Handle): Result {.cdecl, + importc: "svcAcceptSession".} +## unk* are normally 0? +## * +## @brief Accepts an IPC session. +## @return Result code. +## @note Syscall number 0x41. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcReplyAndReceiveLight*(handle: Handle): Result {.cdecl, + importc: "svcReplyAndReceiveLight".} +## * +## @brief Performs light IPC input/output. +## @return Result code. +## @param[in] handle Server or port handle to act on. +## @note Syscall number 0x42. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcReplyAndReceive*(index: ptr S32; handles: ptr Handle; handleCount: S32; + replyTarget: Handle; timeout: U64): Result {.cdecl, + importc: "svcReplyAndReceive".} +## * +## @brief Performs IPC input/output. +## @return Result code. +## @note Syscall number 0x43. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcReplyAndReceiveWithUserBuffer*(index: ptr S32; usrBuffer: pointer; size: U64; + handles: ptr Handle; handleCount: S32; + replyTarget: Handle; timeout: U64): Result {. + cdecl, importc: "svcReplyAndReceiveWithUserBuffer".} +## * +## @brief Performs IPC input/output from an user allocated buffer. +## @return Result code. +## @note Syscall number 0x44. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateEvent*(serverHandle: ptr Handle; clientHandle: ptr Handle): Result {. + cdecl, importc: "svcCreateEvent".} +## /@} +## /@name Synchronization +## /@{ +## * +## @brief Creates a system event. +## @return Result code. +## @note Syscall number 0x45. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapIoRegion*(ioRegionH: Handle; address: pointer; size: U64; perm: U32): Result {. + cdecl, importc: "svcMapIoRegion".} +## /@} +## /@name Memory management +## /@{ +## * +## @brief Maps an IO Region. [13.0.0+] +## @return Result code. +## @note Syscall number 0x46. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapIoRegion*(ioRegionH: Handle; address: pointer; size: U64): Result {.cdecl, + importc: "svcUnmapIoRegion".} +## * +## @brief Undoes the effects of \ref svcMapIoRegion. [13.0.0+] +## @return Result code. +## @note Syscall number 0x47. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapPhysicalMemoryUnsafe*(address: pointer; size: U64): Result {.cdecl, + importc: "svcMapPhysicalMemoryUnsafe".} +## * +## @brief Maps unsafe memory (usable for GPU DMA) for a system module at the desired address. [5.0.0+] +## @return Result code. +## @note Syscall number 0x48. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapPhysicalMemoryUnsafe*(address: pointer; size: U64): Result {.cdecl, + importc: "svcUnmapPhysicalMemoryUnsafe".} +## * +## @brief Undoes the effects of \ref svcMapPhysicalMemoryUnsafe. [5.0.0+] +## @return Result code. +## @note Syscall number 0x49. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetUnsafeLimit*(size: U64): Result {.cdecl, importc: "svcSetUnsafeLimit".} +## * +## @brief Sets the system-wide limit for unsafe memory mappable using \ref svcMapPhysicalMemoryUnsafe. [5.0.0+] +## @return Result code. +## @note Syscall number 0x4A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateCodeMemory*(codeHandle: ptr Handle; srcAddr: pointer; size: U64): Result {. + cdecl, importc: "svcCreateCodeMemory".} +## /@} +## /@name Code memory / Just-in-time (JIT) compilation support +## /@{ +## * +## @brief Creates code memory in the caller's address space [4.0.0+]. +## @return Result code. +## @note Syscall number 0x4B. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcControlCodeMemory*(codeHandle: Handle; op: CodeMapOperation; + dstAddr: pointer; size: U64; perm: U64): Result {.cdecl, + importc: "svcControlCodeMemory".} +## * +## @brief Maps code memory in the caller's address space [4.0.0+]. +## @return Result code. +## @note Syscall number 0x4C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSleepSystem*() {.cdecl, importc: "svcSleepSystem".} +## /@} +## /@name Power Management +## /@{ +## * +## @brief Causes the system to enter deep sleep. +## @note Syscall number 0x4D. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcReadWriteRegister*(outVal: ptr U32; regAddr: U64; rwMask: U32; inVal: U32): Result {. + cdecl, importc: "svcReadWriteRegister".} +## /@} +## /@name Device memory-mapped I/O (MMIO) +## /@{ +## * +## @brief Reads/writes a protected MMIO register. +## @return Result code. +## @note Syscall number 0x4E. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetProcessActivity*(process: Handle; paused: ProcessActivity): Result {.cdecl, + importc: "svcSetProcessActivity".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Configures the pause/unpause status of a process. +## @return Result code. +## @note Syscall number 0x4F. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateSharedMemory*(`out`: ptr Handle; size: csize_t; localPerm: U32; + otherPerm: U32): Result {.cdecl, + importc: "svcCreateSharedMemory".} +## /@} +## /@name Inter-process memory sharing +## /@{ +## * +## @brief Creates a block of shared memory. +## @return Result code. +## @note Syscall number 0x50. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapTransferMemory*(tmemHandle: Handle; `addr`: pointer; size: csize_t; + perm: U32): Result {.cdecl, + importc: "svcMapTransferMemory".} +## * +## @brief Maps a block of transfer memory. +## @return Result code. +## @note Syscall number 0x51. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapTransferMemory*(tmemHandle: Handle; `addr`: pointer; size: csize_t): Result {. + cdecl, importc: "svcUnmapTransferMemory".} +## * +## @brief Unmaps a block of transfer memory. +## @return Result code. +## @note Syscall number 0x52. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateInterruptEvent*(handle: ptr Handle; irqNum: U64; flag: U32): Result {. + cdecl, importc: "svcCreateInterruptEvent".} +## /@} +## /@name Device memory-mapped I/O (MMIO) +## /@{ +## * +## @brief Creates an event and binds it to a specific hardware interrupt. +## @return Result code. +## @note Syscall number 0x53. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcQueryPhysicalAddress*(`out`: ptr PhysicalMemoryInfo; virtaddr: U64): Result {. + cdecl, importc: "svcQueryPhysicalAddress".} +## * +## @brief Queries information about a certain virtual address, including its physical address. +## @return Result code. +## @note Syscall number 0x54. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcQueryIoMapping*(virtaddr: ptr U64; outSize: ptr U64; physaddr: U64; size: U64): Result {. + cdecl, importc: "svcQueryIoMapping".} +## * +## @brief Returns a virtual address mapped to a given IO range. +## @return Result code. +## @note Syscall number 0x55. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping. +## + +proc svcLegacyQueryIoMapping*(virtaddr: ptr U64; physaddr: U64; size: U64): Result {. + cdecl, importc: "svcLegacyQueryIoMapping".} +## * +## @brief Returns a virtual address mapped to a given IO range. +## @return Result code. +## @note Syscall number 0x55. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping. +## + +proc svcCreateDeviceAddressSpace*(handle: ptr Handle; devAddr: U64; devSize: U64): Result {. + cdecl, importc: "svcCreateDeviceAddressSpace".} +## /@} +## /@name I/O memory management unit (IOMMU) +## /@{ +## * +## @brief Creates a virtual address space for binding device address spaces. +## @return Result code. +## @note Syscall number 0x56. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcAttachDeviceAddressSpace*(device: U64; handle: Handle): Result {.cdecl, + importc: "svcAttachDeviceAddressSpace".} +## * +## @brief Attaches a device address space to a device. +## @return Result code. +## @note Syscall number 0x57. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcDetachDeviceAddressSpace*(device: U64; handle: Handle): Result {.cdecl, + importc: "svcDetachDeviceAddressSpace".} +## * +## @brief Detaches a device address space from a device. +## @return Result code. +## @note Syscall number 0x58. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapDeviceAddressSpaceByForce*(handle: Handle; procHandle: Handle; + mapAddr: U64; devSize: U64; devAddr: U64; + option: U32): Result {.cdecl, + importc: "svcMapDeviceAddressSpaceByForce".} +## * +## @brief Maps an attached device address space to an userspace address. +## @return Result code. +## @remark The userspace destination address must have the \ref MemState_MapDeviceAllowed bit set. +## @note Syscall number 0x59. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapDeviceAddressSpaceAligned*(handle: Handle; procHandle: Handle; + mapAddr: U64; devSize: U64; devAddr: U64; + option: U32): Result {.cdecl, + importc: "svcMapDeviceAddressSpaceAligned".} +## * +## @brief Maps an attached device address space to an userspace address. +## @return Result code. +## @remark The userspace destination address must have the \ref MemState_MapDeviceAlignedAllowed bit set. +## @note Syscall number 0x5A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapDeviceAddressSpace*(outMappedSize: ptr U64; handle: Handle; + procHandle: Handle; mapAddr: U64; devSize: U64; + devAddr: U64; perm: U32): Result {.cdecl, + importc: "svcMapDeviceAddressSpace".} +## * +## @brief Maps an attached device address space to an userspace address. [1.0.0-12.1.0] +## @return Result code. +## @remark The userspace destination address must have the \ref MemState_MapDeviceAlignedAllowed bit set. +## @note Syscall number 0x5B. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapDeviceAddressSpace*(handle: Handle; procHandle: Handle; mapAddr: U64; + mapSize: U64; devAddr: U64): Result {.cdecl, + importc: "svcUnmapDeviceAddressSpace".} +## * +## @brief Unmaps an attached device address space from an userspace address. +## @return Result code. +## @note Syscall number 0x5C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcInvalidateProcessDataCache*(process: Handle; address: uintptrT; size: csize_t): Result {. + cdecl, importc: "svcInvalidateProcessDataCache".} +## /@} +## /@name Cache Management +## /@{ +## * +## @brief Invalidates data cache for a virtual address range within a process. +## @param[in] address Address of region to invalidate. +## @param[in] size Size of region to invalidate. +## @note Syscall number 0x5D. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcStoreProcessDataCache*(process: Handle; address: uintptrT; size: csize_t): Result {. + cdecl, importc: "svcStoreProcessDataCache".} +## * +## @brief Stores data cache for a virtual address range within a process. +## @param[in] address Address of region to store. +## @param[in] size Size of region to store. +## @note Syscall number 0x5E. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcFlushProcessDataCache*(process: Handle; address: uintptrT; size: csize_t): Result {. + cdecl, importc: "svcFlushProcessDataCache".} +## * +## @brief Flushes data cache for a virtual address range within a process. +## @param[in] address Address of region to flush. +## @param[in] size Size of region to flush. +## @note Syscall number 0x5F. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcDebugActiveProcess*(debug: ptr Handle; processID: U64): Result {.cdecl, + importc: "svcDebugActiveProcess".} +## /@} +## /@name Debugging +## /@{ +## * +## @brief Debugs an active process. +## @return Result code. +## @note Syscall number 0x60. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcBreakDebugProcess*(debug: Handle): Result {.cdecl, + importc: "svcBreakDebugProcess".} +## * +## @brief Breaks an active debugging session. +## @return Result code. +## @note Syscall number 0x61. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcTerminateDebugProcess*(debug: Handle): Result {.cdecl, + importc: "svcTerminateDebugProcess".} +## * +## @brief Terminates the process of an active debugging session. +## @return Result code. +## @note Syscall number 0x62. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetDebugEvent*(eventOut: pointer; debug: Handle): Result {.cdecl, + importc: "svcGetDebugEvent".} +## * +## @brief Gets an incoming debug event from a debugging session. +## @return Result code. +## @note Syscall number 0x63. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcContinueDebugEvent*(debug: Handle; flags: U32; tidList: ptr U64; numTids: U32): Result {. + cdecl, importc: "svcContinueDebugEvent".} +## * +## @brief Continues a debugging session. +## @return Result code. +## @note Syscall number 0x64. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## @warning Only exists on [3.0.0+]. For older versions use \ref svcLegacyContinueDebugEvent. +## + +proc svcLegacyContinueDebugEvent*(debug: Handle; flags: U32; threadID: U64): Result {. + cdecl, importc: "svcLegacyContinueDebugEvent".} +## * +## @brief Continues a debugging session. +## @return Result code. +## @note Syscall number 0x64. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## @warning Only exists on [1.0.0-2.3.0]. For newer versions use \ref svcContinueDebugEvent. +## + +proc svcGetDebugThreadContext*(ctx: ptr ThreadContext; debug: Handle; threadID: U64; + flags: U32): Result {.cdecl, + importc: "svcGetDebugThreadContext".} +## * +## @brief Gets the context (dump the registers) of a thread in a debugging session. +## @return Result code. +## @param[out] ctx Output thread context (register dump). +## @param[in] debug Debug handle. +## @param[in] threadID ID of the thread to dump the context of. +## @param[in] flags Register groups to select, combination of @ref RegisterGroup flags. +## @note Syscall number 0x67. +## @warning Official kernel will not dump any CPU GPR if the thread is currently executing a system call (except @ref svcBreak and @ref svcReturnFromException). +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetDebugThreadContext*(debug: Handle; threadID: U64; ctx: ptr ThreadContext; + flags: U32): Result {.cdecl, + importc: "svcSetDebugThreadContext".} +## * +## @brief Gets the context (dump the registers) of a thread in a debugging session. +## @return Result code. +## @param[in] debug Debug handle. +## @param[in] threadID ID of the thread to set the context of. +## @param[in] ctx Input thread context (register dump). +## @param[in] flags Register groups to select, combination of @ref RegisterGroup flags. +## @note Syscall number 0x68. +## @warning Official kernel will return an error if the thread is currently executing a system call (except @ref svcBreak and @ref svcReturnFromException). +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetProcessList*(numOut: ptr S32; pidsOut: ptr U64; maxPids: U32): Result {.cdecl, + importc: "svcGetProcessList".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Retrieves a list of all running processes. +## @return Result code. +## @note Syscall number 0x65. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetThreadList*(numOut: ptr S32; tidsOut: ptr U64; maxTids: U32; debug: Handle): Result {. + cdecl, importc: "svcGetThreadList".} +## * +## @brief Retrieves a list of all threads for a debug handle (or zero). +## @return Result code. +## @note Syscall number 0x66. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcQueryDebugProcessMemory*(meminfoPtr: ptr MemoryInfo; pageinfo: ptr U32; + debug: Handle; `addr`: U64): Result {.cdecl, + importc: "svcQueryDebugProcessMemory".} +## /@} +## /@name Debugging +## /@{ +## * +## @brief Queries memory information from a process that is being debugged. +## @return Result code. +## @note Syscall number 0x69. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcReadDebugProcessMemory*(buffer: pointer; debug: Handle; `addr`: U64; size: U64): Result {. + cdecl, importc: "svcReadDebugProcessMemory".} +## * +## @brief Reads memory from a process that is being debugged. +## @return Result code. +## @note Syscall number 0x6A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcWriteDebugProcessMemory*(debug: Handle; buffer: pointer; `addr`: U64; size: U64): Result {. + cdecl, importc: "svcWriteDebugProcessMemory".} +## * +## @brief Writes to memory in a process that is being debugged. +## @return Result code. +## @note Syscall number 0x6B. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetHardwareBreakPoint*(which: U32; flags: U64; value: U64): Result {.cdecl, + importc: "svcSetHardwareBreakPoint".} +## * +## @brief Sets one of the hardware breakpoints. +## @return Result code. +## @note Syscall number 0x6C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetDebugThreadParam*(out64: ptr U64; out32: ptr U32; debug: Handle; + threadID: U64; param: DebugThreadParam): Result {.cdecl, + importc: "svcGetDebugThreadParam".} +## * +## @brief Gets parameters from a thread in a debugging session. +## @return Result code. +## @note Syscall number 0x6D. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetSystemInfo*(`out`: ptr U64; id0: U64; handle: Handle; id1: U64): Result {.cdecl, + importc: "svcGetSystemInfo".} +## /@} +## /@name Miscellaneous +## /@{ +## * +## @brief Retrieves privileged information about the system, or a certain kernel object. +## @param[out] out Variable to which store the information. +## @param[in] id0 First ID of the property to retrieve. +## @param[in] handle Handle of the object to retrieve information from, or \ref INVALID_HANDLE to retrieve information about the system. +## @param[in] id1 Second ID of the property to retrieve. +## @return Result code. +## @remark The full list of property IDs can be found on the switchbrew.org wiki. +## @note Syscall number 0x6F. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreatePort*(portServer: ptr Handle; portClient: ptr Handle; maxSessions: S32; + isLight: bool; name: cstring): Result {.cdecl, + importc: "svcCreatePort".} +## /@} +## /@name Inter-process communication (IPC) +## /@{ +## * +## @brief Creates a port. +## @return Result code. +## @note Syscall number 0x70. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcManageNamedPort*(portServer: ptr Handle; name: cstring; maxSessions: S32): Result {. + cdecl, importc: "svcManageNamedPort".} +## * +## @brief Manages a named port. +## @return Result code. +## @note Syscall number 0x71. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcConnectToPort*(session: ptr Handle; port: Handle): Result {.cdecl, + importc: "svcConnectToPort".} +## * +## @brief Manages a named port. +## @return Result code. +## @note Syscall number 0x72. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetProcessMemoryPermission*(`proc`: Handle; `addr`: U64; size: U64; perm: U32): Result {. + cdecl, importc: "svcSetProcessMemoryPermission".} +## /@} +## /@name Memory management +## /@{ +## * +## @brief Sets the memory permissions for the specified memory with the supplied process handle. +## @param[in] proc Process handle. +## @param[in] addr Address of the memory. +## @param[in] size Size of the memory. +## @param[in] perm Permissions (see \ref Permission). +## @return Result code. +## @remark This returns an error (0xD801) when \p perm is >0x5, hence -WX and RWX are not allowed. +## @note Syscall number 0x73. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapProcessMemory*(dst: pointer; `proc`: Handle; src: U64; size: U64): Result {. + cdecl, importc: "svcMapProcessMemory".} +## * +## @brief Maps the src address from the supplied process handle into the current process. +## @param[in] dst Address to which map the memory in the current process. +## @param[in] proc Process handle. +## @param[in] src Source mapping address. +## @param[in] size Size of the memory. +## @return Result code. +## @remark This allows mapping code and rodata with RW- permission. +## @note Syscall number 0x74. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapProcessMemory*(dst: pointer; `proc`: Handle; src: U64; size: U64): Result {. + cdecl, importc: "svcUnmapProcessMemory".} +## * +## @brief Undoes the effects of \ref svcMapProcessMemory. +## @param[in] dst Destination mapping address +## @param[in] proc Process handle. +## @param[in] src Address of the memory in the process. +## @param[in] size Size of the memory. +## @return Result code. +## @remark This allows mapping code and rodata with RW- permission. +## @note Syscall number 0x75. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcQueryProcessMemory*(meminfoPtr: ptr MemoryInfo; pageinfo: ptr U32; + `proc`: Handle; `addr`: U64): Result {.cdecl, + importc: "svcQueryProcessMemory".} +## * +## @brief Equivalent to \ref svcQueryMemory, for another process. +## @param[out] meminfo_ptr \ref MemoryInfo structure which will be filled in. +## @param[out] pageinfo Page information which will be filled in. +## @param[in] proc Process handle. +## @param[in] addr Address to query. +## @return Result code. +## @note Syscall number 0x76. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapProcessCodeMemory*(`proc`: Handle; dst: U64; src: U64; size: U64): Result {. + cdecl, importc: "svcMapProcessCodeMemory".} +## * +## @brief Maps normal heap in a certain process as executable code (used when loading NROs). +## @param[in] proc Process handle (cannot be \ref CUR_PROCESS_HANDLE). +## @param[in] dst Destination mapping address. +## @param[in] src Source mapping address. +## @param[in] size Size of the mapping. +## @return Result code. +## @note Syscall number 0x77. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcUnmapProcessCodeMemory*(`proc`: Handle; dst: U64; src: U64; size: U64): Result {. + cdecl, importc: "svcUnmapProcessCodeMemory".} +## * +## @brief Undoes the effects of \ref svcMapProcessCodeMemory. +## @param[in] proc Process handle (cannot be \ref CUR_PROCESS_HANDLE). +## @param[in] dst Destination mapping address. +## @param[in] src Source mapping address. +## @param[in] size Size of the mapping. +## @return Result code. +## @note Syscall number 0x78. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateProcess*(`out`: ptr Handle; procInfo: pointer; caps: ptr U32; capNum: U64): Result {. + cdecl, importc: "svcCreateProcess".} +## /@} +## /@name Process and thread management +## /@{ +## * +## @brief Creates a new process. +## @return Result code. +## @note Syscall number 0x79. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcStartProcess*(`proc`: Handle; mainPrio: S32; defaultCpu: S32; stackSize: U32): Result {. + cdecl, importc: "svcStartProcess".} +## * +## @brief Starts executing a freshly created process. +## @return Result code. +## @note Syscall number 0x7A. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcTerminateProcess*(`proc`: Handle): Result {.cdecl, + importc: "svcTerminateProcess".} +## * +## @brief Terminates a running process. +## @return Result code. +## @note Syscall number 0x7B. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcGetProcessInfo*(`out`: ptr S64; `proc`: Handle; which: ProcessInfoType): Result {. + cdecl, importc: "svcGetProcessInfo".} +## * +## @brief Gets a \ref ProcessInfoType for a process. +## @return Result code. +## @note Syscall number 0x7C. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCreateResourceLimit*(`out`: ptr Handle): Result {.cdecl, + importc: "svcCreateResourceLimit".} +## /@} +## /@name Resource Limit Management +## /@{ +## * +## @brief Creates a new Resource Limit handle. +## @return Result code. +## @note Syscall number 0x7D. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcSetResourceLimitLimitValue*(reslimit: Handle; which: LimitableResource; + value: U64): Result {.cdecl, + importc: "svcSetResourceLimitLimitValue".} +## * +## @brief Sets the value for a \ref LimitableResource for a Resource Limit handle. +## @return Result code. +## @note Syscall number 0x7E. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcCallSecureMonitor*(regs: ptr SecmonArgs) {.cdecl, + importc: "svcCallSecureMonitor".} +## /@} +## /@name ( ͡° ͜ʖ ͡°) +## /@{ +## * +## @brief Calls a secure monitor function (TrustZone, EL3). +## @param regs Arguments to pass to the secure monitor. +## @note Syscall number 0x7F. +## @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. +## + +proc svcMapInsecureMemory*(address: pointer; size: U64): Result {.cdecl, + importc: "svcMapInsecureMemory".} +## /@} +## /@name Memory management +## /@{ +## * +## @brief Maps new insecure memory at the desired address. [15.0.0+] +## @return Result code. +## @note Syscall number 0x90. +## + +proc svcUnmapInsecureMemory*(address: pointer; size: U64): Result {.cdecl, + importc: "svcUnmapInsecureMemory".} +## * +## @brief Undoes the effects of \ref svcMapInsecureMemory. [15.0.0+] +## @return Result code. +## @note Syscall number 0x91. +## diff --git a/src/libnx/wrapper/switch/kernel/thread.h b/src/libnx/wrapper/switch/kernel/thread.h new file mode 100644 index 0000000..89cc83b --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/thread.h @@ -0,0 +1,131 @@ +/** + * @file thread.h + * @brief Multi-threading support + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../arm/thread_context.h" +#include "wait.h" + +/// Thread information structure. +typedef struct Thread { + Handle handle; ///< Thread handle. + bool owns_stack_mem; ///< Whether the stack memory is automatically allocated. + void* stack_mem; ///< Pointer to stack memory. + void* stack_mirror; ///< Pointer to stack memory mirror. + size_t stack_sz; ///< Stack size. + void** tls_array; + struct Thread* next; + struct Thread** prev_next; +} Thread; + +/// Creates a \ref Waiter for a \ref Thread. +static inline Waiter waiterForThread(Thread* t) +{ + return waiterForHandle(t->handle); +} + +/** + * @brief Creates a thread. + * @param t Thread information structure which will be filled in. + * @param entry Entrypoint of the thread. + * @param arg Argument to pass to the entrypoint. + * @param stack_mem Memory to use as backing for stack/tls/reent. Must be page-aligned. NULL argument means to allocate new memory. + * @param stack_sz If stack_mem is NULL, size to use for stack. If stack_mem is non-NULL, size to use for stack + reent + tls (must be page-aligned). + * @param prio Thread priority (0x00~0x3F); 0x2C is the usual priority of the main thread, 0x3B is a special priority on cores 0..2 that enables preemptive multithreading (0x3F on core 3). + * @param cpuid ID of the core on which to create the thread (0~3); or -2 to use the default core for the current process. + * @return Result code. + */ +Result threadCreate( + Thread* t, ThreadFunc entry, void* arg, void *stack_mem, size_t stack_sz, + int prio, int cpuid); + +/** + * @brief Starts the execution of a thread. + * @param t Thread information structure. + * @return Result code. + */ +Result threadStart(Thread* t); + +/** + * @brief Exits the current thread immediately. + */ +void NORETURN threadExit(void); + +/** + * @brief Waits for a thread to finish executing. + * @param t Thread information structure. + * @return Result code. + */ +Result threadWaitForExit(Thread* t); + +/** + * @brief Frees up resources associated with a thread. + * @param t Thread information structure. + * @return Result code. + */ +Result threadClose(Thread* t); + +/** + * @brief Pauses the execution of a thread. + * @param t Thread information structure. + * @return Result code. + */ +Result threadPause(Thread* t); + +/** + * @brief Resumes the execution of a thread, after having been paused. + * @param t Thread information structure. + * @return Result code. + */ +Result threadResume(Thread* t); + +/** + * @brief Dumps the registers of a thread paused by @ref threadPause (register groups: all). + * @param[out] ctx Output thread context (register dump). + * @param t Thread information structure. + * @return Result code. + * @warning Official kernel will not dump x0..x18 if the thread is currently executing a system call, and prior to 6.0.0 doesn't dump TPIDR_EL0. + */ +Result threadDumpContext(ThreadContext* ctx, Thread* t); + +/** + * @brief Gets a pointer to the current thread structure. + * @return Thread information structure. + */ +Thread *threadGetSelf(void); + +/** + * @brief Gets the raw handle to the current thread. + * @return The current thread's handle. + */ +Handle threadGetCurHandle(void); + +/** + * @brief Allocates a TLS slot. + * @param destructor Function to run automatically when a thread exits. + * @return TLS slot ID on success, or a negative value on failure. + */ +s32 threadTlsAlloc(void (* destructor)(void*)); + +/** + * @brief Retrieves the value stored in a TLS slot. + * @param slot_id TLS slot ID. + * @return Value. + */ +void* threadTlsGet(s32 slot_id); + +/** + * @brief Stores the specified value into a TLS slot. + * @param slot_id TLS slot ID. + * @param value Value. + */ +void threadTlsSet(s32 slot_id, void* value); + +/** + * @brief Frees a TLS slot. + * @param slot_id TLS slot ID. + */ +void threadTlsFree(s32 slot_id); diff --git a/src/libnx/wrapper/switch/kernel/thread.nim b/src/libnx/wrapper/switch/kernel/thread.nim new file mode 100644 index 0000000..34724b7 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/thread.nim @@ -0,0 +1,132 @@ +## * +## @file thread.h +## @brief Multi-threading support +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../arm/thread_context, wait + +## / Thread information structure. + +type + Thread* {.bycopy.} = object + handle*: Handle ## /< Thread handle. + ownsStackMem*: bool ## /< Whether the stack memory is automatically allocated. + stackMem*: pointer ## /< Pointer to stack memory. + stackMirror*: pointer ## /< Pointer to stack memory mirror. + stackSz*: csize_t ## /< Stack size. + tlsArray*: ptr pointer + next*: ptr Thread + prevNext*: ptr ptr Thread + +proc waiterForThread*(t: ptr Thread): Waiter {.inline, cdecl.} = + ## / Creates a \ref Waiter for a \ref Thread. + return waiterForHandle(t.handle) + +proc threadCreate*(t: ptr Thread; entry: ThreadFunc; arg: pointer; stackMem: pointer; + stackSz: csize_t; prio: cint; cpuid: cint): Result {.cdecl, + importc: "threadCreate".} +## * +## @brief Creates a thread. +## @param t Thread information structure which will be filled in. +## @param entry Entrypoint of the thread. +## @param arg Argument to pass to the entrypoint. +## @param stack_mem Memory to use as backing for stack/tls/reent. Must be page-aligned. NULL argument means to allocate new memory. +## @param stack_sz If stack_mem is NULL, size to use for stack. If stack_mem is non-NULL, size to use for stack + reent + tls (must be page-aligned). +## @param prio Thread priority (0x00~0x3F); 0x2C is the usual priority of the main thread, 0x3B is a special priority on cores 0..2 that enables preemptive multithreading (0x3F on core 3). +## @param cpuid ID of the core on which to create the thread (0~3); or -2 to use the default core for the current process. +## @return Result code. +## + +proc threadStart*(t: ptr Thread): Result {.cdecl, importc: "threadStart".} +## * +## @brief Starts the execution of a thread. +## @param t Thread information structure. +## @return Result code. +## + +proc threadExit*() {.cdecl, importc: "threadExit".} +## * +## @brief Exits the current thread immediately. +## + +proc threadWaitForExit*(t: ptr Thread): Result {.cdecl, importc: "threadWaitForExit".} +## * +## @brief Waits for a thread to finish executing. +## @param t Thread information structure. +## @return Result code. +## + +proc threadClose*(t: ptr Thread): Result {.cdecl, importc: "threadClose".} +## * +## @brief Frees up resources associated with a thread. +## @param t Thread information structure. +## @return Result code. +## + +proc threadPause*(t: ptr Thread): Result {.cdecl, importc: "threadPause".} +## * +## @brief Pauses the execution of a thread. +## @param t Thread information structure. +## @return Result code. +## + +proc threadResume*(t: ptr Thread): Result {.cdecl, importc: "threadResume".} +## * +## @brief Resumes the execution of a thread, after having been paused. +## @param t Thread information structure. +## @return Result code. +## + +proc threadDumpContext*(ctx: ptr ThreadContext; t: ptr Thread): Result {.cdecl, + importc: "threadDumpContext".} +## * +## @brief Dumps the registers of a thread paused by @ref threadPause (register groups: all). +## @param[out] ctx Output thread context (register dump). +## @param t Thread information structure. +## @return Result code. +## @warning Official kernel will not dump x0..x18 if the thread is currently executing a system call, and prior to 6.0.0 doesn't dump TPIDR_EL0. +## + +proc threadGetSelf*(): ptr Thread {.cdecl, importc: "threadGetSelf".} +## * +## @brief Gets a pointer to the current thread structure. +## @return Thread information structure. +## + +proc threadGetCurHandle*(): Handle {.cdecl, importc: "threadGetCurHandle".} +## * +## @brief Gets the raw handle to the current thread. +## @return The current thread's handle. +## + +proc threadTlsAlloc*(destructor: proc (a1: pointer) {.cdecl.}): S32 {.cdecl, + importc: "threadTlsAlloc".} +## * +## @brief Allocates a TLS slot. +## @param destructor Function to run automatically when a thread exits. +## @return TLS slot ID on success, or a negative value on failure. +## + +proc threadTlsGet*(slotId: S32): pointer {.cdecl, importc: "threadTlsGet".} +## * +## @brief Retrieves the value stored in a TLS slot. +## @param slot_id TLS slot ID. +## @return Value. +## + +proc threadTlsSet*(slotId: S32; value: pointer) {.cdecl, importc: "threadTlsSet".} +## * +## @brief Stores the specified value into a TLS slot. +## @param slot_id TLS slot ID. +## @param value Value. +## + +proc threadTlsFree*(slotId: S32) {.cdecl, importc: "threadTlsFree".} +## * +## @brief Frees a TLS slot. +## @param slot_id TLS slot ID. +## + diff --git a/src/libnx/wrapper/switch/kernel/tmem.h b/src/libnx/wrapper/switch/kernel/tmem.h new file mode 100644 index 0000000..a5993ea --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/tmem.h @@ -0,0 +1,80 @@ +/** + * @file tmem.h + * @brief Transfer memory handling + * @author plutoo + * @copyright libnx Authors + * @remark Transfer memory differs from shared memory in the fact that the user process (as opposed to the kernel) allocates and owns its backing memory. + */ +#pragma once +#include "../types.h" +#include "../kernel/svc.h" + +/// Transfer memory information structure. +typedef struct { + Handle handle; ///< Kernel object handle. + size_t size; ///< Size of the transfer memory object. + Permission perm; ///< Permissions of the transfer memory object. + void* src_addr; ///< Address of the source backing memory. + void* map_addr; ///< Address to which the transfer memory object is mapped. +} TransferMemory; + +/** + * @brief Creates a transfer memory object. + * @param t Transfer memory information structure that will be filled in. + * @param size Size of the transfer memory object to create. + * @param perm Permissions with which to protect the transfer memory in the local process. + * @return Result code. + */ +Result tmemCreate(TransferMemory* t, size_t size, Permission perm); + +/** + * @brief Creates a transfer memory object from existing memory. + * @param t Transfer memory information structure that will be filled in. + * @param buf Pointer to a page-aligned buffer. + * @param size Size of the transfer memory object to create. + * @param perm Permissions with which to protect the transfer memory in the local process. + * @return Result code. + */ +Result tmemCreateFromMemory(TransferMemory* t, void* buf, size_t size, Permission perm); + +/** + * @brief Loads a transfer memory object coming from a remote process. + * @param t Transfer memory information structure which will be filled in. + * @param handle Handle of the transfer memory object. + * @param size Size of the transfer memory object that is being loaded. + * @param perm Permissions which the transfer memory is expected to have in the process that owns the memory. + * @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. + */ +void tmemLoadRemote(TransferMemory* t, Handle handle, size_t size, Permission perm); + +/** + * @brief Maps a transfer memory object. + * @param t Transfer memory information structure. + * @return Result code. + * @warning This is a privileged operation; in normal circumstances applications cannot use this function. + */ +Result tmemMap(TransferMemory* t); + +/** + * @brief Unmaps a transfer memory object. + * @param t Transfer memory information structure. + * @return Result code. + * @warning This is a privileged operation; in normal circumstances applications cannot use this function. + */ +Result tmemUnmap(TransferMemory* t); + +/** + * @brief Retrieves the mapped address of a transfer memory object. + * @param t Transfer memory information structure. + * @return Mapped address of the transfer memory object. + */ +static inline void* tmemGetAddr(TransferMemory* t){ + return t->map_addr; +} + +/** + * @brief Frees up resources used by a transfer memory object, unmapping and closing handles, etc. + * @param t Transfer memory information structure. + * @return Result code. + */ +Result tmemClose(TransferMemory* t); diff --git a/src/libnx/wrapper/switch/kernel/tmem.nim b/src/libnx/wrapper/switch/kernel/tmem.nim new file mode 100644 index 0000000..1882cb5 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/tmem.nim @@ -0,0 +1,87 @@ +## * +## @file tmem.h +## @brief Transfer memory handling +## @author plutoo +## @copyright libnx Authors +## @remark Transfer memory differs from shared memory in the fact that the user process (as opposed to the kernel) allocates and owns its backing memory. +## + +import + ../types, ../kernel/svc + +## / Transfer memory information structure. + +type + TransferMemory* {.bycopy.} = object + handle*: Handle ## /< Kernel object handle. + size*: csize_t ## /< Size of the transfer memory object. + perm*: Permission ## /< Permissions of the transfer memory object. + srcAddr*: pointer ## /< Address of the source backing memory. + mapAddr*: pointer ## /< Address to which the transfer memory object is mapped. + + +## * +## @brief Creates a transfer memory object. +## @param t Transfer memory information structure that will be filled in. +## @param size Size of the transfer memory object to create. +## @param perm Permissions with which to protect the transfer memory in the local process. +## @return Result code. +## + +proc tmemCreate*(t: ptr TransferMemory; size: csize_t; perm: Permission): Result {.cdecl, + importc: "tmemCreate".} +## * +## @brief Creates a transfer memory object from existing memory. +## @param t Transfer memory information structure that will be filled in. +## @param buf Pointer to a page-aligned buffer. +## @param size Size of the transfer memory object to create. +## @param perm Permissions with which to protect the transfer memory in the local process. +## @return Result code. +## + +proc tmemCreateFromMemory*(t: ptr TransferMemory; buf: pointer; size: csize_t; + perm: Permission): Result {.cdecl, + importc: "tmemCreateFromMemory".} +## * +## @brief Loads a transfer memory object coming from a remote process. +## @param t Transfer memory information structure which will be filled in. +## @param handle Handle of the transfer memory object. +## @param size Size of the transfer memory object that is being loaded. +## @param perm Permissions which the transfer memory is expected to have in the process that owns the memory. +## @warning This is a privileged operation; in normal circumstances applications shouldn't use this function. +## + +proc tmemLoadRemote*(t: ptr TransferMemory; handle: Handle; size: csize_t; + perm: Permission) {.cdecl, importc: "tmemLoadRemote".} +## * +## @brief Maps a transfer memory object. +## @param t Transfer memory information structure. +## @return Result code. +## @warning This is a privileged operation; in normal circumstances applications cannot use this function. +## + +proc tmemMap*(t: ptr TransferMemory): Result {.cdecl, importc: "tmemMap".} +## * +## @brief Unmaps a transfer memory object. +## @param t Transfer memory information structure. +## @return Result code. +## @warning This is a privileged operation; in normal circumstances applications cannot use this function. +## + +proc tmemUnmap*(t: ptr TransferMemory): Result {.cdecl, importc: "tmemUnmap".} +## * +## @brief Retrieves the mapped address of a transfer memory object. +## @param t Transfer memory information structure. +## @return Mapped address of the transfer memory object. +## + +proc tmemGetAddr*(t: ptr TransferMemory): pointer {.inline, cdecl.} = + return t.mapAddr + +## * +## @brief Frees up resources used by a transfer memory object, unmapping and closing handles, etc. +## @param t Transfer memory information structure. +## @return Result code. +## + +proc tmemClose*(t: ptr TransferMemory): Result {.cdecl, importc: "tmemClose".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/kernel/uevent.h b/src/libnx/wrapper/switch/kernel/uevent.h new file mode 100644 index 0000000..bd20ae2 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/uevent.h @@ -0,0 +1,47 @@ +/** + * @file uevent.h + * @brief User-mode event synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "wait.h" + +typedef struct UEvent UEvent; + +/// User-mode event object. +struct UEvent { + Waitable waitable; + bool signal; + bool auto_clear; +}; + +/// Creates a waiter for a user-mode event. +static inline Waiter waiterForUEvent(UEvent* e) +{ + Waiter wait_obj; + wait_obj.type = WaiterType_Waitable; + wait_obj.waitable = &e->waitable; + return wait_obj; +} + +/** + * @brief Creates a user-mode event. + * @param[out] e UEvent object. + * @param[in] auto_clear Whether to automatically clear the event. + * @note It is safe to wait on this event with several threads simultaneously. + * @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees. + */ +void ueventCreate(UEvent* e, bool auto_clear); + +/** + * @brief Clears the event signal. + * @param[in] e UEvent object. + */ +void ueventClear(UEvent* e); + +/** + * @brief Signals the event. + * @param[in] e UEvent object. + */ +void ueventSignal(UEvent* e); diff --git a/src/libnx/wrapper/switch/kernel/uevent.nim b/src/libnx/wrapper/switch/kernel/uevent.nim new file mode 100644 index 0000000..a05808e --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/uevent.nim @@ -0,0 +1,46 @@ +## * +## @file uevent.h +## @brief User-mode event synchronization primitive. +## @author plutoo +## @copyright libnx Authors +## + +import + wait + +## / User-mode event object. + +type + UEvent* {.bycopy.} = object + waitable*: Waitable + signal*: bool + autoClear*: bool + +proc waiterForUEvent*(e: ptr UEvent): Waiter {.inline, cdecl.} = + ## / Creates a waiter for a user-mode event. + var waitObj: Waiter + waitObj.`type` = WaiterTypeWaitable + waitObj.anoWait3.waitable = addr(e.waitable) + return waitObj + +proc ueventCreate*(e: ptr UEvent; autoClear: bool) {.cdecl, importc: "ueventCreate".} +## * +## @brief Creates a user-mode event. +## @param[out] e UEvent object. +## @param[in] auto_clear Whether to automatically clear the event. +## @note It is safe to wait on this event with several threads simultaneously. +## @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees. +## + +proc ueventClear*(e: ptr UEvent) {.cdecl, importc: "ueventClear".} +## * +## @brief Clears the event signal. +## @param[in] e UEvent object. +## + +proc ueventSignal*(e: ptr UEvent) {.cdecl, importc: "ueventSignal".} +## * +## @brief Signals the event. +## @param[in] e UEvent object. +## + diff --git a/src/libnx/wrapper/switch/kernel/utimer.h b/src/libnx/wrapper/switch/kernel/utimer.h new file mode 100644 index 0000000..cf38d8e --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/utimer.h @@ -0,0 +1,58 @@ +/** + * @file utimer.h + * @brief User-mode timer synchronization primitive. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "wait.h" + +typedef struct UTimer UTimer; + +/// Valid types for a user-mode timer. +typedef enum { + TimerType_OneShot, ///< Timers of this kind fire once and then stop automatically. + TimerType_Repeating, ///< Timers of this kind fire periodically. +} TimerType; + +/// User-mode timer object. +struct UTimer { + Waitable waitable; + TimerType type : 8; + bool started : 1; + u64 next_tick; + u64 interval; +}; + +/// Creates a waiter for a user-mode timer. +static inline Waiter waiterForUTimer(UTimer* t) +{ + Waiter wait_obj; + wait_obj.type = WaiterType_Waitable; + wait_obj.waitable = &t->waitable; + return wait_obj; +} + +/** + * @brief Creates a user-mode timer. + * @param[out] t UTimer object. + * @param[in] interval Interval (in nanoseconds). + * @param[in] type Type of timer to create (see \ref TimerType). + * @note The timer is stopped when it is created. Use \ref utimerStart to start it. + * @note It is safe to wait on this timer with several threads simultaneously. + * @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees. + * @note For a repeating timer: If the timer triggers twice before you wait on it, you will only get one signal. + */ +void utimerCreate(UTimer* t, u64 interval, TimerType type); + +/** + * @brief Starts the timer. + * @param[in] t UTimer object. + */ +void utimerStart(UTimer* t); + +/** + * @brief Stops the timer. + * @param[in] t UTimer object. + */ +void utimerStop(UTimer* t); diff --git a/src/libnx/wrapper/switch/kernel/utimer.nim b/src/libnx/wrapper/switch/kernel/utimer.nim new file mode 100644 index 0000000..1413b8c --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/utimer.nim @@ -0,0 +1,60 @@ +## * +## @file utimer.h +## @brief User-mode timer synchronization primitive. +## @author plutoo +## @copyright libnx Authors +## + +import + wait, ../types + +## / Valid types for a user-mode timer. + +type + TimerType* = enum + TimerTypeOneShot, ## /< Timers of this kind fire once and then stop automatically. + TimerTypeRepeating ## /< Timers of this kind fire periodically. + + +## / User-mode timer object. + +type + UTimer* {.bycopy.} = object + waitable*: Waitable + `type`* {.bitsize: 8.}: TimerType + started* {.bitsize: 1.}: bool + nextTick*: U64 + interval*: U64 + +proc waiterForUTimer*(t: ptr UTimer): Waiter {.inline, cdecl.} = + ## / Creates a waiter for a user-mode timer. + var waitObj: Waiter + waitObj.`type` = WaiterTypeWaitable + waitObj.anoWait3.waitable = addr(t.waitable) + return waitObj + +proc utimerCreate*(t: ptr UTimer; interval: U64; `type`: TimerType) {.cdecl, + importc: "utimerCreate".} +## * +## @brief Creates a user-mode timer. +## @param[out] t UTimer object. +## @param[in] interval Interval (in nanoseconds). +## @param[in] type Type of timer to create (see \ref TimerType). +## @note The timer is stopped when it is created. Use \ref utimerStart to start it. +## @note It is safe to wait on this timer with several threads simultaneously. +## @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees. +## @note For a repeating timer: If the timer triggers twice before you wait on it, you will only get one signal. +## + +proc utimerStart*(t: ptr UTimer) {.cdecl, importc: "utimerStart".} +## * +## @brief Starts the timer. +## @param[in] t UTimer object. +## + +proc utimerStop*(t: ptr UTimer) {.cdecl, importc: "utimerStop".} +## * +## @brief Stops the timer. +## @param[in] t UTimer object. +## + diff --git a/src/libnx/wrapper/switch/kernel/virtmem.h b/src/libnx/wrapper/switch/kernel/virtmem.h new file mode 100644 index 0000000..2411530 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/virtmem.h @@ -0,0 +1,61 @@ +/** + * @file virtmem.h + * @brief Virtual memory mapping utilities + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Address space reservation type (see \ref virtmemAddReservation) +typedef struct VirtmemReservation VirtmemReservation; + +/// Locks the virtual memory manager mutex. +void virtmemLock(void); + +/// Unlocks the virtual memory manager mutex. +void virtmemUnlock(void); + +/** + * @brief Finds a random slice of free general purpose address space. + * @param size Desired size of the slice (rounded up to page alignment). + * @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). + * @return Pointer to the slice of address space, or NULL on failure. + * @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). + */ +void* virtmemFindAslr(size_t size, size_t guard_size); + +/** + * @brief Finds a random slice of free stack address space. + * @param size Desired size of the slice (rounded up to page alignment). + * @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). + * @return Pointer to the slice of address space, or NULL on failure. + * @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). + */ +void* virtmemFindStack(size_t size, size_t guard_size); + +/** + * @brief Finds a random slice of free code memory address space. + * @param size Desired size of the slice (rounded up to page alignment). + * @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). + * @return Pointer to the slice of address space, or NULL on failure. + * @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). + */ +void* virtmemFindCodeMemory(size_t size, size_t guard_size); + +/** + * @brief Reserves a range of memory address space. + * @param mem Pointer to the address space slice. + * @param size Size of the slice. + * @return Pointer to a reservation object, or NULL on failure. + * @remark This function is intended to be used in lieu of a memory map operation when the memory won't be mapped straight away. + * @note The virtual memory manager mutex must be held during the find-and-reserve process (see \ref virtmemLock and \ref virtmemUnlock). + */ +VirtmemReservation* virtmemAddReservation(void* mem, size_t size); + +/** + * @brief Releases a memory address space reservation. + * @param rv Reservation to release. + * @note The virtual memory manager mutex must be held before calling this function (see \ref virtmemLock and \ref virtmemUnlock). + */ +void virtmemRemoveReservation(VirtmemReservation* rv); diff --git a/src/libnx/wrapper/switch/kernel/virtmem.nim b/src/libnx/wrapper/switch/kernel/virtmem.nim new file mode 100644 index 0000000..0c62c6d --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/virtmem.nim @@ -0,0 +1,67 @@ +## * +## @file virtmem.h +## @brief Virtual memory mapping utilities +## @author plutoo +## @copyright libnx Authors +## + +## / Address space reservation type (see \ref virtmemAddReservation) + +type + VirtmemReservation* = object + +proc virtmemLock*() {.cdecl, importc: "virtmemLock".} +## / Locks the virtual memory manager mutex. + +proc virtmemUnlock*() {.cdecl, importc: "virtmemUnlock".} +## / Unlocks the virtual memory manager mutex. + +proc virtmemFindAslr*(size: csize_t; guardSize: csize_t): pointer {.cdecl, + importc: "virtmemFindAslr".} +## * +## @brief Finds a random slice of free general purpose address space. +## @param size Desired size of the slice (rounded up to page alignment). +## @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). +## @return Pointer to the slice of address space, or NULL on failure. +## @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). +## + +proc virtmemFindStack*(size: csize_t; guardSize: csize_t): pointer {.cdecl, + importc: "virtmemFindStack".} +## * +## @brief Finds a random slice of free stack address space. +## @param size Desired size of the slice (rounded up to page alignment). +## @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). +## @return Pointer to the slice of address space, or NULL on failure. +## @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). +## + +proc virtmemFindCodeMemory*(size: csize_t; guardSize: csize_t): pointer {.cdecl, + importc: "virtmemFindCodeMemory".} +## * +## @brief Finds a random slice of free code memory address space. +## @param size Desired size of the slice (rounded up to page alignment). +## @param guard_size Desired size of the unmapped guard areas surrounding the slice (rounded up to page alignment). +## @return Pointer to the slice of address space, or NULL on failure. +## @note The virtual memory manager mutex must be held during the find-and-map process (see \ref virtmemLock and \ref virtmemUnlock). +## + +proc virtmemAddReservation*(mem: pointer; size: csize_t): ptr VirtmemReservation {. + cdecl, importc: "virtmemAddReservation".} +## * +## @brief Reserves a range of memory address space. +## @param mem Pointer to the address space slice. +## @param size Size of the slice. +## @return Pointer to a reservation object, or NULL on failure. +## @remark This function is intended to be used in lieu of a memory map operation when the memory won't be mapped straight away. +## @note The virtual memory manager mutex must be held during the find-and-reserve process (see \ref virtmemLock and \ref virtmemUnlock). +## + +proc virtmemRemoveReservation*(rv: ptr VirtmemReservation) {.cdecl, + importc: "virtmemRemoveReservation".} +## * +## @brief Releases a memory address space reservation. +## @param rv Reservation to release. +## @note The virtual memory manager mutex must be held before calling this function (see \ref virtmemLock and \ref virtmemUnlock). +## + diff --git a/src/libnx/wrapper/switch/kernel/wait.h b/src/libnx/wrapper/switch/kernel/wait.h new file mode 100644 index 0000000..7021e62 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/wait.h @@ -0,0 +1,118 @@ +/** + * @file wait.h + * @brief User mode synchronization primitive waiting operations. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "mutex.h" + +// Implementation details. + +typedef struct Waitable Waitable; +typedef struct WaitableMethods WaitableMethods; +typedef struct WaitableNode WaitableNode; + +struct WaitableNode { + WaitableNode* prev; + WaitableNode* next; +}; + +struct Waitable { + const WaitableMethods* vt; + WaitableNode list; + Mutex mutex; +}; + +typedef enum { + WaiterType_Handle, + WaiterType_HandleWithClear, + WaiterType_Waitable, +} WaiterType; + +// User-facing API starts here. + +/// Waiter structure, representing any generic waitable synchronization object; both kernel-mode and user-mode. +typedef struct { + WaiterType type; + + union { + Handle handle; + Waitable* waitable; + }; +} Waiter; + +/// Creates a \ref Waiter for a kernel-mode \ref Handle. +static inline Waiter waiterForHandle(Handle h) +{ + Waiter wait_obj; + wait_obj.type = WaiterType_Handle; + wait_obj.handle = h; + return wait_obj; +} + +/** + * @brief Waits for an arbitrary number of generic waitable synchronization objects, optionally with a timeout. + * @param[out] idx_out Variable that will received the index of the signalled object. + * @param[in] objects Array containing \ref Waiter structures. + * @param[in] num_objects Number of objects in the array. + * @param[in] timeout Timeout (in nanoseconds). + * @return Result code. + * @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. + */ +Result waitObjects(s32* idx_out, const Waiter* objects, s32 num_objects, u64 timeout); + +/** + * @brief Waits for an arbitrary number of kernel synchronization objects, optionally with a timeout. This function replaces \ref svcWaitSynchronization. + * @param[out] idx_out Variable that will received the index of the signalled object. + * @param[in] handles Array containing handles. + * @param[in] num_handles Number of handles in the array. + * @param[in] timeout Timeout (in nanoseconds). + * @return Result code. + * @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. + */ +Result waitHandles(s32* idx_out, const Handle* handles, s32 num_handles, u64 timeout); + +/** + * @brief Helper macro for \ref waitObjects that accepts \ref Waiter structures as variadic arguments instead of as an array. + * @param[out] idx_out The index of the signalled waiter. + * @param[in] timeout Timeout (in nanoseconds). + * @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. + */ +/* #define waitMulti(idx_out, timeout, ...) ({ \ */ +/* Waiter __objects[] = { __VA_ARGS__ }; \ */ +/* waitObjects((idx_out), __objects, sizeof(__objects) / sizeof(Waiter), (timeout)); \ */ +/* }) */ + +/** + * @brief Helper macro for \ref waitHandles that accepts handles as variadic arguments instead of as an array. + * @param[out] idx_out The index of the signalled handle. + * @param[in] timeout Timeout (in nanoseconds). + * @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. + */ +/* #define waitMultiHandle(idx_out, timeout, ...) ({ \ */ +/* Handle __handles[] = { __VA_ARGS__ }; \ */ +/* waitHandles((idx_out), __handles, sizeof(__handles) / sizeof(Handle), (timeout)); \ */ +/* }) */ + +/** + * @brief Waits on a single generic waitable synchronization object, optionally with a timeout. + * @param[in] w \ref Waiter structure. + * @param[in] timeout Timeout (in nanoseconds). + */ +static inline Result waitSingle(Waiter w, u64 timeout) +{ + s32 idx; + return waitObjects(&idx, &w, 1, timeout); +} + +/** + * @brief Waits for a single kernel synchronization object, optionally with a timeout. + * @param[in] h \ref Handle of the object. + * @param[in] timeout Timeout (in nanoseconds). + */ +static inline Result waitSingleHandle(Handle h, u64 timeout) +{ + s32 idx; + return waitHandles(&idx, &h, 1, timeout); +} diff --git a/src/libnx/wrapper/switch/kernel/wait.nim b/src/libnx/wrapper/switch/kernel/wait.nim new file mode 100644 index 0000000..4834839 --- /dev/null +++ b/src/libnx/wrapper/switch/kernel/wait.nim @@ -0,0 +1,113 @@ +## * +## @file wait.h +## @brief User mode synchronization primitive waiting operations. +## @author plutoo +## @copyright libnx Authors +## + +import + mutex +import ../types + +## Implementation details. + +type + WaitableMethods* = object + WaitableNode* {.bycopy.} = object + prev*: ptr WaitableNode + next*: ptr WaitableNode + + Waitable* {.bycopy.} = object + vt*: ptr WaitableMethods + list*: WaitableNode + mutex*: Mutex + + WaiterType* = enum + WaiterTypeHandle, WaiterTypeHandleWithClear, WaiterTypeWaitable + + +## User-facing API starts here. +## / Waiter structure, representing any generic waitable synchronization object; both kernel-mode and user-mode. + +type + INNER_C_UNION_wait_2* {.bycopy, union.} = object + handle*: Handle + waitable*: ptr Waitable + + Waiter* {.bycopy.} = object + `type`*: WaiterType + anoWait3*: INNER_C_UNION_wait_2 + + +## / Creates a \ref Waiter for a kernel-mode \ref Handle. + +proc waiterForHandle*(h: Handle): Waiter {.inline, cdecl.} = + var waitObj: Waiter + waitObj.`type` = WaiterTypeHandle + waitObj.anoWait3.handle = h + return waitObj + +## * +## @brief Waits for an arbitrary number of generic waitable synchronization objects, optionally with a timeout. +## @param[out] idx_out Variable that will received the index of the signalled object. +## @param[in] objects Array containing \ref Waiter structures. +## @param[in] num_objects Number of objects in the array. +## @param[in] timeout Timeout (in nanoseconds). +## @return Result code. +## @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. +## + +proc waitObjects*(idxOut: ptr S32; objects: ptr Waiter; numObjects: S32; timeout: U64): Result {. + cdecl, importc: "waitObjects".} +## * +## @brief Waits for an arbitrary number of kernel synchronization objects, optionally with a timeout. This function replaces \ref svcWaitSynchronization. +## @param[out] idx_out Variable that will received the index of the signalled object. +## @param[in] handles Array containing handles. +## @param[in] num_handles Number of handles in the array. +## @param[in] timeout Timeout (in nanoseconds). +## @return Result code. +## @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. +## + +proc waitHandles*(idxOut: ptr S32; handles: ptr Handle; numHandles: S32; timeout: U64): Result {. + cdecl, importc: "waitHandles".} + +## * +## @brief Helper macro for \ref waitObjects that accepts \ref Waiter structures as variadic arguments instead of as an array. +## @param[out] idx_out The index of the signalled waiter. +## @param[in] timeout Timeout (in nanoseconds). +## @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. +## +## #define waitMulti(idx_out, timeout, ...) ({ \ +## Waiter __objects[] = { __VA_ARGS__ }; \ +## waitObjects((idx_out), __objects, sizeof(__objects) / sizeof(Waiter), (timeout)); \ +## }) +## * +## @brief Helper macro for \ref waitHandles that accepts handles as variadic arguments instead of as an array. +## @param[out] idx_out The index of the signalled handle. +## @param[in] timeout Timeout (in nanoseconds). +## @note The number of objects must not be greater than \ref MAX_WAIT_OBJECTS. This is a Horizon kernel limitation. +## +## #define waitMultiHandle(idx_out, timeout, ...) ({ \ +## Handle __handles[] = { __VA_ARGS__ }; \ +## waitHandles((idx_out), __handles, sizeof(__handles) / sizeof(Handle), (timeout)); \ +## }) +## * +## @brief Waits on a single generic waitable synchronization object, optionally with a timeout. +## @param[in] w \ref Waiter structure. +## @param[in] timeout Timeout (in nanoseconds). +## + +proc waitSingle*(w: Waiter; timeout: U64): Result {.inline, cdecl.} = + var idx: S32 + return waitObjects(addr(idx), addr(w), 1, timeout) + +## * +## @brief Waits for a single kernel synchronization object, optionally with a timeout. +## @param[in] h \ref Handle of the object. +## @param[in] timeout Timeout (in nanoseconds). +## + +proc waitSingleHandle*(h: Handle; timeout: U64): Result {.inline, cdecl.} = + var idx: S32 + return waitHandles(addr(idx), addr(h), 1, timeout) diff --git a/src/libnx/wrapper/switch/nacp.h b/src/libnx/wrapper/switch/nacp.h new file mode 100644 index 0000000..0a03c4d --- /dev/null +++ b/src/libnx/wrapper/switch/nacp.h @@ -0,0 +1,94 @@ +/** + * @file nacp.h + * @brief Control.nacp structure / related code for nacp. + * @copyright libnx Authors + */ + +#pragma once + +/// Language entry. These strings are UTF-8. +typedef struct { + char name[0x200]; + char author[0x100]; +} NacpLanguageEntry; + +/// ApplicationNeighborDetectionGroupConfiguration +typedef struct { + u64 group_id; ///< GroupId + u8 key[0x10]; +} NacpApplicationNeighborDetectionGroupConfiguration; + +/// NeighborDetectionClientConfiguration +typedef struct { + NacpApplicationNeighborDetectionGroupConfiguration send_group_configuration; ///< SendGroupConfiguration + NacpApplicationNeighborDetectionGroupConfiguration receivable_group_configurations[0x10]; ///< ReceivableGroupConfigurations +} NacpNeighborDetectionClientConfiguration; + +/// ApplicationJitConfiguration +typedef struct { + u64 flags; ///< Flags + u64 memory_size; ///< MemorySize +} NacpApplicationJitConfiguration; + +/// ns ApplicationControlProperty +typedef struct { + NacpLanguageEntry lang[16]; ///< \ref NacpLanguageEntry + u8 isbn[0x25]; ///< Isbn + u8 startup_user_account; ///< StartupUserAccount + u8 user_account_switch_lock; ///< UserAccountSwitchLock + u8 add_on_content_registration_type; ///< AddOnContentRegistrationType + u32 attribute_flag; ///< AttributeFlag + u32 supported_language_flag; ///< SupportedLanguageFlag + u32 parental_control_flag; ///< ParentalControlFlag + u8 screenshot; ///< Screenshot + u8 video_capture; ///< VideoCapture + u8 data_loss_confirmation; ///< DataLossConfirmation + u8 play_log_policy; ///< PlayLogPolicy + u64 presence_group_id; ///< PresenceGroupId + s8 rating_age[0x20]; ///< RatingAge + char display_version[0x10]; ///< DisplayVersion + u64 add_on_content_base_id; ///< AddOnContentBaseId + u64 save_data_owner_id; ///< SaveDataOwnerId + u64 user_account_save_data_size; ///< UserAccountSaveDataSize + u64 user_account_save_data_journal_size; ///< UserAccountSaveDataJournalSize + u64 device_save_data_size; ///< DeviceSaveDataSize + u64 device_save_data_journal_size; ///< DeviceSaveDataJournalSize + u64 bcat_delivery_cache_storage_size; ///< BcatDeliveryCacheStorageSize + u64 application_error_code_category; ///< ApplicationErrorCodeCategory + u64 local_communication_id[0x8]; ///< LocalCommunicationId + u8 logo_type; ///< LogoType + u8 logo_handling; ///< LogoHandling + u8 runtime_add_on_content_install; ///< RuntimeAddOnContentInstall + u8 runtime_parameter_delivery; ///< RuntimeParameterDelivery + u8 reserved_x30f4[0x2]; ///< Reserved + u8 crash_report; ///< CrashReport + u8 hdcp; ///< Hdcp + u64 pseudo_device_id_seed; ///< SeedForPseudoDeviceId + char bcat_passphrase[0x41]; ///< BcatPassphrase + u8 startup_user_account_option; ///< StartupUserAccountOption + u8 reserved_for_user_account_save_data_operation[0x6]; ///< ReservedForUserAccountSaveDataOperation + u64 user_account_save_data_size_max; ///< UserAccountSaveDataSizeMax + u64 user_account_save_data_journal_size_max; ///< UserAccountSaveDataJournalSizeMax + u64 device_save_data_size_max; ///< DeviceSaveDataSizeMax + u64 device_save_data_journal_size_max; ///< DeviceSaveDataJournalSizeMax + u64 temporary_storage_size; ///< TemporaryStorageSize + u64 cache_storage_size; ///< CacheStorageSize + u64 cache_storage_journal_size; ///< CacheStorageJournalSize + u64 cache_storage_data_and_journal_size_max; ///< CacheStorageDataAndJournalSizeMax + u16 cache_storage_index_max; ///< CacheStorageIndexMax + u8 reserved_x318a[0x6]; ///< Reserved + u64 play_log_queryable_application_id[0x10]; ///< PlayLogQueryableApplicationId + u8 play_log_query_capability; ///< PlayLogQueryCapability + u8 repair_flag; ///< RepairFlag + u8 program_index; ///< ProgramIndex + u8 required_network_service_license_on_launch; ///< RequiredNetworkServiceLicenseOnLaunchFlag + u32 reserved_x3214; ///< Reserved + NacpNeighborDetectionClientConfiguration neighbor_detection_client_configuration; ///< NeighborDetectionClientConfiguration + NacpApplicationJitConfiguration jit_configuration; ///< JitConfiguration + u8 reserved_x33c0[0xc40]; ///< Reserved +} NacpStruct; + +/// Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty. +/// If you're using ns you may want to use \ref nsGetApplicationDesiredLanguage instead. +Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry); + diff --git a/src/libnx/wrapper/switch/nacp.nim b/src/libnx/wrapper/switch/nacp.nim new file mode 100644 index 0000000..045bc18 --- /dev/null +++ b/src/libnx/wrapper/switch/nacp.nim @@ -0,0 +1,105 @@ +## * +## @file nacp.h +## @brief Control.nacp structure / related code for nacp. +## @copyright libnx Authors +## + +## / Language entry. These strings are UTF-8. +import types + +type + NacpLanguageEntry* {.bycopy.} = object + name*: array[0x200, char] + author*: array[0x100, char] + + +## / ApplicationNeighborDetectionGroupConfiguration + +type + NacpApplicationNeighborDetectionGroupConfiguration* {.bycopy.} = object + groupId*: U64 ## /< GroupId + key*: array[0x10, U8] + + +## / NeighborDetectionClientConfiguration + +type + NacpNeighborDetectionClientConfiguration* {.bycopy.} = object + sendGroupConfiguration*: NacpApplicationNeighborDetectionGroupConfiguration ## /< SendGroupConfiguration + receivableGroupConfigurations*: array[0x10, + NacpApplicationNeighborDetectionGroupConfiguration] ## /< ReceivableGroupConfigurations + + +## / ApplicationJitConfiguration + +type + NacpApplicationJitConfiguration* {.bycopy.} = object + flags*: U64 ## /< Flags + memorySize*: U64 ## /< MemorySize + + +## / ns ApplicationControlProperty + +type + NacpStruct* {.bycopy.} = object + lang*: array[16, NacpLanguageEntry] ## /< \ref NacpLanguageEntry + isbn*: array[0x25, U8] ## /< Isbn + startupUserAccount*: U8 ## /< StartupUserAccount + userAccountSwitchLock*: U8 ## /< UserAccountSwitchLock + addOnContentRegistrationType*: U8 ## /< AddOnContentRegistrationType + attributeFlag*: U32 ## /< AttributeFlag + supportedLanguageFlag*: U32 ## /< SupportedLanguageFlag + parentalControlFlag*: U32 ## /< ParentalControlFlag + screenshot*: U8 ## /< Screenshot + videoCapture*: U8 ## /< VideoCapture + dataLossConfirmation*: U8 ## /< DataLossConfirmation + playLogPolicy*: U8 ## /< PlayLogPolicy + presenceGroupId*: U64 ## /< PresenceGroupId + ratingAge*: array[0x20, S8] ## /< RatingAge + displayVersion*: array[0x10, char] ## /< DisplayVersion + addOnContentBaseId*: U64 ## /< AddOnContentBaseId + saveDataOwnerId*: U64 ## /< SaveDataOwnerId + userAccountSaveDataSize*: U64 ## /< UserAccountSaveDataSize + userAccountSaveDataJournalSize*: U64 ## /< UserAccountSaveDataJournalSize + deviceSaveDataSize*: U64 ## /< DeviceSaveDataSize + deviceSaveDataJournalSize*: U64 ## /< DeviceSaveDataJournalSize + bcatDeliveryCacheStorageSize*: U64 ## /< BcatDeliveryCacheStorageSize + applicationErrorCodeCategory*: U64 ## /< ApplicationErrorCodeCategory + localCommunicationId*: array[0x8, U64] ## /< LocalCommunicationId + logoType*: U8 ## /< LogoType + logoHandling*: U8 ## /< LogoHandling + runtimeAddOnContentInstall*: U8 ## /< RuntimeAddOnContentInstall + runtimeParameterDelivery*: U8 ## /< RuntimeParameterDelivery + reservedX30f4*: array[0x2, U8] ## /< Reserved + crashReport*: U8 ## /< CrashReport + hdcp*: U8 ## /< Hdcp + pseudoDeviceIdSeed*: U64 ## /< SeedForPseudoDeviceId + bcatPassphrase*: array[0x41, char] ## /< BcatPassphrase + startupUserAccountOption*: U8 ## /< StartupUserAccountOption + reservedForUserAccountSaveDataOperation*: array[0x6, U8] ## /< ReservedForUserAccountSaveDataOperation + userAccountSaveDataSizeMax*: U64 ## /< UserAccountSaveDataSizeMax + userAccountSaveDataJournalSizeMax*: U64 ## /< UserAccountSaveDataJournalSizeMax + deviceSaveDataSizeMax*: U64 ## /< DeviceSaveDataSizeMax + deviceSaveDataJournalSizeMax*: U64 ## /< DeviceSaveDataJournalSizeMax + temporaryStorageSize*: U64 ## /< TemporaryStorageSize + cacheStorageSize*: U64 ## /< CacheStorageSize + cacheStorageJournalSize*: U64 ## /< CacheStorageJournalSize + cacheStorageDataAndJournalSizeMax*: U64 ## /< CacheStorageDataAndJournalSizeMax + cacheStorageIndexMax*: U16 ## /< CacheStorageIndexMax + reservedX318a*: array[0x6, U8] ## /< Reserved + playLogQueryableApplicationId*: array[0x10, U64] ## /< PlayLogQueryableApplicationId + playLogQueryCapability*: U8 ## /< PlayLogQueryCapability + repairFlag*: U8 ## /< RepairFlag + programIndex*: U8 ## /< ProgramIndex + requiredNetworkServiceLicenseOnLaunch*: U8 ## /< RequiredNetworkServiceLicenseOnLaunchFlag + reservedX3214*: U32 ## /< Reserved + neighborDetectionClientConfiguration*: NacpNeighborDetectionClientConfiguration ## /< NeighborDetectionClientConfiguration + jitConfiguration*: NacpApplicationJitConfiguration ## /< JitConfiguration + reservedX33c0*: array[0xc40, U8] ## /< Reserved + +proc nacpGetLanguageEntry*(nacp: ptr NacpStruct; + langentry: ptr ptr NacpLanguageEntry): Result {.cdecl, + importc: "nacpGetLanguageEntry".} +## / Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty. +## / If you're using ns you may want to use \ref nsGetApplicationDesiredLanguage instead. + diff --git a/src/libnx/wrapper/switch/nro.h b/src/libnx/wrapper/switch/nro.h new file mode 100644 index 0000000..53e7c27 --- /dev/null +++ b/src/libnx/wrapper/switch/nro.h @@ -0,0 +1,54 @@ +/** + * @file nro.h + * @brief NRO headers. + * @copyright libnx Authors + */ + +#pragma once + +#define NROHEADER_MAGIC 0x304f524e + +#define NROASSETHEADER_MAGIC 0x54455341 +#define NROASSETHEADER_VERSION 0 + +/// Entry for each segment in the codebin. +typedef struct { + u32 file_off; + u32 size; +} NroSegment; + +/// Offset 0x0 in the NRO. +typedef struct { + u32 unused; + u32 mod_offset; + u8 padding[8]; +} NroStart; + +/// This follows NroStart, the actual nro-header. +typedef struct { + u32 magic; + u32 unk1; + u32 size; + u32 unk2; + NroSegment segments[3]; + u32 bss_size; + u32 unk3; + u8 build_id[0x20]; + u8 padding[0x20]; +} NroHeader; + +/// Custom asset section. +typedef struct { + u64 offset; + u64 size; +} NroAssetSection; + +/// Custom asset header. +typedef struct { + u32 magic; + u32 version; + NroAssetSection icon; + NroAssetSection nacp; + NroAssetSection romfs; +} NroAssetHeader; + diff --git a/src/libnx/wrapper/switch/nro.nim b/src/libnx/wrapper/switch/nro.nim new file mode 100644 index 0000000..c03f0d6 --- /dev/null +++ b/src/libnx/wrapper/switch/nro.nim @@ -0,0 +1,63 @@ +## * +## @file nro.h +## @brief NRO headers. +## @copyright libnx Authors +## + +import types + +const + NROHEADER_MAGIC* = 0x304f524e + NROASSETHEADER_MAGIC* = 0x54455341 + NROASSETHEADER_VERSION* = 0 + +## / Entry for each segment in the codebin. + +type + NroSegment* {.bycopy.} = object + fileOff*: U32 + size*: U32 + + +## / Offset 0x0 in the NRO. + +type + NroStart* {.bycopy.} = object + unused*: U32 + modOffset*: U32 + padding*: array[8, U8] + + +## / This follows NroStart, the actual nro-header. + +type + NroHeader* {.bycopy.} = object + magic*: U32 + unk1*: U32 + size*: U32 + unk2*: U32 + segments*: array[3, NroSegment] + bssSize*: U32 + unk3*: U32 + buildId*: array[0x20, U8] + padding*: array[0x20, U8] + + +## / Custom asset section. + +type + NroAssetSection* {.bycopy.} = object + offset*: U64 + size*: U64 + + +## / Custom asset header. + +type + NroAssetHeader* {.bycopy.} = object + magic*: U32 + version*: U32 + icon*: NroAssetSection + nacp*: NroAssetSection + romfs*: NroAssetSection + diff --git a/src/libnx/wrapper/switch/nvidia/address_space.h b/src/libnx/wrapper/switch/nvidia/address_space.h new file mode 100644 index 0000000..02fa0f3 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/address_space.h @@ -0,0 +1,21 @@ +#pragma once +#include "types.h" +#include "ioctl.h" + +typedef struct NvAddressSpace { + u32 fd; + u32 page_size; + bool has_init; +} NvAddressSpace; + +Result nvAddressSpaceCreate(NvAddressSpace* a, u32 page_size); +void nvAddressSpaceClose(NvAddressSpace* a); + +Result nvAddressSpaceAlloc(NvAddressSpace* a, bool sparse, u64 size, iova_t* iova_out); +Result nvAddressSpaceAllocFixed(NvAddressSpace* a, bool sparse, u64 size, iova_t iova); +Result nvAddressSpaceFree(NvAddressSpace* a, iova_t iova, u64 size); + +Result nvAddressSpaceMap(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t* iova_out); +Result nvAddressSpaceMapFixed(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t iova); +Result nvAddressSpaceModify(NvAddressSpace* a, iova_t iova, u64 offset, u64 size, NvKind kind); +Result nvAddressSpaceUnmap(NvAddressSpace* a, iova_t iova); diff --git a/src/libnx/wrapper/switch/nvidia/address_space.nim b/src/libnx/wrapper/switch/nvidia/address_space.nim new file mode 100644 index 0000000..1c70b4f --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/address_space.nim @@ -0,0 +1,33 @@ +import + types as t, ../types + +type + NvAddressSpace* {.bycopy.} = object + fd*: U32 + pageSize*: U32 + hasInit*: bool + + +proc nvAddressSpaceCreate*(a: ptr NvAddressSpace; pageSize: U32): Result {.cdecl, + importc: "nvAddressSpaceCreate".} +proc nvAddressSpaceClose*(a: ptr NvAddressSpace) {.cdecl, + importc: "nvAddressSpaceClose".} +proc nvAddressSpaceAlloc*(a: ptr NvAddressSpace; sparse: bool; size: U64; + iovaOut: ptr IovaT): Result {.cdecl, + importc: "nvAddressSpaceAlloc".} +proc nvAddressSpaceAllocFixed*(a: ptr NvAddressSpace; sparse: bool; size: U64; + iova: IovaT): Result {.cdecl, + importc: "nvAddressSpaceAllocFixed".} +proc nvAddressSpaceFree*(a: ptr NvAddressSpace; iova: IovaT; size: U64): Result {.cdecl, + importc: "nvAddressSpaceFree".} +proc nvAddressSpaceMap*(a: ptr NvAddressSpace; nvmapHandle: U32; isGpuCacheable: bool; + kind: NvKind; iovaOut: ptr IovaT): Result {.cdecl, + importc: "nvAddressSpaceMap".} +proc nvAddressSpaceMapFixed*(a: ptr NvAddressSpace; nvmapHandle: U32; + isGpuCacheable: bool; kind: NvKind; iova: IovaT): Result {. + cdecl, importc: "nvAddressSpaceMapFixed".} +proc nvAddressSpaceModify*(a: ptr NvAddressSpace; iova: IovaT; offset: U64; size: U64; + kind: NvKind): Result {.cdecl, + importc: "nvAddressSpaceModify".} +proc nvAddressSpaceUnmap*(a: ptr NvAddressSpace; iova: IovaT): Result {.cdecl, + importc: "nvAddressSpaceUnmap".} diff --git a/src/libnx/wrapper/switch/nvidia/channel.h b/src/libnx/wrapper/switch/nvidia/channel.h new file mode 100644 index 0000000..0957246 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/channel.h @@ -0,0 +1,14 @@ +#pragma once +#include "types.h" +#include "ioctl.h" + +typedef struct NvChannel { + u32 fd; + bool has_init; +} NvChannel; + +Result nvChannelCreate(NvChannel* c, const char* dev); +void nvChannelClose(NvChannel* c); + +Result nvChannelSetPriority(NvChannel* c, NvChannelPriority prio); +Result nvChannelSetTimeout(NvChannel* c, u32 timeout); diff --git a/src/libnx/wrapper/switch/nvidia/channel.nim b/src/libnx/wrapper/switch/nvidia/channel.nim new file mode 100644 index 0000000..43ee99b --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/channel.nim @@ -0,0 +1,15 @@ +import ioctl, ../types + +type + NvChannel* {.bycopy.} = object + fd*: U32 + hasInit*: bool + + +proc nvChannelCreate*(c: ptr NvChannel; dev: cstring): Result {.cdecl, + importc: "nvChannelCreate".} +proc nvChannelClose*(c: ptr NvChannel) {.cdecl, importc: "nvChannelClose".} +proc nvChannelSetPriority*(c: ptr NvChannel; prio: NvChannelPriority): Result {.cdecl, + importc: "nvChannelSetPriority".} +proc nvChannelSetTimeout*(c: ptr NvChannel; timeout: U32): Result {.cdecl, + importc: "nvChannelSetTimeout".} diff --git a/src/libnx/wrapper/switch/nvidia/fence.h b/src/libnx/wrapper/switch/nvidia/fence.h new file mode 100644 index 0000000..3f9693e --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/fence.h @@ -0,0 +1,21 @@ +#pragma once +#include "ioctl.h" + +typedef nvioctl_fence NvFence; + +typedef struct { + u32 num_fences; + NvFence fences[4]; +} NvMultiFence; + +Result nvFenceInit(void); +void nvFenceExit(void); + +Result nvFenceWait(NvFence* f, s32 timeout_us); + +static inline void nvMultiFenceCreate(NvMultiFence* mf, const NvFence* fence) { + mf->num_fences = 1; + mf->fences[0] = *fence; +} + +Result nvMultiFenceWait(NvMultiFence* mf, s32 timeout_us); diff --git a/src/libnx/wrapper/switch/nvidia/fence.nim b/src/libnx/wrapper/switch/nvidia/fence.nim new file mode 100644 index 0000000..0133386 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/fence.nim @@ -0,0 +1,20 @@ +import + ioctl, ../types, ../result + +type + NvFence* = NvioctlFence + NvMultiFence* {.bycopy.} = object + numFences*: U32 + fences*: array[4, NvFence] + + +proc nvFenceInit*(): Result {.cdecl, importc: "nvFenceInit".} +proc nvFenceExit*() {.cdecl, importc: "nvFenceExit".} +proc nvFenceWait*(f: ptr NvFence; timeoutUs: S32): Result {.cdecl, + importc: "nvFenceWait".} +proc nvMultiFenceCreate*(mf: ptr NvMultiFence; fence: ptr NvFence) {.inline, cdecl.} = + mf.numFences = 1 + mf.fences[0] = fence[] + +proc nvMultiFenceWait*(mf: ptr NvMultiFence; timeoutUs: S32): Result {.cdecl, + importc: "nvMultiFenceWait".} diff --git a/src/libnx/wrapper/switch/nvidia/gpu.h b/src/libnx/wrapper/switch/nvidia/gpu.h new file mode 100644 index 0000000..69a77e1 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/gpu.h @@ -0,0 +1,16 @@ +#pragma once +#include "types.h" +#include "ioctl.h" + +Result nvGpuInit(void); +void nvGpuExit(void); + +const nvioctl_gpu_characteristics* nvGpuGetCharacteristics(void); +u32 nvGpuGetZcullCtxSize(void); +const nvioctl_zcull_info* nvGpuGetZcullInfo(void); +const u32* nvGpuGetTpcMasks(u32 *num_masks_out); + +Result nvGpuZbcGetActiveSlotMask(u32 *out_slot, u32 *out_mask); +Result nvGpuZbcAddColor(const u32 color_l2[4], const u32 color_ds[4], u32 format); +Result nvGpuZbcAddDepth(float depth); +Result nvGpuGetTimestamp(u64 *ts); diff --git a/src/libnx/wrapper/switch/nvidia/gpu.nim b/src/libnx/wrapper/switch/nvidia/gpu.nim new file mode 100644 index 0000000..d3737ae --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/gpu.nim @@ -0,0 +1,16 @@ +import ioctl, ../result, ../types + +proc nvGpuInit*(): Result {.cdecl, importc: "nvGpuInit".} +proc nvGpuExit*() {.cdecl, importc: "nvGpuExit".} +proc nvGpuGetCharacteristics*(): ptr NvioctlGpuCharacteristics {.cdecl, + importc: "nvGpuGetCharacteristics".} +proc nvGpuGetZcullCtxSize*(): U32 {.cdecl, importc: "nvGpuGetZcullCtxSize".} +proc nvGpuGetZcullInfo*(): ptr NvioctlZcullInfo {.cdecl, importc: "nvGpuGetZcullInfo".} +proc nvGpuGetTpcMasks*(numMasksOut: ptr U32): ptr U32 {.cdecl, + importc: "nvGpuGetTpcMasks".} +proc nvGpuZbcGetActiveSlotMask*(outSlot: ptr U32; outMask: ptr U32): Result {.cdecl, + importc: "nvGpuZbcGetActiveSlotMask".} +proc nvGpuZbcAddColor*(colorL2: array[4, U32]; colorDs: array[4, U32]; format: U32): Result {. + cdecl, importc: "nvGpuZbcAddColor".} +proc nvGpuZbcAddDepth*(depth: cfloat): Result {.cdecl, importc: "nvGpuZbcAddDepth".} +proc nvGpuGetTimestamp*(ts: ptr U64): Result {.cdecl, importc: "nvGpuGetTimestamp".} diff --git a/src/libnx/wrapper/switch/nvidia/gpu_channel.h b/src/libnx/wrapper/switch/nvidia/gpu_channel.h new file mode 100644 index 0000000..7963a56 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/gpu_channel.h @@ -0,0 +1,44 @@ +#pragma once +#include "../kernel/event.h" +#include "channel.h" +#include "fence.h" + +#define GPFIFO_QUEUE_SIZE 0x800 +#define GPFIFO_ENTRY_NOT_MAIN BIT(9) +#define GPFIFO_ENTRY_NO_PREFETCH BIT(31) + +typedef struct NvGpuChannel +{ + NvChannel base; + Event error_event; + u64 object_id; + NvFence fence; + u32 fence_incr; + nvioctl_gpfifo_entry entries[GPFIFO_QUEUE_SIZE]; + u32 num_entries; +} NvGpuChannel; + +Result nvGpuChannelCreate(NvGpuChannel* c, struct NvAddressSpace* as, NvChannelPriority prio); +void nvGpuChannelClose(NvGpuChannel* c); + +Result nvGpuChannelZcullBind(NvGpuChannel* c, iova_t iova); +Result nvGpuChannelAppendEntry(NvGpuChannel* c, iova_t start, size_t num_cmds, u32 flags, u32 flush_threshold); +Result nvGpuChannelKickoff(NvGpuChannel* c); +Result nvGpuChannelGetErrorNotification(NvGpuChannel* c, NvNotification* notif); +Result nvGpuChannelGetErrorInfo(NvGpuChannel* c, NvError* error); + +static inline u32 nvGpuChannelGetSyncpointId(NvGpuChannel* c) +{ + return c->fence.id; +} + +static inline void nvGpuChannelGetFence(NvGpuChannel* c, NvFence* fence_out) +{ + fence_out->id = c->fence.id; + fence_out->value = c->fence.value + c->fence_incr; +} + +static inline void nvGpuChannelIncrFence(NvGpuChannel* c) +{ + ++c->fence_incr; +} diff --git a/src/libnx/wrapper/switch/nvidia/gpu_channel.nim b/src/libnx/wrapper/switch/nvidia/gpu_channel.nim new file mode 100644 index 0000000..7d17e3e --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/gpu_channel.nim @@ -0,0 +1,44 @@ +import + ../kernel/event, channel, fence, ../types, types as t, ioctl, address_space + +const + GPFIFO_QUEUE_SIZE* = 0x800 + GPFIFO_ENTRY_NOT_MAIN* = bit(9) + GPFIFO_ENTRY_NO_PREFETCH* = bit(31) + +type + NvGpuChannel* {.bycopy.} = object + base*: NvChannel + errorEvent*: Event + objectId*: U64 + fence*: NvFence + fenceIncr*: U32 + entries*: array[Gpfifo_Queue_Size, NvioctlGpfifoEntry] + numEntries*: U32 + + +proc nvGpuChannelCreate*(c: ptr NvGpuChannel; `as`: ptr NvAddressSpace; + prio: NvChannelPriority): Result {.cdecl, + importc: "nvGpuChannelCreate".} +proc nvGpuChannelClose*(c: ptr NvGpuChannel) {.cdecl, importc: "nvGpuChannelClose".} +proc nvGpuChannelZcullBind*(c: ptr NvGpuChannel; iova: IovaT): Result {.cdecl, + importc: "nvGpuChannelZcullBind".} +proc nvGpuChannelAppendEntry*(c: ptr NvGpuChannel; start: IovaT; numCmds: csize_t; + flags: U32; flushThreshold: U32): Result {.cdecl, + importc: "nvGpuChannelAppendEntry".} +proc nvGpuChannelKickoff*(c: ptr NvGpuChannel): Result {.cdecl, + importc: "nvGpuChannelKickoff".} +proc nvGpuChannelGetErrorNotification*(c: ptr NvGpuChannel; + notif: ptr NvNotification): Result {.cdecl, + importc: "nvGpuChannelGetErrorNotification".} +proc nvGpuChannelGetErrorInfo*(c: ptr NvGpuChannel; error: ptr NvError): Result {.cdecl, + importc: "nvGpuChannelGetErrorInfo".} +proc nvGpuChannelGetSyncpointId*(c: ptr NvGpuChannel): U32 {.inline, cdecl.} = + return c.fence.id + +proc nvGpuChannelGetFence*(c: ptr NvGpuChannel; fenceOut: ptr NvFence) {.inline, cdecl.} = + fenceOut.id = c.fence.id + fenceOut.value = c.fence.value + c.fenceIncr + +proc nvGpuChannelIncrFence*(c: ptr NvGpuChannel) {.inline, cdecl.} = + inc(c.fenceIncr) diff --git a/src/libnx/wrapper/switch/nvidia/graphic_buffer.h b/src/libnx/wrapper/switch/nvidia/graphic_buffer.h new file mode 100644 index 0000000..f046278 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/graphic_buffer.h @@ -0,0 +1,39 @@ +#pragma once +#include "../display/types.h" +#include "types.h" + +typedef struct { + u32 width; + u32 height; + NvColorFormat color_format; + NvLayout layout; + u32 pitch; + u32 unused; // usually this field contains the nvmap handle, but it's completely unused/overwritten during marshalling + u32 offset; + NvKind kind; + u32 block_height_log2; + NvDisplayScanFormat scan; + u32 second_field_offset; + u64 flags; + u64 size; + u32 unk[6]; // compression related +} NvSurface; + +typedef struct { + NativeHandle header; + s32 unk0; // -1 + s32 nvmap_id; // nvmap object id + u32 unk2; // 0 + u32 magic; // 0xDAFFCAFF + u32 pid; // 42 + u32 type; // ? + u32 usage; // GRALLOC_USAGE_* bitmask + u32 format; // PIXEL_FORMAT_* + u32 ext_format; // copy of the above (in most cases) + u32 stride; // in pixels! + u32 total_size; // in bytes + u32 num_planes; // usually 1 + u32 unk12; // 0 + NvSurface planes[3]; + u64 unused; // official sw writes a pointer to bookkeeping data here, but it's otherwise completely unused/overwritten during marshalling +} NvGraphicBuffer; diff --git a/src/libnx/wrapper/switch/nvidia/graphic_buffer.nim b/src/libnx/wrapper/switch/nvidia/graphic_buffer.nim new file mode 100644 index 0000000..baddf45 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/graphic_buffer.nim @@ -0,0 +1,38 @@ +import + ../display/types as dt, types as t, ../types + +type + NvSurface* {.bycopy.} = object + width*: U32 + height*: U32 + colorFormat*: NvColorFormat + layout*: NvLayout + pitch*: U32 + unused*: U32 ## usually this field contains the nvmap handle, but it's completely unused/overwritten during marshalling + offset*: U32 + kind*: NvKind + blockHeightLog2*: U32 + scan*: NvDisplayScanFormat + secondFieldOffset*: U32 + flags*: U64 + size*: U64 + unk*: array[6, U32] ## compression related + + NvGraphicBuffer* {.bycopy.} = object + header*: NativeHandle + unk0*: S32 ## -1 + nvmapId*: S32 ## nvmap object id + unk2*: U32 ## 0 + magic*: U32 ## 0xDAFFCAFF + pid*: U32 ## 42 + `type`*: U32 ## ? + usage*: U32 ## GRALLOC_USAGE_* bitmask + format*: U32 ## PIXEL_FORMAT_* + extFormat*: U32 ## copy of the above (in most cases) + stride*: U32 ## in pixels! + totalSize*: U32 ## in bytes + numPlanes*: U32 ## usually 1 + unk12*: U32 ## 0 + planes*: array[3, NvSurface] + unused*: U64 ## official sw writes a pointer to bookkeeping data here, but it's otherwise completely unused/overwritten during marshalling + diff --git a/src/libnx/wrapper/switch/nvidia/ioctl.h b/src/libnx/wrapper/switch/nvidia/ioctl.h new file mode 100644 index 0000000..dd0fc5d --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/ioctl.h @@ -0,0 +1,288 @@ +#pragma once +#include "types.h" + +// The below defines are based on Linux kernel ioctl.h. +#define _NV_IOC_NRBITS 8 +#define _NV_IOC_TYPEBITS 8 +#define _NV_IOC_SIZEBITS 14 +#define _NV_IOC_DIRBITS 2 + +#define _NV_IOC_NRMASK ((1 << _NV_IOC_NRBITS)-1) +#define _NV_IOC_TYPEMASK ((1 << _NV_IOC_TYPEBITS)-1) +#define _NV_IOC_SIZEMASK ((1 << _NV_IOC_SIZEBITS)-1) +#define _NV_IOC_DIRMASK ((1 << _NV_IOC_DIRBITS)-1) + +#define _NV_IOC_NRSHIFT 0 +#define _NV_IOC_TYPESHIFT (_NV_IOC_NRSHIFT+_NV_IOC_NRBITS) +#define _NV_IOC_SIZESHIFT (_NV_IOC_TYPESHIFT+_NV_IOC_TYPEBITS) +#define _NV_IOC_DIRSHIFT (_NV_IOC_SIZESHIFT+_NV_IOC_SIZEBITS) + +// Direction bits. +#define _NV_IOC_NONE 0U +#define _NV_IOC_WRITE 1U +#define _NV_IOC_READ 2U + +#define _NV_IOC(dir,type,nr,size) \ + (((dir) << _NV_IOC_DIRSHIFT) | \ + ((type) << _NV_IOC_TYPESHIFT) | \ + ((nr) << _NV_IOC_NRSHIFT) | \ + ((size) << _NV_IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _NV_IO(type,nr) _NV_IOC(_NV_IOC_NONE,(type),(nr),0) +#define _NV_IOR(type,nr,size) _NV_IOC(_NV_IOC_READ,(type),(nr),sizeof(size)) +#define _NV_IOW(type,nr,size) _NV_IOC(_NV_IOC_WRITE,(type),(nr),sizeof(size)) +#define _NV_IOWR(type,nr,size) _NV_IOC(_NV_IOC_READ|_NV_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _NV_IOC_DIR(nr) (((nr) >> _NV_IOC_DIRSHIFT) & _NV_IOC_DIRMASK) +#define _NV_IOC_TYPE(nr) (((nr) >> _NV_IOC_TYPESHIFT) & _NV_IOC_TYPEMASK) +#define _NV_IOC_NR(nr) (((nr) >> _NV_IOC_NRSHIFT) & _NV_IOC_NRMASK) +#define _NV_IOC_SIZE(nr) (((nr) >> _NV_IOC_SIZESHIFT) & _NV_IOC_SIZEMASK) + +#define __nv_in +#define __nv_out +#define __nv_inout + +typedef struct { + u32 width_align_pixels; // 0x20 (32) + u32 height_align_pixels; // 0x20 (32) + u32 pixel_squares_by_aliquots; // 0x400 (1024) + u32 aliquot_total; // 0x800 (2048) + u32 region_byte_multiplier; // 0x20 (32) + u32 region_header_size; // 0x20 (32) + u32 subregion_header_size; // 0xC0 (192) + u32 subregion_width_align_pixels; // 0x20 (32) + u32 subregion_height_align_pixels; // 0x40 (64) + u32 subregion_count; // 0x10 (16) +} nvioctl_zcull_info; + +typedef struct { + u32 color_ds[4]; + u32 color_l2[4]; + u32 depth; + u32 ref_cnt; + u32 format; + u32 type; + u32 size; +} nvioctl_zbc_entry; + +typedef struct { + u32 arch; // 0x120 (NVGPU_GPU_ARCH_GM200) + u32 impl; // 0xB (NVGPU_GPU_IMPL_GM20B) + u32 rev; // 0xA1 (Revision A1) + u32 num_gpc; // 0x1 + u64 L2_cache_size; // 0x40000 + u64 on_board_video_memory_size; // 0x0 (not used) + u32 num_tpc_per_gpc; // 0x2 + u32 bus_type; // 0x20 (NVGPU_GPU_BUS_TYPE_AXI) + u32 big_page_size; // 0x20000 + u32 compression_page_size; // 0x20000 + u32 pde_coverage_bit_count; // 0x1B + u32 available_big_page_sizes; // 0x30000 + u32 gpc_mask; // 0x1 + u32 sm_arch_sm_version; // 0x503 (Maxwell Generation 5.0.3?) + u32 sm_arch_spa_version; // 0x503 (Maxwell Generation 5.0.3?) + u32 sm_arch_warp_count; // 0x80 + u32 gpu_va_bit_count; // 0x28 + u32 reserved; // NULL + u64 flags; // 0x55 + u32 twod_class; // 0x902D (FERMI_TWOD_A) + u32 threed_class; // 0xB197 (MAXWELL_B) + u32 compute_class; // 0xB1C0 (MAXWELL_COMPUTE_B) + u32 gpfifo_class; // 0xB06F (MAXWELL_CHANNEL_GPFIFO_A) + u32 inline_to_memory_class; // 0xA140 (KEPLER_INLINE_TO_MEMORY_B) + u32 dma_copy_class; // 0xB0B5 (MAXWELL_DMA_COPY_A) + u32 max_fbps_count; // 0x1 + u32 fbp_en_mask; // 0x0 (disabled) + u32 max_ltc_per_fbp; // 0x2 + u32 max_lts_per_ltc; // 0x1 + u32 max_tex_per_tpc; // 0x0 (not supported) + u32 max_gpc_count; // 0x1 + u32 rop_l2_en_mask_0; // 0x21D70 (fuse_status_opt_rop_l2_fbp_r) + u32 rop_l2_en_mask_1; // 0x0 + u64 chipname; // 0x6230326D67 ("gm20b") + u64 gr_compbit_store_base_hw; // 0x0 (not supported) +} nvioctl_gpu_characteristics; + +typedef struct { + u64 offset; + u32 page_size; + u32 pad; + u64 pages; +} nvioctl_va_region; + +typedef struct { + u32 slot; // always 0x07 (?) + u32 mask; +} nvioctl_zbc_slot_mask; + +typedef struct { + u64 timestamp; + u64 reserved; +} nvioctl_gpu_time; + +typedef struct { + u32 id; + u32 value; +} nvioctl_fence; + +typedef struct { + union { + u64 desc; + u32 desc32[2]; + }; +} nvioctl_gpfifo_entry; + +typedef struct { + u32 mem; + u32 offset; + u32 words; +} nvioctl_cmdbuf; + +typedef struct { + u32 cmdbuf_mem; + u32 cmdbuf_offset; + u32 target; + u32 target_offset; +} nvioctl_reloc; + +typedef struct { + u32 shift; +} nvioctl_reloc_shift; + +typedef struct { + u32 syncpt_id; + u32 syncpt_incrs; +} nvioctl_syncpt_incr; + +typedef struct { + u32 handle; + u32 iova; +} nvioctl_command_buffer_map; + +#define NVGPU_ZBC_TYPE_INVALID 0 +#define NVGPU_ZBC_TYPE_COLOR 1 +#define NVGPU_ZBC_TYPE_DEPTH 2 + +// Used with nvioctlNvmap_Param(). +typedef enum nvioctl_map_param { + NvMapParam_Size = 1, + NvMapParam_Alignment = 2, + NvMapParam_Base = 3, + NvMapParam_Heap = 4, + NvMapParam_Kind = 5 +} NvMapParam; + +// Used with nvioctlChannel_AllocObjCtx(). +typedef enum nvioctl_channel_obj_classnum { + NvClassNumber_2D = 0x902D, + NvClassNumber_3D = 0xB197, + NvClassNumber_Compute = 0xB1C0, + NvClassNumber_Kepler = 0xA140, + NvClassNumber_DMA = 0xB0B5, + NvClassNumber_ChannelGpfifo = 0xB06F +} NvClassNumber; + +// Used with nvioctlChannel_SetPriority(). +typedef enum nvioctl_channel_priority { + NvChannelPriority_Low = 50, + NvChannelPriority_Medium = 100, + NvChannelPriority_High = 150 +} NvChannelPriority; + +// Used with nvioctlChannel_ZCullBind(). +typedef enum { + NvZcullConfig_Global = 0, + NvZcullConfig_NoCtxSwitch = 1, + NvZcullConfig_SeparateBuffer = 2, + NvZcullConfig_PartOfRegularBuffer = 3 +} NvZcullConfig; + +// Used with nvioctlNvhostAsGpu_AllocSpace(). +typedef enum { + NvAllocSpaceFlags_FixedOffset = 1, + NvAllocSpaceFlags_Sparse = 2, +} NvAllocSpaceFlags; + +// Used with nvioctlNvhostAsGpu_MapBufferEx(). +typedef enum { + NvMapBufferFlags_FixedOffset = 1, + NvMapBufferFlags_IsCacheable = 4, + NvMapBufferFlags_Modify = 0x100, +} NvMapBufferFlags; + +typedef enum { + NvNotificationType_FifoErrorIdleTimeout=8, + NvNotificationType_GrErrorSwNotify=13, + NvNotificationType_GrSemaphoreTimeout=24, + NvNotificationType_GrIllegalNotify=25, + NvNotificationType_FifoErrorMmuErrFlt=31, + NvNotificationType_PbdmaError=32, + NvNotificationType_ResetChannelVerifError=43, + NvNotificationType_PbdmaPushbufferCrcMismatch=80 +} NvNotificationType; + +typedef struct { + u64 timestamp; + u32 info32; // see NvNotificationType + u16 info16; + u16 status; // always -1 +} NvNotification; + +typedef struct { + u32 type; + u32 info[31]; +} NvError; + +Result nvioctlNvhostCtrl_SyncptRead(u32 fd, u32 id, u32* out); +Result nvioctlNvhostCtrl_SyncptIncr(u32 fd, u32 id); +Result nvioctlNvhostCtrl_SyncptWait(u32 fd, u32 id, u32 threshold, u32 timeout); +Result nvioctlNvhostCtrl_EventSignal(u32 fd, u32 event_id); +Result nvioctlNvhostCtrl_EventWait(u32 fd, u32 syncpt_id, u32 threshold, s32 timeout, u32 event_id, u32 *out); +Result nvioctlNvhostCtrl_EventWaitAsync(u32 fd, u32 syncpt_id, u32 threshold, s32 timeout, u32 event_id); +Result nvioctlNvhostCtrl_EventRegister(u32 fd, u32 event_id); +Result nvioctlNvhostCtrl_EventUnregister(u32 fd, u32 event_id); + +Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out); +Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, nvioctl_zcull_info *out); +Result nvioctlNvhostCtrlGpu_ZbcSetTable(u32 fd, const u32 color_ds[4], const u32 color_l2[4], u32 depth, u32 format, u32 type); +Result nvioctlNvhostCtrlGpu_ZbcQueryTable(u32 fd, u32 index, nvioctl_zbc_entry *out); +Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, nvioctl_gpu_characteristics *out); +Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, void *buffer, size_t size); +Result nvioctlNvhostCtrlGpu_ZbcGetActiveSlotMask(u32 fd, nvioctl_zbc_slot_mask *out); +Result nvioctlNvhostCtrlGpu_GetGpuTime(u32 fd, nvioctl_gpu_time *out); + +Result nvioctlNvhostAsGpu_BindChannel(u32 fd, u32 channel_fd); +Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align_or_offset, u64 *offset); +Result nvioctlNvhostAsGpu_FreeSpace(u32 fd, u64 offset, u32 pages, u32 page_size); +Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_handle, u32 page_size, u64 buffer_offset, u64 mapping_size, u64 input_offset, u64 *offset); +Result nvioctlNvhostAsGpu_UnmapBuffer(u32 fd, u64 offset); +Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]); +Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 flags, u32 big_page_size); + +Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle); +Result nvioctlNvmap_FromId(u32 fd, u32 id, u32 *nvmap_handle); +Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr); +Result nvioctlNvmap_Free(u32 fd, u32 nvmap_handle); +Result nvioctlNvmap_Param(u32 fd, u32 nvmap_handle, NvMapParam param, u32 *result); +Result nvioctlNvmap_GetId(u32 fd, u32 nvmap_handle, u32 *id); + +Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd); +Result nvioctlChannel_SubmitGpfifo(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_inout); +Result nvioctlChannel_KickoffPb(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_inout); +Result nvioctlChannel_AllocObjCtx(u32 fd, u32 class_num, u32 flags, u64* id_out); +Result nvioctlChannel_ZCullBind(u32 fd, u64 gpu_va, u32 mode); +Result nvioctlChannel_SetErrorNotifier(u32 fd, u32 enable); +Result nvioctlChannel_GetErrorInfo(u32 fd, NvError* out); +Result nvioctlChannel_GetErrorNotification(u32 fd, NvNotification* out); +Result nvioctlChannel_SetPriority(u32 fd, u32 priority); +Result nvioctlChannel_SetTimeout(u32 fd, u32 timeout); +Result nvioctlChannel_AllocGpfifoEx2(u32 fd, u32 num_entries, u32 flags, u32 unk0, u32 unk1, u32 unk2, u32 unk3, nvioctl_fence *fence_out); +Result nvioctlChannel_SetUserData(u32 fd, void* addr); +Result nvioctlChannel_Submit(u32 fd, const nvioctl_cmdbuf *cmdbufs, u32 num_cmdbufs, const nvioctl_reloc *relocs, const nvioctl_reloc_shift *reloc_shifts, u32 num_relocs, + const nvioctl_syncpt_incr *syncpt_incrs, u32 num_syncpt_incrs, nvioctl_fence *fences, u32 num_fences); +Result nvioctlChannel_GetSyncpt(u32 fd, u32 module_id, u32 *syncpt); +Result nvioctlChannel_GetModuleClockRate(u32 fd, u32 module_id, u32 *freq); +Result nvioctlChannel_MapCommandBuffer(u32 fd, nvioctl_command_buffer_map *maps, u32 num_maps, bool compressed); +Result nvioctlChannel_UnmapCommandBuffer(u32 fd, const nvioctl_command_buffer_map *maps, u32 num_maps, bool compressed); diff --git a/src/libnx/wrapper/switch/nvidia/ioctl.nim b/src/libnx/wrapper/switch/nvidia/ioctl.nim new file mode 100644 index 0000000..93bd4a4 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/ioctl.nim @@ -0,0 +1,353 @@ +import + ../types + +## The below defines are based on Linux kernel ioctl.h. + +const + NV_IOC_NRBITS* = 8 + NV_IOC_TYPEBITS* = 8 + NV_IOC_SIZEBITS* = 14 + NV_IOC_DIRBITS* = 2 + NV_IOC_NRMASK* = ((1 shl Nv_Ioc_Nrbits) - 1) + NV_IOC_TYPEMASK* = ((1 shl Nv_Ioc_Typebits) - 1) + NV_IOC_SIZEMASK* = ((1 shl Nv_Ioc_Sizebits) - 1) + NV_IOC_DIRMASK* = ((1 shl Nv_Ioc_Dirbits) - 1) + NV_IOC_NRSHIFT* = 0 + NV_IOC_TYPESHIFT* = (Nv_Ioc_Nrshift + Nv_Ioc_Nrbits) + NV_IOC_SIZESHIFT* = (Nv_Ioc_Typeshift + Nv_Ioc_Typebits) + NV_IOC_DIRSHIFT* = (Nv_Ioc_Sizeshift + Nv_Ioc_Sizebits) + +## Direction bits. + +const + NV_IOC_NONE* = 0'u + NV_IOC_WRITE* = 1'u + NV_IOC_READ* = 2'u + +template nv_Ioc*(dir, `type`, nr, size: untyped): untyped = + (((dir) shl nv_Ioc_Dirshift) or ((`type`) shl nv_Ioc_Typeshift) or + ((nr) shl nv_Ioc_Nrshift) or ((size) shl nv_Ioc_Sizeshift)) + +## used to create numbers + +template nv_Io*(`type`, nr: untyped): untyped = + nv_Ioc(nv_Ioc_None, (`type`), (nr), 0) + +template nv_Ior*(`type`, nr, size: untyped): untyped = + nv_Ioc(nv_Ioc_Read, (`type`), (nr), sizeof((size))) + +template nv_Iow*(`type`, nr, size: untyped): untyped = + nv_Ioc(nv_Ioc_Write, (`type`), (nr), sizeof((size))) + +template nv_Iowr*(`type`, nr, size: untyped): untyped = + nv_Ioc(nv_Ioc_Read or nv_Ioc_Write, (`type`), (nr), sizeof((size))) + +## used to decode ioctl numbers.. + +template nv_Ioc_Dir*(nr: untyped): untyped = + (((nr) shr nv_Ioc_Dirshift) and nv_Ioc_Dirmask) + +template nv_Ioc_Type*(nr: untyped): untyped = + (((nr) shr nv_Ioc_Typeshift) and nv_Ioc_Typemask) + +template nv_Ioc_Nr*(nr: untyped): untyped = + (((nr) shr nv_Ioc_Nrshift) and nv_Ioc_Nrmask) + +template nv_Ioc_Size*(nr: untyped): untyped = + (((nr) shr nv_Ioc_Sizeshift) and nv_Ioc_Sizemask) + +type + INNER_C_UNION_ioctl_2* {.bycopy, union.} = object + desc*: U64 + desc32*: array[2, U32] + + NvioctlZcullInfo* {.bycopy.} = object + widthAlignPixels*: U32 ## 0x20 (32) + heightAlignPixels*: U32 ## 0x20 (32) + pixelSquaresByAliquots*: U32 ## 0x400 (1024) + aliquotTotal*: U32 ## 0x800 (2048) + regionByteMultiplier*: U32 ## 0x20 (32) + regionHeaderSize*: U32 ## 0x20 (32) + subregionHeaderSize*: U32 ## 0xC0 (192) + subregionWidthAlignPixels*: U32 ## 0x20 (32) + subregionHeightAlignPixels*: U32 ## 0x40 (64) + subregionCount*: U32 ## 0x10 (16) + + NvioctlZbcEntry* {.bycopy.} = object + colorDs*: array[4, U32] + colorL2*: array[4, U32] + depth*: U32 + refCnt*: U32 + format*: U32 + `type`*: U32 + size*: U32 + + NvioctlGpuCharacteristics* {.bycopy.} = object + arch*: U32 ## 0x120 (NVGPU_GPU_ARCH_GM200) + impl*: U32 ## 0xB (NVGPU_GPU_IMPL_GM20B) + rev*: U32 ## 0xA1 (Revision A1) + numGpc*: U32 ## 0x1 + l2CacheSize*: U64 ## 0x40000 + onBoardVideoMemorySize*: U64 ## 0x0 (not used) + numTpcPerGpc*: U32 ## 0x2 + busType*: U32 ## 0x20 (NVGPU_GPU_BUS_TYPE_AXI) + bigPageSize*: U32 ## 0x20000 + compressionPageSize*: U32 ## 0x20000 + pdeCoverageBitCount*: U32 ## 0x1B + availableBigPageSizes*: U32 ## 0x30000 + gpcMask*: U32 ## 0x1 + smArchSmVersion*: U32 ## 0x503 (Maxwell Generation 5.0.3?) + smArchSpaVersion*: U32 ## 0x503 (Maxwell Generation 5.0.3?) + smArchWarpCount*: U32 ## 0x80 + gpuVaBitCount*: U32 ## 0x28 + reserved*: U32 ## NULL + flags*: U64 ## 0x55 + twodClass*: U32 ## 0x902D (FERMI_TWOD_A) + threedClass*: U32 ## 0xB197 (MAXWELL_B) + computeClass*: U32 ## 0xB1C0 (MAXWELL_COMPUTE_B) + gpfifoClass*: U32 ## 0xB06F (MAXWELL_CHANNEL_GPFIFO_A) + inlineToMemoryClass*: U32 ## 0xA140 (KEPLER_INLINE_TO_MEMORY_B) + dmaCopyClass*: U32 ## 0xB0B5 (MAXWELL_DMA_COPY_A) + maxFbpsCount*: U32 ## 0x1 + fbpEnMask*: U32 ## 0x0 (disabled) + maxLtcPerFbp*: U32 ## 0x2 + maxLtsPerLtc*: U32 ## 0x1 + maxTexPerTpc*: U32 ## 0x0 (not supported) + maxGpcCount*: U32 ## 0x1 + ropL2EnMask0*: U32 ## 0x21D70 (fuse_status_opt_rop_l2_fbp_r) + ropL2EnMask1*: U32 ## 0x0 + chipname*: U64 ## 0x6230326D67 ("gm20b") + grCompbitStoreBaseHw*: U64 ## 0x0 (not supported) + + NvioctlVaRegion* {.bycopy.} = object + offset*: U64 + pageSize*: U32 + pad*: U32 + pages*: U64 + + NvioctlZbcSlotMask* {.bycopy.} = object + slot*: U32 ## always 0x07 (?) + mask*: U32 + + NvioctlGpuTime* {.bycopy.} = object + timestamp*: U64 + reserved*: U64 + + NvioctlFence* {.bycopy.} = object + id*: U32 + value*: U32 + + NvioctlGpfifoEntry* {.bycopy.} = object + anoIoctl3*: INNER_C_UNION_ioctl_2 + + NvioctlCmdbuf* {.bycopy.} = object + mem*: U32 + offset*: U32 + words*: U32 + + NvioctlReloc* {.bycopy.} = object + cmdbufMem*: U32 + cmdbufOffset*: U32 + target*: U32 + targetOffset*: U32 + + NvioctlRelocShift* {.bycopy.} = object + shift*: U32 + + NvioctlSyncptIncr* {.bycopy.} = object + syncptId*: U32 + syncptIncrs*: U32 + + NvioctlCommandBufferMap* {.bycopy.} = object + handle*: U32 + iova*: U32 + + +const + NVGPU_ZBC_TYPE_INVALID* = 0 + NVGPU_ZBC_TYPE_COLOR* = 1 + NVGPU_ZBC_TYPE_DEPTH* = 2 + +## Used with nvioctlNvmap_Param(). + +type + NvMapParam* = enum + NvMapParamSize = 1, NvMapParamAlignment = 2, NvMapParamBase = 3, NvMapParamHeap = 4, + NvMapParamKind = 5 + + +## Used with nvioctlChannel_AllocObjCtx(). + +type + NvClassNumber* = enum + NvClassNumber2D = 0x902D, NvClassNumberKepler = 0xA140, + NvClassNumberChannelGpfifo = 0xB06F, NvClassNumberDMA = 0xB0B5, + NvClassNumber3D = 0xB197, NvClassNumberCompute = 0xB1C0 + + +## Used with nvioctlChannel_SetPriority(). + +type + NvChannelPriority* = enum + NvChannelPriorityLow = 50, NvChannelPriorityMedium = 100, + NvChannelPriorityHigh = 150 + + +## Used with nvioctlChannel_ZCullBind(). + +type + NvZcullConfig* = enum + NvZcullConfigGlobal = 0, NvZcullConfigNoCtxSwitch = 1, + NvZcullConfigSeparateBuffer = 2, NvZcullConfigPartOfRegularBuffer = 3 + + +## Used with nvioctlNvhostAsGpu_AllocSpace(). + +type + NvAllocSpaceFlags* = enum + NvAllocSpaceFlagsFixedOffset = 1, NvAllocSpaceFlagsSparse = 2 + + +## Used with nvioctlNvhostAsGpu_MapBufferEx(). + +type + NvMapBufferFlags* = enum + NvMapBufferFlagsFixedOffset = 1, NvMapBufferFlagsIsCacheable = 4, + NvMapBufferFlagsModify = 0x100 + NvNotificationType* = enum + NvNotificationTypeFifoErrorIdleTimeout = 8, + NvNotificationTypeGrErrorSwNotify = 13, + NvNotificationTypeGrSemaphoreTimeout = 24, + NvNotificationTypeGrIllegalNotify = 25, + NvNotificationTypeFifoErrorMmuErrFlt = 31, NvNotificationTypePbdmaError = 32, + NvNotificationTypeResetChannelVerifError = 43, + NvNotificationTypePbdmaPushbufferCrcMismatch = 80 + NvNotification* {.bycopy.} = object + timestamp*: U64 + info32*: U32 ## see NvNotificationType + info16*: U16 + status*: U16 ## always -1 + + NvError* {.bycopy.} = object + `type`*: U32 + info*: array[31, U32] + + + + +proc nvioctlNvhostCtrlSyncptRead*(fd: U32; id: U32; `out`: ptr U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_SyncptRead".} +proc nvioctlNvhostCtrlSyncptIncr*(fd: U32; id: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_SyncptIncr".} +proc nvioctlNvhostCtrlSyncptWait*(fd: U32; id: U32; threshold: U32; timeout: U32): Result {. + cdecl, importc: "nvioctlNvhostCtrl_SyncptWait".} +proc nvioctlNvhostCtrlEventSignal*(fd: U32; eventId: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_EventSignal".} +proc nvioctlNvhostCtrlEventWait*(fd: U32; syncptId: U32; threshold: U32; timeout: S32; + eventId: U32; `out`: ptr U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_EventWait".} +proc nvioctlNvhostCtrlEventWaitAsync*(fd: U32; syncptId: U32; threshold: U32; + timeout: S32; eventId: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_EventWaitAsync".} +proc nvioctlNvhostCtrlEventRegister*(fd: U32; eventId: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_EventRegister".} +proc nvioctlNvhostCtrlEventUnregister*(fd: U32; eventId: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrl_EventUnregister".} +proc nvioctlNvhostCtrlGpuZCullGetCtxSize*(fd: U32; `out`: ptr U32): Result {.cdecl, + importc: "nvioctlNvhostCtrlGpu_ZCullGetCtxSize".} +proc nvioctlNvhostCtrlGpuZCullGetInfo*(fd: U32; `out`: ptr NvioctlZcullInfo): Result {. + cdecl, importc: "nvioctlNvhostCtrlGpu_ZCullGetInfo".} +proc nvioctlNvhostCtrlGpuZbcSetTable*(fd: U32; colorDs: array[4, U32]; + colorL2: array[4, U32]; depth: U32; format: U32; + `type`: U32): Result {.cdecl, + importc: "nvioctlNvhostCtrlGpu_ZbcSetTable".} +proc nvioctlNvhostCtrlGpuZbcQueryTable*(fd: U32; index: U32; + `out`: ptr NvioctlZbcEntry): Result {.cdecl, + importc: "nvioctlNvhostCtrlGpu_ZbcQueryTable".} +proc nvioctlNvhostCtrlGpuGetCharacteristics*(fd: U32; + `out`: ptr NvioctlGpuCharacteristics): Result {.cdecl, + importc: "nvioctlNvhostCtrlGpu_GetCharacteristics".} +proc nvioctlNvhostCtrlGpuGetTpcMasks*(fd: U32; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "nvioctlNvhostCtrlGpu_GetTpcMasks".} +proc nvioctlNvhostCtrlGpuZbcGetActiveSlotMask*(fd: U32; + `out`: ptr NvioctlZbcSlotMask): Result {.cdecl, + importc: "nvioctlNvhostCtrlGpu_ZbcGetActiveSlotMask".} +proc nvioctlNvhostCtrlGpuGetGpuTime*(fd: U32; `out`: ptr NvioctlGpuTime): Result {. + cdecl, importc: "nvioctlNvhostCtrlGpu_GetGpuTime".} +proc nvioctlNvhostAsGpuBindChannel*(fd: U32; channelFd: U32): Result {.cdecl, + importc: "nvioctlNvhostAsGpu_BindChannel".} +proc nvioctlNvhostAsGpuAllocSpace*(fd: U32; pages: U32; pageSize: U32; flags: U32; + alignOrOffset: U64; offset: ptr U64): Result {. + cdecl, importc: "nvioctlNvhostAsGpu_AllocSpace".} +proc nvioctlNvhostAsGpuFreeSpace*(fd: U32; offset: U64; pages: U32; pageSize: U32): Result {. + cdecl, importc: "nvioctlNvhostAsGpu_FreeSpace".} +proc nvioctlNvhostAsGpuMapBufferEx*(fd: U32; flags: U32; kind: U32; nvmapHandle: U32; + pageSize: U32; bufferOffset: U64; + mappingSize: U64; inputOffset: U64; + offset: ptr U64): Result {.cdecl, + importc: "nvioctlNvhostAsGpu_MapBufferEx".} +proc nvioctlNvhostAsGpuUnmapBuffer*(fd: U32; offset: U64): Result {.cdecl, + importc: "nvioctlNvhostAsGpu_UnmapBuffer".} +proc nvioctlNvhostAsGpuGetVARegions*(fd: U32; regions: array[2, NvioctlVaRegion]): Result {. + cdecl, importc: "nvioctlNvhostAsGpu_GetVARegions".} +proc nvioctlNvhostAsGpuInitializeEx*(fd: U32; flags: U32; bigPageSize: U32): Result {. + cdecl, importc: "nvioctlNvhostAsGpu_InitializeEx".} +proc nvioctlNvmapCreate*(fd: U32; size: U32; nvmapHandle: ptr U32): Result {.cdecl, + importc: "nvioctlNvmap_Create".} +proc nvioctlNvmapFromId*(fd: U32; id: U32; nvmapHandle: ptr U32): Result {.cdecl, + importc: "nvioctlNvmap_FromId".} +proc nvioctlNvmapAlloc*(fd: U32; nvmapHandle: U32; heapmask: U32; flags: U32; align: U32; + kind: U8; `addr`: pointer): Result {.cdecl, + importc: "nvioctlNvmap_Alloc".} +proc nvioctlNvmapFree*(fd: U32; nvmapHandle: U32): Result {.cdecl, + importc: "nvioctlNvmap_Free".} +proc nvioctlNvmapParam*(fd: U32; nvmapHandle: U32; param: NvMapParam; result: ptr U32): Result {. + cdecl, importc: "nvioctlNvmap_Param".} +proc nvioctlNvmapGetId*(fd: U32; nvmapHandle: U32; id: ptr U32): Result {.cdecl, + importc: "nvioctlNvmap_GetId".} +proc nvioctlChannelSetNvmapFd*(fd: U32; nvmapFd: U32): Result {.cdecl, + importc: "nvioctlChannel_SetNvmapFd".} +proc nvioctlChannelSubmitGpfifo*(fd: U32; entries: ptr NvioctlGpfifoEntry; + numEntries: U32; flags: U32; + fenceInout: ptr NvioctlFence): Result {.cdecl, + importc: "nvioctlChannel_SubmitGpfifo".} +proc nvioctlChannelKickoffPb*(fd: U32; entries: ptr NvioctlGpfifoEntry; + numEntries: U32; flags: U32; + fenceInout: ptr NvioctlFence): Result {.cdecl, + importc: "nvioctlChannel_KickoffPb".} +proc nvioctlChannelAllocObjCtx*(fd: U32; classNum: U32; flags: U32; idOut: ptr U64): Result {. + cdecl, importc: "nvioctlChannel_AllocObjCtx".} +proc nvioctlChannelZCullBind*(fd: U32; gpuVa: U64; mode: U32): Result {.cdecl, + importc: "nvioctlChannel_ZCullBind".} +proc nvioctlChannelSetErrorNotifier*(fd: U32; enable: U32): Result {.cdecl, + importc: "nvioctlChannel_SetErrorNotifier".} +proc nvioctlChannelGetErrorInfo*(fd: U32; `out`: ptr NvError): Result {.cdecl, + importc: "nvioctlChannel_GetErrorInfo".} +proc nvioctlChannelGetErrorNotification*(fd: U32; `out`: ptr NvNotification): Result {. + cdecl, importc: "nvioctlChannel_GetErrorNotification".} +proc nvioctlChannelSetPriority*(fd: U32; priority: U32): Result {.cdecl, + importc: "nvioctlChannel_SetPriority".} +proc nvioctlChannelSetTimeout*(fd: U32; timeout: U32): Result {.cdecl, + importc: "nvioctlChannel_SetTimeout".} +proc nvioctlChannelAllocGpfifoEx2*(fd: U32; numEntries: U32; flags: U32; unk0: U32; + unk1: U32; unk2: U32; unk3: U32; + fenceOut: ptr NvioctlFence): Result {.cdecl, + importc: "nvioctlChannel_AllocGpfifoEx2".} +proc nvioctlChannelSetUserData*(fd: U32; `addr`: pointer): Result {.cdecl, + importc: "nvioctlChannel_SetUserData".} +proc nvioctlChannelSubmit*(fd: U32; cmdbufs: ptr NvioctlCmdbuf; numCmdbufs: U32; + relocs: ptr NvioctlReloc; + relocShifts: ptr NvioctlRelocShift; numRelocs: U32; + syncptIncrs: ptr NvioctlSyncptIncr; numSyncptIncrs: U32; + fences: ptr NvioctlFence; numFences: U32): Result {.cdecl, + importc: "nvioctlChannel_Submit".} +proc nvioctlChannelGetSyncpt*(fd: U32; moduleId: U32; syncpt: ptr U32): Result {.cdecl, + importc: "nvioctlChannel_GetSyncpt".} +proc nvioctlChannelGetModuleClockRate*(fd: U32; moduleId: U32; freq: ptr U32): Result {. + cdecl, importc: "nvioctlChannel_GetModuleClockRate".} +proc nvioctlChannelMapCommandBuffer*(fd: U32; maps: ptr NvioctlCommandBufferMap; + numMaps: U32; compressed: bool): Result {.cdecl, + importc: "nvioctlChannel_MapCommandBuffer".} +proc nvioctlChannelUnmapCommandBuffer*(fd: U32; maps: ptr NvioctlCommandBufferMap; + numMaps: U32; compressed: bool): Result {. + cdecl, importc: "nvioctlChannel_UnmapCommandBuffer".} diff --git a/src/libnx/wrapper/switch/nvidia/map.h b/src/libnx/wrapper/switch/nvidia/map.h new file mode 100644 index 0000000..7ace589 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/map.h @@ -0,0 +1,50 @@ +#pragma once +#include "types.h" + +typedef struct NvMap { + u32 handle; + u32 id; + u32 size; + void* cpu_addr; + NvKind kind; + bool has_init; + bool is_cpu_cacheable; +} NvMap; + +Result nvMapInit(void); +u32 nvMapGetFd(void); +void nvMapExit(void); + +Result nvMapCreate(NvMap* m, void* cpu_addr, u32 size, u32 align, NvKind kind, bool is_cpu_cacheable); +Result nvMapLoadRemote(NvMap* m, u32 id); +void nvMapClose(NvMap* m); + +static inline u32 nvMapGetHandle(NvMap* m) +{ + return m->handle; +} + +static inline u32 nvMapGetId(NvMap* m) +{ + return m->id; +} + +static inline u32 nvMapGetSize(NvMap* m) +{ + return m->size; +} + +static inline void* nvMapGetCpuAddr(NvMap* m) +{ + return m->cpu_addr; +} + +static inline bool nvMapIsRemote(NvMap* m) +{ + return !m->cpu_addr; +} + +static inline NvKind nvMapGetKind(NvMap* m) +{ + return m->kind; +} diff --git a/src/libnx/wrapper/switch/nvidia/map.nim b/src/libnx/wrapper/switch/nvidia/map.nim new file mode 100644 index 0000000..3f9d138 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/map.nim @@ -0,0 +1,38 @@ +import + types as t, ../types + +type + NvMap* {.bycopy.} = object + handle*: U32 + id*: U32 + size*: U32 + cpuAddr*: pointer + kind*: NvKind + hasInit*: bool + isCpuCacheable*: bool + + +proc nvMapInit*(): Result {.cdecl, importc: "nvMapInit".} +proc nvMapGetFd*(): U32 {.cdecl, importc: "nvMapGetFd".} +proc nvMapExit*() {.cdecl, importc: "nvMapExit".} +proc nvMapCreate*(m: ptr NvMap; cpuAddr: pointer; size: U32; align: U32; kind: NvKind; + isCpuCacheable: bool): Result {.cdecl, importc: "nvMapCreate".} +proc nvMapLoadRemote*(m: ptr NvMap; id: U32): Result {.cdecl, importc: "nvMapLoadRemote".} +proc nvMapClose*(m: ptr NvMap) {.cdecl, importc: "nvMapClose".} +proc nvMapGetHandle*(m: ptr NvMap): U32 {.inline, cdecl.} = + return m.handle + +proc nvMapGetId*(m: ptr NvMap): U32 {.inline, cdecl.} = + return m.id + +proc nvMapGetSize*(m: ptr NvMap): U32 {.inline, cdecl.} = + return m.size + +proc nvMapGetCpuAddr*(m: ptr NvMap): pointer {.inline, cdecl.} = + return m.cpuAddr + +proc nvMapIsRemote*(m: ptr NvMap): bool {.inline, cdecl.} = + return m.cpuAddr == nil + +proc nvMapGetKind*(m: ptr NvMap): NvKind {.inline, cdecl.} = + return m.kind diff --git a/src/libnx/wrapper/switch/nvidia/types.h b/src/libnx/wrapper/switch/nvidia/types.h new file mode 100644 index 0000000..cd415e8 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/types.h @@ -0,0 +1,484 @@ +#pragma once +#include "../types.h" + +typedef u64 iova_t; + +typedef enum { + NvLayout_Pitch = 1, + NvLayout_Tiled = 2, + NvLayout_BlockLinear = 3, +} NvLayout; + +typedef enum { + NvDisplayScanFormat_Progressive = 0, + NvDisplayScanFormat_Interlaced = 1, +} NvDisplayScanFormat; + +typedef enum { + NvKind_Pitch = 0x0, + NvKind_Z16 = 0x1, + NvKind_Z16_2C = 0x2, + NvKind_Z16_MS2_2C = 0x3, + NvKind_Z16_MS4_2C = 0x4, + NvKind_Z16_MS8_2C = 0x5, + NvKind_Z16_MS16_2C = 0x6, + NvKind_Z16_2Z = 0x7, + NvKind_Z16_MS2_2Z = 0x8, + NvKind_Z16_MS4_2Z = 0x9, + NvKind_Z16_MS8_2Z = 0xa, + NvKind_Z16_MS16_2Z = 0xb, + NvKind_Z16_4CZ = 0xc, + NvKind_Z16_MS2_4CZ = 0xd, + NvKind_Z16_MS4_4CZ = 0xe, + NvKind_Z16_MS8_4CZ = 0xf, + NvKind_Z16_MS16_4CZ = 0x10, + NvKind_S8Z24 = 0x11, + NvKind_S8Z24_1Z = 0x12, + NvKind_S8Z24_MS2_1Z = 0x13, + NvKind_S8Z24_MS4_1Z = 0x14, + NvKind_S8Z24_MS8_1Z = 0x15, + NvKind_S8Z24_MS16_1Z = 0x16, + NvKind_S8Z24_2CZ = 0x17, + NvKind_S8Z24_MS2_2CZ = 0x18, + NvKind_S8Z24_MS4_2CZ = 0x19, + NvKind_S8Z24_MS8_2CZ = 0x1a, + NvKind_S8Z24_MS16_2CZ = 0x1b, + NvKind_S8Z24_2CS = 0x1C, + NvKind_S8Z24_MS2_2CS = 0x1d, + NvKind_S8Z24_MS4_2CS = 0x1e, + NvKind_S8Z24_MS8_2CS = 0x1f, + NvKind_S8Z24_MS16_2CS = 0x20, + NvKind_S8Z24_4CSZV = 0x21, + NvKind_S8Z24_MS2_4CSZV = 0x22, + NvKind_S8Z24_MS4_4CSZV = 0x23, + NvKind_S8Z24_MS8_4CSZV = 0x24, + NvKind_S8Z24_MS16_4CSZV = 0x25, + NvKind_V8Z24_MS4_VC12 = 0x26, + NvKind_V8Z24_MS4_VC4 = 0x27, + NvKind_V8Z24_MS8_VC8 = 0x28, + NvKind_V8Z24_MS8_VC24 = 0x29, + NvKind_S8 = 0x2a, + NvKind_S8_2S = 0x2b, + NvKind_V8Z24_MS4_VC12_1ZV = 0x2e, + NvKind_V8Z24_MS4_VC4_1ZV = 0x2f, + NvKind_V8Z24_MS8_VC8_1ZV = 0x30, + NvKind_V8Z24_MS8_VC24_1ZV = 0x31, + NvKind_V8Z24_MS4_VC12_2CS = 0x32, + NvKind_V8Z24_MS4_VC4_2CS = 0x33, + NvKind_V8Z24_MS8_VC8_2CS = 0x34, + NvKind_V8Z24_MS8_VC24_2CS = 0x35, + NvKind_V8Z24_MS4_VC12_2CZV = 0x3a, + NvKind_V8Z24_MS4_VC4_2CZV = 0x3b, + NvKind_V8Z24_MS8_VC8_2CZV = 0x3c, + NvKind_V8Z24_MS8_VC24_2CZV = 0x3d, + NvKind_V8Z24_MS4_VC12_2ZV = 0x3e, + NvKind_V8Z24_MS4_VC4_2ZV = 0x3f, + NvKind_V8Z24_MS8_VC8_2ZV = 0x40, + NvKind_V8Z24_MS8_VC24_2ZV = 0x41, + NvKind_V8Z24_MS4_VC12_4CSZV = 0x42, + NvKind_V8Z24_MS4_VC4_4CSZV = 0x43, + NvKind_V8Z24_MS8_VC8_4CSZV = 0x44, + NvKind_V8Z24_MS8_VC24_4CSZV = 0x45, + NvKind_Z24S8 = 0x46, + NvKind_Z24S8_1Z = 0x47, + NvKind_Z24S8_MS2_1Z = 0x48, + NvKind_Z24S8_MS4_1Z = 0x49, + NvKind_Z24S8_MS8_1Z = 0x4a, + NvKind_Z24S8_MS16_1Z = 0x4b, + NvKind_Z24S8_2CS = 0x4c, + NvKind_Z24S8_MS2_2CS = 0x4d, + NvKind_Z24S8_MS4_2CS = 0x4e, + NvKind_Z24S8_MS8_2CS = 0x4f, + NvKind_Z24S8_MS16_2CS = 0x50, + NvKind_Z24S8_2CZ = 0x51, + NvKind_Z24S8_MS2_2CZ = 0x52, + NvKind_Z24S8_MS4_2CZ = 0x53, + NvKind_Z24S8_MS8_2CZ = 0x54, + NvKind_Z24S8_MS16_2CZ = 0x55, + NvKind_Z24S8_4CSZV = 0x56, + NvKind_Z24S8_MS2_4CSZV = 0x57, + NvKind_Z24S8_MS4_4CSZV = 0x58, + NvKind_Z24S8_MS8_4CSZV = 0x59, + NvKind_Z24S8_MS16_4CSZV = 0x5a, + NvKind_Z24V8_MS4_VC12 = 0x5b, + NvKind_Z24V8_MS4_VC4 = 0x5C, + NvKind_Z24V8_MS8_VC8 = 0x5d, + NvKind_Z24V8_MS8_VC24 = 0x5e, + NvKind_Z24V8_MS4_VC12_1ZV = 0x63, + NvKind_Z24V8_MS4_VC4_1ZV = 0x64, + NvKind_Z24V8_MS8_VC8_1ZV = 0x65, + NvKind_Z24V8_MS8_VC24_1ZV = 0x66, + NvKind_Z24V8_MS4_VC12_2CS = 0x67, + NvKind_Z24V8_MS4_VC4_2CS = 0x68, + NvKind_Z24V8_MS8_VC8_2CS = 0x69, + NvKind_Z24V8_MS8_VC24_2CS = 0x6a, + NvKind_Z24V8_MS4_VC12_2CZV = 0x6f, + NvKind_Z24V8_MS4_VC4_2CZV = 0x70, + NvKind_Z24V8_MS8_VC8_2CZV = 0x71, + NvKind_Z24V8_MS8_VC24_2CZV = 0x72, + NvKind_Z24V8_MS4_VC12_2ZV = 0x73, + NvKind_Z24V8_MS4_VC4_2ZV = 0x74, + NvKind_Z24V8_MS8_VC8_2ZV = 0x75, + NvKind_Z24V8_MS8_VC24_2ZV = 0x76, + NvKind_Z24V8_MS4_VC12_4CSZV = 0x77, + NvKind_Z24V8_MS4_VC4_4CSZV = 0x78, + NvKind_Z24V8_MS8_VC8_4CSZV = 0x79, + NvKind_Z24V8_MS8_VC24_4CSZV = 0x7a, + NvKind_ZF32 = 0x7b, + NvKind_ZF32_1Z = 0x7C, + NvKind_ZF32_MS2_1Z = 0x7d, + NvKind_ZF32_MS4_1Z = 0x7e, + NvKind_ZF32_MS8_1Z = 0x7f, + NvKind_ZF32_MS16_1Z = 0x80, + NvKind_ZF32_2CS = 0x81, + NvKind_ZF32_MS2_2CS = 0x82, + NvKind_ZF32_MS4_2CS = 0x83, + NvKind_ZF32_MS8_2CS = 0x84, + NvKind_ZF32_MS16_2CS = 0x85, + NvKind_ZF32_2CZ = 0x86, + NvKind_ZF32_MS2_2CZ = 0x87, + NvKind_ZF32_MS4_2CZ = 0x88, + NvKind_ZF32_MS8_2CZ = 0x89, + NvKind_ZF32_MS16_2CZ = 0x8a, + NvKind_X8Z24_X16V8S8_MS4_VC12 = 0x8b, + NvKind_X8Z24_X16V8S8_MS4_VC4 = 0x8c, + NvKind_X8Z24_X16V8S8_MS8_VC8 = 0x8d, + NvKind_X8Z24_X16V8S8_MS8_VC24 = 0x8e, + NvKind_X8Z24_X16V8S8_MS4_VC12_1CS = 0x8f, + NvKind_X8Z24_X16V8S8_MS4_VC4_1CS = 0x90, + NvKind_X8Z24_X16V8S8_MS8_VC8_1CS = 0x91, + NvKind_X8Z24_X16V8S8_MS8_VC24_1CS = 0x92, + NvKind_X8Z24_X16V8S8_MS4_VC12_1ZV = 0x97, + NvKind_X8Z24_X16V8S8_MS4_VC4_1ZV = 0x98, + NvKind_X8Z24_X16V8S8_MS8_VC8_1ZV = 0x99, + NvKind_X8Z24_X16V8S8_MS8_VC24_1ZV = 0x9a, + NvKind_X8Z24_X16V8S8_MS4_VC12_1CZV = 0x9b, + NvKind_X8Z24_X16V8S8_MS4_VC4_1CZV = 0x9c, + NvKind_X8Z24_X16V8S8_MS8_VC8_1CZV = 0x9d, + NvKind_X8Z24_X16V8S8_MS8_VC24_1CZV = 0x9e, + NvKind_X8Z24_X16V8S8_MS4_VC12_2CS = 0x9f, + NvKind_X8Z24_X16V8S8_MS4_VC4_2CS = 0xa0, + NvKind_X8Z24_X16V8S8_MS8_VC8_2CS = 0xa1, + NvKind_X8Z24_X16V8S8_MS8_VC24_2CS = 0xa2, + NvKind_X8Z24_X16V8S8_MS4_VC12_2CSZV = 0xa3, + NvKind_X8Z24_X16V8S8_MS4_VC4_2CSZV = 0xa4, + NvKind_X8Z24_X16V8S8_MS8_VC8_2CSZV = 0xa5, + NvKind_X8Z24_X16V8S8_MS8_VC24_2CSZV = 0xa6, + NvKind_ZF32_X16V8S8_MS4_VC12 = 0xa7, + NvKind_ZF32_X16V8S8_MS4_VC4 = 0xa8, + NvKind_ZF32_X16V8S8_MS8_VC8 = 0xa9, + NvKind_ZF32_X16V8S8_MS8_VC24 = 0xaa, + NvKind_ZF32_X16V8S8_MS4_VC12_1CS = 0xab, + NvKind_ZF32_X16V8S8_MS4_VC4_1CS = 0xac, + NvKind_ZF32_X16V8S8_MS8_VC8_1CS = 0xad, + NvKind_ZF32_X16V8S8_MS8_VC24_1CS = 0xae, + NvKind_ZF32_X16V8S8_MS4_VC12_1ZV = 0xb3, + NvKind_ZF32_X16V8S8_MS4_VC4_1ZV = 0xb4, + NvKind_ZF32_X16V8S8_MS8_VC8_1ZV = 0xb5, + NvKind_ZF32_X16V8S8_MS8_VC24_1ZV = 0xb6, + NvKind_ZF32_X16V8S8_MS4_VC12_1CZV = 0xb7, + NvKind_ZF32_X16V8S8_MS4_VC4_1CZV = 0xb8, + NvKind_ZF32_X16V8S8_MS8_VC8_1CZV = 0xb9, + NvKind_ZF32_X16V8S8_MS8_VC24_1CZV = 0xba, + NvKind_ZF32_X16V8S8_MS4_VC12_2CS = 0xbb, + NvKind_ZF32_X16V8S8_MS4_VC4_2CS = 0xbc, + NvKind_ZF32_X16V8S8_MS8_VC8_2CS = 0xbd, + NvKind_ZF32_X16V8S8_MS8_VC24_2CS = 0xbe, + NvKind_ZF32_X16V8S8_MS4_VC12_2CSZV = 0xbf, + NvKind_ZF32_X16V8S8_MS4_VC4_2CSZV = 0xc0, + NvKind_ZF32_X16V8S8_MS8_VC8_2CSZV = 0xc1, + NvKind_ZF32_X16V8S8_MS8_VC24_2CSZV = 0xc2, + NvKind_ZF32_X24S8 = 0xc3, + NvKind_ZF32_X24S8_1CS = 0xc4, + NvKind_ZF32_X24S8_MS2_1CS = 0xc5, + NvKind_ZF32_X24S8_MS4_1CS = 0xc6, + NvKind_ZF32_X24S8_MS8_1CS = 0xc7, + NvKind_ZF32_X24S8_MS16_1CS = 0xc8, + NvKind_SmskedMessage = 0xca, + NvKind_SmhostMessage = 0xcb, + NvKind_C64_MS2_2CRA = 0xcd, + NvKind_ZF32_X24S8_2CSZV = 0xce, + NvKind_ZF32_X24S8_MS2_2CSZV = 0xcf, + NvKind_ZF32_X24S8_MS4_2CSZV = 0xd0, + NvKind_ZF32_X24S8_MS8_2CSZV = 0xd1, + NvKind_ZF32_X24S8_MS16_2CSZV = 0xd2, + NvKind_ZF32_X24S8_2CS = 0xd3, + NvKind_ZF32_X24S8_MS2_2CS = 0xd4, + NvKind_ZF32_X24S8_MS4_2CS = 0xd5, + NvKind_ZF32_X24S8_MS8_2CS = 0xd6, + NvKind_ZF32_X24S8_MS16_2CS = 0xd7, + NvKind_C32_2C = 0xd8, + NvKind_C32_2CBR = 0xd9, + NvKind_C32_2CBA = 0xda, + NvKind_C32_2CRA = 0xdb, + NvKind_C32_2BRA = 0xdc, + NvKind_C32_MS2_2C = 0xdd, + NvKind_C32_MS2_2CBR = 0xde, + NvKind_C32_MS2_2CRA = 0xcc, + NvKind_C32_MS4_2C = 0xdf, + NvKind_C32_MS4_2CBR = 0xe0, + NvKind_C32_MS4_2CBA = 0xe1, + NvKind_C32_MS4_2CRA = 0xe2, + NvKind_C32_MS4_2BRA = 0xe3, + NvKind_C32_MS8_MS16_2C = 0xe4, + NvKind_C32_MS8_MS16_2CRA = 0xe5, + NvKind_C64_2C = 0xe6, + NvKind_C64_2CBR = 0xe7, + NvKind_C64_2CBA = 0xe8, + NvKind_C64_2CRA = 0xe9, + NvKind_C64_2BRA = 0xea, + NvKind_C64_MS2_2C = 0xeb, + NvKind_C64_MS2_2CBR = 0xec, + NvKind_C64_MS4_2C = 0xed, + NvKind_C64_MS4_2CBR = 0xee, + NvKind_C64_MS4_2CBA = 0xef, + NvKind_C64_MS4_2CRA = 0xf0, + NvKind_C64_MS4_2BRA = 0xf1, + NvKind_C64_MS8_MS16_2C = 0xf2, + NvKind_C64_MS8_MS16_2CRA = 0xf3, + NvKind_C128_2C = 0xf4, + NvKind_C128_2CR = 0xf5, + NvKind_C128_MS2_2C = 0xf6, + NvKind_C128_MS2_2CR = 0xf7, + NvKind_C128_MS4_2C = 0xf8, + NvKind_C128_MS4_2CR = 0xf9, + NvKind_C128_MS8_MS16_2C = 0xfa, + NvKind_C128_MS8_MS16_2CR = 0xfb, + NvKind_X8C24 = 0xfc, + NvKind_PitchNoSwizzle = 0xfd, + NvKind_Generic_16BX2 = 0xfe, + NvKind_Invalid = 0xff, +} NvKind; + +typedef enum { + NvColorFormat_Unspecified = 0x0000000000UL, + NvColorFormat_NonColor8 = 0x0009200408UL, + NvColorFormat_NonColor16 = 0x0009200A10UL, + NvColorFormat_NonColor24 = 0x0009201A18UL, + NvColorFormat_NonColor32 = 0x0009201C20UL, + NvColorFormat_X4C4 = 0x0009210508UL, + NvColorFormat_A4L4 = 0x0100490508UL, + NvColorFormat_A8L8 = 0x0100490E10UL, + NvColorFormat_Float_A16L16 = 0x0100495D20UL, + NvColorFormat_A1B5G5R5 = 0x0100531410UL, + NvColorFormat_A4B4G4R4 = 0x0100531510UL, + NvColorFormat_A5B5G5R1 = 0x0100531810UL, + NvColorFormat_A2B10G10R10 = 0x0100532020UL, + NvColorFormat_A8B8G8R8 = 0x0100532120UL, + NvColorFormat_A16B16G16R16 = 0x0100532740UL, + NvColorFormat_Float_A16B16G16R16 = 0x0100536740UL, + NvColorFormat_A1R5G5B5 = 0x0100D11410UL, + NvColorFormat_A4R4G4B4 = 0x0100D11510UL, + NvColorFormat_A5R1G5B5 = 0x0100D11610UL, + NvColorFormat_A2R10G10B10 = 0x0100D12020UL, + NvColorFormat_A8R8G8B8 = 0x0100D12120UL, + NvColorFormat_A1 = 0x0101240101UL, + NvColorFormat_A2 = 0x0101240202UL, + NvColorFormat_A4 = 0x0101240304UL, + NvColorFormat_A8 = 0x0101240408UL, + NvColorFormat_A16 = 0x0101240A10UL, + NvColorFormat_A32 = 0x0101241C20UL, + NvColorFormat_Float_A16 = 0x0101244A10UL, + NvColorFormat_L4A4 = 0x0102000508UL, + NvColorFormat_L8A8 = 0x0102000E10UL, + NvColorFormat_B4G4R4A4 = 0x01060A1510UL, + NvColorFormat_B5G5R1A5 = 0x01060A1710UL, + NvColorFormat_B5G5R5A1 = 0x01060A1810UL, + NvColorFormat_B8G8R8A8 = 0x01060A2120UL, + NvColorFormat_B10G10R10A2 = 0x01060A2320UL, + NvColorFormat_R1G5B5A5 = 0x0106881410UL, + NvColorFormat_R4G4B4A4 = 0x0106881510UL, + NvColorFormat_R5G5B5A1 = 0x0106881810UL, + NvColorFormat_R8G8B8A8 = 0x0106882120UL, + NvColorFormat_R10G10B10A2 = 0x0106882320UL, + NvColorFormat_L1 = 0x010A000101UL, + NvColorFormat_L2 = 0x010A000202UL, + NvColorFormat_L4 = 0x010A000304UL, + NvColorFormat_L8 = 0x010A000408UL, + NvColorFormat_L16 = 0x010A000A10UL, + NvColorFormat_L32 = 0x010A001C20UL, + NvColorFormat_Float_L16 = 0x010A004A10UL, + NvColorFormat_B5G6R5 = 0x010A0A1210UL, + NvColorFormat_B6G5R5 = 0x010A0A1310UL, + NvColorFormat_B5G5R5X1 = 0x010A0A1810UL, + NvColorFormat_B8_G8_R8 = 0x010A0A1918UL, + NvColorFormat_B8G8R8X8 = 0x010A0A2120UL, + NvColorFormat_Float_B10G11R11 = 0x010A0A5E20UL, + NvColorFormat_X1B5G5R5 = 0x010A531410UL, + NvColorFormat_X8B8G8R8 = 0x010A532120UL, + NvColorFormat_X16B16G16R16 = 0x010A532740UL, + NvColorFormat_Float_X16B16G16R16 = 0x010A536740UL, + NvColorFormat_R3G3B2 = 0x010A880608UL, + NvColorFormat_R5G5B6 = 0x010A881110UL, + NvColorFormat_R5G6B5 = 0x010A881210UL, + NvColorFormat_R5G5B5X1 = 0x010A881810UL, + NvColorFormat_R8_G8_B8 = 0x010A881918UL, + NvColorFormat_R8G8B8X8 = 0x010A882120UL, + NvColorFormat_X1R5G5B5 = 0x010AD11410UL, + NvColorFormat_X8R8G8B8 = 0x010AD12120UL, + NvColorFormat_RG8 = 0x010B080E10UL, + NvColorFormat_R16G16 = 0x010B081D20UL, + NvColorFormat_Float_R16G16 = 0x010B085D20UL, + NvColorFormat_R8 = 0x010B200408UL, + NvColorFormat_R16 = 0x010B200A10UL, + NvColorFormat_Float_R16 = 0x010B204A10UL, + NvColorFormat_A2B10G10R10_sRGB = 0x0200532020UL, + NvColorFormat_A8B8G8R8_sRGB = 0x0200532120UL, + NvColorFormat_A16B16G16R16_sRGB = 0x0200532740UL, + NvColorFormat_A2R10G10B10_sRGB = 0x0200D12020UL, + NvColorFormat_B10G10R10A2_sRGB = 0x02060A2320UL, + NvColorFormat_R10G10B10A2_sRGB = 0x0206882320UL, + NvColorFormat_X8B8G8R8_sRGB = 0x020A532120UL, + NvColorFormat_X16B16G16R16_sRGB = 0x020A532740UL, + NvColorFormat_A2B10G10R10_709 = 0x0300532020UL, + NvColorFormat_A8B8G8R8_709 = 0x0300532120UL, + NvColorFormat_A16B16G16R16_709 = 0x0300532740UL, + NvColorFormat_A2R10G10B10_709 = 0x0300D12020UL, + NvColorFormat_B10G10R10A2_709 = 0x03060A2320UL, + NvColorFormat_R10G10B10A2_709 = 0x0306882320UL, + NvColorFormat_X8B8G8R8_709 = 0x030A532120UL, + NvColorFormat_X16B16G16R16_709 = 0x030A532740UL, + NvColorFormat_A2B10G10R10_709_Linear = 0x0400532020UL, + NvColorFormat_A8B8G8R8_709_Linear = 0x0400532120UL, + NvColorFormat_A16B16G16R16_709_Linear = 0x0400532740UL, + NvColorFormat_A2R10G10B10_709_Linear = 0x0400D12020UL, + NvColorFormat_B10G10R10A2_709_Linear = 0x04060A2320UL, + NvColorFormat_R10G10B10A2_709_Linear = 0x0406882320UL, + NvColorFormat_X8B8G8R8_709_Linear = 0x040A532120UL, + NvColorFormat_X16B16G16R16_709_Linear = 0x040A532740UL, + NvColorFormat_Float_A16B16G16R16_scRGB_Linear = 0x0500536740UL, + NvColorFormat_A2B10G10R10_2020 = 0x0600532020UL, + NvColorFormat_A8B8G8R8_2020 = 0x0600532120UL, + NvColorFormat_A16B16G16R16_2020 = 0x0600532740UL, + NvColorFormat_A2R10G10B10_2020 = 0x0600D12020UL, + NvColorFormat_B10G10R10A2_2020 = 0x06060A2320UL, + NvColorFormat_R10G10B10A2_2020 = 0x0606882320UL, + NvColorFormat_X8B8G8R8_2020 = 0x060A532120UL, + NvColorFormat_X16B16G16R16_2020 = 0x060A532740UL, + NvColorFormat_A2B10G10R10_2020_Linear = 0x0700532020UL, + NvColorFormat_A8B8G8R8_2020_Linear = 0x0700532120UL, + NvColorFormat_A16B16G16R16_2020_Linear = 0x0700532740UL, + NvColorFormat_Float_A16B16G16R16_2020_Linear = 0x0700536740UL, + NvColorFormat_A2R10G10B10_2020_Linear = 0x0700D12020UL, + NvColorFormat_B10G10R10A2_2020_Linear = 0x07060A2320UL, + NvColorFormat_R10G10B10A2_2020_Linear = 0x0706882320UL, + NvColorFormat_X8B8G8R8_2020_Linear = 0x070A532120UL, + NvColorFormat_X16B16G16R16_2020_Linear = 0x070A532740UL, + NvColorFormat_Float_A16B16G16R16_2020_PQ = 0x0800536740UL, + NvColorFormat_A4I4 = 0x0901210508UL, + NvColorFormat_A8I8 = 0x0901210E10UL, + NvColorFormat_I4A4 = 0x0903200508UL, + NvColorFormat_I8A8 = 0x0903200E10UL, + NvColorFormat_I1 = 0x0909200101UL, + NvColorFormat_I2 = 0x0909200202UL, + NvColorFormat_I4 = 0x0909200304UL, + NvColorFormat_I8 = 0x0909200408UL, + NvColorFormat_A8Y8U8V8 = 0x0A00D12120UL, + NvColorFormat_A16Y16U16V16 = 0x0A00D12740UL, + NvColorFormat_Y8U8V8A8 = 0x0A06882120UL, + NvColorFormat_V8_U8 = 0x0A080C0710UL, + NvColorFormat_V8U8 = 0x0A080C0E10UL, + NvColorFormat_V10U10 = 0x0A08142220UL, + NvColorFormat_V12U12 = 0x0A08142420UL, + NvColorFormat_V8 = 0x0A08240408UL, + NvColorFormat_V10 = 0x0A08240F10UL, + NvColorFormat_V12 = 0x0A08241010UL, + NvColorFormat_U8_V8 = 0x0A08440710UL, + NvColorFormat_U8V8 = 0x0A08440E10UL, + NvColorFormat_U10V10 = 0x0A08842220UL, + NvColorFormat_U12V12 = 0x0A08842420UL, + NvColorFormat_U8 = 0x0A09040408UL, + NvColorFormat_U10 = 0x0A09040F10UL, + NvColorFormat_U12 = 0x0A09041010UL, + NvColorFormat_Y8 = 0x0A09200408UL, + NvColorFormat_Y10 = 0x0A09200F10UL, + NvColorFormat_Y12 = 0x0A09201010UL, + NvColorFormat_YVYU = 0x0A0A500810UL, + NvColorFormat_VYUY = 0x0A0A500910UL, + NvColorFormat_YUYV = 0x0A0A880810UL, + NvColorFormat_UYVY = 0x0A0A880910UL, + NvColorFormat_Y8_U8_V8 = 0x0A0A881918UL, + NvColorFormat_V8_U8_RR = 0x0B080C0710UL, + NvColorFormat_V8U8_RR = 0x0B080C0E10UL, + NvColorFormat_V8_RR = 0x0B08240408UL, + NvColorFormat_U8_V8_RR = 0x0B08440710UL, + NvColorFormat_U8V8_RR = 0x0B08440E10UL, + NvColorFormat_U8_RR = 0x0B09040408UL, + NvColorFormat_Y8_RR = 0x0B09200408UL, + NvColorFormat_V8_U8_ER = 0x0C080C0710UL, + NvColorFormat_V8U8_ER = 0x0C080C0E10UL, + NvColorFormat_V8_ER = 0x0C08240408UL, + NvColorFormat_U8_V8_ER = 0x0C08440710UL, + NvColorFormat_U8V8_ER = 0x0C08440E10UL, + NvColorFormat_U8_ER = 0x0C09040408UL, + NvColorFormat_Y8_ER = 0x0C09200408UL, + NvColorFormat_V8_U8_709 = 0x0D080C0710UL, + NvColorFormat_V8U8_709 = 0x0D080C0E10UL, + NvColorFormat_V10U10_709 = 0x0D08142220UL, + NvColorFormat_V12U12_709 = 0x0D08142420UL, + NvColorFormat_V8_709 = 0x0D08240408UL, + NvColorFormat_V10_709 = 0x0D08240F10UL, + NvColorFormat_V12_709 = 0x0D08241010UL, + NvColorFormat_U8_V8_709 = 0x0D08440710UL, + NvColorFormat_U8V8_709 = 0x0D08440E10UL, + NvColorFormat_U10V10_709 = 0x0D08842220UL, + NvColorFormat_U12V12_709 = 0x0D08842420UL, + NvColorFormat_U8_709 = 0x0D09040408UL, + NvColorFormat_U10_709 = 0x0D09040F10UL, + NvColorFormat_U12_709 = 0x0D09041010UL, + NvColorFormat_Y8_709 = 0x0D09200408UL, + NvColorFormat_Y10_709 = 0x0D09200F10UL, + NvColorFormat_Y12_709 = 0x0D09201010UL, + NvColorFormat_V8_U8_709_ER = 0x0E080C0710UL, + NvColorFormat_V8U8_709_ER = 0x0E080C0E10UL, + NvColorFormat_V10U10_709_ER = 0x0E08142220UL, + NvColorFormat_V12U12_709_ER = 0x0E08142420UL, + NvColorFormat_V8_709_ER = 0x0E08240408UL, + NvColorFormat_V10_709_ER = 0x0E08240F10UL, + NvColorFormat_V12_709_ER = 0x0E08241010UL, + NvColorFormat_U8_V8_709_ER = 0x0E08440710UL, + NvColorFormat_U8V8_709_ER = 0x0E08440E10UL, + NvColorFormat_U10V10_709_ER = 0x0E08842220UL, + NvColorFormat_U12V12_709_ER = 0x0E08842420UL, + NvColorFormat_U8_709_ER = 0x0E09040408UL, + NvColorFormat_U10_709_ER = 0x0E09040F10UL, + NvColorFormat_U12_709_ER = 0x0E09041010UL, + NvColorFormat_Y8_709_ER = 0x0E09200408UL, + NvColorFormat_Y10_709_ER = 0x0E09200F10UL, + NvColorFormat_Y12_709_ER = 0x0E09201010UL, + NvColorFormat_V10U10_2020 = 0x0F08142220UL, + NvColorFormat_V12U12_2020 = 0x0F08142420UL, + NvColorFormat_V10_2020 = 0x0F08240F10UL, + NvColorFormat_V12_2020 = 0x0F08241010UL, + NvColorFormat_U10V10_2020 = 0x0F08842220UL, + NvColorFormat_U12V12_2020 = 0x0F08842420UL, + NvColorFormat_U10_2020 = 0x0F09040F10UL, + NvColorFormat_U12_2020 = 0x0F09041010UL, + NvColorFormat_Y10_2020 = 0x0F09200F10UL, + NvColorFormat_Y12_2020 = 0x0F09201010UL, + NvColorFormat_Bayer8RGGB = 0x1009200408UL, + NvColorFormat_Bayer16RGGB = 0x1009200A10UL, + NvColorFormat_BayerS16RGGB = 0x1009208A10UL, + NvColorFormat_X2Bayer14RGGB = 0x1009210B10UL, + NvColorFormat_X4Bayer12RGGB = 0x1009210C10UL, + NvColorFormat_X6Bayer10RGGB = 0x1009210D10UL, + NvColorFormat_Bayer8BGGR = 0x1109200408UL, + NvColorFormat_Bayer16BGGR = 0x1109200A10UL, + NvColorFormat_BayerS16BGGR = 0x1109208A10UL, + NvColorFormat_X2Bayer14BGGR = 0x1109210B10UL, + NvColorFormat_X4Bayer12BGGR = 0x1109210C10UL, + NvColorFormat_X6Bayer10BGGR = 0x1109210D10UL, + NvColorFormat_Bayer8GRBG = 0x1209200408UL, + NvColorFormat_Bayer16GRBG = 0x1209200A10UL, + NvColorFormat_BayerS16GRBG = 0x1209208A10UL, + NvColorFormat_X2Bayer14GRBG = 0x1209210B10UL, + NvColorFormat_X4Bayer12GRBG = 0x1209210C10UL, + NvColorFormat_X6Bayer10GRBG = 0x1209210D10UL, + NvColorFormat_Bayer8GBRG = 0x1309200408UL, + NvColorFormat_Bayer16GBRG = 0x1309200A10UL, + NvColorFormat_BayerS16GBRG = 0x1309208A10UL, + NvColorFormat_X2Bayer14GBRG = 0x1309210B10UL, + NvColorFormat_X4Bayer12GBRG = 0x1309210C10UL, + NvColorFormat_X6Bayer10GBRG = 0x1309210D10UL, + NvColorFormat_XYZ = 0x140A886640UL, +} NvColorFormat; diff --git a/src/libnx/wrapper/switch/nvidia/types.nim b/src/libnx/wrapper/switch/nvidia/types.nim new file mode 100644 index 0000000..a69f168 --- /dev/null +++ b/src/libnx/wrapper/switch/nvidia/types.nim @@ -0,0 +1,273 @@ +import + ../types + +type + IovaT* = U64 + NvLayout* = enum + NvLayoutPitch = 1, NvLayoutTiled = 2, NvLayoutBlockLinear = 3 + NvDisplayScanFormat* = enum + NvDisplayScanFormatProgressive = 0, NvDisplayScanFormatInterlaced = 1 + NvKind* = enum + NvKindPitch = 0x0, NvKindZ16 = 0x1, NvKindZ162C = 0x2, NvKindZ16MS22C = 0x3, + NvKindZ16MS42C = 0x4, NvKindZ16MS82C = 0x5, NvKindZ16MS162C = 0x6, NvKindZ162Z = 0x7, + NvKindZ16MS22Z = 0x8, NvKindZ16MS42Z = 0x9, NvKindZ16MS82Z = 0xa, + NvKindZ16MS162Z = 0xb, NvKindZ164CZ = 0xc, NvKindZ16MS24CZ = 0xd, + NvKindZ16MS44CZ = 0xe, NvKindZ16MS84CZ = 0xf, NvKindZ16MS164CZ = 0x10, + NvKindS8Z24 = 0x11, NvKindS8Z241Z = 0x12, NvKindS8Z24MS21Z = 0x13, + NvKindS8Z24MS41Z = 0x14, NvKindS8Z24MS81Z = 0x15, NvKindS8Z24MS161Z = 0x16, + NvKindS8Z242CZ = 0x17, NvKindS8Z24MS22CZ = 0x18, NvKindS8Z24MS42CZ = 0x19, + NvKindS8Z24MS82CZ = 0x1a, NvKindS8Z24MS162CZ = 0x1b, NvKindS8Z242CS = 0x1C, + NvKindS8Z24MS22CS = 0x1d, NvKindS8Z24MS42CS = 0x1e, NvKindS8Z24MS82CS = 0x1f, + NvKindS8Z24MS162CS = 0x20, NvKindS8Z244CSZV = 0x21, NvKindS8Z24MS24CSZV = 0x22, + NvKindS8Z24MS44CSZV = 0x23, NvKindS8Z24MS84CSZV = 0x24, + NvKindS8Z24MS164CSZV = 0x25, NvKindV8Z24MS4VC12 = 0x26, NvKindV8Z24MS4VC4 = 0x27, + NvKindV8Z24MS8VC8 = 0x28, NvKindV8Z24MS8VC24 = 0x29, NvKindS8 = 0x2a, + NvKindS82S = 0x2b, NvKindV8Z24MS4VC121ZV = 0x2e, NvKindV8Z24MS4VC41ZV = 0x2f, + NvKindV8Z24MS8VC81ZV = 0x30, NvKindV8Z24MS8VC241ZV = 0x31, + NvKindV8Z24MS4VC122CS = 0x32, NvKindV8Z24MS4VC42CS = 0x33, + NvKindV8Z24MS8VC82CS = 0x34, NvKindV8Z24MS8VC242CS = 0x35, + NvKindV8Z24MS4VC122CZV = 0x3a, NvKindV8Z24MS4VC42CZV = 0x3b, + NvKindV8Z24MS8VC82CZV = 0x3c, NvKindV8Z24MS8VC242CZV = 0x3d, + NvKindV8Z24MS4VC122ZV = 0x3e, NvKindV8Z24MS4VC42ZV = 0x3f, + NvKindV8Z24MS8VC82ZV = 0x40, NvKindV8Z24MS8VC242ZV = 0x41, + NvKindV8Z24MS4VC124CSZV = 0x42, NvKindV8Z24MS4VC44CSZV = 0x43, + NvKindV8Z24MS8VC84CSZV = 0x44, NvKindV8Z24MS8VC244CSZV = 0x45, NvKindZ24S8 = 0x46, + NvKindZ24S81Z = 0x47, NvKindZ24S8MS21Z = 0x48, NvKindZ24S8MS41Z = 0x49, + NvKindZ24S8MS81Z = 0x4a, NvKindZ24S8MS161Z = 0x4b, NvKindZ24S82CS = 0x4c, + NvKindZ24S8MS22CS = 0x4d, NvKindZ24S8MS42CS = 0x4e, NvKindZ24S8MS82CS = 0x4f, + NvKindZ24S8MS162CS = 0x50, NvKindZ24S82CZ = 0x51, NvKindZ24S8MS22CZ = 0x52, + NvKindZ24S8MS42CZ = 0x53, NvKindZ24S8MS82CZ = 0x54, NvKindZ24S8MS162CZ = 0x55, + NvKindZ24S84CSZV = 0x56, NvKindZ24S8MS24CSZV = 0x57, NvKindZ24S8MS44CSZV = 0x58, + NvKindZ24S8MS84CSZV = 0x59, NvKindZ24S8MS164CSZV = 0x5a, + NvKindZ24V8MS4VC12 = 0x5b, NvKindZ24V8MS4VC4 = 0x5C, NvKindZ24V8MS8VC8 = 0x5d, + NvKindZ24V8MS8VC24 = 0x5e, NvKindZ24V8MS4VC121ZV = 0x63, + NvKindZ24V8MS4VC41ZV = 0x64, NvKindZ24V8MS8VC81ZV = 0x65, + NvKindZ24V8MS8VC241ZV = 0x66, NvKindZ24V8MS4VC122CS = 0x67, + NvKindZ24V8MS4VC42CS = 0x68, NvKindZ24V8MS8VC82CS = 0x69, + NvKindZ24V8MS8VC242CS = 0x6a, NvKindZ24V8MS4VC122CZV = 0x6f, + NvKindZ24V8MS4VC42CZV = 0x70, NvKindZ24V8MS8VC82CZV = 0x71, + NvKindZ24V8MS8VC242CZV = 0x72, NvKindZ24V8MS4VC122ZV = 0x73, + NvKindZ24V8MS4VC42ZV = 0x74, NvKindZ24V8MS8VC82ZV = 0x75, + NvKindZ24V8MS8VC242ZV = 0x76, NvKindZ24V8MS4VC124CSZV = 0x77, + NvKindZ24V8MS4VC44CSZV = 0x78, NvKindZ24V8MS8VC84CSZV = 0x79, + NvKindZ24V8MS8VC244CSZV = 0x7a, NvKindZF32 = 0x7b, NvKindZF321Z = 0x7C, + NvKindZF32MS21Z = 0x7d, NvKindZF32MS41Z = 0x7e, NvKindZF32MS81Z = 0x7f, + NvKindZF32MS161Z = 0x80, NvKindZF322CS = 0x81, NvKindZF32MS22CS = 0x82, + NvKindZF32MS42CS = 0x83, NvKindZF32MS82CS = 0x84, NvKindZF32MS162CS = 0x85, + NvKindZF322CZ = 0x86, NvKindZF32MS22CZ = 0x87, NvKindZF32MS42CZ = 0x88, + NvKindZF32MS82CZ = 0x89, NvKindZF32MS162CZ = 0x8a, + NvKindX8Z24X16V8S8MS4VC12 = 0x8b, NvKindX8Z24X16V8S8MS4VC4 = 0x8c, + NvKindX8Z24X16V8S8MS8VC8 = 0x8d, NvKindX8Z24X16V8S8MS8VC24 = 0x8e, + NvKindX8Z24X16V8S8MS4VC121CS = 0x8f, NvKindX8Z24X16V8S8MS4VC41CS = 0x90, + NvKindX8Z24X16V8S8MS8VC81CS = 0x91, NvKindX8Z24X16V8S8MS8VC241CS = 0x92, + NvKindX8Z24X16V8S8MS4VC121ZV = 0x97, NvKindX8Z24X16V8S8MS4VC41ZV = 0x98, + NvKindX8Z24X16V8S8MS8VC81ZV = 0x99, NvKindX8Z24X16V8S8MS8VC241ZV = 0x9a, + NvKindX8Z24X16V8S8MS4VC121CZV = 0x9b, NvKindX8Z24X16V8S8MS4VC41CZV = 0x9c, + NvKindX8Z24X16V8S8MS8VC81CZV = 0x9d, NvKindX8Z24X16V8S8MS8VC241CZV = 0x9e, + NvKindX8Z24X16V8S8MS4VC122CS = 0x9f, NvKindX8Z24X16V8S8MS4VC42CS = 0xa0, + NvKindX8Z24X16V8S8MS8VC82CS = 0xa1, NvKindX8Z24X16V8S8MS8VC242CS = 0xa2, + NvKindX8Z24X16V8S8MS4VC122CSZV = 0xa3, NvKindX8Z24X16V8S8MS4VC42CSZV = 0xa4, + NvKindX8Z24X16V8S8MS8VC82CSZV = 0xa5, NvKindX8Z24X16V8S8MS8VC242CSZV = 0xa6, + NvKindZF32X16V8S8MS4VC12 = 0xa7, NvKindZF32X16V8S8MS4VC4 = 0xa8, + NvKindZF32X16V8S8MS8VC8 = 0xa9, NvKindZF32X16V8S8MS8VC24 = 0xaa, + NvKindZF32X16V8S8MS4VC121CS = 0xab, NvKindZF32X16V8S8MS4VC41CS = 0xac, + NvKindZF32X16V8S8MS8VC81CS = 0xad, NvKindZF32X16V8S8MS8VC241CS = 0xae, + NvKindZF32X16V8S8MS4VC121ZV = 0xb3, NvKindZF32X16V8S8MS4VC41ZV = 0xb4, + NvKindZF32X16V8S8MS8VC81ZV = 0xb5, NvKindZF32X16V8S8MS8VC241ZV = 0xb6, + NvKindZF32X16V8S8MS4VC121CZV = 0xb7, NvKindZF32X16V8S8MS4VC41CZV = 0xb8, + NvKindZF32X16V8S8MS8VC81CZV = 0xb9, NvKindZF32X16V8S8MS8VC241CZV = 0xba, + NvKindZF32X16V8S8MS4VC122CS = 0xbb, NvKindZF32X16V8S8MS4VC42CS = 0xbc, + NvKindZF32X16V8S8MS8VC82CS = 0xbd, NvKindZF32X16V8S8MS8VC242CS = 0xbe, + NvKindZF32X16V8S8MS4VC122CSZV = 0xbf, NvKindZF32X16V8S8MS4VC42CSZV = 0xc0, + NvKindZF32X16V8S8MS8VC82CSZV = 0xc1, NvKindZF32X16V8S8MS8VC242CSZV = 0xc2, + NvKindZF32X24S8 = 0xc3, NvKindZF32X24S81CS = 0xc4, NvKindZF32X24S8MS21CS = 0xc5, + NvKindZF32X24S8MS41CS = 0xc6, NvKindZF32X24S8MS81CS = 0xc7, + NvKindZF32X24S8MS161CS = 0xc8, NvKindSmskedMessage = 0xca, + NvKindSmhostMessage = 0xcb, NvKindC32MS22CRA = 0xcc, NvKindC64MS22CRA = 0xcd, + NvKindZF32X24S82CSZV = 0xce, NvKindZF32X24S8MS22CSZV = 0xcf, + NvKindZF32X24S8MS42CSZV = 0xd0, NvKindZF32X24S8MS82CSZV = 0xd1, + NvKindZF32X24S8MS162CSZV = 0xd2, NvKindZF32X24S82CS = 0xd3, + NvKindZF32X24S8MS22CS = 0xd4, NvKindZF32X24S8MS42CS = 0xd5, + NvKindZF32X24S8MS82CS = 0xd6, NvKindZF32X24S8MS162CS = 0xd7, NvKindC322C = 0xd8, + NvKindC322CBR = 0xd9, NvKindC322CBA = 0xda, NvKindC322CRA = 0xdb, + NvKindC322BRA = 0xdc, NvKindC32MS22C = 0xdd, NvKindC32MS22CBR = 0xde, + NvKindC32MS42C = 0xdf, NvKindC32MS42CBR = 0xe0, NvKindC32MS42CBA = 0xe1, + NvKindC32MS42CRA = 0xe2, NvKindC32MS42BRA = 0xe3, NvKindC32MS8MS162C = 0xe4, + NvKindC32MS8MS162CRA = 0xe5, NvKindC642C = 0xe6, NvKindC642CBR = 0xe7, + NvKindC642CBA = 0xe8, NvKindC642CRA = 0xe9, NvKindC642BRA = 0xea, + NvKindC64MS22C = 0xeb, NvKindC64MS22CBR = 0xec, NvKindC64MS42C = 0xed, + NvKindC64MS42CBR = 0xee, NvKindC64MS42CBA = 0xef, NvKindC64MS42CRA = 0xf0, + NvKindC64MS42BRA = 0xf1, NvKindC64MS8MS162C = 0xf2, NvKindC64MS8MS162CRA = 0xf3, + NvKindC1282C = 0xf4, NvKindC1282CR = 0xf5, NvKindC128MS22C = 0xf6, + NvKindC128MS22CR = 0xf7, NvKindC128MS42C = 0xf8, NvKindC128MS42CR = 0xf9, + NvKindC128MS8MS162C = 0xfa, NvKindC128MS8MS162CR = 0xfb, NvKindX8C24 = 0xfc, + NvKindPitchNoSwizzle = 0xfd, NvKindGeneric16BX2 = 0xfe, NvKindInvalid = 0xff + NvColorFormat* = enum + NvColorFormatUnspecified = 0x0000000000'u, + NvColorFormatNonColor8 = 0x0009200408'u, + NvColorFormatNonColor16 = 0x0009200A10'u, + NvColorFormatNonColor24 = 0x0009201A18'u, + NvColorFormatNonColor32 = 0x0009201C20'u, NvColorFormatX4C4 = 0x0009210508'u, + NvColorFormatA4L4 = 0x0100490508'u, NvColorFormatA8L8 = 0x0100490E10'u, + NvColorFormatFloatA16L16 = 0x0100495D20'u, + NvColorFormatA1B5G5R5 = 0x0100531410'u, NvColorFormatA4B4G4R4 = 0x0100531510'u, + NvColorFormatA5B5G5R1 = 0x0100531810'u, + NvColorFormatA2B10G10R10 = 0x0100532020'u, + NvColorFormatA8B8G8R8 = 0x0100532120'u, + NvColorFormatA16B16G16R16 = 0x0100532740'u, + NvColorFormatFloatA16B16G16R16 = 0x0100536740'u, + NvColorFormatA1R5G5B5 = 0x0100D11410'u, NvColorFormatA4R4G4B4 = 0x0100D11510'u, + NvColorFormatA5R1G5B5 = 0x0100D11610'u, + NvColorFormatA2R10G10B10 = 0x0100D12020'u, + NvColorFormatA8R8G8B8 = 0x0100D12120'u, NvColorFormatA1 = 0x0101240101'u, + NvColorFormatA2 = 0x0101240202'u, NvColorFormatA4 = 0x0101240304'u, + NvColorFormatA8 = 0x0101240408'u, NvColorFormatA16 = 0x0101240A10'u, + NvColorFormatA32 = 0x0101241C20'u, NvColorFormatFloatA16 = 0x0101244A10'u, + NvColorFormatL4A4 = 0x0102000508'u, NvColorFormatL8A8 = 0x0102000E10'u, + NvColorFormatB4G4R4A4 = 0x01060A1510'u, NvColorFormatB5G5R1A5 = 0x01060A1710'u, + NvColorFormatB5G5R5A1 = 0x01060A1810'u, NvColorFormatB8G8R8A8 = 0x01060A2120'u, + NvColorFormatB10G10R10A2 = 0x01060A2320'u, + NvColorFormatR1G5B5A5 = 0x0106881410'u, NvColorFormatR4G4B4A4 = 0x0106881510'u, + NvColorFormatR5G5B5A1 = 0x0106881810'u, NvColorFormatR8G8B8A8 = 0x0106882120'u, + NvColorFormatR10G10B10A2 = 0x0106882320'u, NvColorFormatL1 = 0x010A000101'u, + NvColorFormatL2 = 0x010A000202'u, NvColorFormatL4 = 0x010A000304'u, + NvColorFormatL8 = 0x010A000408'u, NvColorFormatL16 = 0x010A000A10'u, + NvColorFormatL32 = 0x010A001C20'u, NvColorFormatFloatL16 = 0x010A004A10'u, + NvColorFormatB5G6R5 = 0x010A0A1210'u, NvColorFormatB6G5R5 = 0x010A0A1310'u, + NvColorFormatB5G5R5X1 = 0x010A0A1810'u, NvColorFormatB8G8R8 = 0x010A0A1918'u, + NvColorFormatB8G8R8X8 = 0x010A0A2120'u, + NvColorFormatFloatB10G11R11 = 0x010A0A5E20'u, + NvColorFormatX1B5G5R5 = 0x010A531410'u, NvColorFormatX8B8G8R8 = 0x010A532120'u, + NvColorFormatX16B16G16R16 = 0x010A532740'u, + NvColorFormatFloatX16B16G16R16 = 0x010A536740'u, + NvColorFormatR3G3B2 = 0x010A880608'u, NvColorFormatR5G5B6 = 0x010A881110'u, + NvColorFormatR5G6B5 = 0x010A881210'u, NvColorFormatR5G5B5X1 = 0x010A881810'u, + NvColorFormatR8G8B8 = 0x010A881918'u, NvColorFormatR8G8B8X8 = 0x010A882120'u, + NvColorFormatX1R5G5B5 = 0x010AD11410'u, NvColorFormatX8R8G8B8 = 0x010AD12120'u, + NvColorFormatRG8 = 0x010B080E10'u, NvColorFormatR16G16 = 0x010B081D20'u, + NvColorFormatFloatR16G16 = 0x010B085D20'u, NvColorFormatR8 = 0x010B200408'u, + NvColorFormatR16 = 0x010B200A10'u, NvColorFormatFloatR16 = 0x010B204A10'u, + NvColorFormatA2B10G10R10SRGB = 0x0200532020'u, + NvColorFormatA8B8G8R8SRGB = 0x0200532120'u, + NvColorFormatA16B16G16R16SRGB = 0x0200532740'u, + NvColorFormatA2R10G10B10SRGB = 0x0200D12020'u, + NvColorFormatB10G10R10A2SRGB = 0x02060A2320'u, + NvColorFormatR10G10B10A2SRGB = 0x0206882320'u, + NvColorFormatX8B8G8R8SRGB = 0x020A532120'u, + NvColorFormatX16B16G16R16SRGB = 0x020A532740'u, + NvColorFormatA2B10G10R10709 = 0x0300532020'u, + NvColorFormatA8B8G8R8709 = 0x0300532120'u, + NvColorFormatA16B16G16R16709 = 0x0300532740'u, + NvColorFormatA2R10G10B10709 = 0x0300D12020'u, + NvColorFormatB10G10R10A2709 = 0x03060A2320'u, + NvColorFormatR10G10B10A2709 = 0x0306882320'u, + NvColorFormatX8B8G8R8709 = 0x030A532120'u, + NvColorFormatX16B16G16R16709 = 0x030A532740'u, + NvColorFormatA2B10G10R10709Linear = 0x0400532020'u, + NvColorFormatA8B8G8R8709Linear = 0x0400532120'u, + NvColorFormatA16B16G16R16709Linear = 0x0400532740'u, + NvColorFormatA2R10G10B10709Linear = 0x0400D12020'u, + NvColorFormatB10G10R10A2709Linear = 0x04060A2320'u, + NvColorFormatR10G10B10A2709Linear = 0x0406882320'u, + NvColorFormatX8B8G8R8709Linear = 0x040A532120'u, + NvColorFormatX16B16G16R16709Linear = 0x040A532740'u, + NvColorFormatFloatA16B16G16R16ScRGB_Linear = 0x0500536740'u, + NvColorFormatA2B10G10R102020 = 0x0600532020'u, + NvColorFormatA8B8G8R82020 = 0x0600532120'u, + NvColorFormatA16B16G16R162020 = 0x0600532740'u, + NvColorFormatA2R10G10B102020 = 0x0600D12020'u, + NvColorFormatB10G10R10A22020 = 0x06060A2320'u, + NvColorFormatR10G10B10A22020 = 0x0606882320'u, + NvColorFormatX8B8G8R82020 = 0x060A532120'u, + NvColorFormatX16B16G16R162020 = 0x060A532740'u, + NvColorFormatA2B10G10R102020Linear = 0x0700532020'u, + NvColorFormatA8B8G8R82020Linear = 0x0700532120'u, + NvColorFormatA16B16G16R162020Linear = 0x0700532740'u, + NvColorFormatFloatA16B16G16R162020Linear = 0x0700536740'u, + NvColorFormatA2R10G10B102020Linear = 0x0700D12020'u, + NvColorFormatB10G10R10A22020Linear = 0x07060A2320'u, + NvColorFormatR10G10B10A22020Linear = 0x0706882320'u, + NvColorFormatX8B8G8R82020Linear = 0x070A532120'u, + NvColorFormatX16B16G16R162020Linear = 0x070A532740'u, + NvColorFormatFloatA16B16G16R162020PQ = 0x0800536740'u, + NvColorFormatA4I4 = 0x0901210508'u, NvColorFormatA8I8 = 0x0901210E10'u, + NvColorFormatI4A4 = 0x0903200508'u, NvColorFormatI8A8 = 0x0903200E10'u, + NvColorFormatI1 = 0x0909200101'u, NvColorFormatI2 = 0x0909200202'u, + NvColorFormatI4 = 0x0909200304'u, NvColorFormatI8 = 0x0909200408'u, + NvColorFormatA8Y8U8V8 = 0x0A00D12120'u, + NvColorFormatA16Y16U16V16 = 0x0A00D12740'u, + NvColorFormatY8U8V8A8 = 0x0A06882120'u, NvColorFormatV8U8 = 0x0A080C0710'u, + NvColorFormatV8U8 = 0x0A080C0E10'u, NvColorFormatV10U10 = 0x0A08142220'u, + NvColorFormatV12U12 = 0x0A08142420'u, NvColorFormatV8 = 0x0A08240408'u, + NvColorFormatV10 = 0x0A08240F10'u, NvColorFormatV12 = 0x0A08241010'u, + NvColorFormatU8V8 = 0x0A08440710'u, NvColorFormatU8V8 = 0x0A08440E10'u, + NvColorFormatU10V10 = 0x0A08842220'u, NvColorFormatU12V12 = 0x0A08842420'u, + NvColorFormatU8 = 0x0A09040408'u, NvColorFormatU10 = 0x0A09040F10'u, + NvColorFormatU12 = 0x0A09041010'u, NvColorFormatY8 = 0x0A09200408'u, + NvColorFormatY10 = 0x0A09200F10'u, NvColorFormatY12 = 0x0A09201010'u, + NvColorFormatYVYU = 0x0A0A500810'u, NvColorFormatVYUY = 0x0A0A500910'u, + NvColorFormatYUYV = 0x0A0A880810'u, NvColorFormatUYVY = 0x0A0A880910'u, + NvColorFormatY8U8V8 = 0x0A0A881918'u, NvColorFormatV8U8RR = 0x0B080C0710'u, + NvColorFormatV8U8RR = 0x0B080C0E10'u, NvColorFormatV8RR = 0x0B08240408'u, + NvColorFormatU8V8RR = 0x0B08440710'u, NvColorFormatU8V8RR = 0x0B08440E10'u, + NvColorFormatU8RR = 0x0B09040408'u, NvColorFormatY8RR = 0x0B09200408'u, + NvColorFormatV8U8ER = 0x0C080C0710'u, NvColorFormatV8U8ER = 0x0C080C0E10'u, + NvColorFormatV8ER = 0x0C08240408'u, NvColorFormatU8V8ER = 0x0C08440710'u, + NvColorFormatU8V8ER = 0x0C08440E10'u, NvColorFormatU8ER = 0x0C09040408'u, + NvColorFormatY8ER = 0x0C09200408'u, NvColorFormatV8U8709 = 0x0D080C0710'u, + NvColorFormatV8U8709 = 0x0D080C0E10'u, NvColorFormatV10U10709 = 0x0D08142220'u, + NvColorFormatV12U12709 = 0x0D08142420'u, NvColorFormatV8709 = 0x0D08240408'u, + NvColorFormatV10709 = 0x0D08240F10'u, NvColorFormatV12709 = 0x0D08241010'u, + NvColorFormatU8V8709 = 0x0D08440710'u, NvColorFormatU8V8709 = 0x0D08440E10'u, + NvColorFormatU10V10709 = 0x0D08842220'u, + NvColorFormatU12V12709 = 0x0D08842420'u, NvColorFormatU8709 = 0x0D09040408'u, + NvColorFormatU10709 = 0x0D09040F10'u, NvColorFormatU12709 = 0x0D09041010'u, + NvColorFormatY8709 = 0x0D09200408'u, NvColorFormatY10709 = 0x0D09200F10'u, + NvColorFormatY12709 = 0x0D09201010'u, NvColorFormatV8U8709ER = 0x0E080C0710'u, + NvColorFormatV8U8709ER = 0x0E080C0E10'u, + NvColorFormatV10U10709ER = 0x0E08142220'u, + NvColorFormatV12U12709ER = 0x0E08142420'u, + NvColorFormatV8709ER = 0x0E08240408'u, NvColorFormatV10709ER = 0x0E08240F10'u, + NvColorFormatV12709ER = 0x0E08241010'u, + NvColorFormatU8V8709ER = 0x0E08440710'u, + NvColorFormatU8V8709ER = 0x0E08440E10'u, + NvColorFormatU10V10709ER = 0x0E08842220'u, + NvColorFormatU12V12709ER = 0x0E08842420'u, + NvColorFormatU8709ER = 0x0E09040408'u, NvColorFormatU10709ER = 0x0E09040F10'u, + NvColorFormatU12709ER = 0x0E09041010'u, NvColorFormatY8709ER = 0x0E09200408'u, + NvColorFormatY10709ER = 0x0E09200F10'u, NvColorFormatY12709ER = 0x0E09201010'u, + NvColorFormatV10U102020 = 0x0F08142220'u, + NvColorFormatV12U122020 = 0x0F08142420'u, + NvColorFormatV102020 = 0x0F08240F10'u, NvColorFormatV122020 = 0x0F08241010'u, + NvColorFormatU10V102020 = 0x0F08842220'u, + NvColorFormatU12V122020 = 0x0F08842420'u, + NvColorFormatU102020 = 0x0F09040F10'u, NvColorFormatU122020 = 0x0F09041010'u, + NvColorFormatY102020 = 0x0F09200F10'u, NvColorFormatY122020 = 0x0F09201010'u, + NvColorFormatBayer8RGGB = 0x1009200408'u, + NvColorFormatBayer16RGGB = 0x1009200A10'u, + NvColorFormatBayerS16RGGB = 0x1009208A10'u, + NvColorFormatX2Bayer14RGGB = 0x1009210B10'u, + NvColorFormatX4Bayer12RGGB = 0x1009210C10'u, + NvColorFormatX6Bayer10RGGB = 0x1009210D10'u, + NvColorFormatBayer8BGGR = 0x1109200408'u, + NvColorFormatBayer16BGGR = 0x1109200A10'u, + NvColorFormatBayerS16BGGR = 0x1109208A10'u, + NvColorFormatX2Bayer14BGGR = 0x1109210B10'u, + NvColorFormatX4Bayer12BGGR = 0x1109210C10'u, + NvColorFormatX6Bayer10BGGR = 0x1109210D10'u, + NvColorFormatBayer8GRBG = 0x1209200408'u, + NvColorFormatBayer16GRBG = 0x1209200A10'u, + NvColorFormatBayerS16GRBG = 0x1209208A10'u, + NvColorFormatX2Bayer14GRBG = 0x1209210B10'u, + NvColorFormatX4Bayer12GRBG = 0x1209210C10'u, + NvColorFormatX6Bayer10GRBG = 0x1209210D10'u, + NvColorFormatBayer8GBRG = 0x1309200408'u, + NvColorFormatBayer16GBRG = 0x1309200A10'u, + NvColorFormatBayerS16GBRG = 0x1309208A10'u, + NvColorFormatX2Bayer14GBRG = 0x1309210B10'u, + NvColorFormatX4Bayer12GBRG = 0x1309210C10'u, + NvColorFormatX6Bayer10GBRG = 0x1309210D10'u, NvColorFormatXYZ = 0x140A886640'u + + + + diff --git a/src/libnx/wrapper/switch/result.h b/src/libnx/wrapper/switch/result.h new file mode 100644 index 0000000..8e4db84 --- /dev/null +++ b/src/libnx/wrapper/switch/result.h @@ -0,0 +1,173 @@ +/** + * @file result.h + * @brief Switch result code tools. + * @copyright libnx Authors + */ +#pragma once +#include "types.h" + +/// Checks whether a result code indicates success. +#define R_SUCCEEDED(res) ((res)==0) +/// Checks whether a result code indicates failure. +#define R_FAILED(res) ((res)!=0) +/// Returns the module ID of a result code. +#define R_MODULE(res) ((res)&0x1FF) +/// Returns the description of a result code. +#define R_DESCRIPTION(res) (((res)>>9)&0x1FFF) +/// Masks out unused bits in a result code, retrieving the actual value for use in comparisons. +#define R_VALUE(res) ((res)&0x3FFFFF) + +/// Builds a result code from its constituent components. +#define MAKERESULT(module,description) \ + ((((module)&0x1FF)) | ((description)&0x1FFF)<<9) + +/// Builds a kernel error result code. +#define KERNELRESULT(description) \ + MAKERESULT(Module_Kernel, KernelError_##description) + +/// Module values +enum { + Module_Kernel=1, + Module_Libnx=345, + Module_HomebrewAbi=346, + Module_HomebrewLoader=347, + Module_LibnxNvidia=348, + Module_LibnxBinder=349, +}; + +/// Kernel error codes +enum { + KernelError_OutOfSessions=7, + KernelError_InvalidCapabilityDescriptor=14, + KernelError_NotImplemented=33, + KernelError_ThreadTerminating=59, + KernelError_OutOfDebugEvents=70, + KernelError_InvalidSize=101, + KernelError_InvalidAddress=102, + KernelError_ResourceExhausted=103, + KernelError_OutOfMemory=104, + KernelError_OutOfHandles=105, + KernelError_InvalidMemoryState=106, + KernelError_InvalidMemoryPermissions=108, + KernelError_InvalidMemoryRange=110, + KernelError_InvalidPriority=112, + KernelError_InvalidCoreId=113, + KernelError_InvalidHandle=114, + KernelError_InvalidUserBuffer=115, + KernelError_InvalidCombination=116, + KernelError_TimedOut=117, + KernelError_Cancelled=118, + KernelError_OutOfRange=119, + KernelError_InvalidEnumValue=120, + KernelError_NotFound=121, + KernelError_AlreadyExists=122, + KernelError_ConnectionClosed=123, + KernelError_UnhandledUserInterrupt=124, + KernelError_InvalidState=125, + KernelError_ReservedValue=126, + KernelError_InvalidHwBreakpoint=127, + KernelError_FatalUserException=128, + KernelError_OwnedByAnotherProcess=129, + KernelError_ConnectionRefused=131, + KernelError_OutOfResource=132, + KernelError_IpcMapFailed=259, + KernelError_IpcCmdbufTooSmall=260, + KernelError_NotDebugged=520, +}; + +/// libnx error codes +enum { + LibnxError_BadReloc=1, + LibnxError_OutOfMemory, + LibnxError_AlreadyMapped, + LibnxError_BadGetInfo_Stack, + LibnxError_BadGetInfo_Heap, + LibnxError_BadQueryMemory, + LibnxError_AlreadyInitialized, + LibnxError_NotInitialized, + LibnxError_NotFound, + LibnxError_IoError, + LibnxError_BadInput, + LibnxError_BadReent, + LibnxError_BufferProducerError, + LibnxError_HandleTooEarly, + LibnxError_HeapAllocFailed, + LibnxError_TooManyOverrides, + LibnxError_ParcelError, + LibnxError_BadGfxInit, + LibnxError_BadGfxEventWait, + LibnxError_BadGfxQueueBuffer, + LibnxError_BadGfxDequeueBuffer, + LibnxError_AppletCmdidNotFound, + LibnxError_BadAppletReceiveMessage, + LibnxError_BadAppletNotifyRunning, + LibnxError_BadAppletGetCurrentFocusState, + LibnxError_BadAppletGetOperationMode, + LibnxError_BadAppletGetPerformanceMode, + LibnxError_BadUsbCommsRead, + LibnxError_BadUsbCommsWrite, + LibnxError_InitFail_SM, + LibnxError_InitFail_AM, + LibnxError_InitFail_HID, + LibnxError_InitFail_FS, + LibnxError_BadGetInfo_Rng, + LibnxError_JitUnavailable, + LibnxError_WeirdKernel, + LibnxError_IncompatSysVer, + LibnxError_InitFail_Time, + LibnxError_TooManyDevOpTabs, + LibnxError_DomainMessageUnknownType, + LibnxError_DomainMessageTooManyObjectIds, + LibnxError_AppletFailedToInitialize, + LibnxError_ApmFailedToInitialize, + LibnxError_NvinfoFailedToInitialize, + LibnxError_NvbufFailedToInitialize, + LibnxError_LibAppletBadExit, + LibnxError_InvalidCmifOutHeader, + LibnxError_ShouldNotHappen, + LibnxError_Timeout, +}; + +/// libnx binder error codes +enum { + LibnxBinderError_Unknown=1, + LibnxBinderError_NoMemory, + LibnxBinderError_InvalidOperation, + LibnxBinderError_BadValue, + LibnxBinderError_BadType, + LibnxBinderError_NameNotFound, + LibnxBinderError_PermissionDenied, + LibnxBinderError_NoInit, + LibnxBinderError_AlreadyExists, + LibnxBinderError_DeadObject, + LibnxBinderError_FailedTransaction, + LibnxBinderError_BadIndex, + LibnxBinderError_NotEnoughData, + LibnxBinderError_WouldBlock, + LibnxBinderError_TimedOut, + LibnxBinderError_UnknownTransaction, + LibnxBinderError_FdsNotAllowed, +}; + +/// libnx nvidia error codes +enum { + LibnxNvidiaError_Unknown=1, + LibnxNvidiaError_NotImplemented, ///< Maps to Nvidia: 1 + LibnxNvidiaError_NotSupported, ///< Maps to Nvidia: 2 + LibnxNvidiaError_NotInitialized, ///< Maps to Nvidia: 3 + LibnxNvidiaError_BadParameter, ///< Maps to Nvidia: 4 + LibnxNvidiaError_Timeout, ///< Maps to Nvidia: 5 + LibnxNvidiaError_InsufficientMemory, ///< Maps to Nvidia: 6 + LibnxNvidiaError_ReadOnlyAttribute, ///< Maps to Nvidia: 7 + LibnxNvidiaError_InvalidState, ///< Maps to Nvidia: 8 + LibnxNvidiaError_InvalidAddress, ///< Maps to Nvidia: 9 + LibnxNvidiaError_InvalidSize, ///< Maps to Nvidia: 10 + LibnxNvidiaError_BadValue, ///< Maps to Nvidia: 11 + LibnxNvidiaError_AlreadyAllocated, ///< Maps to Nvidia: 13 + LibnxNvidiaError_Busy, ///< Maps to Nvidia: 14 + LibnxNvidiaError_ResourceError, ///< Maps to Nvidia: 15 + LibnxNvidiaError_CountMismatch, ///< Maps to Nvidia: 16 + LibnxNvidiaError_SharedMemoryTooSmall, ///< Maps to Nvidia: 0x1000 + LibnxNvidiaError_FileOperationFailed, ///< Maps to Nvidia: 0x30003 + LibnxNvidiaError_IoctlFailed, ///< Maps to Nvidia: 0x3000F +}; diff --git a/src/libnx/wrapper/switch/result.nim b/src/libnx/wrapper/switch/result.nim new file mode 100644 index 0000000..d4cd074 --- /dev/null +++ b/src/libnx/wrapper/switch/result.nim @@ -0,0 +1,196 @@ +## * +## @file result.h +## @brief Switch result code tools. +## @copyright libnx Authors +## + +import macros + +macro combineSym(s1, s2: untyped): untyped = + return ident($s1.toStrLit & $s2.toStrLit) + +import + types +export types + +## / Checks whether a result code indicates success. + +template r_Succeeded*(res: untyped): untyped = + ((res) == 0) + +## / Checks whether a result code indicates failure. + +template r_Failed*(res: untyped): untyped = + ((res) != 0) + +## / Returns the module ID of a result code. + +template r_Module*(res: untyped): untyped = + ((res) and 0x1FF) + +## / Returns the description of a result code. + +template r_Description*(res: untyped): untyped = + (((res) shr 9) and 0x1FFF) + +## / Masks out unused bits in a result code, retrieving the actual value for use in comparisons. + +template r_Value*(res: untyped): untyped = + ((res) and 0x3FFFFF) + + + +## / Module values + +const + ModuleKernel* = 1 + ModuleLibnx* = 345 + ModuleHomebrewAbi* = 346 + ModuleHomebrewLoader* = 347 + ModuleLibnxNvidia* = 348 + ModuleLibnxBinder* = 349 + +## / Kernel error codes + +const + KernelErrorOutOfSessions* = 7 + KernelErrorInvalidCapabilityDescriptor* = 14 + KernelErrorNotImplemented* = 33 + KernelErrorThreadTerminating* = 59 + KernelErrorOutOfDebugEvents* = 70 + KernelErrorInvalidSize* = 101 + KernelErrorInvalidAddress* = 102 + KernelErrorResourceExhausted* = 103 + KernelErrorOutOfMemory* = 104 + KernelErrorOutOfHandles* = 105 + KernelErrorInvalidMemoryState* = 106 + KernelErrorInvalidMemoryPermissions* = 108 + KernelErrorInvalidMemoryRange* = 110 + KernelErrorInvalidPriority* = 112 + KernelErrorInvalidCoreId* = 113 + KernelErrorInvalidHandle* = 114 + KernelErrorInvalidUserBuffer* = 115 + KernelErrorInvalidCombination* = 116 + KernelErrorTimedOut* = 117 + KernelErrorCancelled* = 118 + KernelErrorOutOfRange* = 119 + KernelErrorInvalidEnumValue* = 120 + KernelErrorNotFound* = 121 + KernelErrorAlreadyExists* = 122 + KernelErrorConnectionClosed* = 123 + KernelErrorUnhandledUserInterrupt* = 124 + KernelErrorInvalidState* = 125 + KernelErrorReservedValue* = 126 + KernelErrorInvalidHwBreakpoint* = 127 + KernelErrorFatalUserException* = 128 + KernelErrorOwnedByAnotherProcess* = 129 + KernelErrorConnectionRefused* = 131 + KernelErrorOutOfResource* = 132 + KernelErrorIpcMapFailed* = 259 + KernelErrorIpcCmdbufTooSmall* = 260 + KernelErrorNotDebugged* = 520 + +## / libnx error codes + +const + LibnxErrorBadReloc* = 1 + LibnxErrorOutOfMemory* = 2 + LibnxErrorAlreadyMapped* = 3 + LibnxErrorBadGetInfoStack* = 4 + LibnxErrorBadGetInfoHeap* = 5 + LibnxErrorBadQueryMemory* = 6 + LibnxErrorAlreadyInitialized* = 7 + LibnxErrorNotInitialized* = 8 + LibnxErrorNotFound* = 9 + LibnxErrorIoError* = 10 + LibnxErrorBadInput* = 11 + LibnxErrorBadReent* = 12 + LibnxErrorBufferProducerError* = 13 + LibnxErrorHandleTooEarly* = 14 + LibnxErrorHeapAllocFailed* = 15 + LibnxErrorTooManyOverrides* = 16 + LibnxErrorParcelError* = 17 + LibnxErrorBadGfxInit* = 18 + LibnxErrorBadGfxEventWait* = 19 + LibnxErrorBadGfxQueueBuffer* = 20 + LibnxErrorBadGfxDequeueBuffer* = 21 + LibnxErrorAppletCmdidNotFound* = 22 + LibnxErrorBadAppletReceiveMessage* = 23 + LibnxErrorBadAppletNotifyRunning* = 24 + LibnxErrorBadAppletGetCurrentFocusState* = 25 + LibnxErrorBadAppletGetOperationMode* = 26 + LibnxErrorBadAppletGetPerformanceMode* = 27 + LibnxErrorBadUsbCommsRead* = 28 + LibnxErrorBadUsbCommsWrite* = 29 + LibnxErrorInitFailSM* = 30 + LibnxErrorInitFailAM* = 31 + LibnxErrorInitFailHID* = 32 + LibnxErrorInitFailFS* = 33 + LibnxErrorBadGetInfoRng* = 34 + LibnxErrorJitUnavailable* = 35 + LibnxErrorWeirdKernel* = 36 + LibnxErrorIncompatSysVer* = 37 + LibnxErrorInitFailTime* = 38 + LibnxErrorTooManyDevOpTabs* = 39 + LibnxErrorDomainMessageUnknownType* = 40 + LibnxErrorDomainMessageTooManyObjectIds* = 41 + LibnxErrorAppletFailedToInitialize* = 42 + LibnxErrorApmFailedToInitialize* = 43 + LibnxErrorNvinfoFailedToInitialize* = 44 + LibnxErrorNvbufFailedToInitialize* = 45 + LibnxErrorLibAppletBadExit* = 46 + LibnxErrorInvalidCmifOutHeader* = 47 + LibnxErrorShouldNotHappen* = 48 + LibnxErrorTimeout* = 49 + +## / libnx binder error codes + +const + LibnxBinderErrorUnknown* = 1 + LibnxBinderErrorNoMemory* = 2 + LibnxBinderErrorInvalidOperation* = 3 + LibnxBinderErrorBadValue* = 4 + LibnxBinderErrorBadType* = 5 + LibnxBinderErrorNameNotFound* = 6 + LibnxBinderErrorPermissionDenied* = 7 + LibnxBinderErrorNoInit* = 8 + LibnxBinderErrorAlreadyExists* = 9 + LibnxBinderErrorDeadObject* = 10 + LibnxBinderErrorFailedTransaction* = 11 + LibnxBinderErrorBadIndex* = 12 + LibnxBinderErrorNotEnoughData* = 13 + LibnxBinderErrorWouldBlock* = 14 + LibnxBinderErrorTimedOut* = 15 + LibnxBinderErrorUnknownTransaction* = 16 + LibnxBinderErrorFdsNotAllowed* = 17 + +## / libnx nvidia error codes + +const + LibnxNvidiaErrorUnknown* = 1 + LibnxNvidiaErrorNotImplemented* = 2 ## /< Maps to Nvidia: 1 + LibnxNvidiaErrorNotSupported* = 3 ## /< Maps to Nvidia: 2 + LibnxNvidiaErrorNotInitialized* = 4 ## /< Maps to Nvidia: 3 + LibnxNvidiaErrorBadParameter* = 5 ## /< Maps to Nvidia: 4 + LibnxNvidiaErrorTimeout* = 6 ## /< Maps to Nvidia: 5 + LibnxNvidiaErrorInsufficientMemory* = 7 ## /< Maps to Nvidia: 6 + LibnxNvidiaErrorReadOnlyAttribute* = 8 ## /< Maps to Nvidia: 7 + LibnxNvidiaErrorInvalidState* = 9 ## /< Maps to Nvidia: 8 + LibnxNvidiaErrorInvalidAddress* = 10 ## /< Maps to Nvidia: 9 + LibnxNvidiaErrorInvalidSize* = 11 ## /< Maps to Nvidia: 10 + LibnxNvidiaErrorBadValue* = 12 ## /< Maps to Nvidia: 11 + LibnxNvidiaErrorAlreadyAllocated* = 13 ## /< Maps to Nvidia: 13 + LibnxNvidiaErrorBusy* = 14 ## /< Maps to Nvidia: 14 + LibnxNvidiaErrorResourceError* = 15 ## /< Maps to Nvidia: 15 + LibnxNvidiaErrorCountMismatch* = 16 ## /< Maps to Nvidia: 16 + LibnxNvidiaErrorSharedMemoryTooSmall* = 17 ## /< Maps to Nvidia: 0x1000 + LibnxNvidiaErrorFileOperationFailed* = 18 ## /< Maps to Nvidia: 0x30003 + LibnxNvidiaErrorIoctlFailed* = 19 ## /< Maps to Nvidia: 0x3000F + +template makeResult*(module, description: untyped): untyped = + ## / Builds a result code from its constituent components. + ((((module) and 0x1FF)) or ((description) and 0x1FFF) shl 9) + +template kernelResult*(description: untyped): untyped = + ## / Builds a kernel error result code. + makeResult(Module_Kernel, combineSym(KernelError, description)) diff --git a/src/libnx/wrapper/switch/runtime/btdev.h b/src/libnx/wrapper/switch/runtime/btdev.h new file mode 100644 index 0000000..2ff6514 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/btdev.h @@ -0,0 +1,445 @@ +/** + * @file btdev.h + * @brief Wrapper around the bt/btmu services for using bluetooth BLE. + * @note Only available on [5.0.0+]. + * @note See also: https://switchbrew.org/wiki/BTM_services + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/btdrv_types.h" + +/// GattAttribute +typedef struct { + u8 type; ///< Type + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid + u16 handle; ///< Handle + u32 connection_handle; ///< ConnectionHandle +} BtdevGattAttribute; + +/// GattService +typedef struct { + BtdevGattAttribute attr; ///< \ref BtdevGattAttribute + u16 instance_id; ///< InstanceId + u16 end_group_handle; ///< EndGroupHandle + bool primary_service; ///< PrimaryService +} BtdevGattService; + +/// GattCharacteristic +typedef struct { + BtdevGattAttribute attr; ///< \ref BtdevGattAttribute + u16 instance_id; ///< InstanceId + u8 properties; ///< Properties + u64 value_size; ///< Size of value. + u8 value[0x200]; ///< Value +} BtdevGattCharacteristic; + +/// GattDescriptor +typedef struct { + BtdevGattAttribute attr; ///< \ref BtdevGattAttribute + u64 value_size; ///< Size of value. + u8 value[0x200]; ///< Value +} BtdevGattDescriptor; + +/// Initialize bt/btmu. +Result btdevInitialize(void); + +/// Exit bt/btmu. +void btdevExit(void); + +/// Compares two \ref BtdrvGattAttributeUuid, returning whether these match. +bool btdevGattAttributeUuidIsSame(const BtdrvGattAttributeUuid *a, const BtdrvGattAttributeUuid *b); + +/// Wrapper for \ref btmuAcquireBleScanEvent. +Result btdevAcquireBleScanEvent(Event* out_event); + +/// Wrapper for \ref btmuGetBleScanFilterParameter. +Result btdevGetBleScanParameter(u16 parameter_id, BtdrvBleAdvertisePacketParameter *out); + +/// Wrapper for \ref btmuGetBleScanFilterParameter2. +Result btdevGetBleScanParameter2(u16 parameter_id, BtdrvGattAttributeUuid *out); + +/// Wrapper for \ref btdevStartBleScanGeneral. +Result btdevStartBleScanGeneral(BtdrvBleAdvertisePacketParameter param); + +/// Wrapper for \ref btmuStopBleScanForGeneral. +Result btdevStopBleScanGeneral(void); + +/** + * @brief Wrapper for \ref btmuGetBleScanResultsForGeneral and \ref btmuGetBleScanResultsForSmartDevice. + * @param[out] results Output array of \ref BtdrvBleScanResult. + * @param[in] count Size of the results array in entries. + * @param[out] total_out Total output entries. + */ +Result btdevGetBleScanResult(BtdrvBleScanResult *results, u8 count, u8 *total_out); + +/// Wrapper for \ref btmuStartBleScanForPaired. +Result btdevEnableBleAutoConnection(BtdrvBleAdvertisePacketParameter param); + +/// Wrapper for \ref btmuStopBleScanForPaired. +Result btdevDisableBleAutoConnection(void); + +/// Wrapper for \ref btmuStartBleScanForSmartDevice. +Result btdevStartBleScanSmartDevice(const BtdrvGattAttributeUuid *uuid); + +/// Wrapper for \ref btmuStopBleScanForSmartDevice. +Result btdevStopBleScanSmartDevice(void); + +/// Wrapper for \ref btmuAcquireBleConnectionEvent. +Result btdevAcquireBleConnectionStateChangedEvent(Event* out_event); + +/// Wrapper for \ref btmuBleConnect. +Result btdevConnectToGattServer(BtdrvAddress addr); + +/// Wrapper for \ref btmuBleDisconnect. +Result btdevDisconnectFromGattServer(u32 connection_handle); + +/// Wrapper for \ref btmuBleGetConnectionState. +Result btdevGetBleConnectionInfoList(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out); + +/// Wrapper for \ref btmuAcquireBleServiceDiscoveryEvent. +Result btdevAcquireBleServiceDiscoveryEvent(Event* out_event); + +/** + * @brief Wrapper for \ref btmuGetGattServices. + * @param[in] connection_handle ConnectionHandle + * @param[out] services Output array of \ref BtdevGattService. + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btdevGetGattServices(u32 connection_handle, BtdevGattService *services, u8 count, u8 *total_out); + +/** + * @brief Wrapper for \ref btmuGetGattService. + * @param[in] connection_handle ConnectionHandle + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] service \ref BtdevGattService + * @param[out] flag Whether a \ref BtdevGattService was returned. + */ +Result btdevGetGattService(u32 connection_handle, const BtdrvGattAttributeUuid *uuid, BtdevGattService *service, bool *flag); + +/// Wrapper for \ref btmuAcquireBlePairingEvent. +Result btdevAcquireBlePairingEvent(Event* out_event); + +/// Wrapper for \ref btmuBlePairDevice. +Result btdevPairGattServer(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/// Wrapper for \ref btmuBleUnPairDevice. +Result btdevUnpairGattServer(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/// Wrapper for \ref btmuBleUnPairDevice2. +Result btdevUnpairGattServer2(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter param); + +/// Wrapper for \ref btmuBleGetPairedDevices. +Result btdevGetPairedGattServerAddress(BtdrvBleAdvertisePacketParameter param, BtdrvAddress *addrs, u8 count, u8 *total_out); + +/// Wrapper for \ref btmuAcquireBleMtuConfigEvent. +Result btdevAcquireBleMtuConfigEvent(Event* out_event); + +/** + * @brief Wrapper for \ref btmuConfigureBleMtu. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] mtu MTU, must be 0x18-0x200. + */ +Result btdevConfigureBleMtu(u32 connection_handle, u16 mtu); + +/// Wrapper for \ref btmuGetBleMtu. +Result btdevGetBleMtu(u32 connection_handle, u16 *out); + +/// Wrapper for \ref btRegisterBleEvent. +Result btdevAcquireBleGattOperationEvent(Event* out_event); + +/** + * @brief Wrapper for \ref btmuRegisterBleGattDataPath. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdevRegisterGattOperationNotification(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief Wrapper for \ref btmuUnregisterBleGattDataPath. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdevUnregisterGattOperationNotification(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief Wrapper for \ref btGetLeEventInfo. + * @param[out] out \ref BtdrvBleClientGattOperationInfo + */ +Result btdevGetGattOperationResult(BtdrvBleClientGattOperationInfo *out); + +/** + * @brief Wrapper for \ref btLeClientReadCharacteristic. + * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. + * @param c \ref BtdevGattCharacteristic + */ +Result btdevReadGattCharacteristic(BtdevGattCharacteristic *c); + +/** + * @brief Wrapper for \ref btLeClientWriteCharacteristic. + * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. + * @note This uses the Value from \ref btdevGattCharacteristicSetValue. + * @param c \ref BtdevGattCharacteristic + */ +Result btdevWriteGattCharacteristic(BtdevGattCharacteristic *c); + +/** + * @brief Wrapper for \ref btLeClientRegisterNotification / \ref btLeClientDeregisterNotification. + * @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. + * @param c \ref BtdevGattCharacteristic + * @param[in] flag Whether to enable/disable, controls which func to call. + */ +Result btdevEnableGattCharacteristicNotification(BtdevGattCharacteristic *c, bool flag); + +/** + * @brief Wrapper for \ref btLeClientReadDescriptor. + * @param d \ref BtdevGattDescriptor + */ +Result btdevReadGattDescriptor(BtdevGattDescriptor *d); + +/** + * @brief Wrapper for \ref btLeClientWriteDescriptor. + * @note This uses the Value from \ref btdevGattDescriptorSetValue. + * @param d \ref BtdevGattDescriptor + */ +Result btdevWriteGattDescriptor(BtdevGattDescriptor *d); + +///@name GattAttribute +///@{ + +/** + * @brief Creates a \ref BtdevGattAttribute object. This is intended for internal use. + * @param a \ref BtdevGattAttribute + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[in] handle Handle + * @param[in] connection_handle ConnectionHandle + */ +void btdevGattAttributeCreate(BtdevGattAttribute *a, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle); + +/** + * @brief Gets the Type. + * @param a \ref BtdevGattAttribute + */ +NX_CONSTEXPR u8 btdevGattAttributeGetType(BtdevGattAttribute *a) { + return a->type; +} + +/** + * @brief Gets the Uuid. + * @param a \ref BtdevGattAttribute + * @param[out] out \ref BtdrvGattAttributeUuid + */ +NX_CONSTEXPR void btdevGattAttributeGetUuid(BtdevGattAttribute *a, BtdrvGattAttributeUuid *out) { + *out = a->uuid; +} + +/** + * @brief Gets the Handle. + * @param a \ref BtdevGattAttribute + */ +NX_CONSTEXPR u16 btdevGattAttributeGetHandle(BtdevGattAttribute *a) { + return a->handle; +} + +/** + * @brief Gets the ConnectionHandle. + * @param a \ref BtdevGattAttribute + */ +NX_CONSTEXPR u32 btdevGattAttributeGetConnectionHandle(BtdevGattAttribute *a) { + return a->connection_handle; +} + +///@} + +///@name GattService +///@{ + +/** + * @brief Creates a \ref BtdevGattService object. This is intended for internal use. + * @param s \ref BtdevGattService + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[in] handle Handle + * @param[in] connection_handle ConnectionHandle + * @param[in] instance_id InstanceId + * @param[in] end_group_handle EndGroupHandle + * @param[in] primary_service PrimaryService + */ +void btdevGattServiceCreate(BtdevGattService *s, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle, u16 instance_id, u16 end_group_handle, bool primary_service); + +/** + * @brief Gets the InstanceId. + * @param s \ref BtdevGattService + */ +NX_CONSTEXPR u16 btdevGattServiceGetInstanceId(BtdevGattService *s) { + return s->instance_id; +} + +/** + * @brief Gets the EndGroupHandle. + * @param s \ref BtdevGattService + */ +NX_CONSTEXPR u16 btdevGattServiceGetEndGroupHandle(BtdevGattService *s) { + return s->end_group_handle; +} + +/** + * @brief Gets whether this is the PrimaryService. + * @param s \ref BtdevGattService + */ +NX_CONSTEXPR u16 btdevGattServiceIsPrimaryService(BtdevGattService *s) { + return s->primary_service; +} + +/** + * @brief Wrapper for \ref btmuGetGattIncludedServices. + * @param s \ref BtdevGattService + * @param[out] services Output array of \ref BtdevGattService. + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btdevGattServiceGetIncludedServices(BtdevGattService *s, BtdevGattService *services, u8 count, u8 *total_out); + +/** + * @brief Wrapper for \ref btmuGetGattCharacteristics. + * @param s \ref BtdevGattService + * @param[out] characteristics Output array of \ref BtdevGattCharacteristic. + * @param[in] count Size of the characteristics array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btdevGattServiceGetCharacteristics(BtdevGattService *s, BtdevGattCharacteristic *characteristics, u8 count, u8 *total_out); + +/** + * @brief Same as \ref btdevGattServiceGetCharacteristics except this only returns the \ref BtdevGattCharacteristic which contains a matching \ref BtdrvGattAttributeUuid. + * @param s \ref BtdevGattService + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] characteristic \ref BtdevGattCharacteristic + * @param[out] flag Whether a \ref BtdevGattService was returned. + */ +Result btdevGattServiceGetCharacteristic(BtdevGattService *s, const BtdrvGattAttributeUuid *uuid, BtdevGattCharacteristic *characteristic, bool *flag); + +///@} + +///@name GattCharacteristic +///@{ + +/** + * @brief Creates a \ref BtdevGattCharacteristic object. This is intended for internal use. + * @param c \ref BtdevGattCharacteristic + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[in] handle Handle + * @param[in] connection_handle ConnectionHandle + * @param[in] instance_id InstanceId + * @param[in] properties Properties + */ +void btdevGattCharacteristicCreate(BtdevGattCharacteristic *c, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle, u16 instance_id, u8 properties); + +/** + * @brief Gets the InstanceId. + * @param c \ref BtdevGattCharacteristic + */ +NX_CONSTEXPR u16 btdevGattCharacteristicGetInstanceId(BtdevGattCharacteristic *c) { + return c->instance_id; +} + +/** + * @brief Gets the Properties. + * @param c \ref BtdevGattCharacteristic + */ +NX_CONSTEXPR u8 btdevGattCharacteristicGetProperties(BtdevGattCharacteristic *c) { + return c->properties; +} + +/** + * @brief Wrapper for \ref btmuGetBelongingGattService. + * @note Gets the \ref BtdevGattService which belongs to this object. + * @param c \ref BtdevGattCharacteristic. + * @param[out] service \ref BtdevGattService + */ +Result btdevGattCharacteristicGetService(BtdevGattCharacteristic *c, BtdevGattService *service); + +/** + * @brief Wrapper for \ref btmuGetGattDescriptors. + * @note Gets the descriptors which belongs to this object. + * @param c \ref BtdevGattCharacteristic + * @param[out] descriptors Output array of \ref BtdevGattDescriptor. + * @param[in] count Size of the descriptors array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btdevGattCharacteristicGetDescriptors(BtdevGattCharacteristic *c, BtdevGattDescriptor *descriptors, u8 count, u8 *total_out); + +/** + * @brief Same as \ref btdevGattCharacteristicGetDescriptors except this only returns a \ref BtdevGattDescriptor which contains a matching \ref BtdrvGattAttributeUuid. + * @param c \ref BtdevGattCharacteristic + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] descriptor \ref BtdevGattDescriptor + * @param[out] flag Whether a \ref BtdevGattDescriptor was returned. + */ +Result btdevGattCharacteristicGetDescriptor(BtdevGattCharacteristic *c, const BtdrvGattAttributeUuid *uuid, BtdevGattDescriptor *descriptor, bool *flag); + +/** + * @brief Sets the Value in the object. + * @note See also \ref btdevWriteGattCharacteristic. + * @param c \ref BtdevGattCharacteristic + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size, max is 0x200. + */ +void btdevGattCharacteristicSetValue(BtdevGattCharacteristic *c, const void* buffer, size_t size); + +/** + * @brief Gets the Value in the object, returns the copied value size. + * @param c \ref BtdevGattCharacteristic + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size, max is 0x200. + */ +u64 btdevGattCharacteristicGetValue(BtdevGattCharacteristic *c, void* buffer, size_t size); + +///@} + +///@name GattDescriptor +///@{ + +/** + * @brief Creates a \ref BtdevGattDescriptor object. This is intended for internal use. + * @param d \ref BtdevGattDescriptor + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[in] handle Handle + * @param[in] connection_handle ConnectionHandle + */ +void btdevGattDescriptorCreate(BtdevGattDescriptor *d, const BtdrvGattAttributeUuid *uuid, u16 handle, u32 connection_handle); + +/** + * @brief Wrapper for \ref btmuGetBelongingGattService. + * @note Gets the \ref BtdevGattService which belongs to this object. + * @param d \ref BtdevGattDescriptor + * @param[out] service \ref BtdevGattService + */ +Result btdevGattDescriptorGetService(BtdevGattDescriptor *d, BtdevGattService *service); + +/** + * @brief Wrapper for \ref btmuGetGattCharacteristics. + * @note Gets the \ref BtdevGattCharacteristic which belongs to this object. + * @param d \ref BtdevGattDescriptor + * @param[out] characteristic \ref BtdevGattCharacteristic + */ +Result btdevGattDescriptorGetCharacteristic(BtdevGattDescriptor *d, BtdevGattCharacteristic *characteristic); + +/** + * @brief Sets the Value in the object. + * @note See also \ref btdevWriteGattDescriptor. + * @param d \ref BtdevGattDescriptor + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size, max is 0x200. + */ +void btdevGattDescriptorSetValue(BtdevGattDescriptor *d, const void* buffer, size_t size); + +/** + * @brief Gets the Value in the object, returns the copied value size. + * @param d \ref BtdevGattDescriptor + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size, max is 0x200. + */ +u64 btdevGattDescriptorGetValue(BtdevGattDescriptor *d, void* buffer, size_t size); + +///@} + diff --git a/src/libnx/wrapper/switch/runtime/btdev.nim b/src/libnx/wrapper/switch/runtime/btdev.nim new file mode 100644 index 0000000..14aa68d --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/btdev.nim @@ -0,0 +1,529 @@ +## * +## @file btdev.h +## @brief Wrapper around the bt/btmu services for using bluetooth BLE. +## @note Only available on [5.0.0+]. +## @note See also: https://switchbrew.org/wiki/BTM_services +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/btdrv_types + +## / GattAttribute + +type + BtdevGattAttribute* {.bycopy.} = object + `type`*: U8 ## /< Type + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + handle*: U16 ## /< Handle + connectionHandle*: U32 ## /< ConnectionHandle + + +## / GattService + +type + BtdevGattService* {.bycopy.} = object + attr*: BtdevGattAttribute ## /< \ref BtdevGattAttribute + instanceId*: U16 ## /< InstanceId + endGroupHandle*: U16 ## /< EndGroupHandle + primaryService*: bool ## /< PrimaryService + + +## / GattCharacteristic + +type + BtdevGattCharacteristic* {.bycopy.} = object + attr*: BtdevGattAttribute ## /< \ref BtdevGattAttribute + instanceId*: U16 ## /< InstanceId + properties*: U8 ## /< Properties + valueSize*: U64 ## /< Size of value. + value*: array[0x200, U8] ## /< Value + + +## / GattDescriptor + +type + BtdevGattDescriptor* {.bycopy.} = object + attr*: BtdevGattAttribute ## /< \ref BtdevGattAttribute + valueSize*: U64 ## /< Size of value. + value*: array[0x200, U8] ## /< Value + +proc btdevInitialize*(): Result {.cdecl, importc: "btdevInitialize".} +## / Initialize bt/btmu. + +proc btdevExit*() {.cdecl, importc: "btdevExit".} +## / Exit bt/btmu. + +proc btdevGattAttributeUuidIsSame*(a: ptr BtdrvGattAttributeUuid; + b: ptr BtdrvGattAttributeUuid): bool {.cdecl, + importc: "btdevGattAttributeUuidIsSame".} +## / Compares two \ref BtdrvGattAttributeUuid, returning whether these match. + +proc btdevAcquireBleScanEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdevAcquireBleScanEvent".} +## / Wrapper for \ref btmuAcquireBleScanEvent. + +proc btdevGetBleScanParameter*(parameterId: U16; + `out`: ptr BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btdevGetBleScanParameter".} +## / Wrapper for \ref btmuGetBleScanFilterParameter. + +proc btdevGetBleScanParameter2*(parameterId: U16; `out`: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdevGetBleScanParameter2".} +## / Wrapper for \ref btmuGetBleScanFilterParameter2. + +proc btdevStartBleScanGeneral*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btdevStartBleScanGeneral".} +## / Wrapper for \ref btdevStartBleScanGeneral. + +proc btdevStopBleScanGeneral*(): Result {.cdecl, importc: "btdevStopBleScanGeneral".} +## / Wrapper for \ref btmuStopBleScanForGeneral. + +proc btdevGetBleScanResult*(results: ptr BtdrvBleScanResult; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btdevGetBleScanResult".} +## * +## @brief Wrapper for \ref btmuGetBleScanResultsForGeneral and \ref btmuGetBleScanResultsForSmartDevice. +## @param[out] results Output array of \ref BtdrvBleScanResult. +## @param[in] count Size of the results array in entries. +## @param[out] total_out Total output entries. +## + +proc btdevEnableBleAutoConnection*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btdevEnableBleAutoConnection".} +## / Wrapper for \ref btmuStartBleScanForPaired. + +proc btdevDisableBleAutoConnection*(): Result {.cdecl, + importc: "btdevDisableBleAutoConnection".} +## / Wrapper for \ref btmuStopBleScanForPaired. + +proc btdevStartBleScanSmartDevice*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdevStartBleScanSmartDevice".} +## / Wrapper for \ref btmuStartBleScanForSmartDevice. + +proc btdevStopBleScanSmartDevice*(): Result {.cdecl, + importc: "btdevStopBleScanSmartDevice".} +## / Wrapper for \ref btmuStopBleScanForSmartDevice. + +proc btdevAcquireBleConnectionStateChangedEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "btdevAcquireBleConnectionStateChangedEvent".} +## / Wrapper for \ref btmuAcquireBleConnectionEvent. + +proc btdevConnectToGattServer*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdevConnectToGattServer".} +## / Wrapper for \ref btmuBleConnect. + +proc btdevDisconnectFromGattServer*(connectionHandle: U32): Result {.cdecl, + importc: "btdevDisconnectFromGattServer".} +## / Wrapper for \ref btmuBleDisconnect. + +proc btdevGetBleConnectionInfoList*(info: ptr BtdrvBleConnectionInfo; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btdevGetBleConnectionInfoList".} +## / Wrapper for \ref btmuBleGetConnectionState. + +proc btdevAcquireBleServiceDiscoveryEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdevAcquireBleServiceDiscoveryEvent".} +## / Wrapper for \ref btmuAcquireBleServiceDiscoveryEvent. + +proc btdevGetGattServices*(connectionHandle: U32; services: ptr BtdevGattService; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btdevGetGattServices".} +## * +## @brief Wrapper for \ref btmuGetGattServices. +## @param[in] connection_handle ConnectionHandle +## @param[out] services Output array of \ref BtdevGattService. +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btdevGetGattService*(connectionHandle: U32; uuid: ptr BtdrvGattAttributeUuid; + service: ptr BtdevGattService; flag: ptr bool): Result {. + cdecl, importc: "btdevGetGattService".} +## * +## @brief Wrapper for \ref btmuGetGattService. +## @param[in] connection_handle ConnectionHandle +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] service \ref BtdevGattService +## @param[out] flag Whether a \ref BtdevGattService was returned. +## + +proc btdevAcquireBlePairingEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdevAcquireBlePairingEvent".} +## / Wrapper for \ref btmuAcquireBlePairingEvent. + +proc btdevPairGattServer*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btdevPairGattServer".} +## / Wrapper for \ref btmuBlePairDevice. + +proc btdevUnpairGattServer*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btdevUnpairGattServer".} +## / Wrapper for \ref btmuBleUnPairDevice. + +proc btdevUnpairGattServer2*(`addr`: BtdrvAddress; + param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btdevUnpairGattServer2".} +## / Wrapper for \ref btmuBleUnPairDevice2. + +proc btdevGetPairedGattServerAddress*(param: BtdrvBleAdvertisePacketParameter; + addrs: ptr BtdrvAddress; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btdevGetPairedGattServerAddress".} +## / Wrapper for \ref btmuBleGetPairedDevices. + +proc btdevAcquireBleMtuConfigEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdevAcquireBleMtuConfigEvent".} +## / Wrapper for \ref btmuAcquireBleMtuConfigEvent. + +proc btdevConfigureBleMtu*(connectionHandle: U32; mtu: U16): Result {.cdecl, + importc: "btdevConfigureBleMtu".} +## * +## @brief Wrapper for \ref btmuConfigureBleMtu. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] mtu MTU, must be 0x18-0x200. +## + +proc btdevGetBleMtu*(connectionHandle: U32; `out`: ptr U16): Result {.cdecl, + importc: "btdevGetBleMtu".} +## / Wrapper for \ref btmuGetBleMtu. + +proc btdevAcquireBleGattOperationEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdevAcquireBleGattOperationEvent".} +## / Wrapper for \ref btRegisterBleEvent. + +proc btdevRegisterGattOperationNotification*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdevRegisterGattOperationNotification".} +## * +## @brief Wrapper for \ref btmuRegisterBleGattDataPath. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdevUnregisterGattOperationNotification*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdevUnregisterGattOperationNotification".} +## * +## @brief Wrapper for \ref btmuUnregisterBleGattDataPath. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdevGetGattOperationResult*(`out`: ptr BtdrvBleClientGattOperationInfo): Result {. + cdecl, importc: "btdevGetGattOperationResult".} +## * +## @brief Wrapper for \ref btGetLeEventInfo. +## @param[out] out \ref BtdrvBleClientGattOperationInfo +## + +proc btdevReadGattCharacteristic*(c: ptr BtdevGattCharacteristic): Result {.cdecl, + importc: "btdevReadGattCharacteristic".} +## * +## @brief Wrapper for \ref btLeClientReadCharacteristic. +## @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. +## @param c \ref BtdevGattCharacteristic +## + +proc btdevWriteGattCharacteristic*(c: ptr BtdevGattCharacteristic): Result {.cdecl, + importc: "btdevWriteGattCharacteristic".} +## * +## @brief Wrapper for \ref btLeClientWriteCharacteristic. +## @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. +## @note This uses the Value from \ref btdevGattCharacteristicSetValue. +## @param c \ref BtdevGattCharacteristic +## + +proc btdevEnableGattCharacteristicNotification*(c: ptr BtdevGattCharacteristic; + flag: bool): Result {.cdecl, + importc: "btdevEnableGattCharacteristicNotification".} +## * +## @brief Wrapper for \ref btLeClientRegisterNotification / \ref btLeClientDeregisterNotification. +## @note An error is thrown if the properties from \ref btdevGattCharacteristicGetProperties don't allow using this. +## @param c \ref BtdevGattCharacteristic +## @param[in] flag Whether to enable/disable, controls which func to call. +## + +proc btdevReadGattDescriptor*(d: ptr BtdevGattDescriptor): Result {.cdecl, + importc: "btdevReadGattDescriptor".} +## * +## @brief Wrapper for \ref btLeClientReadDescriptor. +## @param d \ref BtdevGattDescriptor +## + +proc btdevWriteGattDescriptor*(d: ptr BtdevGattDescriptor): Result {.cdecl, + importc: "btdevWriteGattDescriptor".} +## * +## @brief Wrapper for \ref btLeClientWriteDescriptor. +## @note This uses the Value from \ref btdevGattDescriptorSetValue. +## @param d \ref BtdevGattDescriptor +## + +proc btdevGattAttributeCreate*(a: ptr BtdevGattAttribute; + uuid: ptr BtdrvGattAttributeUuid; handle: U16; + connectionHandle: U32) {.cdecl, + importc: "btdevGattAttributeCreate".} +## /@name GattAttribute +## /@{ +## * +## @brief Creates a \ref BtdevGattAttribute object. This is intended for internal use. +## @param a \ref BtdevGattAttribute +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[in] handle Handle +## @param[in] connection_handle ConnectionHandle +## + +proc btdevGattAttributeGetType*(a: ptr BtdevGattAttribute): U8 {.inline, cdecl.} = + ## * + ## @brief Gets the Type. + ## @param a \ref BtdevGattAttribute + ## + + return a.`type` + +proc btdevGattAttributeGetUuid*(a: ptr BtdevGattAttribute; + `out`: ptr BtdrvGattAttributeUuid) {.inline, cdecl.} = + ## * + ## @brief Gets the Uuid. + ## @param a \ref BtdevGattAttribute + ## @param[out] out \ref BtdrvGattAttributeUuid + ## + + `out`[] = a.uuid + +proc btdevGattAttributeGetHandle*(a: ptr BtdevGattAttribute): U16 {.inline, cdecl.} = + ## * + ## @brief Gets the Handle. + ## @param a \ref BtdevGattAttribute + ## + + return a.handle + +proc btdevGattAttributeGetConnectionHandle*(a: ptr BtdevGattAttribute): U32 {.inline, cdecl.} = + ## * + ## @brief Gets the ConnectionHandle. + ## @param a \ref BtdevGattAttribute + ## + + return a.connectionHandle + +proc btdevGattServiceCreate*(s: ptr BtdevGattService; + uuid: ptr BtdrvGattAttributeUuid; handle: U16; + connectionHandle: U32; instanceId: U16; + endGroupHandle: U16; primaryService: bool) {.cdecl, + importc: "btdevGattServiceCreate".} +## /@} +## /@name GattService +## /@{ +## * +## @brief Creates a \ref BtdevGattService object. This is intended for internal use. +## @param s \ref BtdevGattService +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[in] handle Handle +## @param[in] connection_handle ConnectionHandle +## @param[in] instance_id InstanceId +## @param[in] end_group_handle EndGroupHandle +## @param[in] primary_service PrimaryService +## + +proc btdevGattServiceGetInstanceId*(s: ptr BtdevGattService): U16 {.inline, cdecl.} = + ## * + ## @brief Gets the InstanceId. + ## @param s \ref BtdevGattService + ## + + return s.instanceId + +proc btdevGattServiceGetEndGroupHandle*(s: ptr BtdevGattService): U16 {.inline, cdecl.} = + ## * + ## @brief Gets the EndGroupHandle. + ## @param s \ref BtdevGattService + ## + + return s.endGroupHandle + +proc btdevGattServiceIsPrimaryService*(s: ptr BtdevGattService): bool {.inline, cdecl.} = + ## * + ## @brief Gets whether this is the PrimaryService. + ## @param s \ref BtdevGattService + ## + + return s.primaryService + +proc btdevGattServiceGetIncludedServices*(s: ptr BtdevGattService; + services: ptr BtdevGattService; count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btdevGattServiceGetIncludedServices".} +## * +## @brief Wrapper for \ref btmuGetGattIncludedServices. +## @param s \ref BtdevGattService +## @param[out] services Output array of \ref BtdevGattService. +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btdevGattServiceGetCharacteristics*(s: ptr BtdevGattService; characteristics: ptr BtdevGattCharacteristic; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btdevGattServiceGetCharacteristics".} +## * +## @brief Wrapper for \ref btmuGetGattCharacteristics. +## @param s \ref BtdevGattService +## @param[out] characteristics Output array of \ref BtdevGattCharacteristic. +## @param[in] count Size of the characteristics array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btdevGattServiceGetCharacteristic*(s: ptr BtdevGattService; + uuid: ptr BtdrvGattAttributeUuid; + characteristic: ptr BtdevGattCharacteristic; flag: ptr bool): Result {.cdecl, + importc: "btdevGattServiceGetCharacteristic".} +## * +## @brief Same as \ref btdevGattServiceGetCharacteristics except this only returns the \ref BtdevGattCharacteristic which contains a matching \ref BtdrvGattAttributeUuid. +## @param s \ref BtdevGattService +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] characteristic \ref BtdevGattCharacteristic +## @param[out] flag Whether a \ref BtdevGattService was returned. +## + +proc btdevGattCharacteristicCreate*(c: ptr BtdevGattCharacteristic; + uuid: ptr BtdrvGattAttributeUuid; handle: U16; + connectionHandle: U32; instanceId: U16; + properties: U8) {.cdecl, + importc: "btdevGattCharacteristicCreate".} +## /@} +## /@name GattCharacteristic +## /@{ +## * +## @brief Creates a \ref BtdevGattCharacteristic object. This is intended for internal use. +## @param c \ref BtdevGattCharacteristic +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[in] handle Handle +## @param[in] connection_handle ConnectionHandle +## @param[in] instance_id InstanceId +## @param[in] properties Properties +## + +proc btdevGattCharacteristicGetInstanceId*(c: ptr BtdevGattCharacteristic): U16 {. + inline, cdecl.} = + ## * + ## @brief Gets the InstanceId. + ## @param c \ref BtdevGattCharacteristic + ## + + return c.instanceId + +proc btdevGattCharacteristicGetProperties*(c: ptr BtdevGattCharacteristic): U8 {. + inline, cdecl.} = + ## * + ## @brief Gets the Properties. + ## @param c \ref BtdevGattCharacteristic + ## + + return c.properties + +proc btdevGattCharacteristicGetService*(c: ptr BtdevGattCharacteristic; + service: ptr BtdevGattService): Result {. + cdecl, importc: "btdevGattCharacteristicGetService".} +## * +## @brief Wrapper for \ref btmuGetBelongingGattService. +## @note Gets the \ref BtdevGattService which belongs to this object. +## @param c \ref BtdevGattCharacteristic. +## @param[out] service \ref BtdevGattService +## + +proc btdevGattCharacteristicGetDescriptors*(c: ptr BtdevGattCharacteristic; + descriptors: ptr BtdevGattDescriptor; count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btdevGattCharacteristicGetDescriptors".} +## * +## @brief Wrapper for \ref btmuGetGattDescriptors. +## @note Gets the descriptors which belongs to this object. +## @param c \ref BtdevGattCharacteristic +## @param[out] descriptors Output array of \ref BtdevGattDescriptor. +## @param[in] count Size of the descriptors array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btdevGattCharacteristicGetDescriptor*(c: ptr BtdevGattCharacteristic; + uuid: ptr BtdrvGattAttributeUuid; descriptor: ptr BtdevGattDescriptor; + flag: ptr bool): Result {.cdecl, importc: "btdevGattCharacteristicGetDescriptor".} +## * +## @brief Same as \ref btdevGattCharacteristicGetDescriptors except this only returns a \ref BtdevGattDescriptor which contains a matching \ref BtdrvGattAttributeUuid. +## @param c \ref BtdevGattCharacteristic +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] descriptor \ref BtdevGattDescriptor +## @param[out] flag Whether a \ref BtdevGattDescriptor was returned. +## + +proc btdevGattCharacteristicSetValue*(c: ptr BtdevGattCharacteristic; + buffer: pointer; size: csize_t) {.cdecl, + importc: "btdevGattCharacteristicSetValue".} +## * +## @brief Sets the Value in the object. +## @note See also \ref btdevWriteGattCharacteristic. +## @param c \ref BtdevGattCharacteristic +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size, max is 0x200. +## + +proc btdevGattCharacteristicGetValue*(c: ptr BtdevGattCharacteristic; + buffer: pointer; size: csize_t): U64 {.cdecl, + importc: "btdevGattCharacteristicGetValue".} +## * +## @brief Gets the Value in the object, returns the copied value size. +## @param c \ref BtdevGattCharacteristic +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size, max is 0x200. +## + +proc btdevGattDescriptorCreate*(d: ptr BtdevGattDescriptor; + uuid: ptr BtdrvGattAttributeUuid; handle: U16; + connectionHandle: U32) {.cdecl, + importc: "btdevGattDescriptorCreate".} +## /@} +## /@name GattDescriptor +## /@{ +## * +## @brief Creates a \ref BtdevGattDescriptor object. This is intended for internal use. +## @param d \ref BtdevGattDescriptor +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[in] handle Handle +## @param[in] connection_handle ConnectionHandle +## + +proc btdevGattDescriptorGetService*(d: ptr BtdevGattDescriptor; + service: ptr BtdevGattService): Result {.cdecl, + importc: "btdevGattDescriptorGetService".} +## * +## @brief Wrapper for \ref btmuGetBelongingGattService. +## @note Gets the \ref BtdevGattService which belongs to this object. +## @param d \ref BtdevGattDescriptor +## @param[out] service \ref BtdevGattService +## + +proc btdevGattDescriptorGetCharacteristic*(d: ptr BtdevGattDescriptor; + characteristic: ptr BtdevGattCharacteristic): Result {.cdecl, + importc: "btdevGattDescriptorGetCharacteristic".} +## * +## @brief Wrapper for \ref btmuGetGattCharacteristics. +## @note Gets the \ref BtdevGattCharacteristic which belongs to this object. +## @param d \ref BtdevGattDescriptor +## @param[out] characteristic \ref BtdevGattCharacteristic +## + +proc btdevGattDescriptorSetValue*(d: ptr BtdevGattDescriptor; buffer: pointer; + size: csize_t) {.cdecl, + importc: "btdevGattDescriptorSetValue".} +## * +## @brief Sets the Value in the object. +## @note See also \ref btdevWriteGattDescriptor. +## @param d \ref BtdevGattDescriptor +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size, max is 0x200. +## + +proc btdevGattDescriptorGetValue*(d: ptr BtdevGattDescriptor; buffer: pointer; + size: csize_t): U64 {.cdecl, + importc: "btdevGattDescriptorGetValue".} +## * +## @brief Gets the Value in the object, returns the copied value size. +## @param d \ref BtdevGattDescriptor +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size, max is 0x200. +## diff --git a/src/libnx/wrapper/switch/runtime/devices/console.h b/src/libnx/wrapper/switch/runtime/devices/console.h new file mode 100644 index 0000000..515105c --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/console.h @@ -0,0 +1,190 @@ +/** + * @file console.h + * @brief Framebuffer text console. + * @author yellows8 + * @author WinterMute + * @copyright libnx Authors + * + * Provides stdio integration for printing to the Switch screen as well as debug print + * functionality provided by stderr. + * + * General usage is to initialize the console by: + * @code + * consoleInit(NULL) + * @endcode + * optionally customizing the console usage by passing a pointer to a custom PrintConsole struct. + */ +#pragma once +#include "../../types.h" + +#define CONSOLE_ESC(x) "\x1b[" #x +#define CONSOLE_RESET CONSOLE_ESC(0m) +#define CONSOLE_BLACK CONSOLE_ESC(30m) +#define CONSOLE_RED CONSOLE_ESC(31;1m) +#define CONSOLE_GREEN CONSOLE_ESC(32;1m) +#define CONSOLE_YELLOW CONSOLE_ESC(33;1m) +#define CONSOLE_BLUE CONSOLE_ESC(34;1m) +#define CONSOLE_MAGENTA CONSOLE_ESC(35;1m) +#define CONSOLE_CYAN CONSOLE_ESC(36;1m) +#define CONSOLE_WHITE CONSOLE_ESC(37;1m) + +// Forward declaration +typedef struct PrintConsole PrintConsole; + +/// Renderer interface for the console. +typedef struct ConsoleRenderer +{ + bool (*init)(PrintConsole* con); + void (*deinit)(PrintConsole* con); + void (*drawChar)(PrintConsole* con, int x, int y, int c); + void (*scrollWindow)(PrintConsole* con); + void (*flushAndSwap)(PrintConsole* con); +} ConsoleRenderer; + +/// A font struct for the console. +typedef struct ConsoleFont +{ + const void* gfx; ///< A pointer to the font graphics + u16 asciiOffset; ///< Offset to the first valid character in the font table + u16 numChars; ///< Number of characters in the font graphics + u16 tileWidth; + u16 tileHeight; +}ConsoleFont; + +/** + * @brief Console structure used to store the state of a console render context. + * + * Default values from consoleGetDefault(); + * @code + * PrintConsole defaultConsole = + * { + * //Font: + * { + * default_font_bin, //font gfx + * 0, //first ascii character in the set + * 256, //number of characters in the font set + * 16, //tile width + * 16, //tile height + * }, + * NULL, //renderer + * 0,0, //cursorX cursorY + * 0,0, //prevcursorX prevcursorY + * 80, //console width + * 45, //console height + * 0, //window x + * 0, //window y + * 80, //window width + * 45, //window height + * 3, //tab size + * 7, // foreground color + * 0, // background color + * 0, // flags + * false //console initialized + * }; + * @endcode + */ +struct PrintConsole +{ + ConsoleFont font; ///< Font of the console + ConsoleRenderer* renderer; ///< Renderer of the console + + int cursorX; ///< Current X location of the cursor (as a tile offset by default) + int cursorY; ///< Current Y location of the cursor (as a tile offset by default) + + int prevCursorX; ///< Internal state + int prevCursorY; ///< Internal state + + int consoleWidth; ///< Width of the console hardware layer in characters + int consoleHeight; ///< Height of the console hardware layer in characters + + int windowX; ///< Window X location in characters + int windowY; ///< Window Y location in characters + int windowWidth; ///< Window width in characters + int windowHeight; ///< Window height in characters + + int tabSize; ///< Size of a tab + u16 fg; ///< Foreground color + u16 bg; ///< Background color + int flags; ///< Reverse/bright flags + + bool consoleInitialised; ///< True if the console is initialized +}; + +#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text +#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text +#define CONSOLE_ITALIC (1<<2) ///< Italic text +#define CONSOLE_UNDERLINE (1<<3) ///< Underlined text +#define CONSOLE_BLINK_SLOW (1<<4) ///< Slow blinking text +#define CONSOLE_BLINK_FAST (1<<5) ///< Fast blinking text +#define CONSOLE_COLOR_REVERSE (1<<6) ///< Reversed color text +#define CONSOLE_CONCEAL (1<<7) ///< Concealed text +#define CONSOLE_CROSSED_OUT (1<<8) ///< Crossed out text +#define CONSOLE_FG_CUSTOM (1<<9) ///< Foreground custom color +#define CONSOLE_BG_CUSTOM (1<<10) ///< Background custom color + +/// Console debug devices supported by libnx. +typedef enum { + debugDevice_NULL, ///< Swallows prints to stderr + debugDevice_SVC, ///< Outputs stderr debug statements using svcOutputDebugString, which can then be captured by interactive debuggers + debugDevice_CONSOLE, ///< Directs stderr debug statements to Switch console window +} debugDevice; + +/** + * @brief Loads the font into the console. + * @param console Pointer to the console to update, if NULL it will update the current console. + * @param font The font to load. + */ +void consoleSetFont(PrintConsole* console, ConsoleFont* font); + +/** + * @brief Sets the print window. + * @param console Console to set, if NULL it will set the current console window. + * @param x X location of the window. + * @param y Y location of the window. + * @param width Width of the window. + * @param height Height of the window. + */ +void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height); + +/** + * @brief Gets a pointer to the console with the default values. + * This should only be used when using a single console or without changing the console that is returned, otherwise use consoleInit(). + * @return A pointer to the console with the default values. + */ +PrintConsole* consoleGetDefault(void); + +/** + * @brief Make the specified console the render target. + * @param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)). + * @return A pointer to the previous console. + */ +PrintConsole *consoleSelect(PrintConsole* console); + +/** + * @brief Initialise the console. + * @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). + * @return A pointer to the current console. + */ +PrintConsole* consoleInit(PrintConsole* console); + +/** + * @brief Deinitialise the console. + * @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). + */ +void consoleExit(PrintConsole* console); + +/** + * @brief Updates the console, submitting a new frame to the display. + * @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). + * @remark This function should be called periodically. Failure to call this function will result in lack of screen updating. + */ +void consoleUpdate(PrintConsole* console); + +/** + * @brief Initializes debug console output on stderr to the specified device. + * @param device The debug device (or devices) to output debug print statements to. + */ +void consoleDebugInit(debugDevice device); + +/// Clears the screan by using printf("\x1b[2J"); +void consoleClear(void); diff --git a/src/libnx/wrapper/switch/runtime/devices/console.nim b/src/libnx/wrapper/switch/runtime/devices/console.nim new file mode 100644 index 0000000..f4f2787 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/console.nim @@ -0,0 +1,190 @@ +## * +## @file console.h +## @brief Framebuffer text console. +## @author yellows8 +## @author WinterMute +## @copyright libnx Authors +## +## Provides stdio integration for printing to the Switch screen as well as debug print +## functionality provided by stderr. +## +## General usage is to initialize the console by: +## @code +## consoleInit(NULL) +## @endcode +## optionally customizing the console usage by passing a pointer to a custom PrintConsole struct. +## + +import + ../../types + +template CONSOLE_ESC*(x: string): string = + ("\x1b[" & x) + +const + CONSOLE_RESET* = "0m".CONSOLE_ESC + CONSOLE_BLACK* = "30m".CONSOLE_ESC + CONSOLE_RED* = "31;1m".CONSOLE_ESC + CONSOLE_GREEN* = "32;1m".CONSOLE_ESC + CONSOLE_YELLOW* = "33;1m".CONSOLE_ESC + CONSOLE_BLUE* = "34;1m".CONSOLE_ESC + CONSOLE_MAGENTA* = "35;1m".CONSOLE_ESC + CONSOLE_CYAN* = "36;1m".CONSOLE_ESC + CONSOLE_WHITE* = "37;1m".CONSOLE_ESC + +## Forward declaration + + +## / Renderer interface for the console. + +type + ConsoleRenderer* {.bycopy.} = object + init*: proc (con: ptr PrintConsole): bool {.cdecl.} + deinit*: proc (con: ptr PrintConsole) {.cdecl.} + drawChar*: proc (con: ptr PrintConsole; x: cint; y: cint; c: cint) {.cdecl.} + scrollWindow*: proc (con: ptr PrintConsole) {.cdecl.} + flushAndSwap*: proc (con: ptr PrintConsole) {.cdecl.} + + PrintConsole* {.bycopy.} = object + ## * + ## @brief Console structure used to store the state of a console render context. + ## + ## Default values from consoleGetDefault(); + ## @code + ## PrintConsole defaultConsole = + ## { + ## //Font: + ## { + ## default_font_bin, //font gfx + ## 0, //first ascii character in the set + ## 256, //number of characters in the font set + ## 16, //tile width + ## 16, //tile height + ## }, + ## NULL, //renderer + ## 0,0, //cursorX cursorY + ## 0,0, //prevcursorX prevcursorY + ## 80, //console width + ## 45, //console height + ## 0, //window x + ## 0, //window y + ## 80, //window width + ## 45, //window height + ## 3, //tab size + ## 7, // foreground color + ## 0, // background color + ## 0, // flags + ## false //console initialized + ## }; + ## @endcode + ## + font*: ConsoleFont ## /< Font of the console + renderer*: ptr ConsoleRenderer ## /< Renderer of the console + cursorX*: cint ## /< Current X location of the cursor (as a tile offset by default) + cursorY*: cint ## /< Current Y location of the cursor (as a tile offset by default) + prevCursorX*: cint ## /< Internal state + prevCursorY*: cint ## /< Internal state + consoleWidth*: cint ## /< Width of the console hardware layer in characters + consoleHeight*: cint ## /< Height of the console hardware layer in characters + windowX*: cint ## /< Window X location in characters + windowY*: cint ## /< Window Y location in characters + windowWidth*: cint ## /< Window width in characters + windowHeight*: cint ## /< Window height in characters + tabSize*: cint ## /< Size of a tab + fg*: U16 ## /< Foreground color + bg*: U16 ## /< Background color + flags*: cint ## /< Reverse/bright flags + consoleInitialised*: bool ## /< True if the console is initialized + + ConsoleFont* {.bycopy.} = object + ## / A font struct for the console. + gfx*: pointer ## /< A pointer to the font graphics + asciiOffset*: U16 ## /< Offset to the first valid character in the font table + numChars*: U16 ## /< Number of characters in the font graphics + tileWidth*: U16 + tileHeight*: U16 + +const + CONSOLE_COLOR_BOLD* = (1 shl 0) ## /< Bold text + CONSOLE_COLOR_FAINT* = (1 shl 1) ## /< Faint text + CONSOLE_ITALIC* = (1 shl 2) ## /< Italic text + CONSOLE_UNDERLINE* = (1 shl 3) ## /< Underlined text + CONSOLE_BLINK_SLOW* = (1 shl 4) ## /< Slow blinking text + CONSOLE_BLINK_FAST* = (1 shl 5) ## /< Fast blinking text + CONSOLE_COLOR_REVERSE* = (1 shl 6) ## /< Reversed color text + CONSOLE_CONCEAL* = (1 shl 7) ## /< Concealed text + CONSOLE_CROSSED_OUT* = (1 shl 8) ## /< Crossed out text + CONSOLE_FG_CUSTOM* = (1 shl 9) ## /< Foreground custom color + CONSOLE_BG_CUSTOM* = (1 shl 10) ## /< Background custom color + +## / Console debug devices supported by libnx. + +type + DebugDevice* = enum + debugDeviceNULL, ## /< Swallows prints to stderr + debugDeviceSVC, ## /< Outputs stderr debug statements using svcOutputDebugString, which can then be captured by interactive debuggers + debugDeviceCONSOLE ## /< Directs stderr debug statements to Switch console window + +proc consoleSetFont*(console: ptr PrintConsole; font: ptr ConsoleFont) {.cdecl, + importc: "consoleSetFont".} +## * +## @brief Loads the font into the console. +## @param console Pointer to the console to update, if NULL it will update the current console. +## @param font The font to load. +## + +proc consoleSetWindow*(console: ptr PrintConsole; x: cint; y: cint; width: cint; + height: cint) {.cdecl, importc: "consoleSetWindow".} +## * +## @brief Sets the print window. +## @param console Console to set, if NULL it will set the current console window. +## @param x X location of the window. +## @param y Y location of the window. +## @param width Width of the window. +## @param height Height of the window. +## + +proc consoleGetDefault*(): ptr PrintConsole {.cdecl, importc: "consoleGetDefault".} +## * +## @brief Gets a pointer to the console with the default values. +## This should only be used when using a single console or without changing the console that is returned, otherwise use consoleInit(). +## @return A pointer to the console with the default values. +## + +proc consoleSelect*(console: ptr PrintConsole): ptr PrintConsole {.cdecl, + importc: "consoleSelect".} +## * +## @brief Make the specified console the render target. +## @param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)). +## @return A pointer to the previous console. +## + +proc consoleInit*(console: ptr PrintConsole): ptr PrintConsole {.cdecl, + importc: "consoleInit".} +## * +## @brief Initialise the console. +## @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). +## @return A pointer to the current console. +## + +proc consoleExit*(console: ptr PrintConsole) {.cdecl, importc: "consoleExit".} +## * +## @brief Deinitialise the console. +## @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). +## + +proc consoleUpdate*(console: ptr PrintConsole) {.cdecl, importc: "consoleUpdate".} +## * +## @brief Updates the console, submitting a new frame to the display. +## @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). +## @remark This function should be called periodically. Failure to call this function will result in lack of screen updating. +## + +proc consoleDebugInit*(device: DebugDevice) {.cdecl, importc: "consoleDebugInit".} +## * +## @brief Initializes debug console output on stderr to the specified device. +## @param device The debug device (or devices) to output debug print statements to. +## + +proc consoleClear*() {.cdecl, importc: "consoleClear".} +## / Clears the screan by using printf("\x1b[2J"); diff --git a/src/libnx/wrapper/switch/runtime/devices/fs_dev.h b/src/libnx/wrapper/switch/runtime/devices/fs_dev.h new file mode 100644 index 0000000..881d1af --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/fs_dev.h @@ -0,0 +1,95 @@ +/** + * @file fs_dev.h + * @brief FS driver, using devoptab. + * @author yellows8 + * @author mtheall + * @copyright libnx Authors + */ +#pragma once + +#include +#include "../../services/fs.h" + +#define FSDEV_DIRITER_MAGIC 0x66736476 ///< "fsdv" + +/// Open directory struct +typedef struct +{ + u32 magic; ///< "fsdv" + FsDir fd; ///< File descriptor + ssize_t index; ///< Current entry index + size_t size; ///< Current batch size +} fsdev_dir_t; + +/// Retrieves a pointer to temporary stage for reading entries +NX_CONSTEXPR FsDirectoryEntry* fsdevDirGetEntries(fsdev_dir_t *dir) +{ + return (FsDirectoryEntry*)(void*)(dir+1); +} + +/// Initializes and mounts the sdmc device if accessible. +Result fsdevMountSdmc(void); + +/// Mounts the specified SaveData. +Result fsdevMountSaveData(const char *name, u64 application_id, AccountUid uid); + +/// Mounts the specified SaveData as ReadOnly. +/// Only available on [2.0.0+]. +Result fsdevMountSaveDataReadOnly(const char *name, u64 application_id, AccountUid uid); + +/// Mounts the specified BcatSaveData. +Result fsdevMountBcatSaveData(const char *name, u64 application_id); + +/// Mounts the specified DeviceSaveData. +Result fsdevMountDeviceSaveData(const char *name, u64 application_id); + +/// Mounts the TemporaryStorage for the current process. +/// Only available on [3.0.0+]. +Result fsdevMountTemporaryStorage(const char *name); + +/// Mounts the specified CacheStorage. +/// Only available on [3.0.0+]. +Result fsdevMountCacheStorage(const char *name, u64 application_id, u16 save_data_index); + +/// Mounts the specified SystemSaveData. +Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid); + +/// Mounts the specified SystemBcatSaveData. +/// Only available on [4.0.0+]. +Result fsdevMountSystemBcatSaveData(const char *name, u64 system_save_data_id); + +/// Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails. +/// Returns -1 when any errors occur. +/// Input device name string shouldn't exceed 31 characters, and shouldn't have a trailing colon. +int fsdevMountDevice(const char *name, FsFileSystem fs); + +/// Unmounts the specified device. +int fsdevUnmountDevice(const char *name); + +/// Uses fsFsCommit() with the specified device. This must be used after any savedata-write operations(not just file-write). This should be used after each file-close where file-writing was done. +/// This is not used automatically at device unmount. +Result fsdevCommitDevice(const char *name); + +/// Returns the FsFileSystem for the specified device. Returns NULL when the specified device isn't found. +FsFileSystem* fsdevGetDeviceFileSystem(const char *name); + +/// Writes the FS-path to outpath (which has buffer size FS_MAX_PATH), for the input path (as used in stdio). The FsFileSystem is also written to device when not NULL. +int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath); + +/// This calls fsFsSetConcatenationFileAttribute on the filesystem specified by the input path (as used in stdio). +Result fsdevSetConcatenationFileAttribute(const char *path); + +// Uses \ref fsFsIsValidSignedSystemPartitionOnSdCard with the specified device. +Result fsdevIsValidSignedSystemPartitionOnSdCard(const char *name, bool *out); + +/// This calls fsFsCreateFile on the filesystem specified by the input path (as used in stdio). +Result fsdevCreateFile(const char* path, size_t size, u32 flags); + +/// Recursively deletes the directory specified by the input path (as used in stdio). +Result fsdevDeleteDirectoryRecursively(const char *path); + +/// Unmounts all devices and cleans up any resources used by the FS driver. +Result fsdevUnmountAll(void); + +/// Retrieves the last native result code generated during a failed fsdev operation. +Result fsdevGetLastResult(void); diff --git a/src/libnx/wrapper/switch/runtime/devices/fs_dev.nim b/src/libnx/wrapper/switch/runtime/devices/fs_dev.nim new file mode 100644 index 0000000..85d7d76 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/fs_dev.nim @@ -0,0 +1,112 @@ +## * +## @file fs_dev.h +## @brief FS driver, using devoptab. +## @author yellows8 +## @author mtheall +## @copyright libnx Authors +## + +import ../../types +import + ../../services/fs, + ../../services/acc + +const + FSDEV_DIRITER_MAGIC* = 0x66736476 + +## / Open directory struct + +type + FsdevDirT* {.bycopy.} = object + magic*: U32 ## /< "fsdv" + fd*: FsDir ## /< File descriptor + index*: SsizeT ## /< Current entry index + size*: csize_t ## /< Current batch size + +proc fsdevDirGetEntries*(dir: ptr FsdevDirT): ptr FsDirectoryEntry {.inline, cdecl.} = + ## / Retrieves a pointer to temporary stage for reading entries + return cast[ptr FsDirectoryEntry](cast[pointer]((cast[int](dir) + 1))) + +proc fsdevMountSdmc*(): Result {.cdecl, importc: "fsdevMountSdmc".} +## / Initializes and mounts the sdmc device if accessible. + +proc fsdevMountSaveData*(name: cstring; applicationId: U64; uid: AccountUid): Result {. + cdecl, importc: "fsdevMountSaveData".} +## / Mounts the specified SaveData. + +proc fsdevMountSaveDataReadOnly*(name: cstring; applicationId: U64; uid: AccountUid): Result {. + cdecl, importc: "fsdevMountSaveDataReadOnly".} +## / Mounts the specified SaveData as ReadOnly. +## / Only available on [2.0.0+]. + +proc fsdevMountBcatSaveData*(name: cstring; applicationId: U64): Result {.cdecl, + importc: "fsdevMountBcatSaveData".} +## / Mounts the specified BcatSaveData. + +proc fsdevMountDeviceSaveData*(name: cstring; applicationId: U64): Result {.cdecl, + importc: "fsdevMountDeviceSaveData".} +## / Mounts the specified DeviceSaveData. + +proc fsdevMountTemporaryStorage*(name: cstring): Result {.cdecl, + importc: "fsdevMountTemporaryStorage".} +## / Mounts the TemporaryStorage for the current process. +## / Only available on [3.0.0+]. + +proc fsdevMountCacheStorage*(name: cstring; applicationId: U64; saveDataIndex: U16): Result {. + cdecl, importc: "fsdevMountCacheStorage".} +## / Mounts the specified CacheStorage. +## / Only available on [3.0.0+]. + +proc fsdevMountSystemSaveData*(name: cstring; saveDataSpaceId: FsSaveDataSpaceId; + systemSaveDataId: U64; uid: AccountUid): Result {. + cdecl, importc: "fsdevMountSystemSaveData".} +## / Mounts the specified SystemSaveData. + +proc fsdevMountSystemBcatSaveData*(name: cstring; systemSaveDataId: U64): Result {. + cdecl, importc: "fsdevMountSystemBcatSaveData".} +## / Mounts the specified SystemBcatSaveData. +## / Only available on [4.0.0+]. + +proc fsdevMountDevice*(name: cstring; fs: FsFileSystem): cint {.cdecl, + importc: "fsdevMountDevice".} +## / Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails. +## / Returns -1 when any errors occur. +## / Input device name string shouldn't exceed 31 characters, and shouldn't have a trailing colon. + +proc fsdevUnmountDevice*(name: cstring): cint {.cdecl, importc: "fsdevUnmountDevice".} +## / Unmounts the specified device. + +proc fsdevCommitDevice*(name: cstring): Result {.cdecl, importc: "fsdevCommitDevice".} +## / Uses fsFsCommit() with the specified device. This must be used after any savedata-write operations(not just file-write). This should be used after each file-close where file-writing was done. +## / This is not used automatically at device unmount. + +proc fsdevGetDeviceFileSystem*(name: cstring): ptr FsFileSystem {.cdecl, + importc: "fsdevGetDeviceFileSystem".} +## / Returns the FsFileSystem for the specified device. Returns NULL when the specified device isn't found. + +proc fsdevTranslatePath*(path: cstring; device: ptr ptr FsFileSystem; outpath: cstring): cint {. + cdecl, importc: "fsdevTranslatePath".} +## / Writes the FS-path to outpath (which has buffer size FS_MAX_PATH), for the input path (as used in stdio). The FsFileSystem is also written to device when not NULL. + +proc fsdevSetConcatenationFileAttribute*(path: cstring): Result {.cdecl, + importc: "fsdevSetConcatenationFileAttribute".} +## / This calls fsFsSetConcatenationFileAttribute on the filesystem specified by the input path (as used in stdio). + +proc fsdevIsValidSignedSystemPartitionOnSdCard*(name: cstring; `out`: ptr bool): Result {. + cdecl, importc: "fsdevIsValidSignedSystemPartitionOnSdCard".} +## Uses \ref fsFsIsValidSignedSystemPartitionOnSdCard with the specified device. + +proc fsdevCreateFile*(path: cstring; size: csize_t; flags: U32): Result {.cdecl, + importc: "fsdevCreateFile".} +## / This calls fsFsCreateFile on the filesystem specified by the input path (as used in stdio). + +proc fsdevDeleteDirectoryRecursively*(path: cstring): Result {.cdecl, + importc: "fsdevDeleteDirectoryRecursively".} +## / Recursively deletes the directory specified by the input path (as used in stdio). + +proc fsdevUnmountAll*(): Result {.cdecl, importc: "fsdevUnmountAll".} +## / Unmounts all devices and cleans up any resources used by the FS driver. + +proc fsdevGetLastResult*(): Result {.cdecl, importc: "fsdevGetLastResult".} +## / Retrieves the last native result code generated during a failed fsdev operation. + diff --git a/src/libnx/wrapper/switch/runtime/devices/romfs_dev.h b/src/libnx/wrapper/switch/runtime/devices/romfs_dev.h new file mode 100644 index 0000000..63a0786 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/romfs_dev.h @@ -0,0 +1,122 @@ +/** + * @file romfs_dev.h + * @brief RomFS driver. + * @author yellows8 + * @author mtheall + * @author fincs + * @copyright libnx Authors + */ +#pragma once + +#include "../../types.h" +#include "../../services/fs.h" +#include "../../services/ncm_types.h" + +/// RomFS header. +typedef struct +{ + u64 headerSize; ///< Size of the header. + u64 dirHashTableOff; ///< Offset of the directory hash table. + u64 dirHashTableSize; ///< Size of the directory hash table. + u64 dirTableOff; ///< Offset of the directory table. + u64 dirTableSize; ///< Size of the directory table. + u64 fileHashTableOff; ///< Offset of the file hash table. + u64 fileHashTableSize; ///< Size of the file hash table. + u64 fileTableOff; ///< Offset of the file table. + u64 fileTableSize; ///< Size of the file table. + u64 fileDataOff; ///< Offset of the file data. +} romfs_header; + +/// RomFS directory. +typedef struct +{ + u32 parent; ///< Offset of the parent directory. + u32 sibling; ///< Offset of the next sibling directory. + u32 childDir; ///< Offset of the first child directory. + u32 childFile; ///< Offset of the first file. + u32 nextHash; ///< Directory hash table pointer. + u32 nameLen; ///< Name length. + uint8_t name[]; ///< Name. (UTF-8) +} romfs_dir; + +/// RomFS file. +typedef struct +{ + u32 parent; ///< Offset of the parent directory. + u32 sibling; ///< Offset of the next sibling file. + u64 dataOff; ///< Offset of the file's data. + u64 dataSize; ///< Length of the file's data. + u32 nextHash; ///< File hash table pointer. + u32 nameLen; ///< Name length. + uint8_t name[]; ///< Name. (UTF-8) +} romfs_file; + +/** + * @brief Mounts the Application's RomFS. + * @param name Device mount name. + * @remark This function is intended to be used to access one's own RomFS. + * If the application is running as NRO, it mounts the embedded RomFS section inside the NRO. + * If on the other hand it's an NSO, it behaves identically to \ref romfsMountFromCurrentProcess. + */ +Result romfsMountSelf(const char *name); + +/** + * @brief Mounts RomFS from an open file. + * @param file FsFile of the RomFS image. + * @param offset Offset of the RomFS within the file. + * @param name Device mount name. + */ +Result romfsMountFromFile(FsFile file, u64 offset, const char *name); + +/** + * @brief Mounts RomFS from an open storage. + * @param storage FsStorage of the RomFS image. + * @param offset Offset of the RomFS within the storage. + * @param name Device mount name. + */ +Result romfsMountFromStorage(FsStorage storage, u64 offset, const char *name); + +/** + * @brief Mounts RomFS using the current process host program RomFS. + * @param name Device mount name. + */ +Result romfsMountFromCurrentProcess(const char *name); + +/** + * @brief Mounts RomFS of a running program. + * @note Permission needs to be set in the NPDM. + * @param program_id ProgramId to mount. + * @param name Device mount name. + */ +Result romfsMountDataStorageFromProgram(u64 program_id, const char *name); + +/** + * @brief Mounts RomFS from a file path in a mounted fsdev device. + * @param path File path. + * @param offset Offset of the RomFS within the file. + * @param name Device mount name. + */ +Result romfsMountFromFsdev(const char *path, u64 offset, const char *name); + +/** + * @brief Mounts RomFS from SystemData. + * @param dataId SystemDataId to mount. + * @param storageId Storage ID to mount from. + * @param name Device mount name. + */ +Result romfsMountFromDataArchive(u64 dataId, NcmStorageId storageId, const char *name); + +/// Unmounts the RomFS device. +Result romfsUnmount(const char *name); + +/// Wrapper for \ref romfsMountSelf with the default "romfs" device name. +static inline Result romfsInit(void) +{ + return romfsMountSelf("romfs"); +} + +/// Wrapper for \ref romfsUnmount with the default "romfs" device name. +static inline Result romfsExit(void) +{ + return romfsUnmount("romfs"); +} diff --git a/src/libnx/wrapper/switch/runtime/devices/romfs_dev.nim b/src/libnx/wrapper/switch/runtime/devices/romfs_dev.nim new file mode 100644 index 0000000..2db039d --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/romfs_dev.nim @@ -0,0 +1,126 @@ +## * +## @file romfs_dev.h +## @brief RomFS driver. +## @author yellows8 +## @author mtheall +## @author fincs +## @copyright libnx Authors +## + +import + ../../types, ../../services/fs, ../../services/ncm_types + +## / RomFS header. + +type + RomfsHeader* {.bycopy.} = object + headerSize*: U64 ## /< Size of the header. + dirHashTableOff*: U64 ## /< Offset of the directory hash table. + dirHashTableSize*: U64 ## /< Size of the directory hash table. + dirTableOff*: U64 ## /< Offset of the directory table. + dirTableSize*: U64 ## /< Size of the directory table. + fileHashTableOff*: U64 ## /< Offset of the file hash table. + fileHashTableSize*: U64 ## /< Size of the file hash table. + fileTableOff*: U64 ## /< Offset of the file table. + fileTableSize*: U64 ## /< Size of the file table. + fileDataOff*: U64 ## /< Offset of the file data. + + +## / RomFS directory. + +type + RomfsDir* {.bycopy.} = object + parent*: U32 ## /< Offset of the parent directory. + sibling*: U32 ## /< Offset of the next sibling directory. + childDir*: U32 ## /< Offset of the first child directory. + childFile*: U32 ## /< Offset of the first file. + nextHash*: U32 ## /< Directory hash table pointer. + nameLen*: U32 ## /< Name length. + name*: UncheckedArray[uint8] ## /< Name. (UTF-8) + + +## / RomFS file. + +type + RomfsFile* {.bycopy.} = object + parent*: U32 ## /< Offset of the parent directory. + sibling*: U32 ## /< Offset of the next sibling file. + dataOff*: U64 ## /< Offset of the file's data. + dataSize*: U64 ## /< Length of the file's data. + nextHash*: U32 ## /< File hash table pointer. + nameLen*: U32 ## /< Name length. + name*: UncheckedArray[uint8] ## /< Name. (UTF-8) + +proc romfsMountSelf*(name: cstring): Result {.cdecl, importc: "romfsMountSelf".} +## * +## @brief Mounts the Application's RomFS. +## @param name Device mount name. +## @remark This function is intended to be used to access one's own RomFS. +## If the application is running as NRO, it mounts the embedded RomFS section inside the NRO. +## If on the other hand it's an NSO, it behaves identically to \ref romfsMountFromCurrentProcess. +## + +proc romfsMountFromFile*(file: FsFile; offset: U64; name: cstring): Result {.cdecl, + importc: "romfsMountFromFile".} +## * +## @brief Mounts RomFS from an open file. +## @param file FsFile of the RomFS image. +## @param offset Offset of the RomFS within the file. +## @param name Device mount name. +## + +proc romfsMountFromStorage*(storage: FsStorage; offset: U64; name: cstring): Result {. + cdecl, importc: "romfsMountFromStorage".} +## * +## @brief Mounts RomFS from an open storage. +## @param storage FsStorage of the RomFS image. +## @param offset Offset of the RomFS within the storage. +## @param name Device mount name. +## + +proc romfsMountFromCurrentProcess*(name: cstring): Result {.cdecl, + importc: "romfsMountFromCurrentProcess".} +## * +## @brief Mounts RomFS using the current process host program RomFS. +## @param name Device mount name. +## + +proc romfsMountDataStorageFromProgram*(programId: U64; name: cstring): Result {.cdecl, + importc: "romfsMountDataStorageFromProgram".} +## * +## @brief Mounts RomFS of a running program. +## @note Permission needs to be set in the NPDM. +## @param program_id ProgramId to mount. +## @param name Device mount name. +## + +proc romfsMountFromFsdev*(path: cstring; offset: U64; name: cstring): Result {.cdecl, + importc: "romfsMountFromFsdev".} +## * +## @brief Mounts RomFS from a file path in a mounted fsdev device. +## @param path File path. +## @param offset Offset of the RomFS within the file. +## @param name Device mount name. +## + +proc romfsMountFromDataArchive*(dataId: U64; storageId: NcmStorageId; name: cstring): Result {. + cdecl, importc: "romfsMountFromDataArchive".} +## * +## @brief Mounts RomFS from SystemData. +## @param dataId SystemDataId to mount. +## @param storageId Storage ID to mount from. +## @param name Device mount name. +## + +proc romfsUnmount*(name: cstring): Result {.cdecl, importc: "romfsUnmount".} +## / Unmounts the RomFS device. + +proc romfsInit*(): Result {.inline, cdecl.} = + ## / Wrapper for \ref romfsMountSelf with the default "romfs" device name. + + return romfsMountSelf("romfs") + +proc romfsExit*(): Result {.inline, cdecl.} = + ## / Wrapper for \ref romfsUnmount with the default "romfs" device name. + + return romfsUnmount("romfs") diff --git a/src/libnx/wrapper/switch/runtime/devices/socket.h b/src/libnx/wrapper/switch/runtime/devices/socket.h new file mode 100644 index 0000000..ad99be4 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/socket.h @@ -0,0 +1,54 @@ +#pragma once +#include "../../types.h" + +/// BSD service type used by the socket driver. +typedef enum { + BsdServiceType_User = BIT(0), ///< Uses bsd:u (default). + BsdServiceType_System = BIT(1), ///< Uses bsd:s. + BsdServiceType_Auto = BsdServiceType_User | BsdServiceType_System, ///< Tries to use bsd:s first, and if that fails uses bsd:u (official software behavior). +} BsdServiceType; + +/// Configuration structure for socketInitalize +typedef struct { + u32 bsdsockets_version; ///< Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. + + u32 tcp_tx_buf_size; ///< Size of the TCP transfer (send) buffer (initial or fixed). + u32 tcp_rx_buf_size; ///< Size of the TCP receive buffer (initial or fixed). + u32 tcp_tx_buf_max_size; ///< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + u32 tcp_rx_buf_max_size; ///< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + + u32 udp_tx_buf_size; ///< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + u32 udp_rx_buf_size; ///< Size of the UDP receive buffer (typically 0xA500 bytes). + + u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). + + u32 num_bsd_sessions; ///< Number of BSD service sessions (typically 3). + BsdServiceType bsd_service_type; ///< BSD service type (typically \ref BsdServiceType_User). +} SocketInitConfig; + +/// Fetch the default configuration for the socket driver. +const SocketInitConfig *socketGetDefaultInitConfig(void); +/// Initalize the socket driver. +Result socketInitialize(const SocketInitConfig *config); +/// Fetch the last bsd:u/s Switch result code (thread-local). +Result socketGetLastResult(void); +/// Deinitialize the socket driver. +void socketExit(void); + +/// Initalize the socket driver using the default configuration. +NX_INLINE Result socketInitializeDefault(void) { + return socketInitialize(NULL); +} + +/// Wrapper for \ref sslConnectionSetSocketDescriptor. Returns the output sockfd on success and -1 on error. errno==ENOENT indicates that no sockfd was returned, this error must be ignored. +int socketSslConnectionSetSocketDescriptor(SslConnection *c, int sockfd); + +/// Wrapper for \ref sslConnectionGetSocketDescriptor. Returns the output sockfd on success and -1 on error. +int socketSslConnectionGetSocketDescriptor(SslConnection *c); + +/// Wrapper for \ref nifmRequestRegisterSocketDescriptor. Returns 0 on success and -1 on error. +int socketNifmRequestRegisterSocketDescriptor(NifmRequest* r, int sockfd); + +/// Wrapper for \ref nifmRequestUnregisterSocketDescriptor. Returns 0 on success and -1 on error. +int socketNifmRequestUnregisterSocketDescriptor(NifmRequest* r, int sockfd); + diff --git a/src/libnx/wrapper/switch/runtime/devices/socket.nim b/src/libnx/wrapper/switch/runtime/devices/socket.nim new file mode 100644 index 0000000..ebbe200 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/socket.nim @@ -0,0 +1,61 @@ +import + ../../types, ../../services/ssl, ../../services/nifm + +## / BSD service type used by the socket driver. + +type + BsdServiceType* = enum + BsdServiceTypeUser = bit(0), ## /< Uses bsd:u (default). + BsdServiceTypeSystem = bit(1), ## /< Uses bsd:s. + BsdServiceTypeAuto = BsdServiceTypeUser.int or BsdServiceTypeSystem.int ## /< Tries to use bsd:s first, and if that fails uses bsd:u (official software behavior). + + +## / Configuration structure for socketInitalize + +type + SocketInitConfig* {.bycopy.} = object + bsdsocketsVersion*: U32 ## /< Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. + tcpTxBufSize*: U32 ## /< Size of the TCP transfer (send) buffer (initial or fixed). + tcpRxBufSize*: U32 ## /< Size of the TCP receive buffer (initial or fixed). + tcpTxBufMaxSize*: U32 ## /< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + tcpRxBufMaxSize*: U32 ## /< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + udpTxBufSize*: U32 ## /< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + udpRxBufSize*: U32 ## /< Size of the UDP receive buffer (typically 0xA500 bytes). + sbEfficiency*: U32 ## /< Number of buffers for each socket (standard values range from 1 to 8). + numBsdSessions*: U32 ## /< Number of BSD service sessions (typically 3). + bsdServiceType*: BsdServiceType ## /< BSD service type (typically \ref BsdServiceType_User). + +proc socketGetDefaultInitConfig*(): ptr SocketInitConfig {.cdecl, + importc: "socketGetDefaultInitConfig".} +## / Fetch the default configuration for the socket driver. + +proc socketInitialize*(config: ptr SocketInitConfig): Result {.cdecl, + importc: "socketInitialize".} +## / Initalize the socket driver. + +proc socketGetLastResult*(): Result {.cdecl, importc: "socketGetLastResult".} +## / Fetch the last bsd:u/s Switch result code (thread-local). + +proc socketExit*() {.cdecl, importc: "socketExit".} +## / Deinitialize the socket driver. + +proc socketInitializeDefault*(): Result {.inline, cdecl.} = + ## / Initalize the socket driver using the default configuration. + return socketInitialize(nil) + +proc socketSslConnectionSetSocketDescriptor*(c: ptr SslConnection; sockfd: cint): cint {. + cdecl, importc: "socketSslConnectionSetSocketDescriptor".} +## / Wrapper for \ref sslConnectionSetSocketDescriptor. Returns the output sockfd on success and -1 on error. errno==ENOENT indicates that no sockfd was returned, this error must be ignored. + +proc socketSslConnectionGetSocketDescriptor*(c: ptr SslConnection): cint {.cdecl, + importc: "socketSslConnectionGetSocketDescriptor".} +## / Wrapper for \ref sslConnectionGetSocketDescriptor. Returns the output sockfd on success and -1 on error. + +proc socketNifmRequestRegisterSocketDescriptor*(r: ptr NifmRequest; sockfd: cint): cint {. + cdecl, importc: "socketNifmRequestRegisterSocketDescriptor".} +## / Wrapper for \ref nifmRequestRegisterSocketDescriptor. Returns 0 on success and -1 on error. + +proc socketNifmRequestUnregisterSocketDescriptor*(r: ptr NifmRequest; sockfd: cint): cint {. + cdecl, importc: "socketNifmRequestUnregisterSocketDescriptor".} +## / Wrapper for \ref nifmRequestUnregisterSocketDescriptor. Returns 0 on success and -1 on error. + diff --git a/src/libnx/wrapper/switch/runtime/devices/usb_comms.h b/src/libnx/wrapper/switch/runtime/devices/usb_comms.h new file mode 100644 index 0000000..9da622d --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/usb_comms.h @@ -0,0 +1,39 @@ +/** + * @file usb_comms.h + * @brief USB comms. + * @author yellows8 + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../../types.h" + +typedef struct { + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; +} UsbCommsInterfaceInfo; + +/// Initializes usbComms with the default number of interfaces (1) +Result usbCommsInitialize(void); + +/// Initializes usbComms with a specific number of interfaces. +Result usbCommsInitializeEx(u32 num_interfaces, const UsbCommsInterfaceInfo *infos); + +/// Exits usbComms. +void usbCommsExit(void); + +/// Sets whether to throw a fatal error in usbComms{Read/Write}* on failure, or just return the transferred size. By default (false) the latter is used. +void usbCommsSetErrorHandling(bool flag); + +/// Read data with the default interface. +size_t usbCommsRead(void* buffer, size_t size); + +/// Write data with the default interface. +size_t usbCommsWrite(const void* buffer, size_t size); + +/// Same as usbCommsRead except with the specified interface. +size_t usbCommsReadEx(void* buffer, size_t size, u32 interface); + +/// Same as usbCommsWrite except with the specified interface. +size_t usbCommsWriteEx(const void* buffer, size_t size, u32 interface); diff --git a/src/libnx/wrapper/switch/runtime/devices/usb_comms.nim b/src/libnx/wrapper/switch/runtime/devices/usb_comms.nim new file mode 100644 index 0000000..535841f --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/devices/usb_comms.nim @@ -0,0 +1,48 @@ +## * +## @file usb_comms.h +## @brief USB comms. +## @author yellows8 +## @author plutoo +## @copyright libnx Authors +## + +import + ../../types + +type + UsbCommsInterfaceInfo* {.bycopy.} = object + bInterfaceClass*: U8 + bInterfaceSubClass*: U8 + bInterfaceProtocol*: U8 + + +## / Initializes usbComms with the default number of interfaces (1) + +proc usbCommsInitialize*(): Result {.cdecl, importc: "usbCommsInitialize".} +## / Initializes usbComms with a specific number of interfaces. + +proc usbCommsInitializeEx*(numInterfaces: U32; infos: ptr UsbCommsInterfaceInfo): Result {. + cdecl, importc: "usbCommsInitializeEx".} +## / Exits usbComms. + +proc usbCommsExit*() {.cdecl, importc: "usbCommsExit".} +## / Sets whether to throw a fatal error in usbComms{Read/Write}* on failure, or just return the transferred size. By default (false) the latter is used. + +proc usbCommsSetErrorHandling*(flag: bool) {.cdecl, + importc: "usbCommsSetErrorHandling".} +## / Read data with the default interface. + +proc usbCommsRead*(buffer: pointer; size: csize_t): csize_t {.cdecl, + importc: "usbCommsRead".} +## / Write data with the default interface. + +proc usbCommsWrite*(buffer: pointer; size: csize_t): csize_t {.cdecl, + importc: "usbCommsWrite".} +## / Same as usbCommsRead except with the specified interface. + +proc usbCommsReadEx*(buffer: pointer; size: csize_t; `interface`: U32): csize_t {.cdecl, + importc: "usbCommsReadEx".} +## / Same as usbCommsWrite except with the specified interface. + +proc usbCommsWriteEx*(buffer: pointer; size: csize_t; `interface`: U32): csize_t {. + cdecl, importc: "usbCommsWriteEx".} diff --git a/src/libnx/wrapper/switch/runtime/diag.h b/src/libnx/wrapper/switch/runtime/diag.h new file mode 100644 index 0000000..fde2426 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/diag.h @@ -0,0 +1,15 @@ +/** + * @file diag.h + * @brief Debugging and diagnostics utilities + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../result.h" + +/** + * @brief Aborts program execution with a result code. + * @param[in] res Result code. + */ +void NORETURN diagAbortWithResult(Result res); diff --git a/src/libnx/wrapper/switch/runtime/diag.nim b/src/libnx/wrapper/switch/runtime/diag.nim new file mode 100644 index 0000000..098fbd6 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/diag.nim @@ -0,0 +1,16 @@ +## * +## @file diag.h +## @brief Debugging and diagnostics utilities +## @author fincs +## @copyright libnx Authors +## + +import + ../types, ../result + +## * +## @brief Aborts program execution with a result code. +## @param[in] res Result code. +## + +proc diagAbortWithResult*(res: Result) {.cdecl, importc: "diagAbortWithResult".} diff --git a/src/libnx/wrapper/switch/runtime/env.h b/src/libnx/wrapper/switch/runtime/env.h new file mode 100644 index 0000000..212e6f5 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/env.h @@ -0,0 +1,119 @@ +/** + * @file env.h + * @brief Homebrew environment definitions and utilities. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/acc.h" + +/// Structure representing an entry in the homebrew environment configuration. +typedef struct { + u32 Key; ///< Type of entry + u32 Flags; ///< Entry flags + u64 Value[2]; ///< Entry arguments (type-specific) +} ConfigEntry; + +/// Entry flags +enum { + EntryFlag_IsMandatory = BIT(0), ///< Specifies that the entry **must** be processed by the homebrew application. +}; + +///< Types of entry +enum { + EntryType_EndOfList=0, ///< Entry list terminator. + EntryType_MainThreadHandle=1, ///< Provides the handle to the main thread. + EntryType_NextLoadPath=2, ///< Provides a buffer containing information about the next homebrew application to load. + EntryType_OverrideHeap=3, ///< Provides heap override information. + EntryType_OverrideService=4, ///< Provides service override information. + EntryType_Argv=5, ///< Provides argv. + EntryType_SyscallAvailableHint=6, ///< Provides syscall availability hints (SVCs 0x00..0x7F). + EntryType_AppletType=7, ///< Provides APT applet type. + EntryType_AppletWorkaround=8, ///< Indicates that APT is broken and should not be used. + EntryType_Reserved9=9, ///< Unused/reserved entry type, formerly used by StdioSockets. + EntryType_ProcessHandle=10, ///< Provides the process handle. + EntryType_LastLoadResult=11, ///< Provides the last load result. + EntryType_RandomSeed=14, ///< Provides random data used to seed the pseudo-random number generator. + EntryType_UserIdStorage=15, ///< Provides persistent storage for the preselected user id. + EntryType_HosVersion=16, ///< Provides the currently running Horizon OS version. + EntryType_SyscallAvailableHint2=17, ///< Provides syscall availability hints (SVCs 0x80..0xBF). +}; + +enum { + EnvAppletFlags_ApplicationOverride = BIT(0) ///< Use AppletType_Application instead of AppletType_SystemApplication. +}; + +/// Loader return function. +typedef void NORETURN (*LoaderReturnFn)(int result_code); + +/** + * @brief Parses the homebrew loader environment block (internally called). + * @param ctx Reserved. + * @param main_thread Reserved. + * @param saved_lr Reserved. + */ +void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr); + +/// Returns information text about the loader, if present. +const char* envGetLoaderInfo(void); +/// Returns the size of the loader information text. +u64 envGetLoaderInfoSize(void); + +/// Retrieves the handle to the main thread. +Handle envGetMainThreadHandle(void); +/// Returns true if the application is running as NSO, otherwise NRO. +bool envIsNso(void); + +/// Returns true if the environment has a heap override. +bool envHasHeapOverride(void); +/// Returns the address of the overriden heap. +void* envGetHeapOverrideAddr(void); +/// Returns the size of the overriden heap. +u64 envGetHeapOverrideSize(void); + +/// Returns true if the environment has an argv array. +bool envHasArgv(void); +/// Returns the pointer to the argv array. +void* envGetArgv(void); + +/** + * @brief Returns whether a syscall is hinted to be available. + * @param svc Syscall number to test. + * @returns true if the syscall is available. + */ +bool envIsSyscallHinted(unsigned svc); + +/// Returns the handle to the running homebrew process. +Handle envGetOwnProcessHandle(void); + +/// Returns the loader's return function, to be called on program exit. +LoaderReturnFn envGetExitFuncPtr(void); + +/// Sets the return function to be called on program exit. +void envSetExitFuncPtr(LoaderReturnFn addr); + +/** + * @brief Configures the next homebrew application to load. + * @param path Path to the next homebrew application to load (.nro). + * @param argv Argument string to pass. + */ +Result envSetNextLoad(const char* path, const char* argv); + +/// Returns true if the environment supports envSetNextLoad. +bool envHasNextLoad(void); + +/// Returns the Result from the last NRO. +Result envGetLastLoadResult(void); + +/// Returns true if the environment provides a random seed. +bool envHasRandomSeed(void); + +/** + * @brief Retrieves the random seed provided by the environment. + * @param out Pointer to a u64[2] buffer which will contain the random seed on return. + */ +void envGetRandomSeed(u64 out[2]); + +/// Returns a pointer to the user id storage area (if present). +AccountUid* envGetUserIdStorage(void); diff --git a/src/libnx/wrapper/switch/runtime/env.nim b/src/libnx/wrapper/switch/runtime/env.nim new file mode 100644 index 0000000..1fb376f --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/env.nim @@ -0,0 +1,131 @@ +## * +## @file env.h +## @brief Homebrew environment definitions and utilities. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../services/acc + +## / Structure representing an entry in the homebrew environment configuration. + +type + ConfigEntry* {.bycopy.} = object + key*: U32 ## /< Type of entry + flags*: U32 ## /< Entry flags + value*: array[2, U64] ## /< Entry arguments (type-specific) + + +## / Entry flags + +const + EntryFlagIsMandatory* = bit(0) ## /< Specifies that the entry **must** be processed by the homebrew application. + +## /< Types of entry + +const + EntryTypeEndOfList* = 0 ## /< Entry list terminator. + EntryTypeMainThreadHandle* = 1 ## /< Provides the handle to the main thread. + EntryTypeNextLoadPath* = 2 ## /< Provides a buffer containing information about the next homebrew application to load. + EntryTypeOverrideHeap* = 3 ## /< Provides heap override information. + EntryTypeOverrideService* = 4 ## /< Provides service override information. + EntryTypeArgv* = 5 ## /< Provides argv. + EntryTypeSyscallAvailableHint* = 6 ## /< Provides syscall availability hints (SVCs 0x00..0x7F). + EntryTypeAppletType* = 7 ## /< Provides APT applet type. + EntryTypeAppletWorkaround* = 8 ## /< Indicates that APT is broken and should not be used. + EntryTypeReserved9* = 9 ## /< Unused/reserved entry type, formerly used by StdioSockets. + EntryTypeProcessHandle* = 10 ## /< Provides the process handle. + EntryTypeLastLoadResult* = 11 ## /< Provides the last load result. + EntryTypeRandomSeed* = 14 ## /< Provides random data used to seed the pseudo-random number generator. + EntryTypeUserIdStorage* = 15 ## /< Provides persistent storage for the preselected user id. + EntryTypeHosVersion* = 16 ## /< Provides the currently running Horizon OS version. + EntryTypeSyscallAvailableHint2* = 17 ## /< Provides syscall availability hints (SVCs 0x80..0xBF). + +const + EnvAppletFlagsApplicationOverride* = bit(0) ## /< Use AppletType_Application instead of AppletType_SystemApplication. + +## / Loader return function. + +type + LoaderReturnFn* = proc (resultCode: cint) {.cdecl.} + +## * +## @brief Parses the homebrew loader environment block (internally called). +## @param ctx Reserved. +## @param main_thread Reserved. +## @param saved_lr Reserved. +## + +proc envSetup*(ctx: pointer; mainThread: Handle; savedLr: LoaderReturnFn) {.cdecl, + importc: "envSetup".} +## / Returns information text about the loader, if present. + +proc envGetLoaderInfo*(): cstring {.cdecl, importc: "envGetLoaderInfo".} +## / Returns the size of the loader information text. + +proc envGetLoaderInfoSize*(): U64 {.cdecl, importc: "envGetLoaderInfoSize".} +## / Retrieves the handle to the main thread. + +proc envGetMainThreadHandle*(): Handle {.cdecl, importc: "envGetMainThreadHandle".} +## / Returns true if the application is running as NSO, otherwise NRO. + +proc envIsNso*(): bool {.cdecl, importc: "envIsNso".} +## / Returns true if the environment has a heap override. + +proc envHasHeapOverride*(): bool {.cdecl, importc: "envHasHeapOverride".} +## / Returns the address of the overriden heap. + +proc envGetHeapOverrideAddr*(): pointer {.cdecl, importc: "envGetHeapOverrideAddr".} +## / Returns the size of the overriden heap. + +proc envGetHeapOverrideSize*(): U64 {.cdecl, importc: "envGetHeapOverrideSize".} +## / Returns true if the environment has an argv array. + +proc envHasArgv*(): bool {.cdecl, importc: "envHasArgv".} +## / Returns the pointer to the argv array. + +proc envGetArgv*(): pointer {.cdecl, importc: "envGetArgv".} +## * +## @brief Returns whether a syscall is hinted to be available. +## @param svc Syscall number to test. +## @returns true if the syscall is available. +## + +proc envIsSyscallHinted*(svc: cuint): bool {.cdecl, importc: "envIsSyscallHinted".} +## / Returns the handle to the running homebrew process. + +proc envGetOwnProcessHandle*(): Handle {.cdecl, importc: "envGetOwnProcessHandle".} +## / Returns the loader's return function, to be called on program exit. + +proc envGetExitFuncPtr*(): LoaderReturnFn {.cdecl, importc: "envGetExitFuncPtr".} +## / Sets the return function to be called on program exit. + +proc envSetExitFuncPtr*(`addr`: LoaderReturnFn) {.cdecl, + importc: "envSetExitFuncPtr".} +## * +## @brief Configures the next homebrew application to load. +## @param path Path to the next homebrew application to load (.nro). +## @param argv Argument string to pass. +## + +proc envSetNextLoad*(path: cstring; argv: cstring): Result {.cdecl, + importc: "envSetNextLoad".} +## / Returns true if the environment supports envSetNextLoad. + +proc envHasNextLoad*(): bool {.cdecl, importc: "envHasNextLoad".} +## / Returns the Result from the last NRO. + +proc envGetLastLoadResult*(): Result {.cdecl, importc: "envGetLastLoadResult".} +## / Returns true if the environment provides a random seed. + +proc envHasRandomSeed*(): bool {.cdecl, importc: "envHasRandomSeed".} +## * +## @brief Retrieves the random seed provided by the environment. +## @param out Pointer to a u64[2] buffer which will contain the random seed on return. +## + +proc envGetRandomSeed*(`out`: array[2, U64]) {.cdecl, importc: "envGetRandomSeed".} +## / Returns a pointer to the user id storage area (if present). + +proc envGetUserIdStorage*(): ptr AccountUid {.cdecl, importc: "envGetUserIdStorage".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/runtime/hosversion.h b/src/libnx/wrapper/switch/runtime/hosversion.h new file mode 100644 index 0000000..3e79430 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/hosversion.h @@ -0,0 +1,45 @@ +/** + * @file hosversion.h + * @brief Horizon OS (HOS) version detection utilities. + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Builds a HOS version value from its constituent components. +#define MAKEHOSVERSION(_major,_minor,_micro) (((u32)(_major) << 16) | ((u32)(_minor) << 8) | (u32)(_micro)) + +/// Extracts the major number from a HOS version value. +#define HOSVER_MAJOR(_version) (((_version) >> 16) & 0xFF) + +/// Extracts the minor number from a HOS version value. +#define HOSVER_MINOR(_version) (((_version) >> 8) & 0xFF) + +/// Extracts the micro number from a HOS version value. +#define HOSVER_MICRO(_version) ( (_version) & 0xFF) + +/// Returns the current HOS version that was previously set with \ref hosversionSet. If version initialization fails during startup (such as in the case set:sys is not available), this function returns zero. +u32 hosversionGet(void); + +/// Sets or overrides the current HOS version. This function is normally called automatically by libnx on startup with the version info obtained with \ref setsysGetFirmwareVersion. +void hosversionSet(u32 version); + +/// Returns whether the current HOS version is augmented by running the Atmosphère custom firmware. +bool hosversionIsAtmosphere(void); + +/// Returns true if the current HOS version is equal to or above the specified major/minor/micro version. +static inline bool hosversionAtLeast(u8 major, u8 minor, u8 micro) { + return hosversionGet() >= MAKEHOSVERSION(major,minor,micro); +} + +/// Returns true if the current HOS version is earlier than the specified major/minor/micro version. +static inline bool hosversionBefore(u8 major, u8 minor, u8 micro) { + return !hosversionAtLeast(major, minor, micro); +} + +/// Returns true if the current HOS version is between the two specified major versions, i.e. [major1, major2). +static inline bool hosversionBetween(u8 major1, u8 major2) { + u32 ver = hosversionGet(); + return ver >= MAKEHOSVERSION(major1,0,0) && ver < MAKEHOSVERSION(major2,0,0); +} diff --git a/src/libnx/wrapper/switch/runtime/hosversion.nim b/src/libnx/wrapper/switch/runtime/hosversion.nim new file mode 100644 index 0000000..27b7720 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/hosversion.nim @@ -0,0 +1,54 @@ +## * +## @file hosversion.h +## @brief Horizon OS (HOS) version detection utilities. +## @author fincs +## @copyright libnx Authors +## + +import + ../types + + +template makehosversion*(major, minor, micro: untyped): untyped = + ## / Builds a HOS version value from its constituent components. + (((U32)(major) shl 16) or ((U32)(minor) shl 8) or (U32)(micro)) + + +template hosver_Major*(version: untyped): untyped = + ## / Extracts the major number from a HOS version value. + (((version) shr 16) and 0xFF) + + +template hosver_Minor*(version: untyped): untyped = + ## / Extracts the minor number from a HOS version value. + (((version) shr 8) and 0xFF) + + +template hosver_Micro*(version: untyped): untyped = + ## / Extracts the micro number from a HOS version value. + ((version) and 0xFF) + +proc hosversionGet*(): U32 {.cdecl, importc: "hosversionGet".} +## / Returns the current HOS version that was previously set with \ref hosversionSet. If version initialization fails during startup (such as in the case set:sys is not available), this function returns zero. + +proc hosversionSet*(version: U32) {.cdecl, importc: "hosversionSet".} +## / Sets or overrides the current HOS version. This function is normally called automatically by libnx on startup with the version info obtained with \ref setsysGetFirmwareVersion. + +proc hosversionIsAtmosphere*(): bool {.cdecl, importc: "hosversionIsAtmosphere".} +## / Returns whether the current HOS version is augmented by running the Atmosphère custom firmware. + +proc hosversionAtLeast*(major: U8; minor: U8; micro: U8): bool {.inline, cdecl.} = + ## / Returns true if the current HOS version is equal to or above the specified major/minor/micro version. + + return hosversionGet() >= makehosversion(major, minor, micro) + +proc hosversionBefore*(major: U8; minor: U8; micro: U8): bool {.inline, cdecl.} = + ## / Returns true if the current HOS version is earlier than the specified major/minor/micro version. + + return not hosversionAtLeast(major, minor, micro) + +proc hosversionBetween*(major1: U8; major2: U8): bool {.inline, cdecl.} = + ## / Returns true if the current HOS version is between the two specified major versions, i.e. [major1, major2). + + var ver: U32 = hosversionGet() + return ver >= makehosversion(major1, 0, 0) and ver < makehosversion(major2, 0, 0) diff --git a/src/libnx/wrapper/switch/runtime/nxlink.h b/src/libnx/wrapper/switch/runtime/nxlink.h new file mode 100644 index 0000000..5072a58 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/nxlink.h @@ -0,0 +1,35 @@ +/** + * @file nxlink.h + * @brief Netloader (nxlink) utilities + * @author WinterMute + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +struct in_addr; + +/// Address of the host connected through nxlink +extern struct in_addr __nxlink_host; + +#define NXLINK_SERVER_PORT 28280 ///< nxlink TCP server port +#define NXLINK_CLIENT_PORT 28771 ///< nxlink TCP client port + +/** + * @brief Connects to the nxlink host, setting up an output stream. + * @param[in] redirStdout Whether to redirect stdout to nxlink output. + * @param[in] redirStderr Whether to redirect stderr to nxlink output. + * @return Socket fd on success, negative number on failure. + * @note The socket should be closed with close() during application cleanup. + */ +int nxlinkConnectToHost(bool redirStdout, bool redirStderr); + +/// Same as \ref nxlinkConnectToHost but redirecting both stdout/stderr. +NX_INLINE int nxlinkStdio(void) { + return nxlinkConnectToHost(true, true); +} + +/// Same as \ref nxlinkConnectToHost but redirecting only stderr. +NX_INLINE int nxlinkStdioForDebug(void) { + return nxlinkConnectToHost(false, true); +} diff --git a/src/libnx/wrapper/switch/runtime/nxlink.nim b/src/libnx/wrapper/switch/runtime/nxlink.nim new file mode 100644 index 0000000..c80c023 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/nxlink.nim @@ -0,0 +1,38 @@ +## * +## @file nxlink.h +## @brief Netloader (nxlink) utilities +## @author WinterMute +## @copyright libnx Authors +## + +import + ../types + +export types + +type + InAddr* = object + +const + NXLINK_SERVER_PORT* = 28280 + NXLINK_CLIENT_PORT* = 28771 + +var nxLinkHost*{.importc: "__nxlink_host".}: InAddr + +proc nxlinkConnectToHost*(redirStdout: bool; redirStderr: bool): cint {.cdecl, + importc: "nxlinkConnectToHost".} +## * +## @brief Connects to the nxlink host, setting up an output stream. +## @param[in] redirStdout Whether to redirect stdout to nxlink output. +## @param[in] redirStderr Whether to redirect stderr to nxlink output. +## @return Socket fd on success, negative number on failure. +## @note The socket should be closed with close() during application cleanup. +## + +proc nxlinkStdio*(): cint {.inline, cdecl.} = + ## / Same as \ref nxlinkConnectToHost but redirecting both stdout/stderr. + return nxlinkConnectToHost(true, true) + +proc nxlinkStdioForDebug*(): cint {.inline, cdecl.} = + ## / Same as \ref nxlinkConnectToHost but redirecting only stderr. + return nxlinkConnectToHost(false, true) diff --git a/src/libnx/wrapper/switch/runtime/pad.h b/src/libnx/wrapper/switch/runtime/pad.h new file mode 100644 index 0000000..9f5b414 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/pad.h @@ -0,0 +1,224 @@ +/** + * @file pad.h + * @brief Simple wrapper for the HID Npad API. + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/hid.h" + +/// Mask including all existing controller IDs. +#define PAD_ANY_ID_MASK 0x1000100FFUL + +/// Pad state object. +typedef struct { + u8 id_mask; + u8 active_id_mask; + bool read_handheld; + bool active_handheld; + u32 style_set; + u32 attributes; + u64 buttons_cur; + u64 buttons_old; + HidAnalogStickState sticks[2]; + u32 gc_triggers[2]; +} PadState; + +/// Pad button repeater state object. +typedef struct { + u64 button_mask; + s32 counter; + u16 delay; + u16 repeat; +} PadRepeater; + +/** + * @brief Configures the input layout supported by the application. + * @param[in] max_players The maximum supported number of players (1 to 8). + * @param[in] style_set Bitfield of supported controller styles (see \ref HidNpadStyleTag). + */ +void padConfigureInput(u32 max_players, u32 style_set); + +/** + * @brief Initializes a \ref PadState object to read input from one or more controller input sources. + * @param[in] _pad Pointer to \ref PadState. + * @remarks This is a variadic macro, pass the \ref HidNpadIdType value of each controller to add to the set. + */ +#define padInitialize(_pad, ...) ({ \ + const HidNpadIdType _pad_ids[] = { __VA_ARGS__ }; \ + u64 _pad_mask = 0; \ + for (unsigned _pad_i = 0; _pad_i < (sizeof(_pad_ids)/sizeof(_pad_ids[0])); ++_pad_i) \ + _pad_mask |= 1UL << (_pad_ids[_pad_i]); \ + padInitializeWithMask((_pad), _pad_mask); \ +}) + +/** + * @brief Same as \ref padInitialize, but taking a bitfield of controller IDs directly. + * @param[in] pad Pointer to \ref PadState. + * @param[in] mask Bitfield of controller IDs (each bit's position indicates a different \ref HidNpadIdType value). + */ +void padInitializeWithMask(PadState* pad, u64 mask); + +/** + * @brief Same as \ref padInitialize, but including every single controller input source. + * @param[in] pad Pointer to \ref PadState. + * @remark Use this function if you want to accept input from any controller. + */ +NX_INLINE void padInitializeAny(PadState* pad) { + padInitializeWithMask(pad, PAD_ANY_ID_MASK); +} + +/** + * @brief Same as \ref padInitialize, but including \ref HidNpadIdType_No1 and \ref HidNpadIdType_Handheld. + * @param[in] pad Pointer to \ref PadState. + * @remark Use this function if you just want to accept input for a single-player application. + */ +NX_INLINE void padInitializeDefault(PadState* pad) { + padInitialize(pad, HidNpadIdType_No1, HidNpadIdType_Handheld); +} + +/** + * @brief Updates pad state by reading from the controller input sources specified during initialization. + * @param[in] pad Pointer to \ref PadState. + */ +void padUpdate(PadState* pad); + +/** + * @brief Retrieves whether \ref HidNpadIdType_Handheld is an active input source (i.e. it was possible to read from it). + * @param[in] pad Pointer to \ref PadState. + * @return Boolean value. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR bool padIsHandheld(const PadState* pad) { + return pad->active_handheld; +} + +/** + * @brief Retrieves whether the specified controller is an active input source (i.e. it was possible to read from it). + * @param[in] pad Pointer to \ref PadState. + * @param[in] id ID of the controller input source (see \ref HidNpadIdType) + * @return Boolean value. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR bool padIsNpadActive(const PadState* pad, HidNpadIdType id) { + if (id <= HidNpadIdType_No8) + return pad->active_id_mask & BIT(id); + else if (id == HidNpadIdType_Handheld) + return pad->active_handheld; + else + return false; +} + +/** + * @brief Retrieves the set of input styles supported by the selected controller input sources. + * @param[in] pad Pointer to \ref PadState. + * @return Bitfield of \ref HidNpadStyleTag. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR u32 padGetStyleSet(const PadState* pad) { + return pad->style_set; +} + +/** + * @brief Retrieves the set of attributes reported by the system for the selected controller input sources. + * @param[in] pad Pointer to \ref PadState. + * @return Bitfield of \ref HidNpadAttribute. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR u32 padGetAttributes(const PadState* pad) { + return pad->attributes; +} + +/** + * @brief Retrieves whether any of the selected controller input sources is connected. + * @param[in] pad Pointer to \ref PadState. + * @return Boolean value. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR bool padIsConnected(const PadState* pad) { + return pad->attributes & HidNpadAttribute_IsConnected; +} + +/** + * @brief Retrieves the current set of pressed buttons across all selected controller input sources. + * @param[in] pad Pointer to \ref PadState. + * @return Bitfield of \ref HidNpadButton. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR u64 padGetButtons(const PadState* pad) { + return pad->buttons_cur; +} + +/** + * @brief Retrieves the set of buttons that are newly pressed. + * @param[in] pad Pointer to \ref PadState. + * @return Bitfield of \ref HidNpadButton. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR u64 padGetButtonsDown(const PadState* pad) { + return ~pad->buttons_old & pad->buttons_cur; +} + +/** + * @brief Retrieves the set of buttons that are newly released. + * @param[in] pad Pointer to \ref PadState. + * @return Bitfield of \ref HidNpadButton. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR u64 padGetButtonsUp(const PadState* pad) { + return pad->buttons_old & ~pad->buttons_cur; +} + +/** + * @brief Retrieves the position of an analog stick in a controller. + * @param[in] pad Pointer to \ref PadState. + * @param[in] i ID of the analog stick to read (0=left, 1=right). + * @return \ref HidAnalogStickState. + * @remark \ref padUpdate must have been previously called. + */ +NX_CONSTEXPR HidAnalogStickState padGetStickPos(const PadState* pad, unsigned i) { + return pad->sticks[i]; +} + +/** + * @brief Retrieves the position of an analog trigger in a GameCube controller. + * @param[in] pad Pointer to \ref PadState. + * @param[in] i ID of the analog trigger to read (0=left, 1=right). + * @return Analog trigger position (range is 0 to 0x7fff). + * @remark \ref padUpdate must have been previously called. + * @remark \ref HidNpadStyleTag_NpadGc must have been previously configured as a supported style in \ref padConfigureInput for GC trigger data to be readable. + */ +NX_CONSTEXPR u32 padGetGcTriggerPos(const PadState* pad, unsigned i) { + return pad->gc_triggers[i]; +} + +/** + * @brief Initializes a \ref PadRepeater object with the specified settings. + * @param[in] r Pointer to \ref PadRepeater. + * @param[in] delay Number of input updates between button presses being first detected and them being considered for repeat. + * @param[in] repeat Number of input updates between autogenerated repeat button presses. + */ +NX_CONSTEXPR void padRepeaterInitialize(PadRepeater* r, u16 delay, u16 repeat) { + r->button_mask = 0; + r->counter = 0; + r->delay = delay; + r->repeat = repeat; +} + +/** + * @brief Updates pad repeat state. + * @param[in] r Pointer to \ref PadRepeater. + * @param[in] button_mask Bitfield of currently pressed \ref HidNpadButton that will be considered for repeat. + */ +void padRepeaterUpdate(PadRepeater* r, u64 button_mask); + +/** + * @brief Retrieves the set of buttons that are being repeated according to the parameters specified in \ref padRepeaterInitialize. + * @param[in] r Pointer to \ref PadRepeater. + * @return Bitfield of \ref HidNpadButton. + * @remark It is suggested to bitwise-OR the return value of this function with that of \ref padGetButtonsDown. + */ +NX_CONSTEXPR u64 padRepeaterGetButtons(const PadRepeater* r) { + return r->counter == 0 ? r->button_mask : 0; +} diff --git a/src/libnx/wrapper/switch/runtime/pad.nim b/src/libnx/wrapper/switch/runtime/pad.nim new file mode 100644 index 0000000..7c399f3 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/pad.nim @@ -0,0 +1,230 @@ +## * +## @file pad.h +## @brief Simple wrapper for the HID Npad API. +## @author fincs +## @copyright libnx Authors +## + +import + ../types, ../services/hid + +## / Mask including all existing controller IDs. + +const + PAD_ANY_ID_MASK* = 0x1000100FF'u + +## / Pad state object. + +type + PadState* {.bycopy.} = object + idMask*: U8 + activeIdMask*: U8 + readHandheld*: bool + activeHandheld*: bool + styleSet*: U32 + attributes*: U32 + buttonsCur*: U64 + buttonsOld*: U64 + sticks*: array[2, HidAnalogStickState] + gcTriggers*: array[2, U32] + + +## / Pad button repeater state object. + +type + PadRepeater* {.bycopy.} = object + buttonMask*: U64 + counter*: S32 + delay*: U16 + repeat*: U16 + + +## * +## @brief Configures the input layout supported by the application. +## @param[in] max_players The maximum supported number of players (1 to 8). +## @param[in] style_set Bitfield of supported controller styles (see \ref HidNpadStyleTag). +## + +proc padConfigureInput*(maxPlayers: U32; styleSet: U32) {.cdecl, + importc: "padConfigureInput".} +## * +## @brief Initializes a \ref PadState object to read input from one or more controller input sources. +## @param[in] _pad Pointer to \ref PadState. +## @remarks This is a variadic macro, pass the \ref HidNpadIdType value of each controller to add to the set. +## + + +## @brief Same as \ref padInitialize, but taking a bitfield of controller IDs directly. +## @param[in] pad Pointer to \ref PadState. +## @param[in] mask Bitfield of controller IDs (each bit's position indicates a different \ref HidNpadIdType value). +proc padInitializeWithMask*(pad: ptr PadState, mask: U64) {.cdecl, importc: "padInitializeWithMask".} + +proc padInitialize*(pad: ptr PadState, padIds: varargs[HidNpadIdType]) {.inline, cdecl.} = + var mask: U64 = 0 + for i in 0..error_flags; +} + +/** + * @brief Gets the value of an error flag, set by \ref ringconSetErrorFlag. + * @param c \ref RingCon + * @param[in] flag \ref RingConErrorFlag + */ +NX_CONSTEXPR bool ringconGetErrorFlag(RingCon *c, RingConErrorFlag flag) { + return (c->error_flags & BIT(flag)) != 0; +} + +/** + * @brief Gets the \ref RingConFwVersion previously loaded by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] out \ref RingConFwVersion + */ +NX_CONSTEXPR RingConFwVersion ringconGetFwVersion(RingCon *c) { + return c->fw_ver; +} + +/** + * @brief Gets the Id previously loaded by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] id_l Id low. + * @param[out] id_h Id high. + */ +NX_CONSTEXPR void ringconGetId(RingCon *c, u64 *id_l, u64 *id_h) { + *id_l = c->id_l; + *id_h = c->id_h; +} + +/** + * @brief Gets the unk_cal previously loaded by \ref ringconCreate with \ref ringconReadUnkCal. Only valid when the output flag from \ref ringconCmdx00020105 is valid. + * @param c \ref RingCon + */ +NX_CONSTEXPR s16 ringconGetUnkCal(RingCon *c) { + return c->unk_cal; +} + +/** + * @brief Gets the total-push-count previously loaded by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] out total_push_count + */ +NX_CONSTEXPR s32 ringconGetTotalPushCount(RingCon *c) { + return c->total_push_count; +} + +/** + * @brief Gets the \ref RingConManuCal previously loaded by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] out \ref RingConManuCal + */ +NX_CONSTEXPR void ringconGetManuCal(RingCon *c, RingConManuCal *out) { + *out = c->manu_cal; +} + +/** + * @brief Gets the \ref RingConUserCal previously loaded by \ref ringconCreate. + * @note The Ring-Con UserCal doesn't seem to be calibrated normally? + * @param c \ref RingCon + * @param[out] out \ref RingConUserCal + */ +NX_CONSTEXPR void ringconGetUserCal(RingCon *c, RingConUserCal *out) { + *out = c->user_cal; +} + +/** + * @brief Updates the \ref RingConUserCal. + * @note The input \ref RingConUserCal is used with \ref ringconWriteUserCal, and the output from \ref ringconReadUserCal is verified with the input \ref RingConUserCal. This does not update the \ref RingConUserCal returned by \ref ringconGetUserCal. + * @note The Ring-Con UserCal doesn't seem to be calibrated normally? + * @param c \ref RingCon + * @param[in] cal \ref RingConUserCal + */ +Result ringconUpdateUserCal(RingCon *c, RingConUserCal cal); + +/** + * @brief Reads the \ref RingConFwVersion. + * @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetFwVersion instead. + * @param c \ref RingCon + * @param[out] out \ref RingConFwVersion + */ +Result ringconReadFwVersion(RingCon *c, RingConFwVersion *out); + +/** + * @brief Reads the Id. + * @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetId instead. + * @param c \ref RingCon + * @param[out] id_l Id low. + * @param[out] id_h Id high. + */ +Result ringconReadId(RingCon *c, u64 *id_l, u64 *id_h); + +/** + * @brief Gets the \ref RingConPollingData. Only returns entries which are new since the last time this was called (or if not previously called, all available entries up to count). + * @param c \ref RingCon + * @param[out] out Output array of \ref RingConPollingData. Entry order is newest -> oldest. + * @param[in] count Total size of the out array in entries, max value is 0x9. + * @param[out] total_out Total output entries. + */ +Result ringconGetPollingData(RingCon *c, RingConPollingData *out, s32 count, s32 *total_out); + +/** + * @brief Uses cmd 0x00020105. + * @note Used internally by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] out Output value. + */ +Result ringconCmdx00020105(RingCon *c, u32 *out); + +/** + * @brief Reads the \ref RingConManuCal. + * @note Used internally by \ref ringconCreate and \ref ringconReadUnkCal. + * @param c \ref RingCon + * @param[out] out \ref RingConManuCal + */ +Result ringconReadManuCal(RingCon *c, RingConManuCal *out); + +/** + * @brief Gets the unknown value derived from the output of cmd 0x00020504 and \ref ringconReadManuCal. + * @note Used internally by \ref ringconCreate. + * @param c \ref RingCon + * @param[out] out Output value. + */ +Result ringconReadUnkCal(RingCon *c, s16 *out); + +/** + * @brief Reads the \ref RingConUserCal. + * @note Used internally by \ref ringconCreate and \ref ringconUpdateUserCal. + * @param c \ref RingCon + * @param[out] out \ref RingConUserCal + */ +Result ringconReadUserCal(RingCon *c, RingConUserCal *out); + +/** + * @brief Reads the rep-count for Multitask Mode. + * @param c \ref RingCon + * @param[out] out Output value. Official sw using this clamps the output to range 0-500. + * @param[out] data_valid \ref RingConDataValid + */ +Result ringconReadRepCount(RingCon *c, s32 *out, RingConDataValid *data_valid); + +/** + * @brief Reads the total-push-count, for Multitask Mode. + * @note Used internally by \ref ringconCreate. Normally \ref ringconGetTotalPushCount should be used instead. + * @param c \ref RingCon + * @param[out] out Output value. + * @param[out] data_valid \ref RingConDataValid + */ +Result ringconReadTotalPushCount(RingCon *c, s32 *out, RingConDataValid *data_valid); + +/** + * @brief This resets the value returned by \ref ringconReadRepCount to 0. + * @param c \ref RingCon + */ +Result ringconResetRepCount(RingCon *c); + +/** + * @brief Writes the \ref RingConUserCal. + * @note Used internally by \ref ringconUpdateUserCal. + * @param c \ref RingCon + * @param[in] cal \ref RingConUserCal + */ +Result ringconWriteUserCal(RingCon *c, RingConUserCal cal); + diff --git a/src/libnx/wrapper/switch/runtime/ringcon.nim b/src/libnx/wrapper/switch/runtime/ringcon.nim new file mode 100644 index 0000000..c5e5a81 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/ringcon.nim @@ -0,0 +1,283 @@ +## * +## @file ringcon.h +## @brief Wrapper for using the Ring-Con attached to a Joy-Con, with hidbus. See also: https://switchbrew.org/wiki/Ring-Con +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/hidbus, ../services/hid + +const + RINGCON_CAL_MAGIC* = -0x3502 ## 0xCAFE + +## / Whether the output data is valid. + +type + RingConDataValid* = enum + RingConDataValidOk = 0, ## /< Valid. + RingConDataValidCRC = 1, ## /< Bad CRC. + RingConDataValidCal = 2 ## /< Only used with \ref ringconReadUserCal. Calibration is needed via \ref ringconUpdateUserCal. + RingConErrorFlag* = enum + RingConErrorFlagBadUserCalUpdate = 0, ## /< The output from \ref ringconReadUserCal doesn't match the input used with \ref ringconWriteUserCal, or the \ref RingConDataValid is not ::RingConDataValid_Ok. + RingConErrorFlagBadFlag = 4, ## /< The output flag from \ref ringconCmdx00020105 when successful is invalid. + RingConErrorFlagBadUserCal = 5, ## /< BadUserCal + RingConErrorFlagBadManuCal = 6 ## /< BadManuCal + + + +## / Ring-Con firmware version. + +type + RingConFwVersion* {.bycopy.} = object + fwMainVer*: U8 ## /< Main firmware version. + fwSubVer*: U8 ## /< Sub firmware version. + + +## / Ring-Con manufacturer calibration. + +type + RingConManuCal* {.bycopy.} = object + osMax*: S16 ## /< (manu_)os_max + hkMax*: S16 ## /< (manu_)hk_max + zeroMin*: S16 ## /< (manu_)zero_min + zeroMax*: S16 ## /< (manu_)zero_max + + +## / Ring-Con user calibration. + +type + RingConUserCal* {.bycopy.} = object + osMax*: S16 ## /< (user_)os_max + hkMax*: S16 ## /< (user_)hk_max + zero*: S16 ## /< (user_)zero + dataValid*: RingConDataValid ## /< \ref RingConDataValid + + +## / Polling data extracted from \ref HidbusJoyPollingReceivedData. + +type + RingConPollingData* {.bycopy.} = object + data*: S16 ## /< Sensor state data. + samplingNumber*: U64 ## /< SamplingNumber + + +## / Ring-Con state object. + +type + RingCon* {.bycopy.} = object + busInitialized*: bool + handle*: HidbusBusHandle + workbuf*: pointer + workbufSize*: csize_t + pollingLastSamplingNumber*: U64 + errorFlags*: U32 + idL*: U64 + idH*: U64 + fwVer*: RingConFwVersion + flag*: U32 + unkCal*: S16 + totalPushCount*: S32 + manuCal*: RingConManuCal + userCal*: RingConUserCal + +proc ringconCreate*(c: ptr RingCon; id: HidNpadIdType): Result {.cdecl, + importc: "ringconCreate".} +## * +## @brief Creates a \ref RingCon object, and handles the various initialization for it. +## @param c \ref RingCon +## @param[in] id \ref HidNpadIdType. A Ring-Con must be attached to this controller. +## + +proc ringconClose*(c: ptr RingCon) {.cdecl, importc: "ringconClose".} +## * +## @brief Close a \ref RingCon. +## @param c \ref RingCon +## + +proc ringconGetErrorFlags*(c: ptr RingCon): U32 {.inline, cdecl.} = + ## * + ## @brief Gets the error flags field. + ## @param c \ref RingCon + ## + + return c.errorFlags + +proc ringconGetErrorFlag*(c: ptr RingCon; flag: RingConErrorFlag): bool {.inline, cdecl.} = + ## * + ## @brief Gets the value of an error flag, set by \ref ringconSetErrorFlag. + ## @param c \ref RingCon + ## @param[in] flag \ref RingConErrorFlag + ## + + return (c.errorFlags and bit(flag)) != 0 + +proc ringconGetFwVersion*(c: ptr RingCon): RingConFwVersion {.inline, cdecl.} = + ## * + ## @brief Gets the \ref RingConFwVersion previously loaded by \ref ringconCreate. + ## @param c \ref RingCon + ## @param[out] out \ref RingConFwVersion + ## + + return c.fwVer + +proc ringconGetId*(c: ptr RingCon; idL: ptr U64; idH: ptr U64) {.inline, cdecl.} = + ## * + ## @brief Gets the Id previously loaded by \ref ringconCreate. + ## @param c \ref RingCon + ## @param[out] id_l Id low. + ## @param[out] id_h Id high. + ## + + idL[] = c.idL + idH[] = c.idH + +proc ringconGetUnkCal*(c: ptr RingCon): S16 {.inline, cdecl.} = + ## * + ## @brief Gets the unk_cal previously loaded by \ref ringconCreate with \ref ringconReadUnkCal. Only valid when the output flag from \ref ringconCmdx00020105 is valid. + ## @param c \ref RingCon + ## + + return c.unkCal + +proc ringconGetTotalPushCount*(c: ptr RingCon): S32 {.inline, cdecl.} = + ## * + ## @brief Gets the total-push-count previously loaded by \ref ringconCreate. + ## @param c \ref RingCon + ## @param[out] out total_push_count + ## + + return c.totalPushCount + +proc ringconGetManuCal*(c: ptr RingCon; `out`: ptr RingConManuCal) {.inline, cdecl.} = + ## * + ## @brief Gets the \ref RingConManuCal previously loaded by \ref ringconCreate. + ## @param c \ref RingCon + ## @param[out] out \ref RingConManuCal + ## + + `out`[] = c.manuCal + +proc ringconGetUserCal*(c: ptr RingCon; `out`: ptr RingConUserCal) {.inline, cdecl.} = + ## * + ## @brief Gets the \ref RingConUserCal previously loaded by \ref ringconCreate. + ## @note The Ring-Con UserCal doesn't seem to be calibrated normally? + ## @param c \ref RingCon + ## @param[out] out \ref RingConUserCal + ## + + `out`[] = c.userCal + +proc ringconUpdateUserCal*(c: ptr RingCon; cal: RingConUserCal): Result {.cdecl, + importc: "ringconUpdateUserCal".} +## * +## @brief Updates the \ref RingConUserCal. +## @note The input \ref RingConUserCal is used with \ref ringconWriteUserCal, and the output from \ref ringconReadUserCal is verified with the input \ref RingConUserCal. This does not update the \ref RingConUserCal returned by \ref ringconGetUserCal. +## @note The Ring-Con UserCal doesn't seem to be calibrated normally? +## @param c \ref RingCon +## @param[in] cal \ref RingConUserCal +## + +proc ringconReadFwVersion*(c: ptr RingCon; `out`: ptr RingConFwVersion): Result {.cdecl, + importc: "ringconReadFwVersion".} +## * +## @brief Reads the \ref RingConFwVersion. +## @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetFwVersion instead. +## @param c \ref RingCon +## @param[out] out \ref RingConFwVersion +## + +proc ringconReadId*(c: ptr RingCon; idL: ptr U64; idH: ptr U64): Result {.cdecl, + importc: "ringconReadId".} +## * +## @brief Reads the Id. +## @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetId instead. +## @param c \ref RingCon +## @param[out] id_l Id low. +## @param[out] id_h Id high. +## + +proc ringconGetPollingData*(c: ptr RingCon; `out`: ptr RingConPollingData; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "ringconGetPollingData".} +## * +## @brief Gets the \ref RingConPollingData. Only returns entries which are new since the last time this was called (or if not previously called, all available entries up to count). +## @param c \ref RingCon +## @param[out] out Output array of \ref RingConPollingData. Entry order is newest -> oldest. +## @param[in] count Total size of the out array in entries, max value is 0x9. +## @param[out] total_out Total output entries. +## + +proc ringconCmdx00020105*(c: ptr RingCon; `out`: ptr U32): Result {.cdecl, + importc: "ringconCmdx00020105".} +## * +## @brief Uses cmd 0x00020105. +## @note Used internally by \ref ringconCreate. +## @param c \ref RingCon +## @param[out] out Output value. +## + +proc ringconReadManuCal*(c: ptr RingCon; `out`: ptr RingConManuCal): Result {.cdecl, + importc: "ringconReadManuCal".} +## * +## @brief Reads the \ref RingConManuCal. +## @note Used internally by \ref ringconCreate and \ref ringconReadUnkCal. +## @param c \ref RingCon +## @param[out] out \ref RingConManuCal +## + +proc ringconReadUnkCal*(c: ptr RingCon; `out`: ptr S16): Result {.cdecl, + importc: "ringconReadUnkCal".} +## * +## @brief Gets the unknown value derived from the output of cmd 0x00020504 and \ref ringconReadManuCal. +## @note Used internally by \ref ringconCreate. +## @param c \ref RingCon +## @param[out] out Output value. +## + +proc ringconReadUserCal*(c: ptr RingCon; `out`: ptr RingConUserCal): Result {.cdecl, + importc: "ringconReadUserCal".} +## * +## @brief Reads the \ref RingConUserCal. +## @note Used internally by \ref ringconCreate and \ref ringconUpdateUserCal. +## @param c \ref RingCon +## @param[out] out \ref RingConUserCal +## + +proc ringconReadRepCount*(c: ptr RingCon; `out`: ptr S32; + dataValid: ptr RingConDataValid): Result {.cdecl, + importc: "ringconReadRepCount".} +## * +## @brief Reads the rep-count for Multitask Mode. +## @param c \ref RingCon +## @param[out] out Output value. Official sw using this clamps the output to range 0-500. +## @param[out] data_valid \ref RingConDataValid +## + +proc ringconReadTotalPushCount*(c: ptr RingCon; `out`: ptr S32; + dataValid: ptr RingConDataValid): Result {.cdecl, + importc: "ringconReadTotalPushCount".} +## * +## @brief Reads the total-push-count, for Multitask Mode. +## @note Used internally by \ref ringconCreate. Normally \ref ringconGetTotalPushCount should be used instead. +## @param c \ref RingCon +## @param[out] out Output value. +## @param[out] data_valid \ref RingConDataValid +## + +proc ringconResetRepCount*(c: ptr RingCon): Result {.cdecl, + importc: "ringconResetRepCount".} +## * +## @brief This resets the value returned by \ref ringconReadRepCount to 0. +## @param c \ref RingCon +## + +proc ringconWriteUserCal*(c: ptr RingCon; cal: RingConUserCal): Result {.cdecl, + importc: "ringconWriteUserCal".} +## * +## @brief Writes the \ref RingConUserCal. +## @note Used internally by \ref ringconUpdateUserCal. +## @param c \ref RingCon +## @param[in] cal \ref RingConUserCal +## + diff --git a/src/libnx/wrapper/switch/runtime/util/utf.h b/src/libnx/wrapper/switch/runtime/util/utf.h new file mode 100644 index 0000000..a9a08df --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/util/utf.h @@ -0,0 +1,157 @@ +/** + * @file utf.h + * @brief UTF conversion functions. + * @author mtheall + * @copyright libnx Authors + */ +#pragma once +#include +#include "../../types.h" + +/** Convert a UTF-8 sequence into a UTF-32 codepoint + * + * @param[out] out Output codepoint + * @param[in] in Input sequence + * + * @returns number of input code units consumed + * @returns -1 for error + */ +ssize_t decode_utf8 (uint32_t *out, const uint8_t *in); + +/** Convert a UTF-16 sequence into a UTF-32 codepoint + * + * @param[out] out Output codepoint + * @param[in] in Input sequence + * + * @returns number of input code units consumed + * @returns -1 for error + */ +ssize_t decode_utf16(uint32_t *out, const uint16_t *in); + +/** Convert a UTF-32 codepoint into a UTF-8 sequence + * + * @param[out] out Output sequence + * @param[in] in Input codepoint + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out must be able to store 4 code units + */ +ssize_t encode_utf8 (uint8_t *out, uint32_t in); + +/** Convert a UTF-32 codepoint into a UTF-16 sequence + * + * @param[out] out Output sequence + * @param[in] in Input codepoint + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out must be able to store 2 code units + */ +ssize_t encode_utf16(uint16_t *out, uint32_t in); + +/** Convert a UTF-8 sequence into a UTF-16 sequence + * + * Fills the output buffer up to \a len code units. + * Returns the number of code units that the input would produce; + * if it returns greater than \a len, the output has been + * truncated. + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf8_to_utf16(uint16_t *out, const uint8_t *in, size_t len); + +/** Convert a UTF-8 sequence into a UTF-32 sequence + * + * Fills the output buffer up to \a len code units. + * Returns the number of code units that the input would produce; + * if it returns greater than \a len, the output has been + * truncated. + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf8_to_utf32(uint32_t *out, const uint8_t *in, size_t len); + +/** Convert a UTF-16 sequence into a UTF-8 sequence + * + * Fills the output buffer up to \a len code units. + * Returns the number of code units that the input would produce; + * if it returns greater than \a len, the output has been + * truncated. + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf16_to_utf8(uint8_t *out, const uint16_t *in, size_t len); + +/** Convert a UTF-16 sequence into a UTF-32 sequence + * + * Fills the output buffer up to \a len code units. + * Returns the number of code units that the input would produce; + * if it returns greater than \a len, the output has been + * truncated. + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf16_to_utf32(uint32_t *out, const uint16_t *in, size_t len); + +/** Convert a UTF-32 sequence into a UTF-8 sequence + * + * Fills the output buffer up to \a len code units. + * Returns the number of code units that the input would produce; + * if it returns greater than \a len, the output has been + * truncated. + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf32_to_utf8(uint8_t *out, const uint32_t *in, size_t len); + +/** Convert a UTF-32 sequence into a UTF-16 sequence + * + * @param[out] out Output sequence + * @param[in] in Input sequence (null-terminated) + * @param[in] len Output length + * + * @returns number of output code units produced + * @returns -1 for error + * + * @note \a out is not null-terminated + */ +ssize_t utf32_to_utf16(uint16_t *out, const uint32_t *in, size_t len); + diff --git a/src/libnx/wrapper/switch/runtime/util/utf.nim b/src/libnx/wrapper/switch/runtime/util/utf.nim new file mode 100644 index 0000000..cc1e470 --- /dev/null +++ b/src/libnx/wrapper/switch/runtime/util/utf.nim @@ -0,0 +1,166 @@ +## * +## @file utf.h +## @brief UTF conversion functions. +## @author mtheall +## @copyright libnx Authors +## + +import + ../../types + +proc decodeUtf8*(`out`: ptr uint32; `in`: ptr uint8): SsizeT {.cdecl, + importc: "decode_utf8".} +## * Convert a UTF-8 sequence into a UTF-32 codepoint +## +## @param[out] out Output codepoint +## @param[in] in Input sequence +## +## @returns number of input code units consumed +## @returns -1 for error +## + +proc decodeUtf16*(`out`: ptr uint32; `in`: ptr uint16): SsizeT {.cdecl, + importc: "decode_utf16".} +## * Convert a UTF-16 sequence into a UTF-32 codepoint +## +## @param[out] out Output codepoint +## @param[in] in Input sequence +## +## @returns number of input code units consumed +## @returns -1 for error +## + +proc encodeUtf8*(`out`: ptr uint8; `in`: uint32): SsizeT {.cdecl, importc: "encode_utf8".} +## * Convert a UTF-32 codepoint into a UTF-8 sequence +## +## @param[out] out Output sequence +## @param[in] in Input codepoint +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out must be able to store 4 code units +## + +proc encodeUtf16*(`out`: ptr uint16; `in`: uint32): SsizeT {.cdecl, + importc: "encode_utf16".} +## * Convert a UTF-32 codepoint into a UTF-16 sequence +## +## @param[out] out Output sequence +## @param[in] in Input codepoint +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out must be able to store 2 code units +## + +proc utf8ToUtf16*(`out`: ptr uint16; `in`: ptr uint8; len: csize_t): SsizeT {.cdecl, + importc: "utf8_to_utf16".} +## * Convert a UTF-8 sequence into a UTF-16 sequence +## +## Fills the output buffer up to \a len code units. +## Returns the number of code units that the input would produce; +## if it returns greater than \a len, the output has been +## truncated. +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + +proc utf8ToUtf32*(`out`: ptr uint32; `in`: ptr uint8; len: csize_t): SsizeT {.cdecl, + importc: "utf8_to_utf32".} +## * Convert a UTF-8 sequence into a UTF-32 sequence +## +## Fills the output buffer up to \a len code units. +## Returns the number of code units that the input would produce; +## if it returns greater than \a len, the output has been +## truncated. +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + +proc utf16ToUtf8*(`out`: ptr uint8; `in`: ptr uint16; len: csize_t): SsizeT {.cdecl, + importc: "utf16_to_utf8".} +## * Convert a UTF-16 sequence into a UTF-8 sequence +## +## Fills the output buffer up to \a len code units. +## Returns the number of code units that the input would produce; +## if it returns greater than \a len, the output has been +## truncated. +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + +proc utf16ToUtf32*(`out`: ptr uint32; `in`: ptr uint16; len: csize_t): SsizeT {.cdecl, + importc: "utf16_to_utf32".} +## * Convert a UTF-16 sequence into a UTF-32 sequence +## +## Fills the output buffer up to \a len code units. +## Returns the number of code units that the input would produce; +## if it returns greater than \a len, the output has been +## truncated. +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + +proc utf32ToUtf8*(`out`: ptr uint8; `in`: ptr uint32; len: csize_t): SsizeT {.cdecl, + importc: "utf32_to_utf8".} +## * Convert a UTF-32 sequence into a UTF-8 sequence +## +## Fills the output buffer up to \a len code units. +## Returns the number of code units that the input would produce; +## if it returns greater than \a len, the output has been +## truncated. +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + +proc utf32ToUtf16*(`out`: ptr uint16; `in`: ptr uint32; len: csize_t): SsizeT {.cdecl, + importc: "utf32_to_utf16".} +## * Convert a UTF-32 sequence into a UTF-16 sequence +## +## @param[out] out Output sequence +## @param[in] in Input sequence (null-terminated) +## @param[in] len Output length +## +## @returns number of output code units produced +## @returns -1 for error +## +## @note \a out is not null-terminated +## + diff --git a/src/libnx/wrapper/switch/services/acc.h b/src/libnx/wrapper/switch/services/acc.h new file mode 100644 index 0000000..429820f --- /dev/null +++ b/src/libnx/wrapper/switch/services/acc.h @@ -0,0 +1,106 @@ +/** + * @file acc.h + * @brief Account (acc:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +#define ACC_USER_LIST_SIZE 8 + +typedef enum { + AccountServiceType_Application = 0, ///< Initializes acc:u0. + AccountServiceType_System = 1, ///< Initializes acc:u1. + AccountServiceType_Administrator = 2, ///< Initializes acc:su. +} AccountServiceType; + +/// Profile +typedef struct { + Service s; ///< IProfile +} AccountProfile; + +/// Account UserId. +typedef struct { + u64 uid[2]; ///< UserId. All-zero is invalid / Uid not set. See also \ref accountUidIsValid. +} AccountUid; + +/// UserData +typedef struct { + u32 unk_x0; ///< Unknown. + u32 iconID; ///< Icon ID. 0 = Mii, the rest are character icon IDs. + u8 iconBackgroundColorID; ///< Profile icon background color ID + u8 unk_x9[0x7]; ///< Unknown. + u8 miiID[0x10]; ///< Some ID related to the Mii? All zeros when a character icon is used. + u8 unk_x20[0x60]; ///< Usually zeros? +} AccountUserData; + +/// ProfileBase +typedef struct { + AccountUid uid; ///< \ref AccountUid + u64 lastEditTimestamp; ///< POSIX UTC timestamp, for the last account edit. + char nickname[0x20]; ///< UTF-8 Nickname. +} AccountProfileBase; + +/// NetworkServiceAccountId +typedef struct { + u64 id; ///< Id. +} AccountNetworkServiceAccountId; + +/// Initialize account. +Result accountInitialize(AccountServiceType service_type); + +/// Exit account. +void accountExit(void); + +/// Gets the Service object for the actual account service session. +Service* accountGetServiceSession(void); + +/// Get the total number of user profiles. +Result accountGetUserCount(s32* user_count); + +/** + * @brief Get a list of all userIds. The returned list will never be larger than ACC_USER_LIST_SIZE. + * @param uids Pointer to array of userIds. + * @param max_uids Maximum number of userIds to return. + * @param actual_total The actual total number of userIds found. + */ +Result accountListAllUsers(AccountUid* uids, s32 max_uids, s32 *actual_total); + +/// Get the userId for the last opened user. +Result accountGetLastOpenedUser(AccountUid *uid); + +/// Get an AccountProfile for the specified userId. +Result accountGetProfile(AccountProfile* out, AccountUid uid); + +/// IsUserRegistrationRequestPermitted +Result accountIsUserRegistrationRequestPermitted(bool *out); + +/// TrySelectUserWithoutInteraction +Result accountTrySelectUserWithoutInteraction(AccountUid *uid, bool is_network_service_account_required); + +/// Close the AccountProfile. +void accountProfileClose(AccountProfile* profile); + +/// Get \ref AccountUserData and \ref AccountProfileBase for the specified profile, userdata is optional (can be NULL). +Result accountProfileGet(AccountProfile* profile, AccountUserData* userdata, AccountProfileBase* profilebase); + +/// Get the icon image size. +Result accountProfileGetImageSize(AccountProfile* profile, u32* image_size); + +/// Load the JPEG profile icon, valid for both Miis and character icons. The output image_size is the same as the one from \ref accountProfileGetImageSize. +Result accountProfileLoadImage(AccountProfile* profile, void* buf, size_t len, u32* image_size); + +/// Gets the userId which was selected by the profile-selector applet (if any), prior to launching the currently running Application. +/// This gets the cached PreselectedUser loaded during accountInitialize, when PreselectedUser is available. +Result accountGetPreselectedUser(AccountUid *uid); + +/** + * @brief Checks whether the specified \ref AccountUid is valid/set (non-zero). + * @param[in] Uid \ref AccountUid + */ +NX_CONSTEXPR bool accountUidIsValid(const AccountUid *Uid) { + return Uid->uid[0]!=0 || Uid->uid[1]!=0; +} + diff --git a/src/libnx/wrapper/switch/services/acc.nim b/src/libnx/wrapper/switch/services/acc.nim new file mode 100644 index 0000000..b3fd380 --- /dev/null +++ b/src/libnx/wrapper/switch/services/acc.nim @@ -0,0 +1,132 @@ +## * +## @file acc.h +## @brief Account (acc:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +const + ACC_USER_LIST_SIZE* = 8 + +type + AccountServiceType* = enum + AccountServiceTypeApplication = 0, ## /< Initializes acc:u0. + AccountServiceTypeSystem = 1, ## /< Initializes acc:u1. + AccountServiceTypeAdministrator = 2 ## /< Initializes acc:su. + + +## / Profile + +type + AccountProfile* {.bycopy.} = object + s*: Service ## /< IProfile + + +## / Account UserId. + +type + AccountUid* {.bycopy.} = object + uid*: array[2, U64] ## /< UserId. All-zero is invalid / Uid not set. See also \ref accountUidIsValid. + + +## / UserData + +type + AccountUserData* {.bycopy.} = object + unkX0*: U32 ## /< Unknown. + iconID*: U32 ## /< Icon ID. 0 = Mii, the rest are character icon IDs. + iconBackgroundColorID*: U8 ## /< Profile icon background color ID + unkX9*: array[0x7, U8] ## /< Unknown. + miiID*: array[0x10, U8] ## /< Some ID related to the Mii? All zeros when a character icon is used. + unkX20*: array[0x60, U8] ## /< Usually zeros? + + +## / ProfileBase + +type + AccountProfileBase* {.bycopy.} = object + uid*: AccountUid ## /< \ref AccountUid + lastEditTimestamp*: U64 ## /< POSIX UTC timestamp, for the last account edit. + nickname*: array[0x20, char] ## /< UTF-8 Nickname. + + +## / NetworkServiceAccountId + +type + AccountNetworkServiceAccountId* {.bycopy.} = object + id*: U64 ## /< Id. + +proc accountInitialize*(serviceType: AccountServiceType): Result {.cdecl, + importc: "accountInitialize".} +## / Initialize account. + +proc accountExit*() {.cdecl, importc: "accountExit".} +## / Exit account. + +proc accountGetServiceSession*(): ptr Service {.cdecl, + importc: "accountGetServiceSession".} +## / Gets the Service object for the actual account service session. + +proc accountGetUserCount*(userCount: ptr S32): Result {.cdecl, + importc: "accountGetUserCount".} +## / Get the total number of user profiles. + +proc accountListAllUsers*(uids: ptr AccountUid; maxUids: S32; actualTotal: ptr S32): Result {. + cdecl, importc: "accountListAllUsers".} +## * +## @brief Get a list of all userIds. The returned list will never be larger than ACC_USER_LIST_SIZE. +## @param uids Pointer to array of userIds. +## @param max_uids Maximum number of userIds to return. +## @param actual_total The actual total number of userIds found. +## + +proc accountGetLastOpenedUser*(uid: ptr AccountUid): Result {.cdecl, + importc: "accountGetLastOpenedUser".} +## / Get the userId for the last opened user. + +proc accountGetProfile*(`out`: ptr AccountProfile; uid: AccountUid): Result {.cdecl, + importc: "accountGetProfile".} +## / Get an AccountProfile for the specified userId. + +proc accountIsUserRegistrationRequestPermitted*(`out`: ptr bool): Result {.cdecl, + importc: "accountIsUserRegistrationRequestPermitted".} +## / IsUserRegistrationRequestPermitted + +proc accountTrySelectUserWithoutInteraction*(uid: ptr AccountUid; + isNetworkServiceAccountRequired: bool): Result {.cdecl, + importc: "accountTrySelectUserWithoutInteraction".} +## / TrySelectUserWithoutInteraction + +proc accountProfileClose*(profile: ptr AccountProfile) {.cdecl, + importc: "accountProfileClose".} +## / Close the AccountProfile. + +proc accountProfileGet*(profile: ptr AccountProfile; userdata: ptr AccountUserData; + profilebase: ptr AccountProfileBase): Result {.cdecl, + importc: "accountProfileGet".} +## / Get \ref AccountUserData and \ref AccountProfileBase for the specified profile, userdata is optional (can be NULL). + +proc accountProfileGetImageSize*(profile: ptr AccountProfile; imageSize: ptr U32): Result {. + cdecl, importc: "accountProfileGetImageSize".} +## / Get the icon image size. + +proc accountProfileLoadImage*(profile: ptr AccountProfile; buf: pointer; len: csize_t; + imageSize: ptr U32): Result {.cdecl, + importc: "accountProfileLoadImage".} +## / Load the JPEG profile icon, valid for both Miis and character icons. The output image_size is the same as the one from \ref accountProfileGetImageSize. + +proc accountGetPreselectedUser*(uid: ptr AccountUid): Result {.cdecl, + importc: "accountGetPreselectedUser".} +## / Gets the userId which was selected by the profile-selector applet (if any), prior to launching the currently running Application. +## / This gets the cached PreselectedUser loaded during accountInitialize, when PreselectedUser is available. + +proc accountUidIsValid*(uid: ptr AccountUid): bool {.inline, cdecl.} = + ## * + ## @brief Checks whether the specified \ref AccountUid is valid/set (non-zero). + ## @param[in] Uid \ref AccountUid + ## + + return uid.uid[0] != 0 or uid.uid[1] != 0 diff --git a/src/libnx/wrapper/switch/services/apm.h b/src/libnx/wrapper/switch/services/apm.h new file mode 100644 index 0000000..8ba4b5f --- /dev/null +++ b/src/libnx/wrapper/switch/services/apm.h @@ -0,0 +1,55 @@ +/** + * @file apm.h + * @brief Performance management (apm) service IPC wrapper. This is used internally by applet with __nx_applet_PerformanceConfiguration, however if you prefer non-init/exit can be used manually. See also: https://switchbrew.org/wiki/PTM_services#apm:am + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// PerformanceMode +typedef enum { + ApmPerformanceMode_Invalid = -1, ///< Invalid + ApmPerformanceMode_Normal = 0, ///< Normal + ApmPerformanceMode_Boost = 1, ///< Boost +} ApmPerformanceMode; + +/// CpuBoostMode. With \ref appletSetCpuBoostMode, only values 0/1 are available. This allows using higher clock rates. +typedef enum { + ApmCpuBoostMode_Normal = 0, ///< Default, boost-mode disabled. + ApmCpuBoostMode_FastLoad = 1, ///< Boost CPU. Additionally, throttle GPU to minimum. Use performance configurations 0x92220009 (Docked) and 0x9222000A (Handheld), or 0x9222000B and 0x9222000C. + ApmCpuBoostMode_Type2 = 2, ///< Conserve power. Only throttle GPU to minimum. Use performance configurations 0x9222000B and 0x9222000C. +} ApmCpuBoostMode; + +/// Initialize apm. Used automatically by \ref appletInitialize with AppletType_Application. +Result apmInitialize(void); + +/// Exit apm. Used automatically by \ref appletExit with AppletType_Application. +void apmExit(void); + +/// Gets the Service object for the actual apm service session. +Service* apmGetServiceSession(void); + +/// Gets the Service object for ISession. +Service* apmGetServiceSession_Session(void); + +/** + * @brief Gets the current ApmPerformanceMode. + * @param[out] out_performanceMode ApmPerformanceMode + */ +Result apmGetPerformanceMode(ApmPerformanceMode* out_performanceMode); + +/** + * @brief Sets the PerformanceConfiguration for the specified PerformanceMode. + * @param[in] PerformanceMode \ref ApmPerformanceMode + * @param[in] PerformanceConfiguration PerformanceConfiguration + */ +Result apmSetPerformanceConfiguration(ApmPerformanceMode PerformanceMode, u32 PerformanceConfiguration); + +/** + * @brief Gets the PerformanceConfiguration for the specified PerformanceMode. + * @param[in] PerformanceMode \ref ApmPerformanceMode + * @param[out] PerformanceConfiguration PerformanceConfiguration + */ +Result apmGetPerformanceConfiguration(ApmPerformanceMode PerformanceMode, u32 *PerformanceConfiguration); diff --git a/src/libnx/wrapper/switch/services/apm.nim b/src/libnx/wrapper/switch/services/apm.nim new file mode 100644 index 0000000..c75efa4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/apm.nim @@ -0,0 +1,66 @@ +## * +## @file apm.h +## @brief Performance management (apm) service IPC wrapper. This is used internally by applet with __nx_applet_PerformanceConfiguration, however if you prefer non-init/exit can be used manually. See also: https://switchbrew.org/wiki/PTM_services#apm:am +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / PerformanceMode + +type + ApmPerformanceMode* = enum + ApmPerformanceModeInvalid = -1, ## /< Invalid + ApmPerformanceModeNormal = 0, ## /< Normal + ApmPerformanceModeBoost = 1 ## /< Boost + + +## / CpuBoostMode. With \ref appletSetCpuBoostMode, only values 0/1 are available. This allows using higher clock rates. + +type + ApmCpuBoostMode* = enum + ApmCpuBoostModeNormal = 0, ## /< Default, boost-mode disabled. + ApmCpuBoostModeFastLoad = 1, ## /< Boost CPU. Additionally, throttle GPU to minimum. Use performance configurations 0x92220009 (Docked) and 0x9222000A (Handheld), or 0x9222000B and 0x9222000C. + ApmCpuBoostModeType2 = 2 ## /< Conserve power. Only throttle GPU to minimum. Use performance configurations 0x9222000B and 0x9222000C. + + +## / Initialize apm. Used automatically by \ref appletInitialize with AppletType_Application. + +proc apmInitialize*(): Result {.cdecl, importc: "apmInitialize".} +## / Exit apm. Used automatically by \ref appletExit with AppletType_Application. + +proc apmExit*() {.cdecl, importc: "apmExit".} +## / Gets the Service object for the actual apm service session. + +proc apmGetServiceSession*(): ptr Service {.cdecl, importc: "apmGetServiceSession".} +## / Gets the Service object for ISession. + +proc apmGetServiceSessionSession*(): ptr Service {.cdecl, + importc: "apmGetServiceSession_Session".} +## * +## @brief Gets the current ApmPerformanceMode. +## @param[out] out_performanceMode ApmPerformanceMode +## + +proc apmGetPerformanceMode*(outPerformanceMode: ptr ApmPerformanceMode): Result {. + cdecl, importc: "apmGetPerformanceMode".} +## * +## @brief Sets the PerformanceConfiguration for the specified PerformanceMode. +## @param[in] PerformanceMode \ref ApmPerformanceMode +## @param[in] PerformanceConfiguration PerformanceConfiguration +## + +proc apmSetPerformanceConfiguration*(performanceMode: ApmPerformanceMode; + performanceConfiguration: U32): Result {.cdecl, + importc: "apmSetPerformanceConfiguration".} +## * +## @brief Gets the PerformanceConfiguration for the specified PerformanceMode. +## @param[in] PerformanceMode \ref ApmPerformanceMode +## @param[out] PerformanceConfiguration PerformanceConfiguration +## + +proc apmGetPerformanceConfiguration*(performanceMode: ApmPerformanceMode; + performanceConfiguration: ptr U32): Result {. + cdecl, importc: "apmGetPerformanceConfiguration".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/applet.h b/src/libnx/wrapper/switch/services/applet.h new file mode 100644 index 0000000..c48abba --- /dev/null +++ b/src/libnx/wrapper/switch/services/applet.h @@ -0,0 +1,2737 @@ +/** + * @file applet.h + * @brief Applet (applet) service IPC wrapper. + * @note For wrappers which launch LibraryApplets etc, see switch/applets/. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/apm.h" +#include "../services/pdm.h" +#include "../services/caps.h" +#include "../services/pm.h" +#include "../services/ncm_types.h" +#include "../services/acc.h" +#include "../services/set.h" +#include "../kernel/tmem.h" +#include "../kernel/event.h" +#include "../nacp.h" + +/// AppletType +typedef enum { + AppletType_None = -2, + AppletType_Default = -1, + AppletType_Application = 0, + AppletType_SystemApplet = 1, + AppletType_LibraryApplet = 2, + AppletType_OverlayApplet = 3, + AppletType_SystemApplication = 4, +} AppletType; + +/// OperationMode +typedef enum { + AppletOperationMode_Handheld = 0, ///< Handheld + AppletOperationMode_Console = 1, ///< Console (Docked / TV-mode) +} AppletOperationMode; + +/// applet hook types. +typedef enum { + AppletHookType_OnFocusState = 0, ///< ::AppletMessage_FocusStateChanged + AppletHookType_OnOperationMode, ///< ::AppletMessage_OperationModeChanged + AppletHookType_OnPerformanceMode, ///< ::AppletMessage_PerformanceModeChanged + AppletHookType_OnExitRequest, ///< ::AppletMessage_ExitRequested + AppletHookType_OnResume, ///< ::AppletMessage_Resume + AppletHookType_OnCaptureButtonShortPressed, ///< ::AppletMessage_CaptureButtonShortPressed + AppletHookType_OnAlbumScreenShotTaken, ///< ::AppletMessage_AlbumScreenShotTaken + AppletHookType_RequestToDisplay, ///< ::AppletMessage_RequestToDisplay + + AppletHookType_Max, ///< Number of applet hook types. +} AppletHookType; + +/// AppletMessage, for \ref appletGetMessage. See also \ref AppletHookType. +typedef enum { + AppletMessage_ExitRequest = 4, ///< Exit request. + AppletMessage_FocusStateChanged = 15, ///< FocusState changed. + AppletMessage_Resume = 16, ///< Current applet execution was resumed. + AppletMessage_OperationModeChanged = 30, ///< OperationMode changed. + AppletMessage_PerformanceModeChanged = 31, ///< PerformanceMode changed. + AppletMessage_RequestToDisplay = 51, ///< Display requested, see \ref appletApproveToDisplay. + AppletMessage_CaptureButtonShortPressed = 90, ///< Capture button was short-pressed. + AppletMessage_AlbumScreenShotTaken = 92, ///< Screenshot was taken. + AppletMessage_AlbumRecordingSaved = 93, ///< AlbumRecordingSaved +} AppletMessage; + +/// FocusState +typedef enum { + AppletFocusState_InFocus = 1, ///< Applet is focused. + AppletFocusState_OutOfFocus = 2, ///< Out of focus - LibraryApplet open. + AppletFocusState_Background = 3 ///< Out of focus - HOME menu open / console is sleeping. +} AppletFocusState; + +/// FocusHandlingMode +typedef enum { + AppletFocusHandlingMode_SuspendHomeSleep = 0, ///< Suspend only when HOME menu is open / console is sleeping (default). + AppletFocusHandlingMode_NoSuspend, ///< Don't suspend when out of focus. + AppletFocusHandlingMode_SuspendHomeSleepNotify, ///< Suspend only when HOME menu is open / console is sleeping but still receive OnFocusState hook. + AppletFocusHandlingMode_AlwaysSuspend, ///< Always suspend when out of focus, regardless of the reason. + + AppletFocusHandlingMode_Max, ///< Number of focus handling modes. +} AppletFocusHandlingMode; + +/// LaunchParameterKind +typedef enum { + AppletLaunchParameterKind_UserChannel = 1, ///< UserChannel. Application-specific LaunchParameter. + AppletLaunchParameterKind_PreselectedUser = 2, ///< account PreselectedUser + AppletLaunchParameterKind_Unknown = 3, ///< Unknown if used by anything? +} AppletLaunchParameterKind; + +/// AppletId +typedef enum { + AppletId_None = 0x00, ///< None + AppletId_application = 0x01, ///< Application. Not valid for use with LibraryApplets. + AppletId_OverlayApplet = 0x02, ///< 010000000000100C "overlayDisp" + AppletId_SystemAppletMenu = 0x03, ///< 0100000000001000 "qlaunch" (SystemAppletMenu) + AppletId_SystemApplication = 0x04, ///< 0100000000001012 "starter" SystemApplication. + AppletId_LibraryAppletAuth = 0x0A, ///< 0100000000001001 "auth" + AppletId_LibraryAppletCabinet = 0x0B, ///< 0100000000001002 "cabinet" + AppletId_LibraryAppletController = 0x0C, ///< 0100000000001003 "controller" + AppletId_LibraryAppletDataErase = 0x0D, ///< 0100000000001004 "dataErase" + AppletId_LibraryAppletError = 0x0E, ///< 0100000000001005 "error" + AppletId_LibraryAppletNetConnect = 0x0F, ///< 0100000000001006 "netConnect" + AppletId_LibraryAppletPlayerSelect = 0x10, ///< 0100000000001007 "playerSelect" + AppletId_LibraryAppletSwkbd = 0x11, ///< 0100000000001008 "swkbd" + AppletId_LibraryAppletMiiEdit = 0x12, ///< 0100000000001009 "miiEdit" + AppletId_LibraryAppletWeb = 0x13, ///< 010000000000100A "LibAppletWeb" WebApplet applet + AppletId_LibraryAppletShop = 0x14, ///< 010000000000100B "LibAppletShop" ShopN applet + AppletId_LibraryAppletPhotoViewer = 0x15, ///< 010000000000100D "photoViewer" + AppletId_LibraryAppletSet = 0x16, ///< 010000000000100E "set" (This applet is currently not present on retail devices.) + AppletId_LibraryAppletOfflineWeb = 0x17, ///< 010000000000100F "LibAppletOff" offlineWeb applet + AppletId_LibraryAppletLoginShare = 0x18, ///< 0100000000001010 "LibAppletLns" loginShare web-applet + AppletId_LibraryAppletWifiWebAuth = 0x19, ///< 0100000000001011 "LibAppletAuth" wifiWebAuth applet + AppletId_LibraryAppletMyPage = 0x1A, ///< 0100000000001013 "myPage" +} AppletId; + +/// LibraryAppletMode +typedef enum { + LibAppletMode_AllForeground = 0, ///< Foreground. + LibAppletMode_Background = 1, ///< Background. + LibAppletMode_NoUi = 2, ///< No UI. + LibAppletMode_BackgroundIndirect = 3, ///< Background with indirect display, see \ref appletHolderGetIndirectLayerConsumerHandle. + LibAppletMode_AllForegroundInitiallyHidden = 4, ///< Foreground except initially hidden. +} LibAppletMode; + +/// LibraryAppletExitReason +typedef enum { + LibAppletExitReason_Normal = 0, + LibAppletExitReason_Canceled = 1, + LibAppletExitReason_Abnormal = 2, + LibAppletExitReason_Unexpected = 10, +} LibAppletExitReason; + +/// AppletApplicationExitReason +typedef enum { + AppletApplicationExitReason_Normal = 0, + AppletApplicationExitReason_Unknown1 = 1, + AppletApplicationExitReason_Unknown2 = 2, + AppletApplicationExitReason_Unknown3 = 3, + AppletApplicationExitReason_Unknown4 = 4, + AppletApplicationExitReason_Unknown5 = 5, + AppletApplicationExitReason_Unexpected = 100, +} AppletApplicationExitReason; + +/// ThemeColorType +typedef enum { + AppletThemeColorType_Default = 0, + AppletThemeColorType_Unknown1 = 1, + AppletThemeColorType_Unknown2 = 2, + AppletThemeColorType_Unknown3 = 3, +} AppletThemeColorType; + +/// Mode values for \ref appletSetTvPowerStateMatchingMode. +typedef enum { + AppletTvPowerStateMatchingMode_Unknown0 = 0, ///< Unknown. + AppletTvPowerStateMatchingMode_Unknown1 = 1, ///< Unknown. +} AppletTvPowerStateMatchingMode; + +/// Type values for \ref appletPerformSystemButtonPressingIfInFocus. +typedef enum { + AppletSystemButtonType_HomeButtonShortPressing = 1, ///< Short-pressing with the HOME-button. + AppletSystemButtonType_HomeButtonLongPressing = 2, ///< Long-pressing with the HOME-button. + AppletSystemButtonType_PowerButtonShortPressing = 3, ///< Short-pressing with the Power-button. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonType_PowerButtonLongPressing = 4, ///< Long-pressing with the Power-button. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonType_Shutdown = 5, ///< Shutdown the system, as if the Power-button was held for longer than ::AppletSystemButtonType_PowerButtonLongPressing. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonType_CaptureButtonShortPressing = 6, ///< Short-pressing with the Capture-button. + AppletSystemButtonType_CaptureButtonLongPressing = 7, ///< Long-pressing with the Capture-button. +} AppletSystemButtonType; + +/// Permission values for \ref appletSetScreenShotPermission. +typedef enum { + AppletScreenShotPermission_Inherit = 0, ///< Inherit from parent applet. + AppletScreenShotPermission_Enable = 1, ///< Enable. + AppletScreenShotPermission_Disable = 2, ///< Disable. +} AppletScreenShotPermission; + +/// Extension values for \ref appletSetIdleTimeDetectionExtension / \ref appletGetIdleTimeDetectionExtension, for extending user inactivity detection. +typedef enum { + AppletIdleTimeDetectionExtension_None = 0, ///< No extension. + AppletIdleTimeDetectionExtension_Extended = 1, ///< Extended + AppletIdleTimeDetectionExtension_ExtendedUnsafe = 2, ///< ExtendedUnsafe +} AppletIdleTimeDetectionExtension; + +/// Input policy values for \ref appletSetInputDetectionPolicy. +typedef enum { + AppletInputDetectionPolicy_Unknown0 = 0, ///< Unknown. + AppletInputDetectionPolicy_Unknown1 = 1, ///< Unknown. +} AppletInputDetectionPolicy; + +/// Input mode values for \ref appletSetWirelessPriorityMode. +typedef enum { + AppletWirelessPriorityMode_Default = 1, ///< Default + AppletWirelessPriorityMode_OptimizedForWlan = 2, ///< OptimizedForWlan +} AppletWirelessPriorityMode; + +/// CaptureSharedBuffer for the IDisplayController commands. +typedef enum { + AppletCaptureSharedBuffer_LastApplication = 0, ///< LastApplication + AppletCaptureSharedBuffer_LastForeground = 1, ///< LastForeground + AppletCaptureSharedBuffer_CallerApplet = 2, ///< CallerApplet +} AppletCaptureSharedBuffer; + +/// WindowOriginMode +typedef enum { + AppletWindowOriginMode_LowerLeft = 0, ///< LowerLeft + AppletWindowOriginMode_UpperLeft = 1, ///< UpperLeft +} AppletWindowOriginMode; + +/// ProgramSpecifyKind for the ExecuteProgram cmd. Controls the type of the u64 passed to the ExecuteProgram cmd. +typedef enum { + AppletProgramSpecifyKind_ExecuteProgram = 0, ///< u8 ProgramIndex. + AppletProgramSpecifyKind_JumpToSubApplicationProgramForDevelopment = 1, ///< u64 application_id. Only available when DebugMode is enabled. + AppletProgramSpecifyKind_RestartProgram = 2, ///< u64 = value 0. +} AppletProgramSpecifyKind; + +/// applet hook function. +typedef void (*AppletHookFn)(AppletHookType hook, void* param); + +/// applet hook cookie. +typedef struct AppletHookCookie AppletHookCookie; + +struct AppletHookCookie +{ + AppletHookCookie* next; ///< Next cookie. + AppletHookFn callback; ///< Hook callback. + void* param; ///< Callback parameter. +}; + +/// LockAccessor +typedef struct { + Service s; ///< ILockAccessor + Event event; ///< Event from the GetEvent cmd, with autoclear=false. +} AppletLockAccessor; + +/// applet IStorage +typedef struct { + Service s; ///< IStorage + TransferMemory tmem; ///< TransferMemory +} AppletStorage; + +/// LibraryApplet state. +typedef struct { + Service s; ///< ILibraryAppletAccessor + Event StateChangedEvent; ///< Output from GetAppletStateChangedEvent, autoclear=false. + Event PopInteractiveOutDataEvent; ///< Output from GetPopInteractiveOutDataEvent, autoclear=false. + LibAppletMode mode; ///< See ref \ref LibAppletMode. + u64 layer_handle; ///< Output from GetIndirectLayerConsumerHandle on [2.0.0+]. + bool creating_self; ///< When set, indicates that the LibraryApplet is creating itself. + LibAppletExitReason exitreason; ///< Set by \ref appletHolderJoin using the output from cmd GetResult, see \ref LibAppletExitReason. +} AppletHolder; + +/// IApplicationAccessor container. +typedef struct { + Service s; ///< IApplicationAccessor + Event StateChangedEvent; ///< Output from GetAppletStateChangedEvent, autoclear=false. + AppletApplicationExitReason exitreason; ///< Set by \ref appletApplicationJoin using the output from cmd GetResult, see \ref AppletApplicationExitReason. +} AppletApplication; + +/// GpuErrorHandler +typedef struct { + Service s; ///< IGpuErrorHandler +} AppletGpuErrorHandler; + +/// Used by \ref appletInitialize with __nx_applet_AppletAttribute for cmd OpenLibraryAppletProxy (AppletType_LibraryApplet), on [3.0.0+]. The default for this struct is all-zero. +typedef struct { + u8 flag; ///< Flag. When non-zero, two state fields are set to 1. + u8 reserved[0x7F]; ///< Unused. +} AppletAttribute; + +/// LibraryAppletInfo +typedef struct { + AppletId appletId; ///< \ref AppletId + LibAppletMode mode; ///< \ref LibAppletMode +} LibAppletInfo; + +/// AppletProcessLaunchReason, from GetLaunchReason. +typedef struct { + u8 flag; ///< When non-zero, indicates that OpenCallingLibraryApplet should be used. + u8 unk_x1[3]; ///< Always zero. +} AppletProcessLaunchReason; + +/// Cached info for the current LibraryApplet, from \ref appletGetAppletInfo. +typedef struct { + LibAppletInfo info; ///< Output from \ref appletGetLibraryAppletInfo. + bool caller_flag; ///< Loaded from AppletProcessLaunchReason::flag, indicates that the below AppletHolder is initialized. + AppletHolder caller; ///< \ref AppletHolder for the CallingLibraryApplet, automatically closed by \ref appletExit when needed. +} AppletInfo; + +/// IdentityInfo +typedef struct { + AppletId appletId; ///< \ref AppletId + u32 pad; ///< Padding. + u64 application_id; ///< ApplicationId, only set with appletId == ::AppletId_application. +} AppletIdentityInfo; + +/// Attributes for launching applications for Quest. +typedef struct { + u32 unk_x0; ///< See AppletApplicationAttribute::unk_x0. + u32 unk_x4; ///< See AppletApplicationAttribute::unk_x4. + float volume; ///< [7.0.0+] See AppletApplicationAttribute::volume. +} AppletApplicationAttributeForQuest; + +/// ApplicationAttribute +typedef struct { + u32 unk_x0; ///< Default is 0 for non-Quest. Only used when non-zero: unknown value in seconds. + u32 unk_x4; ///< Default is 0 for non-Quest. Only used when non-zero: unknown value in seconds. + float volume; ///< Audio volume. Must be in the range of 0.0f-1.0f. The default is 1.0f. + u8 unused[0x14]; ///< Unused. Default is 0. +} AppletApplicationAttribute; + +/// ApplicationLaunchProperty +typedef struct { + u64 application_id; ///< ApplicationId. + u32 version; ///< Application version. + u8 app_storageId; ///< \ref NcmStorageId for the Application. + u8 update_storageId; ///< \ref NcmStorageId for the Application update. + u8 unk_xa; ///< Unknown. + u8 pad; ///< Padding. +} AppletApplicationLaunchProperty; + +/// ApplicationLaunchRequestInfo +typedef struct { + u32 unk_x0; ///< Unknown. The default is 0x0 with \ref appletCreateSystemApplication, 0x3 with \ref appletCreateApplication. + u32 unk_x4; ///< Unknown. The default is 0x0 with \ref appletCreateSystemApplication, 0x3 with \ref appletCreateApplication. + u8 unk_x8[0x8]; ///< Unknown. The default is 0x0. +} AppletApplicationLaunchRequestInfo; + +/// AppletResourceUsageInfo, from \ref appletGetAppletResourceUsageInfo. +typedef struct { + u32 counter0; ///< Unknown counter. + u32 counter1; ///< Unknown counter. + u32 counter2; ///< Output from ns cmd GetRightsEnvironmentCountForDebug. + u8 unused[0x14]; ///< Always zero. +} AppletResourceUsageInfo; + +/// Initialize applet, called automatically during app startup. +Result appletInitialize(void); + +/// Exit applet, called automatically during app exit. +void appletExit(void); + +/// Gets the Service object for the actual "appletOE"/"appletAE" service session. +Service* appletGetServiceSession_Proxy(void); + +/// Gets the Service object for IAppletCommonFunctions. Only initialized with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. +Service* appletGetServiceSession_AppletCommonFunctions(void); + +/// Gets the Service object for I*Functions, specific to each AppletType (IApplicationFunctions for AppletType_*Application). Not initialized with AppletType_LibraryApplet pre-15.0.0. On [15.0.0+] with AppletType_LibraryApplet this returns the object for IHomeMenuFunctions. +Service* appletGetServiceSession_Functions(void); + +/// Gets the Service object for IGlobalStateController. Only initialized with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +Service* appletGetServiceSession_GlobalStateController(void); + +/// Gets the Service object for IApplicationCreator. Only initialized with AppletType_SystemApplet. +Service* appletGetServiceSession_ApplicationCreator(void); + +/// Gets the Service object for ILibraryAppletSelfAccessor. Only initialized with AppletType_LibraryApplet. +Service* appletGetServiceSession_LibraryAppletSelfAccessor(void); + +/// Gets the Service object for IProcessWindingController. Only initialized with AppletType_LibraryApplet. +Service* appletGetServiceSession_ProcessWindingController(void); + +/// Gets the Service object for ILibraryAppletCreator. +Service* appletGetServiceSession_LibraryAppletCreator(void); + +/// Gets the Service object for ICommonStateGetter. +Service* appletGetServiceSession_CommonStateGetter(void); + +/// Gets the Service object for ISelfController. +Service* appletGetServiceSession_SelfController(void); + +/// Gets the Service object for IWindowController. +Service* appletGetServiceSession_WindowController(void); + +/// Gets the Service object for IAudioController. +Service* appletGetServiceSession_AudioController(void); + +/// Gets the Service object for IDisplayController. +Service* appletGetServiceSession_DisplayController(void); + +/// Gets the Service object for IDebugFunctions. +Service* appletGetServiceSession_DebugFunctions(void); + +/// Get the cached AppletResourceUserId. +u64 appletGetAppletResourceUserId(void); + +/// Get the \ref AppletType. +AppletType appletGetAppletType(void); + +/// Sets the state field for \ref AppletThemeColorType. +void appletSetThemeColorType(AppletThemeColorType theme); + +/// Gets the state field for \ref AppletThemeColorType. Used internally by \ref libappletArgsCreate. +AppletThemeColorType appletGetThemeColorType(void); + +///@name ICommonStateGetter +///@{ + +/** + * @brief Gets the CradleStatus. + * @param[out] status Output Dock status. + */ +Result appletGetCradleStatus(u8 *status); + +/** + * @brief Gets the BootMode which originated from \ref pmbmGetBootMode. + * @param[out] mode \ref PmBootMode + */ +Result appletGetBootMode(PmBootMode *mode); + +/** + * @brief Request to AcquireSleepLock. + * @note On success, this then uses cmd GetAcquiredSleepLockEvent and waits on that event. + */ +Result appletRequestToAcquireSleepLock(void); + +/** + * @brief Release the SleepLock. + */ +Result appletReleaseSleepLock(void); + +/** + * @brief Release the SleepLock transiently. + * @note On success, this then uses cmd GetAcquiredSleepLockEvent and waits on that event. + */ +Result appletReleaseSleepLockTransiently(void); + +/** + * @brief GetWakeupCount + * @note Only available with [11.0.0+]. + * @param[out] out Output value. + */ +Result appletGetWakeupCount(u64 *out); + +/** + * @brief Pushes a storage to the general channel. Used for sending requests to SystemApplet. + * @note This is not usable under an Application, however it is usable under a LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletPushToGeneralChannel(AppletStorage *s); + +/** + * @brief Gets a \ref AppletLockAccessor for HomeButtonReader. + * @note Similar to using \ref appletGetReaderLockAccessorEx with inval=0. + * @param a LockAccessor object. + */ +Result appletGetHomeButtonReaderLockAccessor(AppletLockAccessor *a); + +/** + * @brief Gets a Reader \ref AppletLockAccessor. + * @note Only available with [2.0.0+]. + * @param a LockAccessor object. + * @param[in] inval Input value, must be 0-3. 0 = HomeButton. + */ +Result appletGetReaderLockAccessorEx(AppletLockAccessor *a, u32 inval); + +/** + * @brief Gets a Writer \ref AppletLockAccessor. + * @note Only available with [7.0.0+]. On older sysvers, this is only available with AppletType_SystemApplet on [2.0.0+]. + * @param a LockAccessor object. + * @param[in] inval Input value, must be 0-3. 0 = HomeButton. + */ +Result appletGetWriterLockAccessorEx(AppletLockAccessor *a, u32 inval); + +/** + * @brief Gets the Dock firmware version. + * @note Only available with [2.0.0+]. + * @param[out] out0 First output value. + * @param[out] out1 Second output value. + * @param[out] out2 Third output value. + * @param[out] out3 Fourth output value. + */ +Result appletGetCradleFwVersion(u32 *out0, u32 *out1, u32 *out2, u32 *out3); + +/** + * @brief Gets whether VrMode is enabled. + * @note Only available with [3.0.0+]. + * @param out Output flag + */ +Result appletIsVrModeEnabled(bool *out); + +/** + * @brief Sets whether VrMode is enabled. + * @note This is only fully usable system-side with [6.0.0+]. + * @note For checking Parental Controls, see \ref pctlIsStereoVisionPermitted. + * @note On pre-7.0.0 this uses cmd SetVrModeEnabled internally, while on [7.0.0+] this uses cmds BeginVrModeEx/EndVrModeEx. + * @param flag Flag + */ +Result appletSetVrModeEnabled(bool flag); + +/** + * @brief Sets whether the LCD screen backlight is turned off. + * @note Only available with [4.0.0+]. + * @param[in] flag Flag + */ +Result appletSetLcdBacklightOffEnabled(bool flag); + +/** + * @brief Gets the ControllerFirmwareUpdateSection flag. + * @note Only available with [3.0.0+]. + * @param[out] out Output flag. + */ +Result appletIsInControllerFirmwareUpdateSection(bool *out); + +/** + * @brief SetVrPositionForDebug + * @note The cached value loaded from \ref setsysGetDebugModeFlag must be 1, otherwise an error is returned. + * @note Only available with [11.0.0+]. + * @param[in] x X, must not be negative. x+width must be <=1280. + * @param[in] y Y, must not be negative. y+height must be <=720. + * @param[in] width Width, must be 1-1280. + * @param[in] height Height, must be 1-720. + */ +Result appletSetVrPositionForDebug(s32 x, s32 y, s32 width, s32 height); + +/** + * @brief Gets the DefaultDisplayResolution. + * @note Only available with [3.0.0+]. + * @param[out] width Output width. + * @param[out] height Output height. + */ +Result appletGetDefaultDisplayResolution(s32 *width, s32 *height); + +/** + * @brief Gets an Event which is signaled when the output from \ref appletGetDefaultDisplayResolution changes. + * @note Only available with [3.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 appletGetDefaultDisplayResolutionChangeEvent(Event *out_event); + +/** + * @brief Gets the HdcpAuthenticationState. + * @note Only available with [4.0.0+]. + * @param[out] state Output state. + */ +Result appletGetHdcpAuthenticationState(s32 *state); + +/** + * @brief Gets an Event which is signaled when the output from \ref appletGetHdcpAuthenticationState changes. + * @note Only available with [4.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 appletGetHdcpAuthenticationStateChangeEvent(Event *out_event); + +/** + * @brief Sets the \ref AppletTvPowerStateMatchingMode. + * @note Only available with [5.0.0+]. + * @param[in] mode \ref AppletTvPowerStateMatchingMode + */ +Result appletSetTvPowerStateMatchingMode(AppletTvPowerStateMatchingMode mode); + +/** + * @brief Gets the ApplicationId for the specified ContentActionName string. + * @note Only available when the current applet is an AppletType_SystemApplication on [5.1.0+]. + * @param[out] application_id ApplicationId. + * @param[in] name ContentActionName string. + */ +Result appletGetApplicationIdByContentActionName(u64 *application_id, const char *name); + +/** + * @brief Sets the \ref ApmCpuBoostMode. + * @note Only available with [7.0.0+] (not fully usable system-side with 6.x). + * @param mode \ref ApmCpuBoostMode. + */ +Result appletSetCpuBoostMode(ApmCpuBoostMode mode); + +/** + * @brief CancelCpuBoostMode + * @note Only available with [10.0.0+]. + */ +Result appletCancelCpuBoostMode(void); + +/** + * @brief GetBuiltInDisplayType + * @note Only available with [11.0.0+]. + * @param[out] out Output value. + */ +Result appletGetBuiltInDisplayType(s32 *out); + +/** + * @brief Perform SystemButtonPressing with the specified \ref AppletSystemButtonType. Internally this cmd checks a state field, verifies that the type is allowed, then runs the same func as \ref appletPerformSystemButtonPressing internally. + * @note Only available with [6.0.0+]. + * @param[in] type \ref AppletSystemButtonType + */ +Result appletPerformSystemButtonPressingIfInFocus(AppletSystemButtonType type); + +/** + * @brief Sets whether PerformanceConfigurationChangedNotification is enabled. + * @note Only available with [7.0.0+]. + * @param[in] flag Whether to enable the notification. + */ +Result appletSetPerformanceConfigurationChangedNotification(bool flag); + +/** + * @brief Gets the current PerformanceConfiguration. + * @note Only available with [7.0.0+]. + * @param PerformanceConfiguration Output PerformanceConfiguration. + */ +Result appletGetCurrentPerformanceConfiguration(u32 *PerformanceConfiguration); + +/** + * @brief Opens an \ref AppletGpuErrorHandler. + * @note The cached value loaded from \ref setsysGetDebugModeFlag must be 1, otherwise an error is returned. + * @note Only available with [11.0.0+]. + * @param[out] g \ref AppletGpuErrorHandler + */ +Result appletOpenMyGpuErrorHandler(AppletGpuErrorHandler *g); + +/** + * @brief Gets the OperationModeSystemInfo. + * @note Only available with [7.0.0+]. + * @param[out] info Output info. + */ +Result appletGetOperationModeSystemInfo(u32 *info); + +/** + * @brief This uses \ref setsysGetPlatformRegion internally. + * @note Only available with [9.0.0+]. + * @param[out] out \ref SetSysPlatformRegion + */ +Result appletGetSettingsPlatformRegion(SetSysPlatformRegion *out); + +/** + * @brief ActivateMigrationService + * @note Only available with [10.0.0+]. + */ +Result appletActivateMigrationService(void); + +/** + * @brief DeactivateMigrationService + * @note Only available with [10.0.0+]. + */ +Result appletDeactivateMigrationService(void); + +/** + * @brief DisableSleepTillShutdown + * @note Only available with [11.0.0+]. + */ +Result appletDisableSleepTillShutdown(void); + +/** + * @brief SuppressDisablingSleepTemporarily + * @param[in] val Nanoseconds value. + * @note Only available with [11.0.0+]. + */ +Result appletSuppressDisablingSleepTemporarily(u64 val); + +/** + * @brief SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled + * @note Only available with [11.0.0+]. + */ +Result appletSetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(void); + +///@} + +///@name IGpuErrorHandler +///@{ + +/** + * @brief Close an \ref AppletGpuErrorHandler. + * @param g \ref AppletGpuErrorHandler + */ +void appletGpuErrorHandlerClose(AppletGpuErrorHandler *g); + +/** + * @brief Gets the size of the info available with \ref appletGpuErrorHandlerGetManualGpuErrorInfo. + * @param g \ref AppletGpuErrorHandler + * @param[out] out Output size. + */ +Result appletGpuErrorHandlerGetManualGpuErrorInfoSize(AppletGpuErrorHandler *g, u64 *out); + +/** + * @brief GetManualGpuErrorInfo + * @param g \ref AppletGpuErrorHandler + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size, must be >= the output size from \ref appletGpuErrorHandlerGetManualGpuErrorInfoSize. + * @param[out] out Output value. + */ +Result appletGpuErrorHandlerGetManualGpuErrorInfo(AppletGpuErrorHandler *g, void* buffer, size_t size, u64 *out); + +/** + * @brief GetManualGpuErrorDetectionSystemEvent + * @param g \ref AppletGpuErrorHandler + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGpuErrorHandlerGetManualGpuErrorDetectionSystemEvent(AppletGpuErrorHandler *g, Event *out_event); + +/** + * @brief FinishManualGpuErrorHandling + * @param g \ref AppletGpuErrorHandler + */ +Result appletGpuErrorHandlerFinishManualGpuErrorHandling(AppletGpuErrorHandler *g); + +///@} + +///@name ISelfController +///@{ + +/** + * @brief Delay exiting until \ref appletUnlockExit is called, with a 15 second timeout once exit is requested. + * @note When exit is requested \ref appletMainLoop will return false, hence any main-loop using appletMainLoop will exit. This allows the app to handle cleanup post-main-loop instead of being force-terminated. + * @note If the above timeout occurs after exit was requested where \ref appletUnlockExit was not called, the process will be forced-terminated. + * @note \ref appletUnlockExit must be used before main() returns. + */ +Result appletLockExit(void); + +/// Unlocks exiting, see \ref appletLockExit. +Result appletUnlockExit(void); + +/** + * @brief Enter FatalSection. + */ +Result appletEnterFatalSection(void); + +/** + * @brief Leave FatalSection. + */ +Result appletLeaveFatalSection(void); + +/** + * @brief Controls whether screenshot-capture is allowed. + * @param permission \ref AppletScreenShotPermission + */ +Result appletSetScreenShotPermission(AppletScreenShotPermission permission); + +/** + * @brief Sets whether ::AppletMessage_Resume is enabled. + * @param[in] flag Whether to enable the notification. + */ +Result appletSetRestartMessageEnabled(bool flag); + +/** + * @brief Sets the \ref AppletIdentityInfo for screenshots. + * @param[in] info \ref AppletIdentityInfo + */ +Result appletSetScreenShotAppletIdentityInfo(AppletIdentityInfo *info); + +/** + * @brief Sets ControllerFirmwareUpdateSection. + * @note Only available with [3.0.0+]. + * @note This throws error 0x40280 when the internal state flag already matches the input value. + * @param[in] flag Flag + */ +Result appletSetControllerFirmwareUpdateSection(bool flag); + +/** + * @brief Sets whether ::AppletMessage_CaptureButtonShortPressed is enabled. + * @note Only available with [3.0.0+]. + * @note When enabled with a non-Overlay applet, Overlay applet will not be notified of capture button short-presses for screenshots. + * @param[in] flag Whether to enable the notification. + */ +Result appletSetRequiresCaptureButtonShortPressedMessage(bool flag); + +/** + * @brief Sets the Album screenshot ImageOrientation. + * @note Only available with [3.0.0+]. + * @param[in] orientation \ref AlbumImageOrientation + */ +Result appletSetAlbumImageOrientation(AlbumImageOrientation orientation); + +/** + * @brief Sets the DesirableKeyboardLayout. + * @note Only available with [4.0.0+]. + * @param[in] layout Input \ref SetKeyboardLayout. + */ +Result appletSetDesirableKeyboardLayout(SetKeyboardLayout layout); + +Result appletCreateManagedDisplayLayer(u64 *out); + +/** + * @brief Checks whether SystemBufferSharing is enabled, throwing an error otherwise. + * @note Only available with [4.0.0+]. Not usable with AppletType_*Application. + */ +Result appletIsSystemBufferSharingEnabled(void); + +/** + * @brief Gets the System SharedBufferHandle and SharedLayerHandle. + * @note Only available with [4.0.0+]. Not usable with AppletType_*Application. + * @param[out] SharedBufferHandle Output System SharedBufferHandle. + * @param[out] SharedLayerHandle Output System SharedLayerHandle. + */ +Result appletGetSystemSharedLayerHandle(u64 *SharedBufferHandle, u64 *SharedLayerHandle); + +/** + * @brief Same as \ref appletGetSystemSharedLayerHandle except this just gets the SharedBufferHandle. + * @note Only available with [5.0.0+]. Not usable with AppletType_*Application. + * @param[out] SharedBufferHandle Output System SharedBufferHandle. + */ +Result appletGetSystemSharedBufferHandle(u64 *SharedBufferHandle); + +/** + * @brief CreateManagedDisplaySeparableLayer + * @note Only available with [10.0.0+]. + * @param[out] display_layer Output display_layer. + * @param[out] recording_layer Output recording_layer. + */ +Result appletCreateManagedDisplaySeparableLayer(u64 *display_layer, u64 *recording_layer); + +/** + * @brief SetManagedDisplayLayerSeparationMode + * @note Only available with [10.0.0+]. + * @param[in] mode Mode. Must be 0-1. + */ +Result appletSetManagedDisplayLayerSeparationMode(u32 mode); + +/** + * @brief Sets whether ::AppletMessage_RequestToDisplay is enabled. + * @note Sets an internal state flag. When the input flag is 0, this will in additional run the same code as \ref appletApproveToDisplay. + * @param[in] flag Flag + */ +Result appletSetHandlesRequestToDisplay(bool flag); + +/** + * @brief Approve the display requested by ::AppletMessage_RequestToDisplay, see also \ref appletSetHandlesRequestToDisplay. + */ +Result appletApproveToDisplay(void); + +/** + * @brief OverrideAutoSleepTimeAndDimmingTime + * @param[in] inval0 Unknown input value. + * @param[in] inval1 Unknown input value. + * @param[in] inval2 Unknown input value. + * @param[in] inval3 Unknown input value. + */ +Result appletOverrideAutoSleepTimeAndDimmingTime(s32 inval0, s32 inval1, s32 inval2, s32 inval3); + +/** + * @brief Sets the IdleTimeDetectionExtension. + * @param[in] ext \ref AppletIdleTimeDetectionExtension Must be 0-2: 0 = disabled, 1 = Extended, and 2 = ExtendedUnsafe. + */ +Result appletSetIdleTimeDetectionExtension(AppletIdleTimeDetectionExtension ext); + +/** + * @brief Gets the value set by \ref appletSetIdleTimeDetectionExtension. + * @param[out] ext \ref AppletIdleTimeDetectionExtension + */ +Result appletGetIdleTimeDetectionExtension(AppletIdleTimeDetectionExtension *ext); + +/** + * @brief Sets the InputDetectionSourceSet. + * @param[in] val Input value. + */ +Result appletSetInputDetectionSourceSet(u32 val); + +/** + * @brief Reports that the user is active, for idle detection (screen dimming / auto-sleep). This is equivalent to when the user uses HID input. + * @note Only available with [2.0.0+]. + */ +Result appletReportUserIsActive(void); + +/** + * @brief Gets the current Illuminance from the light sensor. + * @note Only available with [3.0.0+]. + * @param fLux Output fLux + */ +Result appletGetCurrentIlluminance(float *fLux); + +/** + * @brief Gets whether Illuminance is available. + * @note Only available with [3.0.0+]. + * @param out Output flag + */ +Result appletIsIlluminanceAvailable(bool *out); + +/** + * @brief Sets AutoSleepDisabled. + * @note Only available with [5.0.0+]. + * @param[in] flag Flag + */ +Result appletSetAutoSleepDisabled(bool flag); + +/** + * @brief Gets AutoSleepDisabled. + * @note Only available with [5.0.0+]. + * @param[out] out Output flag + */ +Result appletIsAutoSleepDisabled(bool *out); + +/** + * @brief Gets the current Illuminance from the light sensor. Same as \ref appletGetCurrentIlluminance except for the additional param. + * @note Only available with [5.0.0+]. + * @param bOverLimit Output bOverLimit + * @param fLux Output fLux + */ +Result appletGetCurrentIlluminanceEx(bool *bOverLimit, float *fLux); + +/** + * @brief Sets the \ref AppletInputDetectionPolicy. + * @note Only available with [9.0.0+]. + * @param[in] policy \ref AppletInputDetectionPolicy + */ +Result appletSetInputDetectionPolicy(AppletInputDetectionPolicy policy); + +/** + * @brief Sets the WirelessPriorityMode. + * @note Only available with [4.0.0+]. + * @param[in] mode \ref AppletWirelessPriorityMode + */ +Result appletSetWirelessPriorityMode(AppletWirelessPriorityMode mode); + +/** + * @brief Gets the total time in nanoseconds that the current process was actively running (not suspended), relative to when \ref appletInitialize was last used. + * @note Only available with [6.0.0+]. + * @param[out] activeTime Output nanoseconds value. + */ +Result appletGetProgramTotalActiveTime(u64 *activeTime); + +/** + * @brief Sets whether ::AppletMessage_AlbumScreenShotTaken is enabled. + * @note Only available with [7.0.0+]. + * @param[in] flag Whether to enable the notification. + */ +Result appletSetAlbumImageTakenNotificationEnabled(bool flag); + +/** + * @brief Sets the Application AlbumUserData. + * @note Only available with [8.0.0+]. + * @param[in] buffer Buffer containing arbitrary UserData. + * @param[in] size Buffer size, must be <=0x400. + */ +Result appletSetApplicationAlbumUserData(const void* buffer, size_t size); + +/** + * @brief SaveCurrentScreenshot + * @note Only available with [11.0.0+]. + * @param[in] option \ref AlbumReportOption + */ +Result appletSaveCurrentScreenshot(AlbumReportOption option); + +///@} + +///@name IWindowController +///@{ + +/** + * @brief Gets the AppletResourceUserId of the CallerApplet. + * @note Only available with [6.0.0+]. + * @param[out] out AppletResourceUserId + */ +Result appletGetAppletResourceUserIdOfCallerApplet(u64 *out); + +/** + * @brief Sets the current applet WindowVisibility. + * @note Only available with [7.0.0+]. + * @param[in] flag Flag + */ +Result appletSetAppletWindowVisibility(bool flag); + +/** + * @brief Sets the AppletGpuTimeSlice. + * @note Only available with [7.0.0+]. + * @param[in] val Input value, must not be negative. + */ +Result appletSetAppletGpuTimeSlice(s64 val); + +///@} + +///@name IAudioController +///@{ + +/** + * @brief Sets the ExpectedMasterVolume for MainApplet and LibraryApplet. + * @note Used by some official apps before/after launching LibraryApplets. Prior to changing the volume, the official app uses \ref appletGetExpectedMasterVolume, with the output being used to restore the volume after LibraryApplet handling. + * @param[in] mainAppletVolume MainApplet ExpectedMasterVolume. + * @param[in] libraryAppletVolume LibraryApplet ExpectedMasterVolume. + */ +Result appletSetExpectedMasterVolume(float mainAppletVolume, float libraryAppletVolume); + +/** + * @brief Gets the ExpectedMasterVolume for MainApplet and LibraryApplet. + * @note See also \ref appletSetExpectedMasterVolume. + * @param[out] mainAppletVolume MainApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetMainAppletExpectedMasterVolume when not NULL. + * @param[out] libraryAppletVolume LibraryApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetLibraryAppletExpectedMasterVolume when not NULL. + */ +Result appletGetExpectedMasterVolume(float *mainAppletVolume, float *libraryAppletVolume); + +/** + * @brief Change the MainApplet MasterVolume. + * @param[in] volume MainApplet MasterVolume. + * @param[in] unk Unknown. + */ +Result appletChangeMainAppletMasterVolume(float volume, u64 unk); + +/** + * @brief Sets the TransparentVolumeRate. + * @param[in] val Input value. + */ +Result appletSetTransparentVolumeRate(float val); + +///@} + +///@name IDisplayController +///@{ + +/** + * @brief Update the LastForeground CaptureImage. + */ +Result appletUpdateLastForegroundCaptureImage(void); + +/** + * @brief Update the CallerApplet CaptureImage. + */ +Result appletUpdateCallerAppletCaptureImage(void); + +/** + * @brief Gets the LastForeground CaptureImage. + * @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. + * @param[out] size Buffer size, must match 0x384000. + * @param[out] flag Output flag. + */ +Result appletGetLastForegroundCaptureImageEx(void* buffer, size_t size, bool *flag); + +/** + * @brief Gets the LastApplication CaptureImage. + * @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. + * @param[out] size Buffer size, must match 0x384000. + * @param[out] flag Output flag. + */ +Result appletGetLastApplicationCaptureImageEx(void* buffer, size_t size, bool *flag); + +/** + * @brief Gets the CallerApplet CaptureImage. + * @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. + * @param[out] size Buffer size, must match 0x384000. + * @param[out] flag Output flag. + */ +Result appletGetCallerAppletCaptureImageEx(void* buffer, size_t size, bool *flag); + +/** + * @brief Takes a screenshot of the current applet Layer into the specified CaptureSharedBuffer. + * @note Only available with [2.0.0+]. + * @param[in] flag Flag. + * @param[in] captureBuf \ref AppletCaptureSharedBuffer + */ +Result appletTakeScreenShotOfOwnLayer(bool flag, AppletCaptureSharedBuffer captureBuf); + +/** + * @brief Copies image data from a CaptureSharedBuffer to another CaptureSharedBuffer. + * @note Only available with [5.0.0+]. + * @param[in] dstCaptureBuf Destination \ref AppletCaptureSharedBuffer. + * @param[in] srcCaptureBuf Source \ref AppletCaptureSharedBuffer. + */ +Result appletCopyBetweenCaptureBuffers(AppletCaptureSharedBuffer dstCaptureBuf, AppletCaptureSharedBuffer srcCaptureBuf); + +/** + * @brief Clear the input CaptureSharedBuffer with the specified color. + * @note Only available with [3.0.0+]. + * @param[in] flag Flag. + * @param[in] captureBuf \ref AppletCaptureSharedBuffer + * @param[in] color RGBA8 color. + */ +Result appletClearCaptureBuffer(bool flag, AppletCaptureSharedBuffer captureBuf, u32 color); + +/** + * @brief Clear the AppletTransitionBuffer with the specified color. + * @note Only available with [3.0.0+]. + * @param[in] color RGBA8 color. + */ +Result appletClearAppletTransitionBuffer(u32 color); + +/** + * @brief Acquire the LastApplication CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + * @param[out] flag Output flag. + * @param[out] id Output ID. + */ +Result appletAcquireLastApplicationCaptureSharedBuffer(bool *flag, s32 *id); + +/** + * @brief Release the LastApplication CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + */ +Result appletReleaseLastApplicationCaptureSharedBuffer(void); + +/** + * @brief Acquire the LastForeground CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + * @param[out] flag Output flag. + * @param[out] id Output ID. + */ +Result appletAcquireLastForegroundCaptureSharedBuffer(bool *flag, s32 *id); + +/** + * @brief Release the LastForeground CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + */ +Result appletReleaseLastForegroundCaptureSharedBuffer(void); + +/** + * @brief Acquire the CallerApplet CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + * @param[out] flag Output flag. + * @param[out] id Output ID. + */ +Result appletAcquireCallerAppletCaptureSharedBuffer(bool *flag, s32 *id); + +/** + * @brief Release the CallerApplet CaptureSharedBuffer. + * @note Only available with [4.0.0+]. + */ +Result appletReleaseCallerAppletCaptureSharedBuffer(void); + +/** + * @brief Takes a screenshot of the current applet Layer into the specified CaptureSharedBuffer. Same as \ref appletTakeScreenShotOfOwnLayer except for the additional immediately param. + * @note Only available with [6.0.0+]. + * @param[in] flag0 Flag0. + * @param[in] immediately Whether the screenshot should be taken immediately. + * @param[in] captureBuf \ref AppletCaptureSharedBuffer + */ +Result appletTakeScreenShotOfOwnLayerEx(bool flag0, bool immediately, AppletCaptureSharedBuffer captureBuf); + +///@} + +///@name IProcessWindingController +///@{ + +/** + * @brief Pushes a storage to the ContextStack. Normally this should only be used when AppletInfo::caller_flag is true. + * @note Only available with AppletType_LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletPushContext(AppletStorage *s); + +/** + * @brief Pops a storage from the ContextStack. Normally this should only be used when AppletInfo::caller_flag is true. + * @note Only available with AppletType_LibraryApplet. + * @param[out] s Storage object. + */ +Result appletPopContext(AppletStorage *s); + +// LockAccessor + +/** + * @brief Closes a LockAccessor. + * @param a LockAccessor object. + */ +void appletLockAccessorClose(AppletLockAccessor *a); + +/** + * @brief TryLock a LockAccessor. + * @param a LockAccessor object. + * @param[out] flag Whether locking was successful, when false this indicates that this func should be called again. + */ +Result appletLockAccessorTryLock(AppletLockAccessor *a, bool *flag); + +/** + * @brief Lock a LockAccessor. + * @note Similar to \ref appletLockAccessorTryLock, except this uses timeout UINT64_MAX with the eventWait call, and this uses TryLock repeatedly until the output flag value is true. + * @param a LockAccessor object. + */ +Result appletLockAccessorLock(AppletLockAccessor *a); + +/** + * @brief Unlock a LockAccessor. + * @param a LockAccessor object. + */ +Result appletLockAccessorUnlock(AppletLockAccessor *a); + +///@} + +///@name ILibraryAppletCreator +///@{ + +/** + * @brief Creates a LibraryApplet. + * @param h AppletHolder object. + * @param id See \ref AppletId. + * @param mode See \ref LibAppletMode. + */ +Result appletCreateLibraryApplet(AppletHolder *h, AppletId id, LibAppletMode mode); + +/** + * @brief Creates a LibraryApplet. This is for when a LibraryApplet creates itself. + * @note Identical to \ref appletCreateLibraryApplet except this sets the creating_self flag to true. + * @param h AppletHolder object. + * @param id See \ref AppletId. + * @param mode See \ref LibAppletMode. + */ +Result appletCreateLibraryAppletSelf(AppletHolder *h, AppletId id, LibAppletMode mode); + +/** + * @brief TerminateAllLibraryApplets which were created by the current applet. + * @note Normally LibraryApplet cleanup should be handled via \ref AppletHolder. + */ +Result appletTerminateAllLibraryApplets(void); + +/** + * @brief AreAnyLibraryAppletsLeft which were created by the current applet. + * @param[out] out Output flag. + */ +Result appletAreAnyLibraryAppletsLeft(bool *out); + +///@} + +///@name ILibraryAppletAccessor +///@{ + +/// Closes an AppletHolder object. +void appletHolderClose(AppletHolder *h); + +/// Returns whether the AppletHolder object was initialized. +bool appletHolderActive(AppletHolder *h); + +/** + * @brief Gets the IndirectLayerConsumerHandle loaded during \ref appletCreateLibraryApplet, on [2.0.0+]. + * @note Only available when \ref LibAppletMode is ::LibAppletMode_BackgroundIndirect. + * @param h AppletHolder object. + * @param out Output IndirectLayerConsumerHandle. + */ +Result appletHolderGetIndirectLayerConsumerHandle(AppletHolder *h, u64 *out); + +/** + * @brief Starts the LibraryApplet. + * @param h AppletHolder object. + */ +Result appletHolderStart(AppletHolder *h); + +/** + * @brief Jumps to the LibraryApplet, with the current-LibraryApplet being terminated. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_LibraryApplet. + * @param h AppletHolder object. + */ +Result appletHolderJump(AppletHolder *h); + +/** + * @brief Requests the LibraryApplet to exit. The command is only used if \ref appletHolderCheckFinished returns false. + * @param h AppletHolder object. + */ +Result appletHolderRequestExit(AppletHolder *h); + +/** + * @brief Terminate the LibraryApplet. + * @param h AppletHolder object. + */ +Result appletHolderTerminate(AppletHolder *h); + +/** + * @brief Uses cmds GetAppletStateChangedEvent and RequestExit, then waits for the LibraryApplet to exit with the specified timeout. If a timeout occurs, the Terminate cmd is used. + * @param h AppletHolder object. + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. + */ +Result appletHolderRequestExitOrTerminate(AppletHolder *h, u64 timeout); + +/** + * @brief Waits for the LibraryApplet to exit. + * @param h AppletHolder object. + */ +void appletHolderJoin(AppletHolder *h); + +/** + * @brief Gets the LibraryApplet StateChangedEvent. + * @param h AppletHolder object. + */ +NX_CONSTEXPR Event *appletHolderGetExitEvent(AppletHolder *h) { + return &h->StateChangedEvent; +} + +/** + * @brief Waits on the LibraryApplet StateChangedEvent with timeout=0, and returns whether it was successful. + * @param h AppletHolder object. + */ +bool appletHolderCheckFinished(AppletHolder *h); + +/** + * @brief Gets the \ref LibAppletExitReason set by \ref appletHolderJoin. + * @param h AppletHolder object. + */ +LibAppletExitReason appletHolderGetExitReason(AppletHolder *h); + +/** + * @brief Sets OutOfFocusApplicationSuspendingEnabled. + * @note Only available with AppletType_*Application. + * @param h AppletHolder object. + * @param[in] flag Flag + */ +Result appletHolderSetOutOfFocusApplicationSuspendingEnabled(AppletHolder *h, bool flag); + +/** + * @brief PresetLibraryAppletGpuTimeSliceZero + * @note Only available with [10.0.0+]. + * @param h AppletHolder object. + */ +Result appletHolderPresetLibraryAppletGpuTimeSliceZero(AppletHolder *h); + +/** + * @brief Gets the PopInteractiveOutDataEvent. + * @param h AppletHolder object. + * @param[out] out_event Output Event. + */ +Result appletHolderGetPopInteractiveOutDataEvent(AppletHolder *h, Event **out_event); + +/** + * @brief Waits for the PopInteractiveOutDataEvent and StateChangedEvent. + * @return false for error / when StateChangedEvent was signaled, and true when PopInteractiveOutDataEvent was signaled. The latter is signaled when a new storage is available with \ref appletHolderPopInteractiveOutData where previously no storage was available (this willl not clear the event), this event is automatically cleared by the system once the last storage is popped. + * @param h AppletHolder object. + */ +bool appletHolderWaitInteractiveOut(AppletHolder *h); + +/** + * @brief Pushes a storage for LibraryApplet input. + * @note This uses \ref appletStorageClose automatically. + * @param h AppletHolder object. + * @param[in] s Storage object. + */ +Result appletHolderPushInData(AppletHolder *h, AppletStorage *s); + +/** + * @brief Pops a storage from LibraryApplet output. + * @param h AppletHolder object. + * @param[out] s Storage object. + */ +Result appletHolderPopOutData(AppletHolder *h, AppletStorage *s); + +/** + * @brief Pushes a storage for LibraryApplet Extra storage input. + * @note This uses \ref appletStorageClose automatically. + * @param h AppletHolder object. + * @param[in] s Storage object. + */ +Result appletHolderPushExtraStorage(AppletHolder *h, AppletStorage *s); + +/** + * @brief Pushes a storage for LibraryApplet Interactive input. + * @note This uses \ref appletStorageClose automatically. + * @param h AppletHolder object. + * @param[in] s Storage object. + */ +Result appletHolderPushInteractiveInData(AppletHolder *h, AppletStorage *s); + +/** + * @brief Pops a storage from LibraryApplet Interactive output. + * @param h AppletHolder object. + * @param[out] s Storage object. + */ +Result appletHolderPopInteractiveOutData(AppletHolder *h, AppletStorage *s); + +/** + * @brief Gets the \ref LibAppletInfo for the specified LibraryApplet. + * @param h AppletHolder object. + * @param[out] info \ref LibAppletInfo + */ +Result appletHolderGetLibraryAppletInfo(AppletHolder *h, LibAppletInfo *info); + +///@} + +///@name (ILibraryAppletCreator ->) IStorage +///@{ + +/** + * @brief Creates a storage. + * @param s Storage object. + * @param size Size of storage. + */ +Result appletCreateStorage(AppletStorage *s, s64 size); + +/** + * @brief Creates a TransferMemory storage. + * @param s Storage object. + * @param buffer TransferMemory buffer, will be automatically allocated if NULL. + * @param size Size of storage. + * @param writable Controls whether writing to the storage is allowed with \ref appletStorageWrite. + */ +Result appletCreateTransferMemoryStorage(AppletStorage *s, void* buffer, s64 size, bool writable); + +/** + * @brief Creates a HandleStorage. + * @note Only available on [2.0.0+]. + * @param s Storage object. + * @param inval Arbitrary input value. + * @param handle Arbitrary input handle. + */ +Result appletCreateHandleStorage(AppletStorage *s, s64 inval, Handle handle); + +/** + * @brief Creates a HandleStorage using TransferMemory. Wrapper for \ref appletCreateHandleStorage. + * @param s Storage object. + * @param buffer TransferMemory buffer, will be automatically allocated if NULL. + * @param size Size of storage. + */ +Result appletCreateHandleStorageTmem(AppletStorage *s, void* buffer, s64 size); + +/// Closes the storage object. TransferMemory closing is seperate, see \ref appletStorageCloseTmem. +/// Other applet functions which push an input storage will automatically call this. +void appletStorageClose(AppletStorage *s); + +/// Closes the TransferMemory in the storage object. For TransferMemory storage created by the current process, this must be called after the LibraryApplet finishes using it (if sent to one). +void appletStorageCloseTmem(AppletStorage *s); + +/// Gets the size of the storage. This is not usable with HandleStorage, use \ref appletStorageGetHandle or \ref appletStorageMap instead for that. +Result appletStorageGetSize(AppletStorage *s, s64 *size); + +/** + * @brief Writes to a storage. offset(+size) must be within the actual storage size. + * @note This is not usable with HandleStorage. + * @param s Storage object. + * @param offset Offset in storage. + * @param buffer Input data. + * @param size Data size. + */ +Result appletStorageWrite(AppletStorage *s, s64 offset, const void* buffer, size_t size); + +/** + * @brief Reads from a storage. offset(+size) must be within the actual storage size. + * @note This is not usable with HandleStorage. + * @param s Storage object. + * @param offset Offset in storage. + * @param buffer Input data. + * @param size Data size. + */ +Result appletStorageRead(AppletStorage *s, s64 offset, void* buffer, size_t size); + +/** + * @brief Gets data for a HandleStorage originally from \ref appletCreateHandleStorage input. + * @note Only available on [2.0.0+]. + * @param s Storage object. + * @param out Output value. + * @param handle Output handle. + */ +Result appletStorageGetHandle(AppletStorage *s, s64 *out, Handle *handle); + +/** + * @brief Maps TransferMemory for a HandleStorage. Wrapper for \ref appletCreateHandleStorage. + * @note The TransferMemory can be unmapped with \ref appletStorageCloseTmem. + * @note Do not use this if the AppletStorage already contains initialized TransferMemory state. + * @param s Storage object. + * @param addr Output mapped address (optional). + * @param size Output size (optional). + */ +Result appletStorageMap(AppletStorage *s, void** addr, size_t *size); + +///@} + +///@name IApplicationFunctions: IFunctions for AppletType_*Application. +///@{ + +/** + * @brief Pops a LaunchParameter AppletStorage, the storage will be removed from sysmodule state during this. + * @param[out] s Output storage. + * @param kind See \ref AppletLaunchParameterKind. + * @note Only available with AppletType_*Application. + * @note See also acc.h \ref accountGetPreselectedUser (wrapper for appletPopLaunchParameter etc). + */ +Result appletPopLaunchParameter(AppletStorage *s, AppletLaunchParameterKind kind); + +/** + * @brief Requests to launch the specified application. + * @note Only available with AppletType_*Application, or AppletType_LibraryApplet on [5.0.0+]. + * @param[in] application_id ApplicationId. Value 0 can be used to relaunch the current application. + * @param[in] s Optional AppletStorage object, can be NULL. This is automatically closed. When NULL on pre-4.0.0 (or with AppletType_LibraryApplet), this will internally create a tmp storage with size 0 for use with the cmd. This is the storage available to the launched application via \ref appletPopLaunchParameter with ::AppletLaunchParameterKind_UserChannel. + */ +Result appletRequestLaunchApplication(u64 application_id, AppletStorage* s); + +/** + * @brief Requests to launch the specified application, for kiosk systems. + * @note Only available with AppletType_*Application on [3.0.0+]. + * @note Identical to \ref appletRequestLaunchApplication, except this allows the user to specify the attribute fields instead of the defaults being used. + * @param[in] application_id ApplicationId + * @param[in] s Optional AppletStorage object, can be NULL. This is automatically closed. When NULL on pre-4.0.0, this will internally create a tmp storage with size 0 for use with the cmd. This is the storage available to the launched application via \ref appletPopLaunchParameter with ::AppletLaunchParameterKind_UserChannel. + * @param[in] attr Kiosk application attributes. + */ +Result appletRequestLaunchApplicationForQuest(u64 application_id, AppletStorage* s, const AppletApplicationAttributeForQuest *attr); + +/** + * @brief Gets the DesiredLanguage for the current host application control.nacp. + * @note Only available with AppletType_*Application. + * @param[out] LanguageCode Output LanguageCode, see set.h. + */ +Result appletGetDesiredLanguage(u64 *LanguageCode); + +/** + * @brief Gets the DisplayVersion for the current host application control.nacp. + * @note Only available with AppletType_*Application. + * @param[out] displayVersion Output DisplayVersion string, must be at least 0x10-bytes. This is always NUL-terminated. + */ +Result appletGetDisplayVersion(char *displayVersion); + +/** + * @brief Blocks the usage of the home button, for short (Home Menu) and long (Overlay) presses. + * @note Only available with AppletType_*Application. + * @param val Unknown. Official sw only uses hard-coded value 0 for this. + */ +Result appletBeginBlockingHomeButtonShortAndLongPressed(s64 val); + +/** + * @brief Ends the blocking started by \ref appletBeginBlockingHomeButtonShortAndLongPressed. + * @note Only available with AppletType_*Application. + */ +Result appletEndBlockingHomeButtonShortAndLongPressed(void); + +/** + * @brief Blocks the usage of the home button, for short presses (Home Menu). + * @note Only available with AppletType_*Application. + * @param val Unknown nanoseconds. Value 0 can be used. + */ +Result appletBeginBlockingHomeButton(s64 val); + +/** + * @brief Ends the blocking started by \ref appletBeginBlockingHomeButton. + * @note Only available with AppletType_*Application. + */ +Result appletEndBlockingHomeButton(void); + +/** + * @brief Notify that the app is now running, for the Application logo screen. This throws a fatal-error on failure. + * @note This will just return when applet-type isn't AppletType_Application, or when this was already used previously. Used automatically by \ref appletInitialize when __nx_applet_auto_notifyrunning is set to true (the default value). + */ +void appletNotifyRunning(bool *out); + +/** + * @brief Gets the PseudoDeviceId. This is derived from the output of a ns command, and from data in the host application control.nacp. + * @note Only available with AppletType_*Application on [2.0.0+]. + * @param[out] out Output PseudoDeviceId. + */ +Result appletGetPseudoDeviceId(Uuid *out); + +/// Set media playback state. +/// If state is set to true, screen dimming and auto sleep is disabled. +/// For *Application, this uses cmd SetMediaPlaybackStateForApplication, otherwise cmd SetMediaPlaybackState is used. +Result appletSetMediaPlaybackState(bool state); + +/// Gets whether video recording is supported. +/// See also \ref appletInitializeGamePlayRecording. +Result appletIsGamePlayRecordingSupported(bool *flag); + +/// Disable/enable video recording. Only available after \ref appletInitializeGamePlayRecording was used. +/// See also \ref appletInitializeGamePlayRecording. +Result appletSetGamePlayRecordingState(bool state); + +/// Initializes video recording. This allocates a 0x6000000-byte buffer for the TransferMemory, cleanup is handled automatically during app exit in \ref appletExit. +/// Only available with AppletType_Application on [3.0.0+], hence errors from this can be ignored. +/// Video recording is only fully available system-side with [4.0.0+]. +/// Only usable when running under an application which supports video recording. Using this is only needed when the host application control.nacp has VideoCaptureMode set to Enabled, with Automatic appletInitializeGamePlayRecording is not needed. +Result appletInitializeGamePlayRecording(void); + +/** + * @brief Requests to save the video recording, as if the Capture-button was held. + * @note Only available with AppletType_*Application on [4.0.0+]. + */ +Result appletRequestFlushGamePlayingMovieForDebug(void); + +/** + * @brief Requests a system shutdown. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_*Application on [3.0.0+]. + */ +Result appletRequestToShutdown(void); + +/** + * @brief Requests a system reboot. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_*Application on [3.0.0+]. + */ +Result appletRequestToReboot(void); + +/** + * @brief RequestToSleep + * @note Only available with AppletType_*Application on [10.0.0+]. + */ +Result appletRequestToSleep(void); + +/** + * @brief Exit the application and return to the kiosk demo menu. This terminates the current process. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_*Application on [4.0.0+], on kiosk systems (QuestFlag set). + */ +Result appletExitAndRequestToShowThanksMessage(void); + +/** + * @brief Initializes the ApplicationCopyrightFrameBuffer, with dimensions 1280x720 + the tmem for it. This is used as an overlay for screenshots. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note Cleanup for this is handled automatically during app exit in \ref appletExit. + */ +Result appletInitializeApplicationCopyrightFrameBuffer(void); + +/** + * @brief Sets the RGBA8 image for use with \ref appletInitializeApplicationCopyrightFrameBuffer. Overrides the current image, if this was already used previously. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note The specified coordinates and width/height must be within the bounds of the framebuffer setup by \ref appletInitializeApplicationCopyrightFrameBuffer. + * @param[in] buffer Input image buffer. + * @param[in] size Input image buffer size. + * @param[in] x X coordinate. Must not be negative. + * @param[in] y Y coordinate. Must not be negative. + * @param[in] width Image width. Must be >=1. + * @param[in] height Image height. Must be >=1. + * @param[in] mode \ref AppletWindowOriginMode + */ +Result appletSetApplicationCopyrightImage(const void* buffer, size_t size, s32 x, s32 y, s32 width, s32 height, AppletWindowOriginMode mode); + +/** + * @brief Sets the visibility for the image set by \ref appletSetApplicationCopyrightImage, in screenshots. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @param[in] visible Whether the image is visible. The default is true. + */ +Result appletSetApplicationCopyrightVisibility(bool visible); + +/** + * @brief Gets ApplicationPlayStatistics. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note The input ApplicationIds must be allowed via control.nacp with the current host application. The minimum allowed ApplicationId is the ApplicationId for the current application. + * @param stats Output \ref PdmApplicationPlayStatistics array. + * @param application_ids Input ApplicationIds array. + * @param count Total entries in the input/output arrays. + * @param total_out Total output entries. + */ +Result appletQueryApplicationPlayStatistics(PdmApplicationPlayStatistics *stats, const u64 *application_ids, s32 count, s32 *total_out); + +/** + * @brief Same as \ref appletQueryApplicationPlayStatistics except this gets playstats specific to the input userId. + * @note Only available with AppletType_*Application on [6.0.0+]. + * @param[in] uid \ref AccountUid + * @param[out] stats Output \ref PdmApplicationPlayStatistics array. + * @param[in] application_ids Input ApplicationIds array. + * @param[in] count Total entries in the input/output arrays. + * @param[out] total_out Total output entries. + */ +Result appletQueryApplicationPlayStatisticsByUid(AccountUid uid, PdmApplicationPlayStatistics *stats, const u64 *application_ids, s32 count, s32 *total_out); + +/** + * @brief Launches Application {current_ApplicationId}+programIndex. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. + * @param[in] programIndex ProgramIndex, must be 0x0-0xFF. 0 is the same as the current application. ProgramIndex values where the application is not installed should not be used. + * @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. + * @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. + */ +Result appletExecuteProgram(s32 programIndex, const void* buffer, size_t size); + +/** + * @brief Launches the specified ApplicationId. + * @note Only available with AppletType_*Application on [5.0.0+], with DebugMode enabled. + * @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. + * @param[in] application_id ApplicationId. + * @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. + * @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. + */ +Result appletJumpToSubApplicationProgramForDevelopment(u64 application_id, const void* buffer, size_t size); + +/** + * @brief Relaunches the current Application. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. + * @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. + * @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. + */ +Result appletRestartProgram(const void* buffer, size_t size); + +/** + * @brief Gets the ProgramIndex of the program which launched this program. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @param[out] programIndex ProgramIndex, -1 when there was no previous program. + */ +Result appletGetPreviousProgramIndex(s32 *programIndex); + +/** + * @brief SetDelayTimeToAbortOnGpuError + * @note Only available with AppletType_*Application on [11.0.0+]. + * @param[in] val Input nanoseconds value. + */ +Result appletSetDelayTimeToAbortOnGpuError(u64 val); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletTryPopFromFriendInvitationStorageChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note This is used by \ref friendsGetFriendInvitationNotificationEvent. + * @note Only available with AppletType_*Application on [9.0.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetFriendInvitationStorageChannelEvent(Event *out_event); + +/** + * @brief Pops a storage from the FriendInvitation StorageChannel. + * @note This is used by \ref friendsTryPopFriendInvitationNotificationInfo. + * @note Only available with AppletType_*Application on [9.0.0+]. + * @param[out] s Storage object. + */ +Result appletTryPopFromFriendInvitationStorageChannel(AppletStorage *s); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletTryPopFromNotificationStorageChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note This is used by \ref notifGetNotificationSystemEvent. + * @note Only available with AppletType_*Application on [9.0.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetNotificationStorageChannelEvent(Event *out_event); + +/** + * @brief Pops a storage from the Notification StorageChannel. + * @note This is used by \ref notifTryPopNotifiedApplicationParameter. + * @note Only available with AppletType_*Application on [9.0.0+]. + * @param[out] s Storage object. + */ +Result appletTryPopFromNotificationStorageChannel(AppletStorage *s); + +/** + * @brief GetHealthWarningDisappearedSystemEvent + * @note Only available with AppletType_*Application on [9.0.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetHealthWarningDisappearedSystemEvent(Event *out_event); + +/** + * @brief SetHdcpAuthenticationActivated + * @note Only available with AppletType_*Application on [9.0.0+]. + * @param[in] flag Whether HdcpAuthentication is activated. + */ +Result appletSetHdcpAuthenticationActivated(bool flag); + +/** + * @brief GetLastApplicationExitReason + * @note Only available with AppletType_*Application on [11.0.0+]. + * @param[out] out Output value. + */ +Result appletGetLastApplicationExitReason(s32 *out); + +/** + * @brief CreateMovieMaker. Do not use this directly, use \ref grcCreateMovieMaker instead. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @param[out] srv_out Output Service for applet IMovieMaker. + * @param[in] tmem TransferMemory + */ +Result appletCreateMovieMaker(Service* srv_out, TransferMemory *tmem); + +/** + * @brief Launches the jit-sysmodule when it was not previously launched by this cmd. Returns 0 when it was previously launched. + * @note Only available with AppletType_*Application on [5.0.0+]. + * @note Requires the jit-sysmodule to actually be installed. + */ +Result appletPrepareForJit(void); + +///@} + +///@name IHomeMenuFunctions: IFunctions for AppletType_SystemApplet and on [15.0.0+] for AppletType_LibraryApplet. +///@{ + +/** + * @brief RequestToGetForeground + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + */ +Result appletRequestToGetForeground(void); + +/** + * @brief LockForeground + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + */ +Result appletLockForeground(void); + +/** + * @brief UnlockForeground + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + */ +Result appletUnlockForeground(void); + +/** + * @brief Pops a storage from the general channel. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + * @param[out] s Storage object. + */ +Result appletPopFromGeneralChannel(AppletStorage *s); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletPopFromGeneralChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetPopFromGeneralChannelEvent(Event *out_event); + +/** + * @brief Gets a \ref AppletLockAccessor for HomeButtonWriter. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. + * @note Similar to using \ref appletGetWriterLockAccessorEx with inval=0. + * @param a LockAccessor object. + */ +Result appletGetHomeButtonWriterLockAccessor(AppletLockAccessor *a); + +/** + * @brief IsSleepEnabled + * @note Only available with AppletType_SystemApplet on [11.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. + * @param[out] out Output flag. + */ +Result appletIsSleepEnabled(bool *out); + +/** + * @brief PopRequestLaunchApplicationForDebug + * @note Only available with AppletType_SystemApplet on [6.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. + * @param[out] uids Output array of \ref AccountUid. + * @param[in] count Size of the uids array in entries, must be at least the size stored in state. + * @param[out] application_id Output ApplicationId. + * @param[out] total_out Total output userID entries. + */ +Result appletPopRequestLaunchApplicationForDebug(AccountUid *uids, s32 count, u64 *application_id, s32 *total_out); + +/** + * @brief IsForceTerminateApplicationDisabledForDebug + * @note Only available with AppletType_SystemApplet on [9.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. + * @param[out] out Output flag. 0 when DebugMode is not enabled, otherwise this is loaded from a system-setting. + */ +Result appletIsForceTerminateApplicationDisabledForDebug(bool *out); + +/** + * @brief Launches DevMenu and the dev Overlay-applet. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_SystemApplet on [8.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. + * @note This verifies that DebugMode is enabled, then uses a ns cmd. That cmd then loads the system-settings for these two ProgramIds (which normally only exist on devunits), and verifies that these programs are installed + launches them. + */ +Result appletLaunchDevMenu(void); + +/** + * @brief SetLastApplicationExitReason + * @note Only available with AppletType_SystemApplet on [11.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. + * @param[in] reason Reason + */ +Result appletSetLastApplicationExitReason(s32 reason); + +///@} + +///@name IGlobalStateController +///@{ + +/** + * @brief Start the sequence for entering sleep-mode. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + * @param[in] flag Flag, official sw uses hard-coded value = true. + */ +Result appletStartSleepSequence(bool flag); + +/** + * @brief Start the system-shutdown sequence. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + */ +Result appletStartShutdownSequence(void); + +/** + * @brief Start the system-reboot sequence. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + */ +Result appletStartRebootSequence(void); + +/** + * @brief IsAutoPowerDownRequested. Uses an idle:sys cmd internally. + * @note Only available with AppletType_SystemApplet on [7.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + * @param[out] out Output flag. + */ +Result appletIsAutoPowerDownRequested(bool *out); + +/** + * @brief LoadAndApplyIdlePolicySettings. Uses an idle:sys cmd internally. + * @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + */ +Result appletLoadAndApplyIdlePolicySettings(void); + +/** + * @brief NotifyCecSettingsChanged. Uses an omm cmd internally. + * @note Only available with AppletType_SystemApplet on [2.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + */ +Result appletNotifyCecSettingsChanged(void); + +/** + * @brief Sets the DefaultHomeButtonLongPressTime. + * @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + * @param[in] val Input value. + */ +Result appletSetDefaultHomeButtonLongPressTime(s64 val); + +/** + * @brief UpdateDefaultDisplayResolution. Uses an omm cmd internally. + * @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + */ +Result appletUpdateDefaultDisplayResolution(void); + +/** + * @brief ShouldSleepOnBoot. Uses an omm cmd internally. + * @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + * @param[out] out Output flag. + */ +Result appletShouldSleepOnBoot(bool *out); + +/** + * @brief Gets an Event which is signaled for HdcpAuthenticationFailed. + * @note Only available with AppletType_SystemApplet on [4.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetHdcpAuthenticationFailedEvent(Event *out_event); + +///@} + +///@name IApplicationCreator +///@{ + +/** + * @brief Creates an Application. + * @note Only available with AppletType_SystemApplet. + * @param[out] a \ref AppletApplication + * @param[in] application_id ApplicationId. + */ +Result appletCreateApplication(AppletApplication *a, u64 application_id); + +/** + * @brief Pops a \ref AppletApplication for a requested Application launch. + * @note Only available with AppletType_SystemApplet. + * @param[out] a \ref AppletApplication + */ +Result appletPopLaunchRequestedApplication(AppletApplication *a); + +/** + * @brief Creates a SystemApplication. + * @note Only available with AppletType_SystemApplet. + * @param[out] a \ref AppletApplication + * @param[in] system_application_id SystemApplicationId. + */ +Result appletCreateSystemApplication(AppletApplication *a, u64 system_application_id); + +/** + * @brief PopFloatingApplicationForDevelopment. + * @note Only available with AppletType_SystemApplet. Should not be used if no FloatingApplication is available. + * @param[out] a \ref AppletApplication + */ +Result appletPopFloatingApplicationForDevelopment(AppletApplication *a); + +///@} + +///@name IApplicationAccessor +///@{ + +/** + * @brief Close an \ref AppletApplication. + * @param a \ref AppletApplication + */ +void appletApplicationClose(AppletApplication *a); + +/** + * @brief Returns whether the AppletApplication object was initialized. + * @param a \ref AppletApplication + */ +bool appletApplicationActive(AppletApplication *a); + +/** + * @brief Starts the Application. + * @param a \ref AppletApplication + */ +Result appletApplicationStart(AppletApplication *a); + +/** + * @brief Requests the Application to exit. + * @param a \ref AppletApplication + */ +Result appletApplicationRequestExit(AppletApplication *a); + +/** + * @brief Terminate the Application. + * @param a \ref AppletApplication + */ +Result appletApplicationTerminate(AppletApplication *a); + +/** + * @brief Waits for the Application to exit. + * @param a \ref AppletApplication + */ +void appletApplicationJoin(AppletApplication *a); + +/** + * @brief Waits on the Application StateChangedEvent with timeout=0, and returns whether it was successful. + * @param a \ref AppletApplication + */ +bool appletApplicationCheckFinished(AppletApplication *a); + +/** + * @brief Gets the \ref AppletApplicationExitReason set by \ref appletApplicationJoin. + * @param a \ref AppletApplication + */ +AppletApplicationExitReason appletApplicationGetExitReason(AppletApplication *a); + +/** + * @brief RequestForApplicationToGetForeground. + * @param a \ref AppletApplication + */ +Result appletApplicationRequestForApplicationToGetForeground(AppletApplication *a); + +/** + * @brief TerminateAllLibraryApplets which were created by the Application. + */ +Result appletApplicationTerminateAllLibraryApplets(AppletApplication *a); + +/** + * @brief AreAnyLibraryAppletsLeft which were created by the Application. + * @param a \ref AppletApplication + * @param[out] out Output flag. + */ +Result appletApplicationAreAnyLibraryAppletsLeft(AppletApplication *a, bool *out); + +/** + * @brief Calls the same func as \ref appletHolderRequestExitOrTerminate with the output IAppletAccessor from the GetCurrentLibraryApplet cmd. + * @param a \ref AppletApplication + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. + */ +Result appletApplicationRequestExitLibraryAppletOrTerminate(AppletApplication *a, u64 timeout); + +/** + * @brief Gets the ApplicationId for the Application. + * @param a \ref AppletApplication + * @param[out] application_id Output ApplicationId. + */ +Result appletApplicationGetApplicationId(AppletApplication *a, u64 *application_id); + +/** + * @brief Pushes a LaunchParameter AppletStorage to the Application. + * @note This uses \ref appletStorageClose automatically. + * @param a \ref AppletApplication + * @param[in] kind \ref AppletLaunchParameterKind + * @param[in] s Input storage. + */ +Result appletApplicationPushLaunchParameter(AppletApplication *a, AppletLaunchParameterKind kind, AppletStorage* s); + +/** + * @brief Gets the \ref NacpStruct for the Application. + * @note Not usable when the \ref AppletApplication is for an AppletType_SystemApplication. + * @param a \ref AppletApplication + * @param[out] nacp \ref NacpStruct + */ +Result appletApplicationGetApplicationControlProperty(AppletApplication *a, NacpStruct *nacp); + +/** + * @brief Gets the \ref AppletApplicationLaunchProperty for the Application. + * @note Only available on [2.0.0+]. Not usable when the \ref AppletApplication is for an AppletType_SystemApplication. + * @param a \ref AppletApplication + * @param[out] out \ref AppletApplicationLaunchProperty + */ +Result appletApplicationGetApplicationLaunchProperty(AppletApplication *a, AppletApplicationLaunchProperty *out); + +/** + * @brief Gets the \ref AppletApplicationLaunchRequestInfo for the Application. + * @note Only available on [6.0.0+]. + * @param a \ref AppletApplication + * @param[out] out \ref AppletApplicationLaunchRequestInfo + */ +Result appletApplicationGetApplicationLaunchRequestInfo(AppletApplication *a, AppletApplicationLaunchRequestInfo *out); + +/** + * @brief SetUsers for the Application. + * @note Only available on [6.0.0+]. + * @param a \ref AppletApplication + * @param[in] uids Input array of \ref AccountUid. + * @param[in] count Size of the uids array in entries, must be <=ACC_USER_LIST_SIZE. + * @param[in] flag When this flag is true, this just clears the users_available state flag to 0 and returns. + */ +Result appletApplicationSetUsers(AppletApplication *a, const AccountUid *uids, s32 count, bool flag); + +/** + * @brief CheckRightsEnvironmentAvailable. + * @note Only available on [6.0.0+]. + * @param a \ref AppletApplication + * @param[out] out Output flag. + */ +Result appletApplicationCheckRightsEnvironmentAvailable(AppletApplication *a, bool *out); + +/** + * @brief GetNsRightsEnvironmentHandle. + * @note Only available on [6.0.0+]. + * @param a \ref AppletApplication + * @param[out] handle Output NsRightsEnvironmentHandle. + */ +Result appletApplicationGetNsRightsEnvironmentHandle(AppletApplication *a, u64 *handle); + +/** + * @brief Gets an array of userIds for the Application DesirableUids. + * @note Only available on [6.0.0+]. + * @note qlaunch only uses 1 userId with this. + * @param a \ref AppletApplication + * @param[out] uids Output array of \ref AccountUid. + * @param[in] count Size of the uids array in entries, must be at least the size stored in state. + * @param[out] total_out Total output entries. + */ +Result appletApplicationGetDesirableUids(AppletApplication *a, AccountUid *uids, s32 count, s32 *total_out); + +/** + * @brief ReportApplicationExitTimeout. + * @note Only available on [6.0.0+]. + * @param a \ref AppletApplication + */ +Result appletApplicationReportApplicationExitTimeout(AppletApplication *a); + +/** + * @brief Sets the \ref AppletApplicationAttribute for the Application. + * @note Only available on [8.0.0+]. + * @param a \ref AppletApplication + * @param[in] attr \ref AppletApplicationAttribute + */ +Result appletApplicationSetApplicationAttribute(AppletApplication *a, const AppletApplicationAttribute *attr); + +/** + * @brief Gets whether the savedata specified by the input ApplicationId is accessible. + * @note Only available on [8.0.0+]. + * @param a \ref AppletApplication + * @param[in] application_id ApplicationId for the savedata. + * @param[out] out Output flag. + */ +Result appletApplicationHasSaveDataAccessPermission(AppletApplication *a, u64 application_id, bool *out); + +/** + * @brief Creates a storage using the specified input then pushes it to the FriendInvitation StorageChannel. + * @note The system will clear the StorageChannel before pushing the storage. + * @note Only available on [9.0.0+]. + * @param a \ref AppletApplication + * @param[in] uid \ref AccountUid + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + */ +Result appletApplicationPushToFriendInvitationStorageChannel(AppletApplication *a, AccountUid uid, const void* buffer, u64 size); + +/** + * @brief Creates a storage using the specified input then pushes it to the Notification StorageChannel. + * @note The system will clear the StorageChannel before pushing the storage. + * @note Only available on [9.0.0+]. + * @param a \ref AppletApplication + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + */ +Result appletApplicationPushToNotificationStorageChannel(AppletApplication *a, const void* buffer, u64 size); + +/** + * @brief RequestApplicationSoftReset + * @note Only available on [10.0.0+]. + * @param a \ref AppletApplication + */ +Result appletApplicationRequestApplicationSoftReset(AppletApplication *a); + +/** + * @brief RestartApplicationTimer + * @note Only available on [10.0.0+]. + * @param a \ref AppletApplication + */ +Result appletApplicationRestartApplicationTimer(AppletApplication *a); + +///@} + +///@name ILibraryAppletSelfAccessor +///@{ + +/** + * @brief Pops a storage from current-LibraryApplet input. + * @note Only available with AppletType_LibraryApplet. + * @param[out] s Storage object. + */ +Result appletPopInData(AppletStorage *s); + +/** + * @brief Pushes a storage for current-LibraryApplet output. + * @note Only available with AppletType_LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletPushOutData(AppletStorage *s); + +/** + * @brief Pops a storage from current-LibraryApplet Interactive input. + * @note Only available with AppletType_LibraryApplet. + * @param[out] s Storage object. + */ +Result appletPopInteractiveInData(AppletStorage *s); + +/** + * @brief Pushes a storage for current-LibraryApplet Interactive output. + * @note Only available with AppletType_LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletPushInteractiveOutData(AppletStorage *s); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletPopInData where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note Only available with AppletType_LibraryApplet. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetPopInDataEvent(Event *out_event); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletPopInteractiveInData where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note Only available with AppletType_LibraryApplet. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetPopInteractiveInDataEvent(Event *out_event); + +/** + * @brief Gets the \ref LibAppletInfo for the current LibraryApplet. + * @note Only available with AppletType_LibraryApplet. + * @param[out] info \ref LibAppletInfo + */ +Result appletGetLibraryAppletInfo(LibAppletInfo *info); + +/** + * @brief Gets the \ref AppletIdentityInfo for the MainApplet. + * @note Only available with AppletType_LibraryApplet. + * @param[out] info \ref AppletIdentityInfo + */ +Result appletGetMainAppletIdentityInfo(AppletIdentityInfo *info); + +/** + * @brief CanUseApplicationCore + * @note Only available with AppletType_LibraryApplet. + * @param[out] out Output flag. + */ +Result appletCanUseApplicationCore(bool *out); + +/** + * @brief Gets the \ref AppletIdentityInfo for the CallerApplet. + * @note Only available with AppletType_LibraryApplet. + * @param[out] info \ref AppletIdentityInfo + */ +Result appletGetCallerAppletIdentityInfo(AppletIdentityInfo *info); + +/** + * @brief Gets the \ref NacpStruct for the MainApplet. + * @note Only available with AppletType_LibraryApplet on [2.0.0+]. + * @param[out] nacp \ref NacpStruct + */ +Result appletGetMainAppletApplicationControlProperty(NacpStruct *nacp); + +/** + * @brief Gets the NcmStorageId for the MainApplet. + * @note Only available with AppletType_LibraryApplet on [2.0.0+]. + * @param[out] storageId \ref NcmStorageId + */ +Result appletGetMainAppletStorageId(NcmStorageId *storageId); + +/** + * @brief Gets an array of \ref AppletIdentityInfo for the CallerStack. + * @note Only available with AppletType_LibraryApplet on [3.0.0+]. + * @param[out] stack Output array of \ref AppletIdentityInfo. + * @param[in] count Size of the stack array. + * @param[out] total_out Total output entries. + */ +Result appletGetCallerAppletIdentityInfoStack(AppletIdentityInfo *stack, s32 count, s32 *total_out); + +/** + * @brief Gets the \ref AppletIdentityInfo for the NextReturnDestinationApplet. + * @note Only available with AppletType_LibraryApplet on [4.0.0+]. + * @param[out] info \ref AppletIdentityInfo + */ +Result appletGetNextReturnDestinationAppletIdentityInfo(AppletIdentityInfo *info); + +/** + * @brief Gets the DesirableKeyboardLayout previously set by \ref appletSetDesirableKeyboardLayout. An error is returned when it's not set. + * @note Only available with AppletType_LibraryApplet on [4.0.0+]. + * @param[out] layout Output \ref SetKeyboardLayout. + */ +Result appletGetDesirableKeyboardLayout(SetKeyboardLayout *layout); + +/** + * @brief Pops a storage from current-LibraryApplet Extra input. + * @note Only available with AppletType_LibraryApplet. + * @param[out] s Storage object. + */ +Result appletPopExtraStorage(AppletStorage *s); + +/** + * @brief Gets an Event which is signaled when a new storage is available with \ref appletPopExtraStorage where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. + * @note Only available with AppletType_LibraryApplet. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetPopExtraStorageEvent(Event *out_event); + +/** + * @brief Unpop a storage for current-LibraryApplet input. + * @note Only available with AppletType_LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletUnpopInData(AppletStorage *s); + +/** + * @brief Unpop a storage for current-LibraryApplet Extra input. + * @note Only available with AppletType_LibraryApplet. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletUnpopExtraStorage(AppletStorage *s); + +/** + * @brief Gets the IndirectLayerProducerHandle. + * @note Only available with AppletType_LibraryApplet on [2.0.0+]. + * @param[out] out Output IndirectLayerProducerHandle. + */ +Result appletGetIndirectLayerProducerHandle(u64 *out); + +/** + * @brief Gets the DesiredLanguage for the MainApplet. + * @note Only available with AppletType_LibraryApplet on [4.0.0+]. + * @param[out] LanguageCode Output LanguageCode, see set.h. + */ +Result appletGetMainAppletApplicationDesiredLanguage(u64 *LanguageCode); + +/** + * @brief Gets the ApplicationId for the currently running Application. + * @note Only available with AppletType_LibraryApplet on [8.0.0+]. + * @param[out] application_id Output ApplicationId, 0 when no Application is running. + */ +Result appletGetCurrentApplicationId(u64 *application_id); + +/** + * @brief Exits the current applet. Same as \ref appletHolderRequestExit except this is for the current applet. + * @note Only available with AppletType_LibraryApplet on [6.0.0+]. + */ +Result appletRequestExitToSelf(void); + +/** + * @brief CreateGameMovieTrimmer. Do not use this directly, use \ref grcTrimGameMovie instead. + * @note Only available with AppletType_LibraryApplet on [4.0.0+]. + * @note See also \ref appletReserveResourceForMovieOperation and \ref appletUnreserveResourceForMovieOperation. + * @param[out] srv_out Output Service for grc IGameMovieTrimmer. + * @param[in] tmem TransferMemory + */ +Result appletCreateGameMovieTrimmer(Service* srv_out, TransferMemory *tmem); + +/** + * @brief ReserveResourceForMovieOperation. Must be used at some point prior to \ref appletCreateGameMovieTrimmer. + * @note Only available with AppletType_LibraryApplet on [5.0.0+]. + */ +Result appletReserveResourceForMovieOperation(void); + +/** + * @brief UnreserveResourceForMovieOperation. Must be used at some point after all finished with GameMovieTrimmer usage (\ref appletCreateGameMovieTrimmer). + * @note Only available with AppletType_LibraryApplet on [5.0.0+]. + */ +Result appletUnreserveResourceForMovieOperation(void); + +/** + * @brief Gets an array of userIds for the MainApplet AvailableUsers. + * @note Only available with AppletType_LibraryApplet on [6.0.0+]. + * @param[out] uids Output array of \ref AccountUid. + * @param[in] count Size of the uids array in entries, must be at least ACC_USER_LIST_SIZE. + * @param[out] flag When true, this indicates that no users are available. + * @param[out] total_out Total output entries. This is -1 when flag is true. + */ +Result appletGetMainAppletAvailableUsers(AccountUid *uids, s32 count, bool *flag, s32 *total_out); + +/** + * @brief SetApplicationMemoryReservation + * @note Only available with AppletType_LibraryApplet on [10.0.0+]. + * @note An Application must be currently running. + * @param[in] val Input value. + */ +Result appletSetApplicationMemoryReservation(u64 val); + +/** + * @brief ShouldSetGpuTimeSliceManually + * @note Only available with AppletType_LibraryApplet on [10.0.0+]. + * @param[out] out Output flag. + */ +Result appletShouldSetGpuTimeSliceManually(bool *out); + +///@} + +///@name IOverlayFunctions: IFunctions for AppletType_OverlayApplet. +///@{ + +/** + * @brief Stops forwarding the input to the foreground app. + * @note Only available with AppletType_OverlayApplet. + * @note You have to call this to receive inputs through the hid service when running as the overlay applet. + */ +Result appletBeginToWatchShortHomeButtonMessage(void); + +/** + * @brief Forwards input to the foreground app. + * @note Only available with AppletType_OverlayApplet. + * @note After calling this the overlay applet won't receive any input until \ref appletBeginToWatchShortHomeButtonMessage is called again. + */ +Result appletEndToWatchShortHomeButtonMessage(void); + +/** + * @brief Gets the ApplicationId for displaying the logo screen during application launch. + * @note Only available with AppletType_OverlayApplet. + * @param[out] application_id Output ApplicationId, 0 when no application is running. + */ +Result appletGetApplicationIdForLogo(u64 *application_id); + +/** + * @brief Sets the GpuTimeSliceBoost. + * @note Only available with AppletType_OverlayApplet. + * @param[in] val Input value. + */ +Result appletSetGpuTimeSliceBoost(u64 val); + +/** + * @brief Sets AutoSleepTimeAndDimmingTimeEnabled. + * @note Only available with AppletType_OverlayApplet on [2.0.0+]. + * @param[in] flag Flag + */ +Result appletSetAutoSleepTimeAndDimmingTimeEnabled(bool flag); + +/** + * @brief TerminateApplicationAndSetReason + * @note Only available with AppletType_OverlayApplet on [2.0.0+]. + * @param[in] reason Result reason. + */ +Result appletTerminateApplicationAndSetReason(Result reason); + +/** + * @brief Sets ScreenShotPermissionGlobally. + * @note Only available with AppletType_OverlayApplet on [3.0.0+]. + * @param[in] flag Flag + */ +Result appletSetScreenShotPermissionGlobally(bool flag); + +/** + * @brief Start the system-shutdown sequence. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_OverlayApplet on [6.0.0+]. + */ +Result appletStartShutdownSequenceForOverlay(void); + +/** + * @brief Start the system-reboot sequence. This will enter an infinite-sleep-loop on success. + * @note Only available with AppletType_OverlayApplet on [6.0.0+]. + */ +Result appletStartRebootSequenceForOverlay(void); + +/** + * @brief SetHealthWarningShowingState + * @note Only available with AppletType_OverlayApplet on [9.0.0+]. + * @param[in] flag Flag + */ +Result appletSetHealthWarningShowingState(bool flag); + +/** + * @brief IsHealthWarningRequired + * @note Only available with AppletType_OverlayApplet on [10.0.0+]. + * @param[out] out Output flag. + */ +Result appletIsHealthWarningRequired(bool *out); + +/** + * @brief Enables HID input for the OverlayApplet, without disabling input for the foreground applet. Generally \ref appletBeginToWatchShortHomeButtonMessage / appletEndToWatchShortHomeButtonMessage should be used instead. + * @note Only available with AppletType_OverlayApplet on [5.0.0+]. + */ +Result appletBeginToObserveHidInputForDevelop(void); + +///@} + +///@name IAppletCommonFunctions +///@{ + +/** + * @brief Reads the ThemeStorage for the current applet. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. + * @note offset(+size) must be <=0x400. + * @param[out] buffer Output buffer data. + * @param[in] size Size to read. + * @param[in] offset Offset within the ThemeStorage. + * @param[out] transfer_size Actual read size. + */ +Result appletReadThemeStorage(void* buffer, size_t size, u64 offset, u64 *transfer_size); + +/** + * @brief Writes the ThemeStorage for the current applet. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. + * @note offset(+size) must be <=0x400. + * @param[in] buffer Input buffer data. + * @param[in] size Size to write. + * @param[in] offset Offset within the ThemeStorage. + */ +Result appletWriteThemeStorage(const void* buffer, size_t size, u64 offset); + +/** + * @brief This is similar to \ref appletPushToAppletBoundChannelForDebug (no DebugMode check), except the used channel is loaded from elsewhere and must be in the range 31-32. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + */ +Result appletPushToAppletBoundChannel(AppletStorage *s); + +/** + * @brief This is similar to \ref appletTryPopFromAppletBoundChannelForDebug (no DebugMode check), except the used channel is loaded from elsewhere and must be in the range 31-32. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. + * @param[out] s Storage object. + */ +Result appletTryPopFromAppletBoundChannel(AppletStorage *s); + +/** + * @brief Gets the DisplayLogicalResolution. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. + * @param[out] width Output width. + * @param[out] height Output height. + */ +Result appletGetDisplayLogicalResolution(s32 *width, s32 *height); + +/** + * @brief Sets the DisplayMagnification. This is essentially layer image crop, for everything non-Overlay. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. + * @note x and width are multiplied with the same width value returned by \ref appletGetDisplayLogicalResolution, so these should be in the range 0.0f-1.0f. Likewise for y and height, except these are multipled with the height value. + * @param[in] x X position. + * @param[in] y Y position. + * @param[in] width Width. + * @param[in] height Height. + */ +Result appletSetDisplayMagnification(float x, float y, float width, float height); + +/** + * @brief Sets whether HomeButtonDoubleClick is enabled. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. + * @param[in] flag Flag + */ +Result appletSetHomeButtonDoubleClickEnabled(bool flag); + +/** + * @brief Gets whether HomeButtonDoubleClick is enabled. + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. + * @param[out] out Output flag. + */ +Result appletGetHomeButtonDoubleClickEnabled(bool *out); + +/** + * @brief IsHomeButtonShortPressedBlocked + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [10.0.0+]. + * @param[out] out Output flag. + */ +Result appletIsHomeButtonShortPressedBlocked(bool *out); + +/** + * @brief IsVrModeCurtainRequired + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [11.0.0+]. + * @param[out] out Output flag. + */ +Result appletIsVrModeCurtainRequired(bool *out); + +/** + * @brief SetCpuBoostRequestPriority + * @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [11.0.0+]. + * @param[in] priority Priority + */ +Result appletSetCpuBoostRequestPriority(s32 priority); + +///@} + +///@name IDebugFunctions +///@{ + +/** + * @brief Open an \ref AppletApplication for the currently running Application. + * @note Should not be used when no Application is running. + * @note Only available on [1.0.0-9.2.0]. + * @param[out] a \ref AppletApplication + */ +Result appletOpenMainApplication(AppletApplication *a); + +/** + * @brief Perform SystemButtonPressing with the specified \ref AppletSystemButtonType. + * @param[in] type \ref AppletSystemButtonType + */ +Result appletPerformSystemButtonPressing(AppletSystemButtonType type); + +/** + * @brief InvalidateTransitionLayer. + */ +Result appletInvalidateTransitionLayer(void); + +/** + * @brief Requests to launch the specified Application, with the specified users. + * @note Only available on [6.0.0+]. + * @param[in] application_id ApplicationId. + * @param[in] uids Input array of \ref AccountUid. + * @param[in] total_uids Total input uids, must be <=ACC_USER_LIST_SIZE. + * @param[in] flag Whether to use the specified buffer to create a storage which will be pushed for ::AppletLaunchParameterKind_UserChannel. + * @param[in] buffer Buffer containing the above storage data. + * @param[in] size Size of the storage buffer. + */ +Result appletRequestLaunchApplicationWithUserAndArgumentForDebug(u64 application_id, const AccountUid *uids, s32 total_uids, bool flag, const void* buffer, size_t size); + +/** + * @brief Gets the \ref AppletResourceUsageInfo. + * @note Only available on [6.0.0+]. + * @param[out] info \ref AppletResourceUsageInfo + */ +Result appletGetAppletResourceUsageInfo(AppletResourceUsageInfo *info); + +/** + * @brief The channel must match the value already stored in state when the state value is non-zero, otherwise an error is returned. When the state value is 0, the channel is written into state. Then the input storage is pushed to the StorageChannel. + * @note Only available on [9.0.0+]. DebugMode must be enabled. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + * @param[in] channel Channel. + */ +Result appletPushToAppletBoundChannelForDebug(AppletStorage *s, s32 channel); + +/** + * @brief The channel must not be 0 and must match the value previously saved by \ref appletPushToAppletBoundChannelForDebug, otherwise errors are returned. Then the output storage is popped from the StorageChannel. + * @note Only available on [9.0.0+]. DebugMode must be enabled. + * @param[out] s Storage object. + * @param[in] channel Channel. + */ +Result appletTryPopFromAppletBoundChannelForDebug(AppletStorage *s, s32 channel); + +/** + * @brief Clears a StorageChannel, pushes the input storage there, and writes the ApplicationId into state. + * @note Only available on [9.0.0+]. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + * @param[in] application_id ApplicationId + */ +Result appletAlarmSettingNotificationEnableAppEventReserve(AppletStorage *s, u64 application_id); + +/** + * @brief Clears the StorageChannel/saved-ApplicationId used by \ref appletAlarmSettingNotificationEnableAppEventReserve. + * @note Only available on [9.0.0+]. + */ +Result appletAlarmSettingNotificationDisableAppEventReserve(void); + +/** + * @brief Same as \ref appletApplicationPushToNotificationStorageChannel except this uses the MainApplication. + * @note Only available on [9.0.0+]. + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + */ +Result appletAlarmSettingNotificationPushAppEventNotify(const void* buffer, u64 size); + +/** + * @brief Clears a StorageChannel, pushes the input storage there, and writes the ApplicationId into state. + * @note Only available on [9.0.0+]. + * @note This uses \ref appletStorageClose automatically. + * @param[in] s Storage object. + * @param[in] application_id ApplicationId + */ +Result appletFriendInvitationSetApplicationParameter(AppletStorage *s, u64 application_id); + +/** + * @brief Clears the StorageChannel/saved-ApplicationId used by \ref appletFriendInvitationSetApplicationParameter. + * @note Only available on [9.0.0+]. + */ +Result appletFriendInvitationClearApplicationParameter(void); + +/** + * @brief Same as \ref appletApplicationPushToFriendInvitationStorageChannel except this uses the MainApplication. + * @note Only available on [9.0.0+]. + * @param[in] uid \ref AccountUid + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + */ +Result appletFriendInvitationPushApplicationParameter(AccountUid uid, const void* buffer, u64 size); + +///@} + +///@name Common cmds +///@{ + +/** + * @brief SetTerminateResult + * @note Only available with AppletType_*Application. Or with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. + * @param[in] res Result + */ +Result appletSetTerminateResult(Result res); + +/** + * @brief Gets the LaunchStorageInfo. + * @note Only available with AppletType_*Application on [2.0.0+], or with AppletType_LibraryApplet on [9.0.0+]. + * @param[out] app_storageId Same as AppletApplicationLaunchProperty::app_storageId. + * @param[out] update_storageId Same as AppletApplicationLaunchProperty::update_storageId. + */ +Result appletGetLaunchStorageInfoForDebug(NcmStorageId *app_storageId, NcmStorageId *update_storageId); + +/** + * @brief Gets an Event which is signaled for GpuErrorDetected. + * @note Only available with AppletType_*Application on [8.0.0+], or with AppletType_LibraryApplet on [9.0.0+]. + * @note The Event must be closed by the user once finished with it. + * @note Official sw waits on this Event from a seperate thread, triggering an abort when it's signaled. + * @param[out] out_event Output Event with autoclear=false. + */ +Result appletGetGpuErrorDetectedSystemEvent(Event *out_event); + +/** + * @brief Sets HandlingHomeButtonShortPressedEnabled. + * @note Only available with AppletType_OverlayApplet on [8.0.0+]. Or with non-AppletType_OverlayApplet on [9.1.0+]. + * @param[in] flag Flag + */ +Result appletSetHandlingHomeButtonShortPressedEnabled(bool flag); + +///@} + +///@name State / other +///@{ + +/** + * @brief Gets the cached \ref AppletInfo loaded during \ref appletInitialize. This will return NULL when the info is not initialized, due to not running as AppletType_LibraryApplet, or when any of the used cmds fail. + * @note Only available with AppletType_LibraryApplet. + */ +AppletInfo *appletGetAppletInfo(void); + +/** + * @brief Gets a notification message, see \ref AppletMessage. + */ +Result appletGetMessage(u32 *msg); + +/** + * @brief Processes the current applet status using the specified msg. + * @param msg Notification message, normally from \ref appletGetMessage. + * @return Whether the application should continue running. + */ +bool appletProcessMessage(u32 msg); + +/** + * @brief Processes the current applet status. Generally used within a main loop. + * @note Uses \ref appletGetMessage and \ref appletProcessMessage internally. + * @return Whether the application should continue running. + */ +bool appletMainLoop(void); + + +/** + * @brief Sets up an applet status hook. + * @param cookie Hook cookie to use. + * @param callback Function to call when applet's status changes. + * @param param User-defined parameter to pass to the callback. + */ +void appletHook(AppletHookCookie* cookie, AppletHookFn callback, void* param); + +/** + * @brief Removes an applet status hook. + * @param cookie Hook cookie to remove. + */ +void appletUnhook(AppletHookCookie* cookie); + +/// These return state which is updated by appletMainLoop() when notifications are received. +AppletOperationMode appletGetOperationMode(void); +ApmPerformanceMode appletGetPerformanceMode(void); +AppletFocusState appletGetFocusState(void); + +/** + * @brief Sets the current \ref AppletFocusHandlingMode. + * @note Should only be called with AppletType_Application. + */ +Result appletSetFocusHandlingMode(AppletFocusHandlingMode mode); + +///@} diff --git a/src/libnx/wrapper/switch/services/applet.nim b/src/libnx/wrapper/switch/services/applet.nim new file mode 100644 index 0000000..a03b178 --- /dev/null +++ b/src/libnx/wrapper/switch/services/applet.nim @@ -0,0 +1,3099 @@ +## * +## @file applet.h +## @brief Applet (applet) service IPC wrapper. +## @note For wrappers which launch LibraryApplets etc, see switch/applets/. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/apm, ../services/pdm, ../services/caps, + ../services/pm, ../services/ncm_types, ../services/acc, ../services/set, + ../kernel/tmem, ../kernel/event, ../nacp + +## / AppletType + +type + AppletType* = enum + AppletTypeNone = -2, AppletTypeDefault = -1, AppletTypeApplication = 0, + AppletTypeSystemApplet = 1, AppletTypeLibraryApplet = 2, + AppletTypeOverlayApplet = 3, AppletTypeSystemApplication = 4 + + +## / OperationMode + +type + AppletOperationMode* = enum + AppletOperationModeHandheld = 0, ## /< Handheld + AppletOperationModeConsole = 1 ## /< Console (Docked / TV-mode) + + +## / applet hook types. + +type + AppletHookType* = enum + AppletHookTypeOnFocusState = 0, ## /< ::AppletMessage_FocusStateChanged + AppletHookTypeOnOperationMode, ## /< ::AppletMessage_OperationModeChanged + AppletHookTypeOnPerformanceMode, ## /< ::AppletMessage_PerformanceModeChanged + AppletHookTypeOnExitRequest, ## /< ::AppletMessage_ExitRequested + AppletHookTypeOnResume, ## /< ::AppletMessage_Resume + AppletHookTypeOnCaptureButtonShortPressed, ## /< ::AppletMessage_CaptureButtonShortPressed + AppletHookTypeOnAlbumScreenShotTaken, ## /< ::AppletMessage_AlbumScreenShotTaken + AppletHookTypeRequestToDisplay, ## /< ::AppletMessage_RequestToDisplay + AppletHookTypeMax ## /< Number of applet hook types. + + +## / AppletMessage, for \ref appletGetMessage. See also \ref AppletHookType. + +type + AppletMessage* = enum + AppletMessageExitRequest = 4, ## /< Exit request. + AppletMessageFocusStateChanged = 15, ## /< FocusState changed. + AppletMessageResume = 16, ## /< Current applet execution was resumed. + AppletMessageOperationModeChanged = 30, ## /< OperationMode changed. + AppletMessagePerformanceModeChanged = 31, ## /< PerformanceMode changed. + AppletMessageRequestToDisplay = 51, ## /< Display requested, see \ref appletApproveToDisplay. + AppletMessageCaptureButtonShortPressed = 90, ## /< Capture button was short-pressed. + AppletMessageAlbumScreenShotTaken = 92, ## /< Screenshot was taken. + AppletMessageAlbumRecordingSaved = 93 ## /< AlbumRecordingSaved + + +## / FocusState + +type + AppletFocusState* = enum + AppletFocusStateInFocus = 1, ## /< Applet is focused. + AppletFocusStateOutOfFocus = 2, ## /< Out of focus - LibraryApplet open. + AppletFocusStateBackground = 3 ## /< Out of focus - HOME menu open / console is sleeping. + + +## / FocusHandlingMode + +type + AppletFocusHandlingMode* = enum + AppletFocusHandlingModeSuspendHomeSleep = 0, ## /< Suspend only when HOME menu is open / console is sleeping (default). + AppletFocusHandlingModeNoSuspend, ## /< Don't suspend when out of focus. + AppletFocusHandlingModeSuspendHomeSleepNotify, ## /< Suspend only when HOME menu is open / console is sleeping but still receive OnFocusState hook. + AppletFocusHandlingModeAlwaysSuspend, ## /< Always suspend when out of focus, regardless of the reason. + AppletFocusHandlingModeMax ## /< Number of focus handling modes. + + +## / LaunchParameterKind + +type + AppletLaunchParameterKind* = enum + AppletLaunchParameterKindUserChannel = 1, ## /< UserChannel. Application-specific LaunchParameter. + AppletLaunchParameterKindPreselectedUser = 2, ## /< account PreselectedUser + AppletLaunchParameterKindUnknown = 3 ## /< Unknown if used by anything? + + +## / AppletId + +type + AppletId* = enum + AppletIdNone = 0x00, ## /< None + AppletIdApplication = 0x01, ## /< Application. Not valid for use with LibraryApplets. + AppletIdOverlayApplet = 0x02, ## /< 010000000000100C "overlayDisp" + AppletIdSystemAppletMenu = 0x03, ## /< 0100000000001000 "qlaunch" (SystemAppletMenu) + AppletIdSystemApplication = 0x04, ## /< 0100000000001012 "starter" SystemApplication. + AppletIdLibraryAppletAuth = 0x0A, ## /< 0100000000001001 "auth" + AppletIdLibraryAppletCabinet = 0x0B, ## /< 0100000000001002 "cabinet" + AppletIdLibraryAppletController = 0x0C, ## /< 0100000000001003 "controller" + AppletIdLibraryAppletDataErase = 0x0D, ## /< 0100000000001004 "dataErase" + AppletIdLibraryAppletError = 0x0E, ## /< 0100000000001005 "error" + AppletIdLibraryAppletNetConnect = 0x0F, ## /< 0100000000001006 "netConnect" + AppletIdLibraryAppletPlayerSelect = 0x10, ## /< 0100000000001007 "playerSelect" + AppletIdLibraryAppletSwkbd = 0x11, ## /< 0100000000001008 "swkbd" + AppletIdLibraryAppletMiiEdit = 0x12, ## /< 0100000000001009 "miiEdit" + AppletIdLibraryAppletWeb = 0x13, ## /< 010000000000100A "LibAppletWeb" WebApplet applet + AppletIdLibraryAppletShop = 0x14, ## /< 010000000000100B "LibAppletShop" ShopN applet + AppletIdLibraryAppletPhotoViewer = 0x15, ## /< 010000000000100D "photoViewer" + AppletIdLibraryAppletSet = 0x16, ## /< 010000000000100E "set" (This applet is currently not present on retail devices.) + AppletIdLibraryAppletOfflineWeb = 0x17, ## /< 010000000000100F "LibAppletOff" offlineWeb applet + AppletIdLibraryAppletLoginShare = 0x18, ## /< 0100000000001010 "LibAppletLns" loginShare web-applet + AppletIdLibraryAppletWifiWebAuth = 0x19, ## /< 0100000000001011 "LibAppletAuth" wifiWebAuth applet + AppletIdLibraryAppletMyPage = 0x1A ## /< 0100000000001013 "myPage" + + +## / LibraryAppletMode + +type + LibAppletMode* = enum + LibAppletModeAllForeground = 0, ## /< Foreground. + LibAppletModeBackground = 1, ## /< Background. + LibAppletModeNoUi = 2, ## /< No UI. + LibAppletModeBackgroundIndirect = 3, ## /< Background with indirect display, see \ref appletHolderGetIndirectLayerConsumerHandle. + LibAppletModeAllForegroundInitiallyHidden = 4 ## /< Foreground except initially hidden. + + +## / LibraryAppletExitReason + +type + LibAppletExitReason* = enum + LibAppletExitReasonNormal = 0, LibAppletExitReasonCanceled = 1, + LibAppletExitReasonAbnormal = 2, LibAppletExitReasonUnexpected = 10 + + +## / AppletApplicationExitReason + +type + AppletApplicationExitReason* = enum + AppletApplicationExitReasonNormal = 0, AppletApplicationExitReasonUnknown1 = 1, + AppletApplicationExitReasonUnknown2 = 2, + AppletApplicationExitReasonUnknown3 = 3, + AppletApplicationExitReasonUnknown4 = 4, + AppletApplicationExitReasonUnknown5 = 5, + AppletApplicationExitReasonUnexpected = 100 + + +## / ThemeColorType + +type + AppletThemeColorType* = enum + AppletThemeColorTypeDefault = 0, AppletThemeColorTypeUnknown1 = 1, + AppletThemeColorTypeUnknown2 = 2, AppletThemeColorTypeUnknown3 = 3 + + +## / Mode values for \ref appletSetTvPowerStateMatchingMode. + +type + AppletTvPowerStateMatchingMode* = enum + AppletTvPowerStateMatchingModeUnknown0 = 0, ## /< Unknown. + AppletTvPowerStateMatchingModeUnknown1 = 1 ## /< Unknown. + + +## / Type values for \ref appletPerformSystemButtonPressingIfInFocus. + +type + AppletSystemButtonType* = enum + AppletSystemButtonTypeHomeButtonShortPressing = 1, ## /< Short-pressing with the HOME-button. + AppletSystemButtonTypeHomeButtonLongPressing = 2, ## /< Long-pressing with the HOME-button. + AppletSystemButtonTypePowerButtonShortPressing = 3, ## /< Short-pressing with the Power-button. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonTypePowerButtonLongPressing = 4, ## /< Long-pressing with the Power-button. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonTypeShutdown = 5, ## /< Shutdown the system, as if the Power-button was held for longer than ::AppletSystemButtonType_PowerButtonLongPressing. Only available with \ref appletPerformSystemButtonPressing. + AppletSystemButtonTypeCaptureButtonShortPressing = 6, ## /< Short-pressing with the Capture-button. + AppletSystemButtonTypeCaptureButtonLongPressing = 7 ## /< Long-pressing with the Capture-button. + + +## / Permission values for \ref appletSetScreenShotPermission. + +type + AppletScreenShotPermission* = enum + AppletScreenShotPermissionInherit = 0, ## /< Inherit from parent applet. + AppletScreenShotPermissionEnable = 1, ## /< Enable. + AppletScreenShotPermissionDisable = 2 ## /< Disable. + + +## / Extension values for \ref appletSetIdleTimeDetectionExtension / \ref appletGetIdleTimeDetectionExtension, for extending user inactivity detection. + +type + AppletIdleTimeDetectionExtension* = enum + AppletIdleTimeDetectionExtensionNone = 0, ## /< No extension. + AppletIdleTimeDetectionExtensionExtended = 1, ## /< Extended + AppletIdleTimeDetectionExtensionExtendedUnsafe = 2 ## /< ExtendedUnsafe + + +## / Input policy values for \ref appletSetInputDetectionPolicy. + +type + AppletInputDetectionPolicy* = enum + AppletInputDetectionPolicyUnknown0 = 0, ## /< Unknown. + AppletInputDetectionPolicyUnknown1 = 1 ## /< Unknown. + + +## / Input mode values for \ref appletSetWirelessPriorityMode. + +type + AppletWirelessPriorityMode* = enum + AppletWirelessPriorityModeDefault = 1, ## /< Default + AppletWirelessPriorityModeOptimizedForWlan = 2 ## /< OptimizedForWlan + + +## / CaptureSharedBuffer for the IDisplayController commands. + +type + AppletCaptureSharedBuffer* = enum + AppletCaptureSharedBufferLastApplication = 0, ## /< LastApplication + AppletCaptureSharedBufferLastForeground = 1, ## /< LastForeground + AppletCaptureSharedBufferCallerApplet = 2 ## /< CallerApplet + + +## / WindowOriginMode + +type + AppletWindowOriginMode* = enum + AppletWindowOriginModeLowerLeft = 0, ## /< LowerLeft + AppletWindowOriginModeUpperLeft = 1 ## /< UpperLeft + + +## / ProgramSpecifyKind for the ExecuteProgram cmd. Controls the type of the u64 passed to the ExecuteProgram cmd. + +type + AppletProgramSpecifyKind* = enum + AppletProgramSpecifyKindExecuteProgram = 0, ## /< u8 ProgramIndex. + AppletProgramSpecifyKindJumpToSubApplicationProgramForDevelopment = 1, ## /< u64 application_id. Only available when DebugMode is enabled. + AppletProgramSpecifyKindRestartProgram = 2 ## /< u64 = value 0. + + +## / applet hook function. + +type + AppletHookFn* = proc (hook: AppletHookType; param: pointer) {.cdecl.} + +## / applet hook cookie. + +type + AppletHookCookie* {.bycopy.} = object + next*: ptr AppletHookCookie ## /< Next cookie. + callback*: AppletHookFn ## /< Hook callback. + param*: pointer ## /< Callback parameter. + + +## / LockAccessor + +type + AppletLockAccessor* {.bycopy.} = object + s*: Service ## /< ILockAccessor + event*: Event ## /< Event from the GetEvent cmd, with autoclear=false. + + +## / applet IStorage + +type + AppletStorage* {.bycopy.} = object + s*: Service ## /< IStorage + tmem*: TransferMemory ## /< TransferMemory + + +## / LibraryApplet state. + +type + AppletHolder* {.bycopy.} = object + s*: Service ## /< ILibraryAppletAccessor + stateChangedEvent*: Event ## /< Output from GetAppletStateChangedEvent, autoclear=false. + popInteractiveOutDataEvent*: Event ## /< Output from GetPopInteractiveOutDataEvent, autoclear=false. + mode*: LibAppletMode ## /< See ref \ref LibAppletMode. + layerHandle*: U64 ## /< Output from GetIndirectLayerConsumerHandle on [2.0.0+]. + creatingSelf*: bool ## /< When set, indicates that the LibraryApplet is creating itself. + exitreason*: LibAppletExitReason ## /< Set by \ref appletHolderJoin using the output from cmd GetResult, see \ref LibAppletExitReason. + + +## / IApplicationAccessor container. + +type + AppletApplication* {.bycopy.} = object + s*: Service ## /< IApplicationAccessor + stateChangedEvent*: Event ## /< Output from GetAppletStateChangedEvent, autoclear=false. + exitreason*: AppletApplicationExitReason ## /< Set by \ref appletApplicationJoin using the output from cmd GetResult, see \ref AppletApplicationExitReason. + + +## / GpuErrorHandler + +type + AppletGpuErrorHandler* {.bycopy.} = object + s*: Service ## /< IGpuErrorHandler + + +## / Used by \ref appletInitialize with __nx_applet_AppletAttribute for cmd OpenLibraryAppletProxy (AppletType_LibraryApplet), on [3.0.0+]. The default for this struct is all-zero. + +type + AppletAttribute* {.bycopy.} = object + flag*: U8 ## /< Flag. When non-zero, two state fields are set to 1. + reserved*: array[0x7F, U8] ## /< Unused. + + +## / LibraryAppletInfo + +type + LibAppletInfo* {.bycopy.} = object + appletId*: AppletId ## /< \ref AppletId + mode*: LibAppletMode ## /< \ref LibAppletMode + + +## / AppletProcessLaunchReason, from GetLaunchReason. + +type + AppletProcessLaunchReason* {.bycopy.} = object + flag*: U8 ## /< When non-zero, indicates that OpenCallingLibraryApplet should be used. + unkX1*: array[3, U8] ## /< Always zero. + + +## / Cached info for the current LibraryApplet, from \ref appletGetAppletInfo. + +type + AppletInfo* {.bycopy.} = object + info*: LibAppletInfo ## /< Output from \ref appletGetLibraryAppletInfo. + callerFlag*: bool ## /< Loaded from AppletProcessLaunchReason::flag, indicates that the below AppletHolder is initialized. + caller*: AppletHolder ## /< \ref AppletHolder for the CallingLibraryApplet, automatically closed by \ref appletExit when needed. + + +## / IdentityInfo + +type + AppletIdentityInfo* {.bycopy.} = object + appletId*: AppletId ## /< \ref AppletId + pad*: U32 ## /< Padding. + applicationId*: U64 ## /< ApplicationId, only set with appletId == ::AppletId_application. + + +## / Attributes for launching applications for Quest. + +type + AppletApplicationAttributeForQuest* {.bycopy.} = object + unkX0*: U32 ## /< See AppletApplicationAttribute::unk_x0. + unkX4*: U32 ## /< See AppletApplicationAttribute::unk_x4. + volume*: cfloat ## /< [7.0.0+] See AppletApplicationAttribute::volume. + + +## / ApplicationAttribute + +type + AppletApplicationAttribute* {.bycopy.} = object + unkX0*: U32 ## /< Default is 0 for non-Quest. Only used when non-zero: unknown value in seconds. + unkX4*: U32 ## /< Default is 0 for non-Quest. Only used when non-zero: unknown value in seconds. + volume*: cfloat ## /< Audio volume. Must be in the range of 0.0f-1.0f. The default is 1.0f. + unused*: array[0x14, U8] ## /< Unused. Default is 0. + + +## / ApplicationLaunchProperty + +type + AppletApplicationLaunchProperty* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + version*: U32 ## /< Application version. + appStorageId*: U8 ## /< \ref NcmStorageId for the Application. + updateStorageId*: U8 ## /< \ref NcmStorageId for the Application update. + unkXa*: U8 ## /< Unknown. + pad*: U8 ## /< Padding. + + +## / ApplicationLaunchRequestInfo + +type + AppletApplicationLaunchRequestInfo* {.bycopy.} = object + unkX0*: U32 ## /< Unknown. The default is 0x0 with \ref appletCreateSystemApplication, 0x3 with \ref appletCreateApplication. + unkX4*: U32 ## /< Unknown. The default is 0x0 with \ref appletCreateSystemApplication, 0x3 with \ref appletCreateApplication. + unkX8*: array[0x8, U8] ## /< Unknown. The default is 0x0. + + +## / AppletResourceUsageInfo, from \ref appletGetAppletResourceUsageInfo. + +type + AppletResourceUsageInfo* {.bycopy.} = object + counter0*: U32 ## /< Unknown counter. + counter1*: U32 ## /< Unknown counter. + counter2*: U32 ## /< Output from ns cmd GetRightsEnvironmentCountForDebug. + unused*: array[0x14, U8] ## /< Always zero. + +proc appletInitialize*(): Result {.cdecl, importc: "appletInitialize".} +## / Initialize applet, called automatically during app startup. + +proc appletExit*() {.cdecl, importc: "appletExit".} +## / Exit applet, called automatically during app exit. + +proc appletGetServiceSessionProxy*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_Proxy".} +## / Gets the Service object for the actual "appletOE"/"appletAE" service session. + +proc appletGetServiceSessionAppletCommonFunctions*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_AppletCommonFunctions".} +## / Gets the Service object for IAppletCommonFunctions. Only initialized with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. + +proc appletGetServiceSessionFunctions*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_Functions".} +## / Gets the Service object for I*Functions, specific to each AppletType (IApplicationFunctions for AppletType_*Application). Not initialized with AppletType_LibraryApplet pre-15.0.0. On [15.0.0+] with AppletType_LibraryApplet this returns the object for IHomeMenuFunctions. + +proc appletGetServiceSessionGlobalStateController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_GlobalStateController".} +## / Gets the Service object for IGlobalStateController. Only initialized with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. + +proc appletGetServiceSessionApplicationCreator*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_ApplicationCreator".} +## / Gets the Service object for IApplicationCreator. Only initialized with AppletType_SystemApplet. + +proc appletGetServiceSessionLibraryAppletSelfAccessor*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_LibraryAppletSelfAccessor".} +## / Gets the Service object for ILibraryAppletSelfAccessor. Only initialized with AppletType_LibraryApplet. + +proc appletGetServiceSessionProcessWindingController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_ProcessWindingController".} +## / Gets the Service object for IProcessWindingController. Only initialized with AppletType_LibraryApplet. + +proc appletGetServiceSessionLibraryAppletCreator*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_LibraryAppletCreator".} +## / Gets the Service object for ILibraryAppletCreator. + +proc appletGetServiceSessionCommonStateGetter*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_CommonStateGetter".} +## / Gets the Service object for ICommonStateGetter. + +proc appletGetServiceSessionSelfController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_SelfController".} +## / Gets the Service object for ISelfController. + +proc appletGetServiceSessionWindowController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_WindowController".} +## / Gets the Service object for IWindowController. + +proc appletGetServiceSessionAudioController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_AudioController".} +## / Gets the Service object for IAudioController. + +proc appletGetServiceSessionDisplayController*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_DisplayController".} +## / Gets the Service object for IDisplayController. + +proc appletGetServiceSessionDebugFunctions*(): ptr Service {.cdecl, + importc: "appletGetServiceSession_DebugFunctions".} +## / Gets the Service object for IDebugFunctions. + +proc appletGetAppletResourceUserId*(): U64 {.cdecl, + importc: "appletGetAppletResourceUserId".} +## / Get the cached AppletResourceUserId. + +proc appletGetAppletType*(): AppletType {.cdecl, importc: "appletGetAppletType".} +## / Get the \ref AppletType. + +proc appletSetThemeColorType*(theme: AppletThemeColorType) {.cdecl, + importc: "appletSetThemeColorType".} +## / Sets the state field for \ref AppletThemeColorType. + +proc appletGetThemeColorType*(): AppletThemeColorType {.cdecl, + importc: "appletGetThemeColorType".} +## / Gets the state field for \ref AppletThemeColorType. Used internally by \ref libappletArgsCreate. + +proc appletGetCradleStatus*(status: ptr U8): Result {.cdecl, + importc: "appletGetCradleStatus".} +## /@name ICommonStateGetter +## /@{ +## * +## @brief Gets the CradleStatus. +## @param[out] status Output Dock status. +## + +proc appletGetBootMode*(mode: ptr PmBootMode): Result {.cdecl, + importc: "appletGetBootMode".} +## * +## @brief Gets the BootMode which originated from \ref pmbmGetBootMode. +## @param[out] mode \ref PmBootMode +## + +proc appletRequestToAcquireSleepLock*(): Result {.cdecl, + importc: "appletRequestToAcquireSleepLock".} +## * +## @brief Request to AcquireSleepLock. +## @note On success, this then uses cmd GetAcquiredSleepLockEvent and waits on that event. +## + +proc appletReleaseSleepLock*(): Result {.cdecl, importc: "appletReleaseSleepLock".} +## * +## @brief Release the SleepLock. +## + +proc appletReleaseSleepLockTransiently*(): Result {.cdecl, + importc: "appletReleaseSleepLockTransiently".} +## * +## @brief Release the SleepLock transiently. +## @note On success, this then uses cmd GetAcquiredSleepLockEvent and waits on that event. +## + +proc appletGetWakeupCount*(`out`: ptr U64): Result {.cdecl, + importc: "appletGetWakeupCount".} +## * +## @brief GetWakeupCount +## @note Only available with [11.0.0+]. +## @param[out] out Output value. +## + +proc appletPushToGeneralChannel*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPushToGeneralChannel".} +## * +## @brief Pushes a storage to the general channel. Used for sending requests to SystemApplet. +## @note This is not usable under an Application, however it is usable under a LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletGetHomeButtonReaderLockAccessor*(a: ptr AppletLockAccessor): Result {. + cdecl, importc: "appletGetHomeButtonReaderLockAccessor".} +## * +## @brief Gets a \ref AppletLockAccessor for HomeButtonReader. +## @note Similar to using \ref appletGetReaderLockAccessorEx with inval=0. +## @param a LockAccessor object. +## + +proc appletGetReaderLockAccessorEx*(a: ptr AppletLockAccessor; inval: U32): Result {. + cdecl, importc: "appletGetReaderLockAccessorEx".} +## * +## @brief Gets a Reader \ref AppletLockAccessor. +## @note Only available with [2.0.0+]. +## @param a LockAccessor object. +## @param[in] inval Input value, must be 0-3. 0 = HomeButton. +## + +proc appletGetWriterLockAccessorEx*(a: ptr AppletLockAccessor; inval: U32): Result {. + cdecl, importc: "appletGetWriterLockAccessorEx".} +## * +## @brief Gets a Writer \ref AppletLockAccessor. +## @note Only available with [7.0.0+]. On older sysvers, this is only available with AppletType_SystemApplet on [2.0.0+]. +## @param a LockAccessor object. +## @param[in] inval Input value, must be 0-3. 0 = HomeButton. +## + +proc appletGetCradleFwVersion*(out0: ptr U32; out1: ptr U32; out2: ptr U32; out3: ptr U32): Result {. + cdecl, importc: "appletGetCradleFwVersion".} +## * +## @brief Gets the Dock firmware version. +## @note Only available with [2.0.0+]. +## @param[out] out0 First output value. +## @param[out] out1 Second output value. +## @param[out] out2 Third output value. +## @param[out] out3 Fourth output value. +## + +proc appletIsVrModeEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsVrModeEnabled".} +## * +## @brief Gets whether VrMode is enabled. +## @note Only available with [3.0.0+]. +## @param out Output flag +## + +proc appletSetVrModeEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetVrModeEnabled".} +## * +## @brief Sets whether VrMode is enabled. +## @note This is only fully usable system-side with [6.0.0+]. +## @note For checking Parental Controls, see \ref pctlIsStereoVisionPermitted. +## @note On pre-7.0.0 this uses cmd SetVrModeEnabled internally, while on [7.0.0+] this uses cmds BeginVrModeEx/EndVrModeEx. +## @param flag Flag +## + +proc appletSetLcdBacklightOffEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetLcdBacklightOffEnabled".} +## * +## @brief Sets whether the LCD screen backlight is turned off. +## @note Only available with [4.0.0+]. +## @param[in] flag Flag +## + +proc appletIsInControllerFirmwareUpdateSection*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsInControllerFirmwareUpdateSection".} +## * +## @brief Gets the ControllerFirmwareUpdateSection flag. +## @note Only available with [3.0.0+]. +## @param[out] out Output flag. +## + +proc appletSetVrPositionForDebug*(x: S32; y: S32; width: S32; height: S32): Result {. + cdecl, importc: "appletSetVrPositionForDebug".} +## * +## @brief SetVrPositionForDebug +## @note The cached value loaded from \ref setsysGetDebugModeFlag must be 1, otherwise an error is returned. +## @note Only available with [11.0.0+]. +## @param[in] x X, must not be negative. x+width must be <=1280. +## @param[in] y Y, must not be negative. y+height must be <=720. +## @param[in] width Width, must be 1-1280. +## @param[in] height Height, must be 1-720. +## + +proc appletGetDefaultDisplayResolution*(width: ptr S32; height: ptr S32): Result {. + cdecl, importc: "appletGetDefaultDisplayResolution".} +## * +## @brief Gets the DefaultDisplayResolution. +## @note Only available with [3.0.0+]. +## @param[out] width Output width. +## @param[out] height Output height. +## + +proc appletGetDefaultDisplayResolutionChangeEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "appletGetDefaultDisplayResolutionChangeEvent".} +## * +## @brief Gets an Event which is signaled when the output from \ref appletGetDefaultDisplayResolution changes. +## @note Only available with [3.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc appletGetHdcpAuthenticationState*(state: ptr S32): Result {.cdecl, + importc: "appletGetHdcpAuthenticationState".} +## * +## @brief Gets the HdcpAuthenticationState. +## @note Only available with [4.0.0+]. +## @param[out] state Output state. +## + +proc appletGetHdcpAuthenticationStateChangeEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "appletGetHdcpAuthenticationStateChangeEvent".} +## * +## @brief Gets an Event which is signaled when the output from \ref appletGetHdcpAuthenticationState changes. +## @note Only available with [4.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc appletSetTvPowerStateMatchingMode*(mode: AppletTvPowerStateMatchingMode): Result {. + cdecl, importc: "appletSetTvPowerStateMatchingMode".} +## * +## @brief Sets the \ref AppletTvPowerStateMatchingMode. +## @note Only available with [5.0.0+]. +## @param[in] mode \ref AppletTvPowerStateMatchingMode +## + +proc appletGetApplicationIdByContentActionName*(applicationId: ptr U64; + name: cstring): Result {.cdecl, + importc: "appletGetApplicationIdByContentActionName".} +## * +## @brief Gets the ApplicationId for the specified ContentActionName string. +## @note Only available when the current applet is an AppletType_SystemApplication on [5.1.0+]. +## @param[out] application_id ApplicationId. +## @param[in] name ContentActionName string. +## + +proc appletSetCpuBoostMode*(mode: ApmCpuBoostMode): Result {.cdecl, + importc: "appletSetCpuBoostMode".} +## * +## @brief Sets the \ref ApmCpuBoostMode. +## @note Only available with [7.0.0+] (not fully usable system-side with 6.x). +## @param mode \ref ApmCpuBoostMode. +## + +proc appletCancelCpuBoostMode*(): Result {.cdecl, + importc: "appletCancelCpuBoostMode".} +## * +## @brief CancelCpuBoostMode +## @note Only available with [10.0.0+]. +## + +proc appletGetBuiltInDisplayType*(`out`: ptr S32): Result {.cdecl, + importc: "appletGetBuiltInDisplayType".} +## * +## @brief GetBuiltInDisplayType +## @note Only available with [11.0.0+]. +## @param[out] out Output value. +## + +proc appletPerformSystemButtonPressingIfInFocus*(`type`: AppletSystemButtonType): Result {. + cdecl, importc: "appletPerformSystemButtonPressingIfInFocus".} +## * +## @brief Perform SystemButtonPressing with the specified \ref AppletSystemButtonType. Internally this cmd checks a state field, verifies that the type is allowed, then runs the same func as \ref appletPerformSystemButtonPressing internally. +## @note Only available with [6.0.0+]. +## @param[in] type \ref AppletSystemButtonType +## + +proc appletSetPerformanceConfigurationChangedNotification*(flag: bool): Result {. + cdecl, importc: "appletSetPerformanceConfigurationChangedNotification".} +## * +## @brief Sets whether PerformanceConfigurationChangedNotification is enabled. +## @note Only available with [7.0.0+]. +## @param[in] flag Whether to enable the notification. +## + +proc appletGetCurrentPerformanceConfiguration*(performanceConfiguration: ptr U32): Result {. + cdecl, importc: "appletGetCurrentPerformanceConfiguration".} +## * +## @brief Gets the current PerformanceConfiguration. +## @note Only available with [7.0.0+]. +## @param PerformanceConfiguration Output PerformanceConfiguration. +## + +proc appletOpenMyGpuErrorHandler*(g: ptr AppletGpuErrorHandler): Result {.cdecl, + importc: "appletOpenMyGpuErrorHandler".} +## * +## @brief Opens an \ref AppletGpuErrorHandler. +## @note The cached value loaded from \ref setsysGetDebugModeFlag must be 1, otherwise an error is returned. +## @note Only available with [11.0.0+]. +## @param[out] g \ref AppletGpuErrorHandler +## + +proc appletGetOperationModeSystemInfo*(info: ptr U32): Result {.cdecl, + importc: "appletGetOperationModeSystemInfo".} +## * +## @brief Gets the OperationModeSystemInfo. +## @note Only available with [7.0.0+]. +## @param[out] info Output info. +## + +proc appletGetSettingsPlatformRegion*(`out`: ptr SetSysPlatformRegion): Result {. + cdecl, importc: "appletGetSettingsPlatformRegion".} +## * +## @brief This uses \ref setsysGetPlatformRegion internally. +## @note Only available with [9.0.0+]. +## @param[out] out \ref SetSysPlatformRegion +## + +proc appletActivateMigrationService*(): Result {.cdecl, + importc: "appletActivateMigrationService".} +## * +## @brief ActivateMigrationService +## @note Only available with [10.0.0+]. +## + +proc appletDeactivateMigrationService*(): Result {.cdecl, + importc: "appletDeactivateMigrationService".} +## * +## @brief DeactivateMigrationService +## @note Only available with [10.0.0+]. +## + +proc appletDisableSleepTillShutdown*(): Result {.cdecl, + importc: "appletDisableSleepTillShutdown".} +## * +## @brief DisableSleepTillShutdown +## @note Only available with [11.0.0+]. +## + +proc appletSuppressDisablingSleepTemporarily*(val: U64): Result {.cdecl, + importc: "appletSuppressDisablingSleepTemporarily".} +## * +## @brief SuppressDisablingSleepTemporarily +## @param[in] val Nanoseconds value. +## @note Only available with [11.0.0+]. +## + +proc appletSetRequestExitToLibraryAppletAtExecuteNextProgramEnabled*(): Result {. + cdecl, + importc: "appletSetRequestExitToLibraryAppletAtExecuteNextProgramEnabled".} +## * +## @brief SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled +## @note Only available with [11.0.0+]. +## + +proc appletGpuErrorHandlerClose*(g: ptr AppletGpuErrorHandler) {.cdecl, + importc: "appletGpuErrorHandlerClose".} +## /@} +## /@name IGpuErrorHandler +## /@{ +## * +## @brief Close an \ref AppletGpuErrorHandler. +## @param g \ref AppletGpuErrorHandler +## + +proc appletGpuErrorHandlerGetManualGpuErrorInfoSize*( + g: ptr AppletGpuErrorHandler; `out`: ptr U64): Result {.cdecl, + importc: "appletGpuErrorHandlerGetManualGpuErrorInfoSize".} +## * +## @brief Gets the size of the info available with \ref appletGpuErrorHandlerGetManualGpuErrorInfo. +## @param g \ref AppletGpuErrorHandler +## @param[out] out Output size. +## + +proc appletGpuErrorHandlerGetManualGpuErrorInfo*(g: ptr AppletGpuErrorHandler; + buffer: pointer; size: csize_t; `out`: ptr U64): Result {.cdecl, + importc: "appletGpuErrorHandlerGetManualGpuErrorInfo".} +## * +## @brief GetManualGpuErrorInfo +## @param g \ref AppletGpuErrorHandler +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size, must be >= the output size from \ref appletGpuErrorHandlerGetManualGpuErrorInfoSize. +## @param[out] out Output value. +## + +proc appletGpuErrorHandlerGetManualGpuErrorDetectionSystemEvent*( + g: ptr AppletGpuErrorHandler; outEvent: ptr Event): Result {.cdecl, + importc: "appletGpuErrorHandlerGetManualGpuErrorDetectionSystemEvent".} +## * +## @brief GetManualGpuErrorDetectionSystemEvent +## @param g \ref AppletGpuErrorHandler +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletGpuErrorHandlerFinishManualGpuErrorHandling*( + g: ptr AppletGpuErrorHandler): Result {.cdecl, importc: "appletGpuErrorHandlerFinishManualGpuErrorHandling".} +## * +## @brief FinishManualGpuErrorHandling +## @param g \ref AppletGpuErrorHandler +## + +proc appletLockExit*(): Result {.cdecl, importc: "appletLockExit".} +## /@} +## /@name ISelfController +## /@{ +## * +## @brief Delay exiting until \ref appletUnlockExit is called, with a 15 second timeout once exit is requested. +## @note When exit is requested \ref appletMainLoop will return false, hence any main-loop using appletMainLoop will exit. This allows the app to handle cleanup post-main-loop instead of being force-terminated. +## @note If the above timeout occurs after exit was requested where \ref appletUnlockExit was not called, the process will be forced-terminated. +## @note \ref appletUnlockExit must be used before main() returns. +## + +proc appletUnlockExit*(): Result {.cdecl, importc: "appletUnlockExit".} +## / Unlocks exiting, see \ref appletLockExit. + +proc appletEnterFatalSection*(): Result {.cdecl, importc: "appletEnterFatalSection".} +## * +## @brief Enter FatalSection. +## + +proc appletLeaveFatalSection*(): Result {.cdecl, importc: "appletLeaveFatalSection".} +## * +## @brief Leave FatalSection. +## + +proc appletSetScreenShotPermission*(permission: AppletScreenShotPermission): Result {. + cdecl, importc: "appletSetScreenShotPermission".} +## * +## @brief Controls whether screenshot-capture is allowed. +## @param permission \ref AppletScreenShotPermission +## + +proc appletSetRestartMessageEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetRestartMessageEnabled".} +## * +## @brief Sets whether ::AppletMessage_Resume is enabled. +## @param[in] flag Whether to enable the notification. +## + +proc appletSetScreenShotAppletIdentityInfo*(info: ptr AppletIdentityInfo): Result {. + cdecl, importc: "appletSetScreenShotAppletIdentityInfo".} +## * +## @brief Sets the \ref AppletIdentityInfo for screenshots. +## @param[in] info \ref AppletIdentityInfo +## + +proc appletSetControllerFirmwareUpdateSection*(flag: bool): Result {.cdecl, + importc: "appletSetControllerFirmwareUpdateSection".} +## * +## @brief Sets ControllerFirmwareUpdateSection. +## @note Only available with [3.0.0+]. +## @note This throws error 0x40280 when the internal state flag already matches the input value. +## @param[in] flag Flag +## + +proc appletSetRequiresCaptureButtonShortPressedMessage*(flag: bool): Result {.cdecl, + importc: "appletSetRequiresCaptureButtonShortPressedMessage".} +## * +## @brief Sets whether ::AppletMessage_CaptureButtonShortPressed is enabled. +## @note Only available with [3.0.0+]. +## @note When enabled with a non-Overlay applet, Overlay applet will not be notified of capture button short-presses for screenshots. +## @param[in] flag Whether to enable the notification. +## + +proc appletSetAlbumImageOrientation*(orientation: AlbumImageOrientation): Result {. + cdecl, importc: "appletSetAlbumImageOrientation".} +## * +## @brief Sets the Album screenshot ImageOrientation. +## @note Only available with [3.0.0+]. +## @param[in] orientation \ref AlbumImageOrientation +## + +proc appletSetDesirableKeyboardLayout*(layout: SetKeyboardLayout): Result {.cdecl, + importc: "appletSetDesirableKeyboardLayout".} +## * +## @brief Sets the DesirableKeyboardLayout. +## @note Only available with [4.0.0+]. +## @param[in] layout Input \ref SetKeyboardLayout. +## + +proc appletCreateManagedDisplayLayer*(`out`: ptr U64): Result {.cdecl, + importc: "appletCreateManagedDisplayLayer".} +## appletCreateManagedDisplayLayer + +proc appletIsSystemBufferSharingEnabled*(): Result {.cdecl, + importc: "appletIsSystemBufferSharingEnabled".} +## * +## @brief Checks whether SystemBufferSharing is enabled, throwing an error otherwise. +## @note Only available with [4.0.0+]. Not usable with AppletType_*Application. +## + +proc appletGetSystemSharedLayerHandle*(sharedBufferHandle: ptr U64; + sharedLayerHandle: ptr U64): Result {.cdecl, + importc: "appletGetSystemSharedLayerHandle".} +## * +## @brief Gets the System SharedBufferHandle and SharedLayerHandle. +## @note Only available with [4.0.0+]. Not usable with AppletType_*Application. +## @param[out] SharedBufferHandle Output System SharedBufferHandle. +## @param[out] SharedLayerHandle Output System SharedLayerHandle. +## + +proc appletGetSystemSharedBufferHandle*(sharedBufferHandle: ptr U64): Result {.cdecl, + importc: "appletGetSystemSharedBufferHandle".} +## * +## @brief Same as \ref appletGetSystemSharedLayerHandle except this just gets the SharedBufferHandle. +## @note Only available with [5.0.0+]. Not usable with AppletType_*Application. +## @param[out] SharedBufferHandle Output System SharedBufferHandle. +## + +proc appletCreateManagedDisplaySeparableLayer*(displayLayer: ptr U64; + recordingLayer: ptr U64): Result {.cdecl, importc: "appletCreateManagedDisplaySeparableLayer".} +## * +## @brief CreateManagedDisplaySeparableLayer +## @note Only available with [10.0.0+]. +## @param[out] display_layer Output display_layer. +## @param[out] recording_layer Output recording_layer. +## + +proc appletSetManagedDisplayLayerSeparationMode*(mode: U32): Result {.cdecl, + importc: "appletSetManagedDisplayLayerSeparationMode".} +## * +## @brief SetManagedDisplayLayerSeparationMode +## @note Only available with [10.0.0+]. +## @param[in] mode Mode. Must be 0-1. +## + +proc appletSetHandlesRequestToDisplay*(flag: bool): Result {.cdecl, + importc: "appletSetHandlesRequestToDisplay".} +## * +## @brief Sets whether ::AppletMessage_RequestToDisplay is enabled. +## @note Sets an internal state flag. When the input flag is 0, this will in additional run the same code as \ref appletApproveToDisplay. +## @param[in] flag Flag +## + +proc appletApproveToDisplay*(): Result {.cdecl, importc: "appletApproveToDisplay".} +## * +## @brief Approve the display requested by ::AppletMessage_RequestToDisplay, see also \ref appletSetHandlesRequestToDisplay. +## + +proc appletOverrideAutoSleepTimeAndDimmingTime*(inval0: S32; inval1: S32; + inval2: S32; inval3: S32): Result {.cdecl, importc: "appletOverrideAutoSleepTimeAndDimmingTime".} +## * +## @brief OverrideAutoSleepTimeAndDimmingTime +## @param[in] inval0 Unknown input value. +## @param[in] inval1 Unknown input value. +## @param[in] inval2 Unknown input value. +## @param[in] inval3 Unknown input value. +## + +proc appletSetIdleTimeDetectionExtension*(ext: AppletIdleTimeDetectionExtension): Result {. + cdecl, importc: "appletSetIdleTimeDetectionExtension".} +## * +## @brief Sets the IdleTimeDetectionExtension. +## @param[in] ext \ref AppletIdleTimeDetectionExtension Must be 0-2: 0 = disabled, 1 = Extended, and 2 = ExtendedUnsafe. +## + +proc appletGetIdleTimeDetectionExtension*( + ext: ptr AppletIdleTimeDetectionExtension): Result {.cdecl, + importc: "appletGetIdleTimeDetectionExtension".} +## * +## @brief Gets the value set by \ref appletSetIdleTimeDetectionExtension. +## @param[out] ext \ref AppletIdleTimeDetectionExtension +## + +proc appletSetInputDetectionSourceSet*(val: U32): Result {.cdecl, + importc: "appletSetInputDetectionSourceSet".} +## * +## @brief Sets the InputDetectionSourceSet. +## @param[in] val Input value. +## + +proc appletReportUserIsActive*(): Result {.cdecl, + importc: "appletReportUserIsActive".} +## * +## @brief Reports that the user is active, for idle detection (screen dimming / auto-sleep). This is equivalent to when the user uses HID input. +## @note Only available with [2.0.0+]. +## + +proc appletGetCurrentIlluminance*(fLux: ptr cfloat): Result {.cdecl, + importc: "appletGetCurrentIlluminance".} +## * +## @brief Gets the current Illuminance from the light sensor. +## @note Only available with [3.0.0+]. +## @param fLux Output fLux +## + +proc appletIsIlluminanceAvailable*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsIlluminanceAvailable".} +## * +## @brief Gets whether Illuminance is available. +## @note Only available with [3.0.0+]. +## @param out Output flag +## + +proc appletSetAutoSleepDisabled*(flag: bool): Result {.cdecl, + importc: "appletSetAutoSleepDisabled".} +## * +## @brief Sets AutoSleepDisabled. +## @note Only available with [5.0.0+]. +## @param[in] flag Flag +## + +proc appletIsAutoSleepDisabled*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsAutoSleepDisabled".} +## * +## @brief Gets AutoSleepDisabled. +## @note Only available with [5.0.0+]. +## @param[out] out Output flag +## + +proc appletGetCurrentIlluminanceEx*(bOverLimit: ptr bool; fLux: ptr cfloat): Result {. + cdecl, importc: "appletGetCurrentIlluminanceEx".} +## * +## @brief Gets the current Illuminance from the light sensor. Same as \ref appletGetCurrentIlluminance except for the additional param. +## @note Only available with [5.0.0+]. +## @param bOverLimit Output bOverLimit +## @param fLux Output fLux +## + +proc appletSetInputDetectionPolicy*(policy: AppletInputDetectionPolicy): Result {. + cdecl, importc: "appletSetInputDetectionPolicy".} +## * +## @brief Sets the \ref AppletInputDetectionPolicy. +## @note Only available with [9.0.0+]. +## @param[in] policy \ref AppletInputDetectionPolicy +## + +proc appletSetWirelessPriorityMode*(mode: AppletWirelessPriorityMode): Result {. + cdecl, importc: "appletSetWirelessPriorityMode".} +## * +## @brief Sets the WirelessPriorityMode. +## @note Only available with [4.0.0+]. +## @param[in] mode \ref AppletWirelessPriorityMode +## + +proc appletGetProgramTotalActiveTime*(activeTime: ptr U64): Result {.cdecl, + importc: "appletGetProgramTotalActiveTime".} +## * +## @brief Gets the total time in nanoseconds that the current process was actively running (not suspended), relative to when \ref appletInitialize was last used. +## @note Only available with [6.0.0+]. +## @param[out] activeTime Output nanoseconds value. +## + +proc appletSetAlbumImageTakenNotificationEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetAlbumImageTakenNotificationEnabled".} +## * +## @brief Sets whether ::AppletMessage_AlbumScreenShotTaken is enabled. +## @note Only available with [7.0.0+]. +## @param[in] flag Whether to enable the notification. +## + +proc appletSetApplicationAlbumUserData*(buffer: pointer; size: csize_t): Result {. + cdecl, importc: "appletSetApplicationAlbumUserData".} +## * +## @brief Sets the Application AlbumUserData. +## @note Only available with [8.0.0+]. +## @param[in] buffer Buffer containing arbitrary UserData. +## @param[in] size Buffer size, must be <=0x400. +## + +proc appletSaveCurrentScreenshot*(option: AlbumReportOption): Result {.cdecl, + importc: "appletSaveCurrentScreenshot".} +## * +## @brief SaveCurrentScreenshot +## @note Only available with [11.0.0+]. +## @param[in] option \ref AlbumReportOption +## + +proc appletGetAppletResourceUserIdOfCallerApplet*(`out`: ptr U64): Result {.cdecl, + importc: "appletGetAppletResourceUserIdOfCallerApplet".} +## /@} +## /@name IWindowController +## /@{ +## * +## @brief Gets the AppletResourceUserId of the CallerApplet. +## @note Only available with [6.0.0+]. +## @param[out] out AppletResourceUserId +## + +proc appletSetAppletWindowVisibility*(flag: bool): Result {.cdecl, + importc: "appletSetAppletWindowVisibility".} +## * +## @brief Sets the current applet WindowVisibility. +## @note Only available with [7.0.0+]. +## @param[in] flag Flag +## + +proc appletSetAppletGpuTimeSlice*(val: S64): Result {.cdecl, + importc: "appletSetAppletGpuTimeSlice".} +## * +## @brief Sets the AppletGpuTimeSlice. +## @note Only available with [7.0.0+]. +## @param[in] val Input value, must not be negative. +## + +proc appletSetExpectedMasterVolume*(mainAppletVolume: cfloat; + libraryAppletVolume: cfloat): Result {.cdecl, + importc: "appletSetExpectedMasterVolume".} +## /@} +## /@name IAudioController +## /@{ +## * +## @brief Sets the ExpectedMasterVolume for MainApplet and LibraryApplet. +## @note Used by some official apps before/after launching LibraryApplets. Prior to changing the volume, the official app uses \ref appletGetExpectedMasterVolume, with the output being used to restore the volume after LibraryApplet handling. +## @param[in] mainAppletVolume MainApplet ExpectedMasterVolume. +## @param[in] libraryAppletVolume LibraryApplet ExpectedMasterVolume. +## + +proc appletGetExpectedMasterVolume*(mainAppletVolume: ptr cfloat; + libraryAppletVolume: ptr cfloat): Result {.cdecl, + importc: "appletGetExpectedMasterVolume".} +## * +## @brief Gets the ExpectedMasterVolume for MainApplet and LibraryApplet. +## @note See also \ref appletSetExpectedMasterVolume. +## @param[out] mainAppletVolume MainApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetMainAppletExpectedMasterVolume when not NULL. +## @param[out] libraryAppletVolume LibraryApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetLibraryAppletExpectedMasterVolume when not NULL. +## + +proc appletChangeMainAppletMasterVolume*(volume: cfloat; unk: U64): Result {.cdecl, + importc: "appletChangeMainAppletMasterVolume".} +## * +## @brief Change the MainApplet MasterVolume. +## @param[in] volume MainApplet MasterVolume. +## @param[in] unk Unknown. +## + +proc appletSetTransparentVolumeRate*(val: cfloat): Result {.cdecl, + importc: "appletSetTransparentVolumeRate".} +## * +## @brief Sets the TransparentVolumeRate. +## @param[in] val Input value. +## + +proc appletUpdateLastForegroundCaptureImage*(): Result {.cdecl, + importc: "appletUpdateLastForegroundCaptureImage".} +## /@} +## /@name IDisplayController +## /@{ +## * +## @brief Update the LastForeground CaptureImage. +## + +proc appletUpdateCallerAppletCaptureImage*(): Result {.cdecl, + importc: "appletUpdateCallerAppletCaptureImage".} +## * +## @brief Update the CallerApplet CaptureImage. +## + +proc appletGetLastForegroundCaptureImageEx*(buffer: pointer; size: csize_t; + flag: ptr bool): Result {.cdecl, importc: "appletGetLastForegroundCaptureImageEx".} +## * +## @brief Gets the LastForeground CaptureImage. +## @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. +## @param[out] size Buffer size, must match 0x384000. +## @param[out] flag Output flag. +## + +proc appletGetLastApplicationCaptureImageEx*(buffer: pointer; size: csize_t; + flag: ptr bool): Result {.cdecl, + importc: "appletGetLastApplicationCaptureImageEx".} +## * +## @brief Gets the LastApplication CaptureImage. +## @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. +## @param[out] size Buffer size, must match 0x384000. +## @param[out] flag Output flag. +## + +proc appletGetCallerAppletCaptureImageEx*(buffer: pointer; size: csize_t; + flag: ptr bool): Result {.cdecl, importc: "appletGetCallerAppletCaptureImageEx".} +## * +## @brief Gets the CallerApplet CaptureImage. +## @param[out] buffer Output buffer containing the 1280x720 RGBA8 image. +## @param[out] size Buffer size, must match 0x384000. +## @param[out] flag Output flag. +## + +proc appletTakeScreenShotOfOwnLayer*(flag: bool; + captureBuf: AppletCaptureSharedBuffer): Result {. + cdecl, importc: "appletTakeScreenShotOfOwnLayer".} +## * +## @brief Takes a screenshot of the current applet Layer into the specified CaptureSharedBuffer. +## @note Only available with [2.0.0+]. +## @param[in] flag Flag. +## @param[in] captureBuf \ref AppletCaptureSharedBuffer +## + +proc appletCopyBetweenCaptureBuffers*(dstCaptureBuf: AppletCaptureSharedBuffer; + srcCaptureBuf: AppletCaptureSharedBuffer): Result {. + cdecl, importc: "appletCopyBetweenCaptureBuffers".} +## * +## @brief Copies image data from a CaptureSharedBuffer to another CaptureSharedBuffer. +## @note Only available with [5.0.0+]. +## @param[in] dstCaptureBuf Destination \ref AppletCaptureSharedBuffer. +## @param[in] srcCaptureBuf Source \ref AppletCaptureSharedBuffer. +## + +proc appletClearCaptureBuffer*(flag: bool; captureBuf: AppletCaptureSharedBuffer; + color: U32): Result {.cdecl, + importc: "appletClearCaptureBuffer".} +## * +## @brief Clear the input CaptureSharedBuffer with the specified color. +## @note Only available with [3.0.0+]. +## @param[in] flag Flag. +## @param[in] captureBuf \ref AppletCaptureSharedBuffer +## @param[in] color RGBA8 color. +## + +proc appletClearAppletTransitionBuffer*(color: U32): Result {.cdecl, + importc: "appletClearAppletTransitionBuffer".} +## * +## @brief Clear the AppletTransitionBuffer with the specified color. +## @note Only available with [3.0.0+]. +## @param[in] color RGBA8 color. +## + +proc appletAcquireLastApplicationCaptureSharedBuffer*(flag: ptr bool; id: ptr S32): Result {. + cdecl, importc: "appletAcquireLastApplicationCaptureSharedBuffer".} +## * +## @brief Acquire the LastApplication CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## @param[out] flag Output flag. +## @param[out] id Output ID. +## + +proc appletReleaseLastApplicationCaptureSharedBuffer*(): Result {.cdecl, + importc: "appletReleaseLastApplicationCaptureSharedBuffer".} +## * +## @brief Release the LastApplication CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## + +proc appletAcquireLastForegroundCaptureSharedBuffer*(flag: ptr bool; id: ptr S32): Result {. + cdecl, importc: "appletAcquireLastForegroundCaptureSharedBuffer".} +## * +## @brief Acquire the LastForeground CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## @param[out] flag Output flag. +## @param[out] id Output ID. +## + +proc appletReleaseLastForegroundCaptureSharedBuffer*(): Result {.cdecl, + importc: "appletReleaseLastForegroundCaptureSharedBuffer".} +## * +## @brief Release the LastForeground CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## + +proc appletAcquireCallerAppletCaptureSharedBuffer*(flag: ptr bool; id: ptr S32): Result {. + cdecl, importc: "appletAcquireCallerAppletCaptureSharedBuffer".} +## * +## @brief Acquire the CallerApplet CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## @param[out] flag Output flag. +## @param[out] id Output ID. +## + +proc appletReleaseCallerAppletCaptureSharedBuffer*(): Result {.cdecl, + importc: "appletReleaseCallerAppletCaptureSharedBuffer".} +## * +## @brief Release the CallerApplet CaptureSharedBuffer. +## @note Only available with [4.0.0+]. +## + +proc appletTakeScreenShotOfOwnLayerEx*(flag0: bool; immediately: bool; + captureBuf: AppletCaptureSharedBuffer): Result {. + cdecl, importc: "appletTakeScreenShotOfOwnLayerEx".} +## * +## @brief Takes a screenshot of the current applet Layer into the specified CaptureSharedBuffer. Same as \ref appletTakeScreenShotOfOwnLayer except for the additional immediately param. +## @note Only available with [6.0.0+]. +## @param[in] flag0 Flag0. +## @param[in] immediately Whether the screenshot should be taken immediately. +## @param[in] captureBuf \ref AppletCaptureSharedBuffer +## + +proc appletPushContext*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPushContext".} +## /@} +## /@name IProcessWindingController +## /@{ +## * +## @brief Pushes a storage to the ContextStack. Normally this should only be used when AppletInfo::caller_flag is true. +## @note Only available with AppletType_LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletPopContext*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPopContext".} +## * +## @brief Pops a storage from the ContextStack. Normally this should only be used when AppletInfo::caller_flag is true. +## @note Only available with AppletType_LibraryApplet. +## @param[out] s Storage object. +## + +proc appletLockAccessorClose*(a: ptr AppletLockAccessor) {.cdecl, + importc: "appletLockAccessorClose".} +## LockAccessor +## * +## @brief Closes a LockAccessor. +## @param a LockAccessor object. +## + +proc appletLockAccessorTryLock*(a: ptr AppletLockAccessor; flag: ptr bool): Result {. + cdecl, importc: "appletLockAccessorTryLock".} +## * +## @brief TryLock a LockAccessor. +## @param a LockAccessor object. +## @param[out] flag Whether locking was successful, when false this indicates that this func should be called again. +## + +proc appletLockAccessorLock*(a: ptr AppletLockAccessor): Result {.cdecl, + importc: "appletLockAccessorLock".} +## * +## @brief Lock a LockAccessor. +## @note Similar to \ref appletLockAccessorTryLock, except this uses timeout UINT64_MAX with the eventWait call, and this uses TryLock repeatedly until the output flag value is true. +## @param a LockAccessor object. +## + +proc appletLockAccessorUnlock*(a: ptr AppletLockAccessor): Result {.cdecl, + importc: "appletLockAccessorUnlock".} +## * +## @brief Unlock a LockAccessor. +## @param a LockAccessor object. +## + +proc appletCreateLibraryApplet*(h: ptr AppletHolder; id: AppletId; mode: LibAppletMode): Result {. + cdecl, importc: "appletCreateLibraryApplet".} +## /@} +## /@name ILibraryAppletCreator +## /@{ +## * +## @brief Creates a LibraryApplet. +## @param h AppletHolder object. +## @param id See \ref AppletId. +## @param mode See \ref LibAppletMode. +## + +proc appletCreateLibraryAppletSelf*(h: ptr AppletHolder; id: AppletId; + mode: LibAppletMode): Result {.cdecl, + importc: "appletCreateLibraryAppletSelf".} +## * +## @brief Creates a LibraryApplet. This is for when a LibraryApplet creates itself. +## @note Identical to \ref appletCreateLibraryApplet except this sets the creating_self flag to true. +## @param h AppletHolder object. +## @param id See \ref AppletId. +## @param mode See \ref LibAppletMode. +## + +proc appletTerminateAllLibraryApplets*(): Result {.cdecl, + importc: "appletTerminateAllLibraryApplets".} +## * +## @brief TerminateAllLibraryApplets which were created by the current applet. +## @note Normally LibraryApplet cleanup should be handled via \ref AppletHolder. +## + +proc appletAreAnyLibraryAppletsLeft*(`out`: ptr bool): Result {.cdecl, + importc: "appletAreAnyLibraryAppletsLeft".} +## * +## @brief AreAnyLibraryAppletsLeft which were created by the current applet. +## @param[out] out Output flag. +## + +proc appletHolderClose*(h: ptr AppletHolder) {.cdecl, importc: "appletHolderClose".} +## /@} +## /@name ILibraryAppletAccessor +## /@{ +## / Closes an AppletHolder object. + +proc appletHolderActive*(h: ptr AppletHolder): bool {.cdecl, + importc: "appletHolderActive".} +## / Returns whether the AppletHolder object was initialized. + +proc appletHolderGetIndirectLayerConsumerHandle*(h: ptr AppletHolder; `out`: ptr U64): Result {. + cdecl, importc: "appletHolderGetIndirectLayerConsumerHandle".} +## * +## @brief Gets the IndirectLayerConsumerHandle loaded during \ref appletCreateLibraryApplet, on [2.0.0+]. +## @note Only available when \ref LibAppletMode is ::LibAppletMode_BackgroundIndirect. +## @param h AppletHolder object. +## @param out Output IndirectLayerConsumerHandle. +## + +proc appletHolderStart*(h: ptr AppletHolder): Result {.cdecl, + importc: "appletHolderStart".} +## * +## @brief Starts the LibraryApplet. +## @param h AppletHolder object. +## + +proc appletHolderJump*(h: ptr AppletHolder): Result {.cdecl, + importc: "appletHolderJump".} +## * +## @brief Jumps to the LibraryApplet, with the current-LibraryApplet being terminated. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_LibraryApplet. +## @param h AppletHolder object. +## + +proc appletHolderRequestExit*(h: ptr AppletHolder): Result {.cdecl, + importc: "appletHolderRequestExit".} +## * +## @brief Requests the LibraryApplet to exit. The command is only used if \ref appletHolderCheckFinished returns false. +## @param h AppletHolder object. +## + +proc appletHolderTerminate*(h: ptr AppletHolder): Result {.cdecl, + importc: "appletHolderTerminate".} +## * +## @brief Terminate the LibraryApplet. +## @param h AppletHolder object. +## + +proc appletHolderRequestExitOrTerminate*(h: ptr AppletHolder; timeout: U64): Result {. + cdecl, importc: "appletHolderRequestExitOrTerminate".} +## * +## @brief Uses cmds GetAppletStateChangedEvent and RequestExit, then waits for the LibraryApplet to exit with the specified timeout. If a timeout occurs, the Terminate cmd is used. +## @param h AppletHolder object. +## @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. +## + +proc appletHolderJoin*(h: ptr AppletHolder) {.cdecl, importc: "appletHolderJoin".} +## * +## @brief Waits for the LibraryApplet to exit. +## @param h AppletHolder object. +## + +proc appletHolderGetExitEvent*(h: ptr AppletHolder): ptr Event {.inline, cdecl.} = + ## * + ## @brief Gets the LibraryApplet StateChangedEvent. + ## @param h AppletHolder object. + ## + return addr(h.stateChangedEvent) + +proc appletHolderCheckFinished*(h: ptr AppletHolder): bool {.cdecl, + importc: "appletHolderCheckFinished".} +## * +## @brief Waits on the LibraryApplet StateChangedEvent with timeout=0, and returns whether it was successful. +## @param h AppletHolder object. +## + +proc appletHolderGetExitReason*(h: ptr AppletHolder): LibAppletExitReason {.cdecl, + importc: "appletHolderGetExitReason".} +## * +## @brief Gets the \ref LibAppletExitReason set by \ref appletHolderJoin. +## @param h AppletHolder object. +## + +proc appletHolderSetOutOfFocusApplicationSuspendingEnabled*(h: ptr AppletHolder; + flag: bool): Result {.cdecl, importc: "appletHolderSetOutOfFocusApplicationSuspendingEnabled".} +## * +## @brief Sets OutOfFocusApplicationSuspendingEnabled. +## @note Only available with AppletType_*Application. +## @param h AppletHolder object. +## @param[in] flag Flag +## + +proc appletHolderPresetLibraryAppletGpuTimeSliceZero*(h: ptr AppletHolder): Result {. + cdecl, importc: "appletHolderPresetLibraryAppletGpuTimeSliceZero".} +## * +## @brief PresetLibraryAppletGpuTimeSliceZero +## @note Only available with [10.0.0+]. +## @param h AppletHolder object. +## + +proc appletHolderGetPopInteractiveOutDataEvent*(h: ptr AppletHolder; + outEvent: ptr ptr Event): Result {.cdecl, importc: "appletHolderGetPopInteractiveOutDataEvent".} +## * +## @brief Gets the PopInteractiveOutDataEvent. +## @param h AppletHolder object. +## @param[out] out_event Output Event. +## + +proc appletHolderWaitInteractiveOut*(h: ptr AppletHolder): bool {.cdecl, + importc: "appletHolderWaitInteractiveOut".} +## * +## @brief Waits for the PopInteractiveOutDataEvent and StateChangedEvent. +## @return false for error / when StateChangedEvent was signaled, and true when PopInteractiveOutDataEvent was signaled. The latter is signaled when a new storage is available with \ref appletHolderPopInteractiveOutData where previously no storage was available (this willl not clear the event), this event is automatically cleared by the system once the last storage is popped. +## @param h AppletHolder object. +## + +proc appletHolderPushInData*(h: ptr AppletHolder; s: ptr AppletStorage): Result {.cdecl, + importc: "appletHolderPushInData".} +## * +## @brief Pushes a storage for LibraryApplet input. +## @note This uses \ref appletStorageClose automatically. +## @param h AppletHolder object. +## @param[in] s Storage object. +## + +proc appletHolderPopOutData*(h: ptr AppletHolder; s: ptr AppletStorage): Result {.cdecl, + importc: "appletHolderPopOutData".} +## * +## @brief Pops a storage from LibraryApplet output. +## @param h AppletHolder object. +## @param[out] s Storage object. +## + +proc appletHolderPushExtraStorage*(h: ptr AppletHolder; s: ptr AppletStorage): Result {. + cdecl, importc: "appletHolderPushExtraStorage".} +## * +## @brief Pushes a storage for LibraryApplet Extra storage input. +## @note This uses \ref appletStorageClose automatically. +## @param h AppletHolder object. +## @param[in] s Storage object. +## + +proc appletHolderPushInteractiveInData*(h: ptr AppletHolder; s: ptr AppletStorage): Result {. + cdecl, importc: "appletHolderPushInteractiveInData".} +## * +## @brief Pushes a storage for LibraryApplet Interactive input. +## @note This uses \ref appletStorageClose automatically. +## @param h AppletHolder object. +## @param[in] s Storage object. +## + +proc appletHolderPopInteractiveOutData*(h: ptr AppletHolder; s: ptr AppletStorage): Result {. + cdecl, importc: "appletHolderPopInteractiveOutData".} +## * +## @brief Pops a storage from LibraryApplet Interactive output. +## @param h AppletHolder object. +## @param[out] s Storage object. +## + +proc appletHolderGetLibraryAppletInfo*(h: ptr AppletHolder; info: ptr LibAppletInfo): Result {. + cdecl, importc: "appletHolderGetLibraryAppletInfo".} +## * +## @brief Gets the \ref LibAppletInfo for the specified LibraryApplet. +## @param h AppletHolder object. +## @param[out] info \ref LibAppletInfo +## + +proc appletCreateStorage*(s: ptr AppletStorage; size: S64): Result {.cdecl, + importc: "appletCreateStorage".} +## /@} +## /@name (ILibraryAppletCreator ->) IStorage +## /@{ +## * +## @brief Creates a storage. +## @param s Storage object. +## @param size Size of storage. +## + +proc appletCreateTransferMemoryStorage*(s: ptr AppletStorage; buffer: pointer; + size: S64; writable: bool): Result {.cdecl, + importc: "appletCreateTransferMemoryStorage".} +## * +## @brief Creates a TransferMemory storage. +## @param s Storage object. +## @param buffer TransferMemory buffer, will be automatically allocated if NULL. +## @param size Size of storage. +## @param writable Controls whether writing to the storage is allowed with \ref appletStorageWrite. +## + +proc appletCreateHandleStorage*(s: ptr AppletStorage; inval: S64; handle: Handle): Result {. + cdecl, importc: "appletCreateHandleStorage".} +## * +## @brief Creates a HandleStorage. +## @note Only available on [2.0.0+]. +## @param s Storage object. +## @param inval Arbitrary input value. +## @param handle Arbitrary input handle. +## + +proc appletCreateHandleStorageTmem*(s: ptr AppletStorage; buffer: pointer; size: S64): Result {. + cdecl, importc: "appletCreateHandleStorageTmem".} +## * +## @brief Creates a HandleStorage using TransferMemory. Wrapper for \ref appletCreateHandleStorage. +## @param s Storage object. +## @param buffer TransferMemory buffer, will be automatically allocated if NULL. +## @param size Size of storage. +## + +proc appletStorageClose*(s: ptr AppletStorage) {.cdecl, importc: "appletStorageClose".} +## / Closes the storage object. TransferMemory closing is seperate, see \ref appletStorageCloseTmem. +## / Other applet functions which push an input storage will automatically call this. + +proc appletStorageCloseTmem*(s: ptr AppletStorage) {.cdecl, + importc: "appletStorageCloseTmem".} +## / Closes the TransferMemory in the storage object. For TransferMemory storage created by the current process, this must be called after the LibraryApplet finishes using it (if sent to one). + +proc appletStorageGetSize*(s: ptr AppletStorage; size: ptr S64): Result {.cdecl, + importc: "appletStorageGetSize".} +## / Gets the size of the storage. This is not usable with HandleStorage, use \ref appletStorageGetHandle or \ref appletStorageMap instead for that. + +proc appletStorageWrite*(s: ptr AppletStorage; offset: S64; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "appletStorageWrite".} +## * +## @brief Writes to a storage. offset(+size) must be within the actual storage size. +## @note This is not usable with HandleStorage. +## @param s Storage object. +## @param offset Offset in storage. +## @param buffer Input data. +## @param size Data size. +## + +proc appletStorageRead*(s: ptr AppletStorage; offset: S64; buffer: pointer; + size: csize_t): Result {.cdecl, importc: "appletStorageRead".} +## * +## @brief Reads from a storage. offset(+size) must be within the actual storage size. +## @note This is not usable with HandleStorage. +## @param s Storage object. +## @param offset Offset in storage. +## @param buffer Input data. +## @param size Data size. +## + +proc appletStorageGetHandle*(s: ptr AppletStorage; `out`: ptr S64; handle: ptr Handle): Result {. + cdecl, importc: "appletStorageGetHandle".} +## * +## @brief Gets data for a HandleStorage originally from \ref appletCreateHandleStorage input. +## @note Only available on [2.0.0+]. +## @param s Storage object. +## @param out Output value. +## @param handle Output handle. +## + +proc appletStorageMap*(s: ptr AppletStorage; `addr`: ptr pointer; size: ptr csize_t): Result {. + cdecl, importc: "appletStorageMap".} +## * +## @brief Maps TransferMemory for a HandleStorage. Wrapper for \ref appletCreateHandleStorage. +## @note The TransferMemory can be unmapped with \ref appletStorageCloseTmem. +## @note Do not use this if the AppletStorage already contains initialized TransferMemory state. +## @param s Storage object. +## @param addr Output mapped address (optional). +## @param size Output size (optional). +## + +proc appletPopLaunchParameter*(s: ptr AppletStorage; kind: AppletLaunchParameterKind): Result {. + cdecl, importc: "appletPopLaunchParameter".} +## /@} +## /@name IApplicationFunctions: IFunctions for AppletType_*Application. +## /@{ +## * +## @brief Pops a LaunchParameter AppletStorage, the storage will be removed from sysmodule state during this. +## @param[out] s Output storage. +## @param kind See \ref AppletLaunchParameterKind. +## @note Only available with AppletType_*Application. +## @note See also acc.h \ref accountGetPreselectedUser (wrapper for appletPopLaunchParameter etc). +## + +proc appletRequestLaunchApplication*(applicationId: U64; s: ptr AppletStorage): Result {. + cdecl, importc: "appletRequestLaunchApplication".} +## * +## @brief Requests to launch the specified application. +## @note Only available with AppletType_*Application, or AppletType_LibraryApplet on [5.0.0+]. +## @param[in] application_id ApplicationId. Value 0 can be used to relaunch the current application. +## @param[in] s Optional AppletStorage object, can be NULL. This is automatically closed. When NULL on pre-4.0.0 (or with AppletType_LibraryApplet), this will internally create a tmp storage with size 0 for use with the cmd. This is the storage available to the launched application via \ref appletPopLaunchParameter with ::AppletLaunchParameterKind_UserChannel. +## + +proc appletRequestLaunchApplicationForQuest*(applicationId: U64; + s: ptr AppletStorage; attr: ptr AppletApplicationAttributeForQuest): Result {. + cdecl, importc: "appletRequestLaunchApplicationForQuest".} +## * +## @brief Requests to launch the specified application, for kiosk systems. +## @note Only available with AppletType_*Application on [3.0.0+]. +## @note Identical to \ref appletRequestLaunchApplication, except this allows the user to specify the attribute fields instead of the defaults being used. +## @param[in] application_id ApplicationId +## @param[in] s Optional AppletStorage object, can be NULL. This is automatically closed. When NULL on pre-4.0.0, this will internally create a tmp storage with size 0 for use with the cmd. This is the storage available to the launched application via \ref appletPopLaunchParameter with ::AppletLaunchParameterKind_UserChannel. +## @param[in] attr Kiosk application attributes. +## + +proc appletGetDesiredLanguage*(languageCode: ptr U64): Result {.cdecl, + importc: "appletGetDesiredLanguage".} +## * +## @brief Gets the DesiredLanguage for the current host application control.nacp. +## @note Only available with AppletType_*Application. +## @param[out] LanguageCode Output LanguageCode, see set.h. +## + +proc appletGetDisplayVersion*(displayVersion: cstring): Result {.cdecl, + importc: "appletGetDisplayVersion".} +## * +## @brief Gets the DisplayVersion for the current host application control.nacp. +## @note Only available with AppletType_*Application. +## @param[out] displayVersion Output DisplayVersion string, must be at least 0x10-bytes. This is always NUL-terminated. +## + +proc appletBeginBlockingHomeButtonShortAndLongPressed*(val: S64): Result {.cdecl, + importc: "appletBeginBlockingHomeButtonShortAndLongPressed".} +## * +## @brief Blocks the usage of the home button, for short (Home Menu) and long (Overlay) presses. +## @note Only available with AppletType_*Application. +## @param val Unknown. Official sw only uses hard-coded value 0 for this. +## + +proc appletEndBlockingHomeButtonShortAndLongPressed*(): Result {.cdecl, + importc: "appletEndBlockingHomeButtonShortAndLongPressed".} +## * +## @brief Ends the blocking started by \ref appletBeginBlockingHomeButtonShortAndLongPressed. +## @note Only available with AppletType_*Application. +## + +proc appletBeginBlockingHomeButton*(val: S64): Result {.cdecl, + importc: "appletBeginBlockingHomeButton".} +## * +## @brief Blocks the usage of the home button, for short presses (Home Menu). +## @note Only available with AppletType_*Application. +## @param val Unknown nanoseconds. Value 0 can be used. +## + +proc appletEndBlockingHomeButton*(): Result {.cdecl, + importc: "appletEndBlockingHomeButton".} +## * +## @brief Ends the blocking started by \ref appletBeginBlockingHomeButton. +## @note Only available with AppletType_*Application. +## + +proc appletNotifyRunning*(`out`: ptr bool) {.cdecl, importc: "appletNotifyRunning".} +## * +## @brief Notify that the app is now running, for the Application logo screen. This throws a fatal-error on failure. +## @note This will just return when applet-type isn't AppletType_Application, or when this was already used previously. Used automatically by \ref appletInitialize when __nx_applet_auto_notifyrunning is set to true (the default value). +## + +proc appletGetPseudoDeviceId*(`out`: ptr Uuid): Result {.cdecl, + importc: "appletGetPseudoDeviceId".} +## * +## @brief Gets the PseudoDeviceId. This is derived from the output of a ns command, and from data in the host application control.nacp. +## @note Only available with AppletType_*Application on [2.0.0+]. +## @param[out] out Output PseudoDeviceId. +## + +proc appletSetMediaPlaybackState*(state: bool): Result {.cdecl, + importc: "appletSetMediaPlaybackState".} +## / Set media playback state. +## / If state is set to true, screen dimming and auto sleep is disabled. +## / For *Application, this uses cmd SetMediaPlaybackStateForApplication, otherwise cmd SetMediaPlaybackState is used. + +proc appletIsGamePlayRecordingSupported*(flag: ptr bool): Result {.cdecl, + importc: "appletIsGamePlayRecordingSupported".} +## / Gets whether video recording is supported. +## / See also \ref appletInitializeGamePlayRecording. + +proc appletSetGamePlayRecordingState*(state: bool): Result {.cdecl, + importc: "appletSetGamePlayRecordingState".} +## / Disable/enable video recording. Only available after \ref appletInitializeGamePlayRecording was used. +## / See also \ref appletInitializeGamePlayRecording. + +proc appletInitializeGamePlayRecording*(): Result {.cdecl, + importc: "appletInitializeGamePlayRecording".} +## / Initializes video recording. This allocates a 0x6000000-byte buffer for the TransferMemory, cleanup is handled automatically during app exit in \ref appletExit. +## / Only available with AppletType_Application on [3.0.0+], hence errors from this can be ignored. +## / Video recording is only fully available system-side with [4.0.0+]. +## / Only usable when running under an application which supports video recording. Using this is only needed when the host application control.nacp has VideoCaptureMode set to Enabled, with Automatic appletInitializeGamePlayRecording is not needed. + +proc appletRequestFlushGamePlayingMovieForDebug*(): Result {.cdecl, + importc: "appletRequestFlushGamePlayingMovieForDebug".} +## * +## @brief Requests to save the video recording, as if the Capture-button was held. +## @note Only available with AppletType_*Application on [4.0.0+]. +## + +proc appletRequestToShutdown*(): Result {.cdecl, importc: "appletRequestToShutdown".} +## * +## @brief Requests a system shutdown. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_*Application on [3.0.0+]. +## + +proc appletRequestToReboot*(): Result {.cdecl, importc: "appletRequestToReboot".} +## * +## @brief Requests a system reboot. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_*Application on [3.0.0+]. +## + +proc appletRequestToSleep*(): Result {.cdecl, importc: "appletRequestToSleep".} +## * +## @brief RequestToSleep +## @note Only available with AppletType_*Application on [10.0.0+]. +## + +proc appletExitAndRequestToShowThanksMessage*(): Result {.cdecl, + importc: "appletExitAndRequestToShowThanksMessage".} +## * +## @brief Exit the application and return to the kiosk demo menu. This terminates the current process. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_*Application on [4.0.0+], on kiosk systems (QuestFlag set). +## + +proc appletInitializeApplicationCopyrightFrameBuffer*(): Result {.cdecl, + importc: "appletInitializeApplicationCopyrightFrameBuffer".} +## * +## @brief Initializes the ApplicationCopyrightFrameBuffer, with dimensions 1280x720 + the tmem for it. This is used as an overlay for screenshots. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note Cleanup for this is handled automatically during app exit in \ref appletExit. +## + +proc appletSetApplicationCopyrightImage*(buffer: pointer; size: csize_t; x: S32; + y: S32; width: S32; height: S32; + mode: AppletWindowOriginMode): Result {. + cdecl, importc: "appletSetApplicationCopyrightImage".} +## * +## @brief Sets the RGBA8 image for use with \ref appletInitializeApplicationCopyrightFrameBuffer. Overrides the current image, if this was already used previously. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note The specified coordinates and width/height must be within the bounds of the framebuffer setup by \ref appletInitializeApplicationCopyrightFrameBuffer. +## @param[in] buffer Input image buffer. +## @param[in] size Input image buffer size. +## @param[in] x X coordinate. Must not be negative. +## @param[in] y Y coordinate. Must not be negative. +## @param[in] width Image width. Must be >=1. +## @param[in] height Image height. Must be >=1. +## @param[in] mode \ref AppletWindowOriginMode +## + +proc appletSetApplicationCopyrightVisibility*(visible: bool): Result {.cdecl, + importc: "appletSetApplicationCopyrightVisibility".} +## * +## @brief Sets the visibility for the image set by \ref appletSetApplicationCopyrightImage, in screenshots. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @param[in] visible Whether the image is visible. The default is true. +## + +proc appletQueryApplicationPlayStatistics*( + stats: ptr PdmApplicationPlayStatistics; applicationIds: ptr U64; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "appletQueryApplicationPlayStatistics".} +## * +## @brief Gets ApplicationPlayStatistics. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note The input ApplicationIds must be allowed via control.nacp with the current host application. The minimum allowed ApplicationId is the ApplicationId for the current application. +## @param stats Output \ref PdmApplicationPlayStatistics array. +## @param application_ids Input ApplicationIds array. +## @param count Total entries in the input/output arrays. +## @param total_out Total output entries. +## + +proc appletQueryApplicationPlayStatisticsByUid*(uid: AccountUid; + stats: ptr PdmApplicationPlayStatistics; applicationIds: ptr U64; count: S32; + totalOut: ptr S32): Result {.cdecl, importc: "appletQueryApplicationPlayStatisticsByUid".} +## * +## @brief Same as \ref appletQueryApplicationPlayStatistics except this gets playstats specific to the input userId. +## @note Only available with AppletType_*Application on [6.0.0+]. +## @param[in] uid \ref AccountUid +## @param[out] stats Output \ref PdmApplicationPlayStatistics array. +## @param[in] application_ids Input ApplicationIds array. +## @param[in] count Total entries in the input/output arrays. +## @param[out] total_out Total output entries. +## + +proc appletExecuteProgram*(programIndex: S32; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "appletExecuteProgram".} +## * +## @brief Launches Application {current_ApplicationId}+programIndex. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. +## @param[in] programIndex ProgramIndex, must be 0x0-0xFF. 0 is the same as the current application. ProgramIndex values where the application is not installed should not be used. +## @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. +## @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. +## + +proc appletJumpToSubApplicationProgramForDevelopment*(applicationId: U64; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "appletJumpToSubApplicationProgramForDevelopment".} +## * +## @brief Launches the specified ApplicationId. +## @note Only available with AppletType_*Application on [5.0.0+], with DebugMode enabled. +## @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. +## @param[in] application_id ApplicationId. +## @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. +## @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. +## + +proc appletRestartProgram*(buffer: pointer; size: csize_t): Result {.cdecl, + importc: "appletRestartProgram".} +## * +## @brief Relaunches the current Application. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note Creates the storage if needed. Uses cmd ClearUserChannel. Uses cmd UnpopToUserChannel when the storage was created. Lastly cmd ExecuteProgramCmd is used. +## @param[in] buffer Optional buffer containing the storage data which will be used for ::AppletLaunchParameterKind_UserChannel with the launched Application, can be NULL. +## @param[in] size Size of the above buffer, 0 to not use the storage. Must be <=0x1000. +## + +proc appletGetPreviousProgramIndex*(programIndex: ptr S32): Result {.cdecl, + importc: "appletGetPreviousProgramIndex".} +## * +## @brief Gets the ProgramIndex of the program which launched this program. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @param[out] programIndex ProgramIndex, -1 when there was no previous program. +## + +proc appletSetDelayTimeToAbortOnGpuError*(val: U64): Result {.cdecl, + importc: "appletSetDelayTimeToAbortOnGpuError".} +## * +## @brief SetDelayTimeToAbortOnGpuError +## @note Only available with AppletType_*Application on [11.0.0+]. +## @param[in] val Input nanoseconds value. +## + +proc appletGetFriendInvitationStorageChannelEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "appletGetFriendInvitationStorageChannelEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletTryPopFromFriendInvitationStorageChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note This is used by \ref friendsGetFriendInvitationNotificationEvent. +## @note Only available with AppletType_*Application on [9.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletTryPopFromFriendInvitationStorageChannel*(s: ptr AppletStorage): Result {. + cdecl, importc: "appletTryPopFromFriendInvitationStorageChannel".} +## * +## @brief Pops a storage from the FriendInvitation StorageChannel. +## @note This is used by \ref friendsTryPopFriendInvitationNotificationInfo. +## @note Only available with AppletType_*Application on [9.0.0+]. +## @param[out] s Storage object. +## + +proc appletGetNotificationStorageChannelEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetNotificationStorageChannelEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletTryPopFromNotificationStorageChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note This is used by \ref notifGetNotificationSystemEvent. +## @note Only available with AppletType_*Application on [9.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletTryPopFromNotificationStorageChannel*(s: ptr AppletStorage): Result {. + cdecl, importc: "appletTryPopFromNotificationStorageChannel".} +## * +## @brief Pops a storage from the Notification StorageChannel. +## @note This is used by \ref notifTryPopNotifiedApplicationParameter. +## @note Only available with AppletType_*Application on [9.0.0+]. +## @param[out] s Storage object. +## + +proc appletGetHealthWarningDisappearedSystemEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "appletGetHealthWarningDisappearedSystemEvent".} +## * +## @brief GetHealthWarningDisappearedSystemEvent +## @note Only available with AppletType_*Application on [9.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletSetHdcpAuthenticationActivated*(flag: bool): Result {.cdecl, + importc: "appletSetHdcpAuthenticationActivated".} +## * +## @brief SetHdcpAuthenticationActivated +## @note Only available with AppletType_*Application on [9.0.0+]. +## @param[in] flag Whether HdcpAuthentication is activated. +## + +proc appletGetLastApplicationExitReason*(`out`: ptr S32): Result {.cdecl, + importc: "appletGetLastApplicationExitReason".} +## * +## @brief GetLastApplicationExitReason +## @note Only available with AppletType_*Application on [11.0.0+]. +## @param[out] out Output value. +## + +proc appletCreateMovieMaker*(srvOut: ptr Service; tmem: ptr TransferMemory): Result {. + cdecl, importc: "appletCreateMovieMaker".} +## * +## @brief CreateMovieMaker. Do not use this directly, use \ref grcCreateMovieMaker instead. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @param[out] srv_out Output Service for applet IMovieMaker. +## @param[in] tmem TransferMemory +## + +proc appletPrepareForJit*(): Result {.cdecl, importc: "appletPrepareForJit".} +## * +## @brief Launches the jit-sysmodule when it was not previously launched by this cmd. Returns 0 when it was previously launched. +## @note Only available with AppletType_*Application on [5.0.0+]. +## @note Requires the jit-sysmodule to actually be installed. +## + +proc appletRequestToGetForeground*(): Result {.cdecl, + importc: "appletRequestToGetForeground".} +## /@} +## /@name IHomeMenuFunctions: IFunctions for AppletType_SystemApplet and on [15.0.0+] for AppletType_LibraryApplet. +## /@{ +## * +## @brief RequestToGetForeground +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## + +proc appletLockForeground*(): Result {.cdecl, importc: "appletLockForeground".} +## * +## @brief LockForeground +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## + +proc appletUnlockForeground*(): Result {.cdecl, importc: "appletUnlockForeground".} +## * +## @brief UnlockForeground +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## + +proc appletPopFromGeneralChannel*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPopFromGeneralChannel".} +## * +## @brief Pops a storage from the general channel. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## @param[out] s Storage object. +## + +proc appletGetPopFromGeneralChannelEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetPopFromGeneralChannelEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletPopFromGeneralChannel where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletGetHomeButtonWriterLockAccessor*(a: ptr AppletLockAccessor): Result {. + cdecl, importc: "appletGetHomeButtonWriterLockAccessor".} +## * +## @brief Gets a \ref AppletLockAccessor for HomeButtonWriter. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet. +## @note Similar to using \ref appletGetWriterLockAccessorEx with inval=0. +## @param a LockAccessor object. +## + +proc appletIsSleepEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsSleepEnabled".} +## * +## @brief IsSleepEnabled +## @note Only available with AppletType_SystemApplet on [11.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. +## @param[out] out Output flag. +## + +proc appletPopRequestLaunchApplicationForDebug*(uids: ptr AccountUid; count: S32; + applicationId: ptr U64; totalOut: ptr S32): Result {.cdecl, + importc: "appletPopRequestLaunchApplicationForDebug".} +## * +## @brief PopRequestLaunchApplicationForDebug +## @note Only available with AppletType_SystemApplet on [6.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. +## @param[out] uids Output array of \ref AccountUid. +## @param[in] count Size of the uids array in entries, must be at least the size stored in state. +## @param[out] application_id Output ApplicationId. +## @param[out] total_out Total output userID entries. +## + +proc appletIsForceTerminateApplicationDisabledForDebug*(`out`: ptr bool): Result {. + cdecl, importc: "appletIsForceTerminateApplicationDisabledForDebug".} +## * +## @brief IsForceTerminateApplicationDisabledForDebug +## @note Only available with AppletType_SystemApplet on [9.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. +## @param[out] out Output flag. 0 when DebugMode is not enabled, otherwise this is loaded from a system-setting. +## + +proc appletLaunchDevMenu*(): Result {.cdecl, importc: "appletLaunchDevMenu".} +## * +## @brief Launches DevMenu and the dev Overlay-applet. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_SystemApplet on [8.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. +## @note This verifies that DebugMode is enabled, then uses a ns cmd. That cmd then loads the system-settings for these two ProgramIds (which normally only exist on devunits), and verifies that these programs are installed + launches them. +## + +proc appletSetLastApplicationExitReason*(reason: S32): Result {.cdecl, + importc: "appletSetLastApplicationExitReason".} +## * +## @brief SetLastApplicationExitReason +## @note Only available with AppletType_SystemApplet on [11.0.0+], or on [15.0.0+] with AppletType_LibraryApplet. +## @param[in] reason Reason +## + +proc appletStartSleepSequence*(flag: bool): Result {.cdecl, + importc: "appletStartSleepSequence".} +## /@} +## /@name IGlobalStateController +## /@{ +## * +## @brief Start the sequence for entering sleep-mode. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## @param[in] flag Flag, official sw uses hard-coded value = true. +## + +proc appletStartShutdownSequence*(): Result {.cdecl, + importc: "appletStartShutdownSequence".} +## * +## @brief Start the system-shutdown sequence. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## + +proc appletStartRebootSequence*(): Result {.cdecl, + importc: "appletStartRebootSequence".} +## * +## @brief Start the system-reboot sequence. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## + +proc appletIsAutoPowerDownRequested*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsAutoPowerDownRequested".} +## * +## @brief IsAutoPowerDownRequested. Uses an idle:sys cmd internally. +## @note Only available with AppletType_SystemApplet on [7.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## @param[out] out Output flag. +## + +proc appletLoadAndApplyIdlePolicySettings*(): Result {.cdecl, + importc: "appletLoadAndApplyIdlePolicySettings".} +## * +## @brief LoadAndApplyIdlePolicySettings. Uses an idle:sys cmd internally. +## @note Only available with AppletType_SystemApplet, or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## + +proc appletNotifyCecSettingsChanged*(): Result {.cdecl, + importc: "appletNotifyCecSettingsChanged".} +## * +## @brief NotifyCecSettingsChanged. Uses an omm cmd internally. +## @note Only available with AppletType_SystemApplet on [2.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## + +proc appletSetDefaultHomeButtonLongPressTime*(val: S64): Result {.cdecl, + importc: "appletSetDefaultHomeButtonLongPressTime".} +## * +## @brief Sets the DefaultHomeButtonLongPressTime. +## @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## @param[in] val Input value. +## + +proc appletUpdateDefaultDisplayResolution*(): Result {.cdecl, + importc: "appletUpdateDefaultDisplayResolution".} +## * +## @brief UpdateDefaultDisplayResolution. Uses an omm cmd internally. +## @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## + +proc appletShouldSleepOnBoot*(`out`: ptr bool): Result {.cdecl, + importc: "appletShouldSleepOnBoot".} +## * +## @brief ShouldSleepOnBoot. Uses an omm cmd internally. +## @note Only available with AppletType_SystemApplet on [3.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## @param[out] out Output flag. +## + +proc appletGetHdcpAuthenticationFailedEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetHdcpAuthenticationFailedEvent".} +## * +## @brief Gets an Event which is signaled for HdcpAuthenticationFailed. +## @note Only available with AppletType_SystemApplet on [4.0.0+], or on [15.0.0+] with AppletType_LibraryApplet/AppletType_OverlayApplet. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletCreateApplication*(a: ptr AppletApplication; applicationId: U64): Result {. + cdecl, importc: "appletCreateApplication".} +## /@} +## /@name IApplicationCreator +## /@{ +## * +## @brief Creates an Application. +## @note Only available with AppletType_SystemApplet. +## @param[out] a \ref AppletApplication +## @param[in] application_id ApplicationId. +## + +proc appletPopLaunchRequestedApplication*(a: ptr AppletApplication): Result {.cdecl, + importc: "appletPopLaunchRequestedApplication".} +## * +## @brief Pops a \ref AppletApplication for a requested Application launch. +## @note Only available with AppletType_SystemApplet. +## @param[out] a \ref AppletApplication +## + +proc appletCreateSystemApplication*(a: ptr AppletApplication; + systemApplicationId: U64): Result {.cdecl, + importc: "appletCreateSystemApplication".} +## * +## @brief Creates a SystemApplication. +## @note Only available with AppletType_SystemApplet. +## @param[out] a \ref AppletApplication +## @param[in] system_application_id SystemApplicationId. +## + +proc appletPopFloatingApplicationForDevelopment*(a: ptr AppletApplication): Result {. + cdecl, importc: "appletPopFloatingApplicationForDevelopment".} +## * +## @brief PopFloatingApplicationForDevelopment. +## @note Only available with AppletType_SystemApplet. Should not be used if no FloatingApplication is available. +## @param[out] a \ref AppletApplication +## + +proc appletApplicationClose*(a: ptr AppletApplication) {.cdecl, + importc: "appletApplicationClose".} +## /@} +## /@name IApplicationAccessor +## /@{ +## * +## @brief Close an \ref AppletApplication. +## @param a \ref AppletApplication +## + +proc appletApplicationActive*(a: ptr AppletApplication): bool {.cdecl, + importc: "appletApplicationActive".} +## * +## @brief Returns whether the AppletApplication object was initialized. +## @param a \ref AppletApplication +## + +proc appletApplicationStart*(a: ptr AppletApplication): Result {.cdecl, + importc: "appletApplicationStart".} +## * +## @brief Starts the Application. +## @param a \ref AppletApplication +## + +proc appletApplicationRequestExit*(a: ptr AppletApplication): Result {.cdecl, + importc: "appletApplicationRequestExit".} +## * +## @brief Requests the Application to exit. +## @param a \ref AppletApplication +## + +proc appletApplicationTerminate*(a: ptr AppletApplication): Result {.cdecl, + importc: "appletApplicationTerminate".} +## * +## @brief Terminate the Application. +## @param a \ref AppletApplication +## + +proc appletApplicationJoin*(a: ptr AppletApplication) {.cdecl, + importc: "appletApplicationJoin".} +## * +## @brief Waits for the Application to exit. +## @param a \ref AppletApplication +## + +proc appletApplicationCheckFinished*(a: ptr AppletApplication): bool {.cdecl, + importc: "appletApplicationCheckFinished".} +## * +## @brief Waits on the Application StateChangedEvent with timeout=0, and returns whether it was successful. +## @param a \ref AppletApplication +## + +proc appletApplicationGetExitReason*(a: ptr AppletApplication): AppletApplicationExitReason {. + cdecl, importc: "appletApplicationGetExitReason".} +## * +## @brief Gets the \ref AppletApplicationExitReason set by \ref appletApplicationJoin. +## @param a \ref AppletApplication +## + +proc appletApplicationRequestForApplicationToGetForeground*( + a: ptr AppletApplication): Result {.cdecl, importc: "appletApplicationRequestForApplicationToGetForeground".} +## * +## @brief RequestForApplicationToGetForeground. +## @param a \ref AppletApplication +## + +proc appletApplicationTerminateAllLibraryApplets*(a: ptr AppletApplication): Result {. + cdecl, importc: "appletApplicationTerminateAllLibraryApplets".} +## * +## @brief TerminateAllLibraryApplets which were created by the Application. +## + +proc appletApplicationAreAnyLibraryAppletsLeft*(a: ptr AppletApplication; + `out`: ptr bool): Result {.cdecl, + importc: "appletApplicationAreAnyLibraryAppletsLeft".} +## * +## @brief AreAnyLibraryAppletsLeft which were created by the Application. +## @param a \ref AppletApplication +## @param[out] out Output flag. +## + +proc appletApplicationRequestExitLibraryAppletOrTerminate*( + a: ptr AppletApplication; timeout: U64): Result {.cdecl, + importc: "appletApplicationRequestExitLibraryAppletOrTerminate".} +## * +## @brief Calls the same func as \ref appletHolderRequestExitOrTerminate with the output IAppletAccessor from the GetCurrentLibraryApplet cmd. +## @param a \ref AppletApplication +## @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. +## + +proc appletApplicationGetApplicationId*(a: ptr AppletApplication; + applicationId: ptr U64): Result {.cdecl, + importc: "appletApplicationGetApplicationId".} +## * +## @brief Gets the ApplicationId for the Application. +## @param a \ref AppletApplication +## @param[out] application_id Output ApplicationId. +## + +proc appletApplicationPushLaunchParameter*(a: ptr AppletApplication; + kind: AppletLaunchParameterKind; s: ptr AppletStorage): Result {.cdecl, + importc: "appletApplicationPushLaunchParameter".} +## * +## @brief Pushes a LaunchParameter AppletStorage to the Application. +## @note This uses \ref appletStorageClose automatically. +## @param a \ref AppletApplication +## @param[in] kind \ref AppletLaunchParameterKind +## @param[in] s Input storage. +## + +proc appletApplicationGetApplicationControlProperty*(a: ptr AppletApplication; + nacp: ptr NacpStruct): Result {.cdecl, importc: "appletApplicationGetApplicationControlProperty".} +## * +## @brief Gets the \ref NacpStruct for the Application. +## @note Not usable when the \ref AppletApplication is for an AppletType_SystemApplication. +## @param a \ref AppletApplication +## @param[out] nacp \ref NacpStruct +## + +proc appletApplicationGetApplicationLaunchProperty*(a: ptr AppletApplication; + `out`: ptr AppletApplicationLaunchProperty): Result {.cdecl, + importc: "appletApplicationGetApplicationLaunchProperty".} +## * +## @brief Gets the \ref AppletApplicationLaunchProperty for the Application. +## @note Only available on [2.0.0+]. Not usable when the \ref AppletApplication is for an AppletType_SystemApplication. +## @param a \ref AppletApplication +## @param[out] out \ref AppletApplicationLaunchProperty +## + +proc appletApplicationGetApplicationLaunchRequestInfo*(a: ptr AppletApplication; + `out`: ptr AppletApplicationLaunchRequestInfo): Result {.cdecl, + importc: "appletApplicationGetApplicationLaunchRequestInfo".} +## * +## @brief Gets the \ref AppletApplicationLaunchRequestInfo for the Application. +## @note Only available on [6.0.0+]. +## @param a \ref AppletApplication +## @param[out] out \ref AppletApplicationLaunchRequestInfo +## + +proc appletApplicationSetUsers*(a: ptr AppletApplication; uids: ptr AccountUid; + count: S32; flag: bool): Result {.cdecl, + importc: "appletApplicationSetUsers".} +## * +## @brief SetUsers for the Application. +## @note Only available on [6.0.0+]. +## @param a \ref AppletApplication +## @param[in] uids Input array of \ref AccountUid. +## @param[in] count Size of the uids array in entries, must be <=ACC_USER_LIST_SIZE. +## @param[in] flag When this flag is true, this just clears the users_available state flag to 0 and returns. +## + +proc appletApplicationCheckRightsEnvironmentAvailable*(a: ptr AppletApplication; + `out`: ptr bool): Result {.cdecl, importc: "appletApplicationCheckRightsEnvironmentAvailable".} +## * +## @brief CheckRightsEnvironmentAvailable. +## @note Only available on [6.0.0+]. +## @param a \ref AppletApplication +## @param[out] out Output flag. +## + +proc appletApplicationGetNsRightsEnvironmentHandle*(a: ptr AppletApplication; + handle: ptr U64): Result {.cdecl, importc: "appletApplicationGetNsRightsEnvironmentHandle".} +## * +## @brief GetNsRightsEnvironmentHandle. +## @note Only available on [6.0.0+]. +## @param a \ref AppletApplication +## @param[out] handle Output NsRightsEnvironmentHandle. +## + +proc appletApplicationGetDesirableUids*(a: ptr AppletApplication; + uids: ptr AccountUid; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "appletApplicationGetDesirableUids".} +## * +## @brief Gets an array of userIds for the Application DesirableUids. +## @note Only available on [6.0.0+]. +## @note qlaunch only uses 1 userId with this. +## @param a \ref AppletApplication +## @param[out] uids Output array of \ref AccountUid. +## @param[in] count Size of the uids array in entries, must be at least the size stored in state. +## @param[out] total_out Total output entries. +## + +proc appletApplicationReportApplicationExitTimeout*(a: ptr AppletApplication): Result {. + cdecl, importc: "appletApplicationReportApplicationExitTimeout".} +## * +## @brief ReportApplicationExitTimeout. +## @note Only available on [6.0.0+]. +## @param a \ref AppletApplication +## + +proc appletApplicationSetApplicationAttribute*(a: ptr AppletApplication; + attr: ptr AppletApplicationAttribute): Result {.cdecl, + importc: "appletApplicationSetApplicationAttribute".} +## * +## @brief Sets the \ref AppletApplicationAttribute for the Application. +## @note Only available on [8.0.0+]. +## @param a \ref AppletApplication +## @param[in] attr \ref AppletApplicationAttribute +## + +proc appletApplicationHasSaveDataAccessPermission*(a: ptr AppletApplication; + applicationId: U64; `out`: ptr bool): Result {.cdecl, + importc: "appletApplicationHasSaveDataAccessPermission".} +## * +## @brief Gets whether the savedata specified by the input ApplicationId is accessible. +## @note Only available on [8.0.0+]. +## @param a \ref AppletApplication +## @param[in] application_id ApplicationId for the savedata. +## @param[out] out Output flag. +## + +proc appletApplicationPushToFriendInvitationStorageChannel*( + a: ptr AppletApplication; uid: AccountUid; buffer: pointer; size: U64): Result {. + cdecl, importc: "appletApplicationPushToFriendInvitationStorageChannel".} +## * +## @brief Creates a storage using the specified input then pushes it to the FriendInvitation StorageChannel. +## @note The system will clear the StorageChannel before pushing the storage. +## @note Only available on [9.0.0+]. +## @param a \ref AppletApplication +## @param[in] uid \ref AccountUid +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## + +proc appletApplicationPushToNotificationStorageChannel*(a: ptr AppletApplication; + buffer: pointer; size: U64): Result {.cdecl, importc: "appletApplicationPushToNotificationStorageChannel".} +## * +## @brief Creates a storage using the specified input then pushes it to the Notification StorageChannel. +## @note The system will clear the StorageChannel before pushing the storage. +## @note Only available on [9.0.0+]. +## @param a \ref AppletApplication +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## + +proc appletApplicationRequestApplicationSoftReset*(a: ptr AppletApplication): Result {. + cdecl, importc: "appletApplicationRequestApplicationSoftReset".} +## * +## @brief RequestApplicationSoftReset +## @note Only available on [10.0.0+]. +## @param a \ref AppletApplication +## + +proc appletApplicationRestartApplicationTimer*(a: ptr AppletApplication): Result {. + cdecl, importc: "appletApplicationRestartApplicationTimer".} +## * +## @brief RestartApplicationTimer +## @note Only available on [10.0.0+]. +## @param a \ref AppletApplication +## + +proc appletPopInData*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPopInData".} +## /@} +## /@name ILibraryAppletSelfAccessor +## /@{ +## * +## @brief Pops a storage from current-LibraryApplet input. +## @note Only available with AppletType_LibraryApplet. +## @param[out] s Storage object. +## + +proc appletPushOutData*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPushOutData".} +## * +## @brief Pushes a storage for current-LibraryApplet output. +## @note Only available with AppletType_LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletPopInteractiveInData*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPopInteractiveInData".} +## * +## @brief Pops a storage from current-LibraryApplet Interactive input. +## @note Only available with AppletType_LibraryApplet. +## @param[out] s Storage object. +## + +proc appletPushInteractiveOutData*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPushInteractiveOutData".} +## * +## @brief Pushes a storage for current-LibraryApplet Interactive output. +## @note Only available with AppletType_LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletGetPopInDataEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetPopInDataEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletPopInData where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note Only available with AppletType_LibraryApplet. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletGetPopInteractiveInDataEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetPopInteractiveInDataEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletPopInteractiveInData where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note Only available with AppletType_LibraryApplet. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletGetLibraryAppletInfo*(info: ptr LibAppletInfo): Result {.cdecl, + importc: "appletGetLibraryAppletInfo".} +## * +## @brief Gets the \ref LibAppletInfo for the current LibraryApplet. +## @note Only available with AppletType_LibraryApplet. +## @param[out] info \ref LibAppletInfo +## + +proc appletGetMainAppletIdentityInfo*(info: ptr AppletIdentityInfo): Result {.cdecl, + importc: "appletGetMainAppletIdentityInfo".} +## * +## @brief Gets the \ref AppletIdentityInfo for the MainApplet. +## @note Only available with AppletType_LibraryApplet. +## @param[out] info \ref AppletIdentityInfo +## + +proc appletCanUseApplicationCore*(`out`: ptr bool): Result {.cdecl, + importc: "appletCanUseApplicationCore".} +## * +## @brief CanUseApplicationCore +## @note Only available with AppletType_LibraryApplet. +## @param[out] out Output flag. +## + +proc appletGetCallerAppletIdentityInfo*(info: ptr AppletIdentityInfo): Result {. + cdecl, importc: "appletGetCallerAppletIdentityInfo".} +## * +## @brief Gets the \ref AppletIdentityInfo for the CallerApplet. +## @note Only available with AppletType_LibraryApplet. +## @param[out] info \ref AppletIdentityInfo +## + +proc appletGetMainAppletApplicationControlProperty*(nacp: ptr NacpStruct): Result {. + cdecl, importc: "appletGetMainAppletApplicationControlProperty".} +## * +## @brief Gets the \ref NacpStruct for the MainApplet. +## @note Only available with AppletType_LibraryApplet on [2.0.0+]. +## @param[out] nacp \ref NacpStruct +## + +proc appletGetMainAppletStorageId*(storageId: ptr NcmStorageId): Result {.cdecl, + importc: "appletGetMainAppletStorageId".} +## * +## @brief Gets the NcmStorageId for the MainApplet. +## @note Only available with AppletType_LibraryApplet on [2.0.0+]. +## @param[out] storageId \ref NcmStorageId +## + +proc appletGetCallerAppletIdentityInfoStack*(stack: ptr AppletIdentityInfo; + count: S32; totalOut: ptr S32): Result {.cdecl, importc: "appletGetCallerAppletIdentityInfoStack".} +## * +## @brief Gets an array of \ref AppletIdentityInfo for the CallerStack. +## @note Only available with AppletType_LibraryApplet on [3.0.0+]. +## @param[out] stack Output array of \ref AppletIdentityInfo. +## @param[in] count Size of the stack array. +## @param[out] total_out Total output entries. +## + +proc appletGetNextReturnDestinationAppletIdentityInfo*( + info: ptr AppletIdentityInfo): Result {.cdecl, importc: "appletGetNextReturnDestinationAppletIdentityInfo".} +## * +## @brief Gets the \ref AppletIdentityInfo for the NextReturnDestinationApplet. +## @note Only available with AppletType_LibraryApplet on [4.0.0+]. +## @param[out] info \ref AppletIdentityInfo +## + +proc appletGetDesirableKeyboardLayout*(layout: ptr SetKeyboardLayout): Result {. + cdecl, importc: "appletGetDesirableKeyboardLayout".} +## * +## @brief Gets the DesirableKeyboardLayout previously set by \ref appletSetDesirableKeyboardLayout. An error is returned when it's not set. +## @note Only available with AppletType_LibraryApplet on [4.0.0+]. +## @param[out] layout Output \ref SetKeyboardLayout. +## + +proc appletPopExtraStorage*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPopExtraStorage".} +## * +## @brief Pops a storage from current-LibraryApplet Extra input. +## @note Only available with AppletType_LibraryApplet. +## @param[out] s Storage object. +## + +proc appletGetPopExtraStorageEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetPopExtraStorageEvent".} +## * +## @brief Gets an Event which is signaled when a new storage is available with \ref appletPopExtraStorage where previously no storage was available, this event is automatically cleared by the system once the last storage is popped. +## @note Only available with AppletType_LibraryApplet. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletUnpopInData*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletUnpopInData".} +## * +## @brief Unpop a storage for current-LibraryApplet input. +## @note Only available with AppletType_LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletUnpopExtraStorage*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletUnpopExtraStorage".} +## * +## @brief Unpop a storage for current-LibraryApplet Extra input. +## @note Only available with AppletType_LibraryApplet. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletGetIndirectLayerProducerHandle*(`out`: ptr U64): Result {.cdecl, + importc: "appletGetIndirectLayerProducerHandle".} +## * +## @brief Gets the IndirectLayerProducerHandle. +## @note Only available with AppletType_LibraryApplet on [2.0.0+]. +## @param[out] out Output IndirectLayerProducerHandle. +## + +proc appletGetMainAppletApplicationDesiredLanguage*(languageCode: ptr U64): Result {. + cdecl, importc: "appletGetMainAppletApplicationDesiredLanguage".} +## * +## @brief Gets the DesiredLanguage for the MainApplet. +## @note Only available with AppletType_LibraryApplet on [4.0.0+]. +## @param[out] LanguageCode Output LanguageCode, see set.h. +## + +proc appletGetCurrentApplicationId*(applicationId: ptr U64): Result {.cdecl, + importc: "appletGetCurrentApplicationId".} +## * +## @brief Gets the ApplicationId for the currently running Application. +## @note Only available with AppletType_LibraryApplet on [8.0.0+]. +## @param[out] application_id Output ApplicationId, 0 when no Application is running. +## + +proc appletRequestExitToSelf*(): Result {.cdecl, importc: "appletRequestExitToSelf".} +## * +## @brief Exits the current applet. Same as \ref appletHolderRequestExit except this is for the current applet. +## @note Only available with AppletType_LibraryApplet on [6.0.0+]. +## + +proc appletCreateGameMovieTrimmer*(srvOut: ptr Service; tmem: ptr TransferMemory): Result {. + cdecl, importc: "appletCreateGameMovieTrimmer".} +## * +## @brief CreateGameMovieTrimmer. Do not use this directly, use \ref grcTrimGameMovie instead. +## @note Only available with AppletType_LibraryApplet on [4.0.0+]. +## @note See also \ref appletReserveResourceForMovieOperation and \ref appletUnreserveResourceForMovieOperation. +## @param[out] srv_out Output Service for grc IGameMovieTrimmer. +## @param[in] tmem TransferMemory +## + +proc appletReserveResourceForMovieOperation*(): Result {.cdecl, + importc: "appletReserveResourceForMovieOperation".} +## * +## @brief ReserveResourceForMovieOperation. Must be used at some point prior to \ref appletCreateGameMovieTrimmer. +## @note Only available with AppletType_LibraryApplet on [5.0.0+]. +## + +proc appletUnreserveResourceForMovieOperation*(): Result {.cdecl, + importc: "appletUnreserveResourceForMovieOperation".} +## * +## @brief UnreserveResourceForMovieOperation. Must be used at some point after all finished with GameMovieTrimmer usage (\ref appletCreateGameMovieTrimmer). +## @note Only available with AppletType_LibraryApplet on [5.0.0+]. +## + +proc appletGetMainAppletAvailableUsers*(uids: ptr AccountUid; count: S32; + flag: ptr bool; totalOut: ptr S32): Result {. + cdecl, importc: "appletGetMainAppletAvailableUsers".} +## * +## @brief Gets an array of userIds for the MainApplet AvailableUsers. +## @note Only available with AppletType_LibraryApplet on [6.0.0+]. +## @param[out] uids Output array of \ref AccountUid. +## @param[in] count Size of the uids array in entries, must be at least ACC_USER_LIST_SIZE. +## @param[out] flag When true, this indicates that no users are available. +## @param[out] total_out Total output entries. This is -1 when flag is true. +## + +proc appletSetApplicationMemoryReservation*(val: U64): Result {.cdecl, + importc: "appletSetApplicationMemoryReservation".} +## * +## @brief SetApplicationMemoryReservation +## @note Only available with AppletType_LibraryApplet on [10.0.0+]. +## @note An Application must be currently running. +## @param[in] val Input value. +## + +proc appletShouldSetGpuTimeSliceManually*(`out`: ptr bool): Result {.cdecl, + importc: "appletShouldSetGpuTimeSliceManually".} +## * +## @brief ShouldSetGpuTimeSliceManually +## @note Only available with AppletType_LibraryApplet on [10.0.0+]. +## @param[out] out Output flag. +## + +proc appletBeginToWatchShortHomeButtonMessage*(): Result {.cdecl, + importc: "appletBeginToWatchShortHomeButtonMessage".} +## /@} +## /@name IOverlayFunctions: IFunctions for AppletType_OverlayApplet. +## /@{ +## * +## @brief Stops forwarding the input to the foreground app. +## @note Only available with AppletType_OverlayApplet. +## @note You have to call this to receive inputs through the hid service when running as the overlay applet. +## + +proc appletEndToWatchShortHomeButtonMessage*(): Result {.cdecl, + importc: "appletEndToWatchShortHomeButtonMessage".} +## * +## @brief Forwards input to the foreground app. +## @note Only available with AppletType_OverlayApplet. +## @note After calling this the overlay applet won't receive any input until \ref appletBeginToWatchShortHomeButtonMessage is called again. +## + +proc appletGetApplicationIdForLogo*(applicationId: ptr U64): Result {.cdecl, + importc: "appletGetApplicationIdForLogo".} +## * +## @brief Gets the ApplicationId for displaying the logo screen during application launch. +## @note Only available with AppletType_OverlayApplet. +## @param[out] application_id Output ApplicationId, 0 when no application is running. +## + +proc appletSetGpuTimeSliceBoost*(val: U64): Result {.cdecl, + importc: "appletSetGpuTimeSliceBoost".} +## * +## @brief Sets the GpuTimeSliceBoost. +## @note Only available with AppletType_OverlayApplet. +## @param[in] val Input value. +## + +proc appletSetAutoSleepTimeAndDimmingTimeEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetAutoSleepTimeAndDimmingTimeEnabled".} +## * +## @brief Sets AutoSleepTimeAndDimmingTimeEnabled. +## @note Only available with AppletType_OverlayApplet on [2.0.0+]. +## @param[in] flag Flag +## + +proc appletTerminateApplicationAndSetReason*(reason: Result): Result {.cdecl, + importc: "appletTerminateApplicationAndSetReason".} +## * +## @brief TerminateApplicationAndSetReason +## @note Only available with AppletType_OverlayApplet on [2.0.0+]. +## @param[in] reason Result reason. +## + +proc appletSetScreenShotPermissionGlobally*(flag: bool): Result {.cdecl, + importc: "appletSetScreenShotPermissionGlobally".} +## * +## @brief Sets ScreenShotPermissionGlobally. +## @note Only available with AppletType_OverlayApplet on [3.0.0+]. +## @param[in] flag Flag +## + +proc appletStartShutdownSequenceForOverlay*(): Result {.cdecl, + importc: "appletStartShutdownSequenceForOverlay".} +## * +## @brief Start the system-shutdown sequence. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_OverlayApplet on [6.0.0+]. +## + +proc appletStartRebootSequenceForOverlay*(): Result {.cdecl, + importc: "appletStartRebootSequenceForOverlay".} +## * +## @brief Start the system-reboot sequence. This will enter an infinite-sleep-loop on success. +## @note Only available with AppletType_OverlayApplet on [6.0.0+]. +## + +proc appletSetHealthWarningShowingState*(flag: bool): Result {.cdecl, + importc: "appletSetHealthWarningShowingState".} +## * +## @brief SetHealthWarningShowingState +## @note Only available with AppletType_OverlayApplet on [9.0.0+]. +## @param[in] flag Flag +## + +proc appletIsHealthWarningRequired*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsHealthWarningRequired".} +## * +## @brief IsHealthWarningRequired +## @note Only available with AppletType_OverlayApplet on [10.0.0+]. +## @param[out] out Output flag. +## + +proc appletBeginToObserveHidInputForDevelop*(): Result {.cdecl, + importc: "appletBeginToObserveHidInputForDevelop".} +## * +## @brief Enables HID input for the OverlayApplet, without disabling input for the foreground applet. Generally \ref appletBeginToWatchShortHomeButtonMessage / appletEndToWatchShortHomeButtonMessage should be used instead. +## @note Only available with AppletType_OverlayApplet on [5.0.0+]. +## + +proc appletReadThemeStorage*(buffer: pointer; size: csize_t; offset: U64; + transferSize: ptr U64): Result {.cdecl, + importc: "appletReadThemeStorage".} +## /@} +## /@name IAppletCommonFunctions +## /@{ +## * +## @brief Reads the ThemeStorage for the current applet. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. +## @note offset(+size) must be <=0x400. +## @param[out] buffer Output buffer data. +## @param[in] size Size to read. +## @param[in] offset Offset within the ThemeStorage. +## @param[out] transfer_size Actual read size. +## + +proc appletWriteThemeStorage*(buffer: pointer; size: csize_t; offset: U64): Result {. + cdecl, importc: "appletWriteThemeStorage".} +## * +## @brief Writes the ThemeStorage for the current applet. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [7.0.0+]. +## @note offset(+size) must be <=0x400. +## @param[in] buffer Input buffer data. +## @param[in] size Size to write. +## @param[in] offset Offset within the ThemeStorage. +## + +proc appletPushToAppletBoundChannel*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletPushToAppletBoundChannel".} +## * +## @brief This is similar to \ref appletPushToAppletBoundChannelForDebug (no DebugMode check), except the used channel is loaded from elsewhere and must be in the range 31-32. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## + +proc appletTryPopFromAppletBoundChannel*(s: ptr AppletStorage): Result {.cdecl, + importc: "appletTryPopFromAppletBoundChannel".} +## * +## @brief This is similar to \ref appletTryPopFromAppletBoundChannelForDebug (no DebugMode check), except the used channel is loaded from elsewhere and must be in the range 31-32. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. +## @param[out] s Storage object. +## + +proc appletGetDisplayLogicalResolution*(width: ptr S32; height: ptr S32): Result {. + cdecl, importc: "appletGetDisplayLogicalResolution".} +## * +## @brief Gets the DisplayLogicalResolution. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. +## @param[out] width Output width. +## @param[out] height Output height. +## + +proc appletSetDisplayMagnification*(x: cfloat; y: cfloat; width: cfloat; height: cfloat): Result {. + cdecl, importc: "appletSetDisplayMagnification".} +## * +## @brief Sets the DisplayMagnification. This is essentially layer image crop, for everything non-Overlay. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. +## @note x and width are multiplied with the same width value returned by \ref appletGetDisplayLogicalResolution, so these should be in the range 0.0f-1.0f. Likewise for y and height, except these are multipled with the height value. +## @param[in] x X position. +## @param[in] y Y position. +## @param[in] width Width. +## @param[in] height Height. +## + +proc appletSetHomeButtonDoubleClickEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetHomeButtonDoubleClickEnabled".} +## * +## @brief Sets whether HomeButtonDoubleClick is enabled. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. +## @param[in] flag Flag +## + +proc appletGetHomeButtonDoubleClickEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "appletGetHomeButtonDoubleClickEnabled".} +## * +## @brief Gets whether HomeButtonDoubleClick is enabled. +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [8.0.0+]. +## @param[out] out Output flag. +## + +proc appletIsHomeButtonShortPressedBlocked*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsHomeButtonShortPressedBlocked".} +## * +## @brief IsHomeButtonShortPressedBlocked +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [10.0.0+]. +## @param[out] out Output flag. +## + +proc appletIsVrModeCurtainRequired*(`out`: ptr bool): Result {.cdecl, + importc: "appletIsVrModeCurtainRequired".} +## * +## @brief IsVrModeCurtainRequired +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [11.0.0+]. +## @param[out] out Output flag. +## + +proc appletSetCpuBoostRequestPriority*(priority: S32): Result {.cdecl, + importc: "appletSetCpuBoostRequestPriority".} +## * +## @brief SetCpuBoostRequestPriority +## @note Only available with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [11.0.0+]. +## @param[in] priority Priority +## + +proc appletOpenMainApplication*(a: ptr AppletApplication): Result {.cdecl, + importc: "appletOpenMainApplication".} +## /@} +## /@name IDebugFunctions +## /@{ +## * +## @brief Open an \ref AppletApplication for the currently running Application. +## @note Should not be used when no Application is running. +## @note Only available on [1.0.0-9.2.0]. +## @param[out] a \ref AppletApplication +## + +proc appletPerformSystemButtonPressing*(`type`: AppletSystemButtonType): Result {. + cdecl, importc: "appletPerformSystemButtonPressing".} +## * +## @brief Perform SystemButtonPressing with the specified \ref AppletSystemButtonType. +## @param[in] type \ref AppletSystemButtonType +## + +proc appletInvalidateTransitionLayer*(): Result {.cdecl, + importc: "appletInvalidateTransitionLayer".} +## * +## @brief InvalidateTransitionLayer. +## + +proc appletRequestLaunchApplicationWithUserAndArgumentForDebug*( + applicationId: U64; uids: ptr AccountUid; totalUids: S32; flag: bool; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "appletRequestLaunchApplicationWithUserAndArgumentForDebug".} +## * +## @brief Requests to launch the specified Application, with the specified users. +## @note Only available on [6.0.0+]. +## @param[in] application_id ApplicationId. +## @param[in] uids Input array of \ref AccountUid. +## @param[in] total_uids Total input uids, must be <=ACC_USER_LIST_SIZE. +## @param[in] flag Whether to use the specified buffer to create a storage which will be pushed for ::AppletLaunchParameterKind_UserChannel. +## @param[in] buffer Buffer containing the above storage data. +## @param[in] size Size of the storage buffer. +## + +proc appletGetAppletResourceUsageInfo*(info: ptr AppletResourceUsageInfo): Result {. + cdecl, importc: "appletGetAppletResourceUsageInfo".} +## * +## @brief Gets the \ref AppletResourceUsageInfo. +## @note Only available on [6.0.0+]. +## @param[out] info \ref AppletResourceUsageInfo +## + +proc appletPushToAppletBoundChannelForDebug*(s: ptr AppletStorage; channel: S32): Result {. + cdecl, importc: "appletPushToAppletBoundChannelForDebug".} +## * +## @brief The channel must match the value already stored in state when the state value is non-zero, otherwise an error is returned. When the state value is 0, the channel is written into state. Then the input storage is pushed to the StorageChannel. +## @note Only available on [9.0.0+]. DebugMode must be enabled. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## @param[in] channel Channel. +## + +proc appletTryPopFromAppletBoundChannelForDebug*(s: ptr AppletStorage; channel: S32): Result {. + cdecl, importc: "appletTryPopFromAppletBoundChannelForDebug".} +## * +## @brief The channel must not be 0 and must match the value previously saved by \ref appletPushToAppletBoundChannelForDebug, otherwise errors are returned. Then the output storage is popped from the StorageChannel. +## @note Only available on [9.0.0+]. DebugMode must be enabled. +## @param[out] s Storage object. +## @param[in] channel Channel. +## + +proc appletAlarmSettingNotificationEnableAppEventReserve*(s: ptr AppletStorage; + applicationId: U64): Result {.cdecl, importc: "appletAlarmSettingNotificationEnableAppEventReserve".} +## * +## @brief Clears a StorageChannel, pushes the input storage there, and writes the ApplicationId into state. +## @note Only available on [9.0.0+]. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## @param[in] application_id ApplicationId +## + +proc appletAlarmSettingNotificationDisableAppEventReserve*(): Result {.cdecl, + importc: "appletAlarmSettingNotificationDisableAppEventReserve".} +## * +## @brief Clears the StorageChannel/saved-ApplicationId used by \ref appletAlarmSettingNotificationEnableAppEventReserve. +## @note Only available on [9.0.0+]. +## + +proc appletAlarmSettingNotificationPushAppEventNotify*(buffer: pointer; size: U64): Result {. + cdecl, importc: "appletAlarmSettingNotificationPushAppEventNotify".} +## * +## @brief Same as \ref appletApplicationPushToNotificationStorageChannel except this uses the MainApplication. +## @note Only available on [9.0.0+]. +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## + +proc appletFriendInvitationSetApplicationParameter*(s: ptr AppletStorage; + applicationId: U64): Result {.cdecl, importc: "appletFriendInvitationSetApplicationParameter".} +## * +## @brief Clears a StorageChannel, pushes the input storage there, and writes the ApplicationId into state. +## @note Only available on [9.0.0+]. +## @note This uses \ref appletStorageClose automatically. +## @param[in] s Storage object. +## @param[in] application_id ApplicationId +## + +proc appletFriendInvitationClearApplicationParameter*(): Result {.cdecl, + importc: "appletFriendInvitationClearApplicationParameter".} +## * +## @brief Clears the StorageChannel/saved-ApplicationId used by \ref appletFriendInvitationSetApplicationParameter. +## @note Only available on [9.0.0+]. +## + +proc appletFriendInvitationPushApplicationParameter*(uid: AccountUid; + buffer: pointer; size: U64): Result {.cdecl, importc: "appletFriendInvitationPushApplicationParameter".} +## * +## @brief Same as \ref appletApplicationPushToFriendInvitationStorageChannel except this uses the MainApplication. +## @note Only available on [9.0.0+]. +## @param[in] uid \ref AccountUid +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## + +proc appletSetTerminateResult*(res: Result): Result {.cdecl, + importc: "appletSetTerminateResult".} +## /@} +## /@name Common cmds +## /@{ +## * +## @brief SetTerminateResult +## @note Only available with AppletType_*Application. Or with AppletType_SystemApplet, AppletType_LibraryApplet, or AppletType_OverlayApplet, on [9.0.0+]. +## @param[in] res Result +## + +proc appletGetLaunchStorageInfoForDebug*(appStorageId: ptr NcmStorageId; + updateStorageId: ptr NcmStorageId): Result {. + cdecl, importc: "appletGetLaunchStorageInfoForDebug".} +## * +## @brief Gets the LaunchStorageInfo. +## @note Only available with AppletType_*Application on [2.0.0+], or with AppletType_LibraryApplet on [9.0.0+]. +## @param[out] app_storageId Same as AppletApplicationLaunchProperty::app_storageId. +## @param[out] update_storageId Same as AppletApplicationLaunchProperty::update_storageId. +## + +proc appletGetGpuErrorDetectedSystemEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "appletGetGpuErrorDetectedSystemEvent".} +## * +## @brief Gets an Event which is signaled for GpuErrorDetected. +## @note Only available with AppletType_*Application on [8.0.0+], or with AppletType_LibraryApplet on [9.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @note Official sw waits on this Event from a seperate thread, triggering an abort when it's signaled. +## @param[out] out_event Output Event with autoclear=false. +## + +proc appletSetHandlingHomeButtonShortPressedEnabled*(flag: bool): Result {.cdecl, + importc: "appletSetHandlingHomeButtonShortPressedEnabled".} +## * +## @brief Sets HandlingHomeButtonShortPressedEnabled. +## @note Only available with AppletType_OverlayApplet on [8.0.0+]. Or with non-AppletType_OverlayApplet on [9.1.0+]. +## @param[in] flag Flag +## + +proc appletGetAppletInfo*(): ptr AppletInfo {.cdecl, importc: "appletGetAppletInfo".} +## /@} +## /@name State / other +## /@{ +## * +## @brief Gets the cached \ref AppletInfo loaded during \ref appletInitialize. This will return NULL when the info is not initialized, due to not running as AppletType_LibraryApplet, or when any of the used cmds fail. +## @note Only available with AppletType_LibraryApplet. +## + +proc appletGetMessage*(msg: ptr U32): Result {.cdecl, importc: "appletGetMessage".} +## * +## @brief Gets a notification message, see \ref AppletMessage. +## + +proc appletProcessMessage*(msg: U32): bool {.cdecl, importc: "appletProcessMessage".} +## * +## @brief Processes the current applet status using the specified msg. +## @param msg Notification message, normally from \ref appletGetMessage. +## @return Whether the application should continue running. +## + +proc appletMainLoop*(): bool {.cdecl, importc: "appletMainLoop".} +## * +## @brief Processes the current applet status. Generally used within a main loop. +## @note Uses \ref appletGetMessage and \ref appletProcessMessage internally. +## @return Whether the application should continue running. +## + +proc appletHook*(cookie: ptr AppletHookCookie; callback: AppletHookFn; param: pointer) {. + cdecl, importc: "appletHook".} +## * +## @brief Sets up an applet status hook. +## @param cookie Hook cookie to use. +## @param callback Function to call when applet's status changes. +## @param param User-defined parameter to pass to the callback. +## + +proc appletUnhook*(cookie: ptr AppletHookCookie) {.cdecl, importc: "appletUnhook".} +## * +## @brief Removes an applet status hook. +## @param cookie Hook cookie to remove. +## + +proc appletGetOperationMode*(): AppletOperationMode {.cdecl, + importc: "appletGetOperationMode".} +## / These return state which is updated by appletMainLoop() when notifications are received. + +proc appletGetPerformanceMode*(): ApmPerformanceMode {.cdecl, + importc: "appletGetPerformanceMode".} +## appletgetperformanceMode + +proc appletGetFocusState*(): AppletFocusState {.cdecl, + importc: "appletGetFocusState".} +## appletGetFocusState + +proc appletSetFocusHandlingMode*(mode: AppletFocusHandlingMode): Result {.cdecl, + importc: "appletSetFocusHandlingMode".} +## * +## @brief Sets the current \ref AppletFocusHandlingMode. +## @note Should only be called with AppletType_Application. +## + diff --git a/src/libnx/wrapper/switch/services/async.h b/src/libnx/wrapper/switch/services/async.h new file mode 100644 index 0000000..c4181d3 --- /dev/null +++ b/src/libnx/wrapper/switch/services/async.h @@ -0,0 +1,115 @@ +/** + * @file async.h + * @brief NS/NIM IAsync* IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../applets/error.h" +#include "../kernel/event.h" + +/// AsyncValue +typedef struct { + Service s; ///< IAsyncValue + Event event; ///< Event with autoclear=false. +} AsyncValue; + +/// AsyncResult +typedef struct { + Service s; ///< IAsyncResult + Event event; ///< Event with autoclear=false. +} AsyncResult; + +///@name IAsyncValue +///@{ + +/** + * @brief Close a \ref AsyncValue. + * @note When the object is initialized, this uses \ref asyncValueCancel then \ref asyncValueWait with timeout=UINT64_MAX. + * @param a \ref AsyncValue + */ +void asyncValueClose(AsyncValue *a); + +/** + * @brief Waits for the async operation to finish using the specified timeout. + * @param a \ref AsyncValue + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. + */ +Result asyncValueWait(AsyncValue *a, u64 timeout); + +/** + * @brief Gets the value size. + * @param a \ref AsyncValue + * @param[out] size Output size. + */ +Result asyncValueGetSize(AsyncValue *a, u64 *size); + +/** + * @brief Gets the value. + * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. + * @param a \ref AsyncValue + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size. + */ +Result asyncValueGet(AsyncValue *a, void* buffer, size_t size); + +/** + * @brief Cancels the async operation. + * @note Used automatically by \ref asyncValueClose. + * @param a \ref AsyncValue + */ +Result asyncValueCancel(AsyncValue *a); + +/** + * @brief Gets the \ref ErrorContext. + * @note Only available on [4.0.0+]. + * @param a \ref AsyncValue + * @param[out] context \ref ErrorContext + */ +Result asyncValueGetErrorContext(AsyncValue *a, ErrorContext *context); + +///@} + +///@name IAsyncResult +///@{ + +/** + * @brief Close a \ref AsyncResult. + * @note When the object is initialized, this uses \ref asyncResultCancel then \ref asyncResultWait with timeout=UINT64_MAX. + * @param a \ref AsyncResult + */ +void asyncResultClose(AsyncResult *a); + +/** + * @brief Waits for the async operation to finish using the specified timeout. + * @param a \ref AsyncResult + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. + */ +Result asyncResultWait(AsyncResult *a, u64 timeout); + +/** + * @brief Gets the Result. + * @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. + * @param a \ref AsyncResult + */ +Result asyncResultGet(AsyncResult *a); + +/** + * @brief Cancels the async operation. + * @note Used automatically by \ref asyncResultClose. + * @param a \ref AsyncResult + */ +Result asyncResultCancel(AsyncResult *a); + +/** + * @brief Gets the \ref ErrorContext. + * @note Only available on [4.0.0+]. + * @param a \ref AsyncResult + * @param[out] context \ref ErrorContext + */ +Result asyncResultGetErrorContext(AsyncResult *a, ErrorContext *context); + +///@} + diff --git a/src/libnx/wrapper/switch/services/async.nim b/src/libnx/wrapper/switch/services/async.nim new file mode 100644 index 0000000..3e6da2a --- /dev/null +++ b/src/libnx/wrapper/switch/services/async.nim @@ -0,0 +1,120 @@ +## * +## @file async.h +## @brief NS/NIM IAsync* IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../applets/error, ../kernel/event + +## / AsyncValue + +type + AsyncValue* {.bycopy.} = object + s*: Service ## /< IAsyncValue + event*: Event ## /< Event with autoclear=false. + + +## / AsyncResult + +type + AsyncResult* {.bycopy.} = object + s*: Service ## /< IAsyncResult + event*: Event ## /< Event with autoclear=false. + + +## /@name IAsyncValue +## /@{ +## * +## @brief Close a \ref AsyncValue. +## @note When the object is initialized, this uses \ref asyncValueCancel then \ref asyncValueWait with timeout=UINT64_MAX. +## @param a \ref AsyncValue +## + +proc asyncValueClose*(a: ptr AsyncValue) {.cdecl, importc: "asyncValueClose".} +## * +## @brief Waits for the async operation to finish using the specified timeout. +## @param a \ref AsyncValue +## @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. +## + +proc asyncValueWait*(a: ptr AsyncValue; timeout: U64): Result {.cdecl, + importc: "asyncValueWait".} +## * +## @brief Gets the value size. +## @param a \ref AsyncValue +## @param[out] size Output size. +## + +proc asyncValueGetSize*(a: ptr AsyncValue; size: ptr U64): Result {.cdecl, + importc: "asyncValueGetSize".} +## * +## @brief Gets the value. +## @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. +## @param a \ref AsyncValue +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size. +## + +proc asyncValueGet*(a: ptr AsyncValue; buffer: pointer; size: csize_t): Result {.cdecl, + importc: "asyncValueGet".} +## * +## @brief Cancels the async operation. +## @note Used automatically by \ref asyncValueClose. +## @param a \ref AsyncValue +## + +proc asyncValueCancel*(a: ptr AsyncValue): Result {.cdecl, importc: "asyncValueCancel".} +## * +## @brief Gets the \ref ErrorContext. +## @note Only available on [4.0.0+]. +## @param a \ref AsyncValue +## @param[out] context \ref ErrorContext +## + +proc asyncValueGetErrorContext*(a: ptr AsyncValue; context: ptr ErrorContext): Result {. + cdecl, importc: "asyncValueGetErrorContext".} +## /@} +## /@name IAsyncResult +## /@{ +## * +## @brief Close a \ref AsyncResult. +## @note When the object is initialized, this uses \ref asyncResultCancel then \ref asyncResultWait with timeout=UINT64_MAX. +## @param a \ref AsyncResult +## + +proc asyncResultClose*(a: ptr AsyncResult) {.cdecl, importc: "asyncResultClose".} +## * +## @brief Waits for the async operation to finish using the specified timeout. +## @param a \ref AsyncResult +## @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. +## + +proc asyncResultWait*(a: ptr AsyncResult; timeout: U64): Result {.cdecl, + importc: "asyncResultWait".} +## * +## @brief Gets the Result. +## @note Prior to using the cmd, this uses \ref asyncResultWait with timeout=UINT64_MAX. +## @param a \ref AsyncResult +## + +proc asyncResultGet*(a: ptr AsyncResult): Result {.cdecl, importc: "asyncResultGet".} +## * +## @brief Cancels the async operation. +## @note Used automatically by \ref asyncResultClose. +## @param a \ref AsyncResult +## + +proc asyncResultCancel*(a: ptr AsyncResult): Result {.cdecl, + importc: "asyncResultCancel".} +## * +## @brief Gets the \ref ErrorContext. +## @note Only available on [4.0.0+]. +## @param a \ref AsyncResult +## @param[out] context \ref ErrorContext +## + +proc asyncResultGetErrorContext*(a: ptr AsyncResult; context: ptr ErrorContext): Result {. + cdecl, importc: "asyncResultGetErrorContext".} +## /@} diff --git a/src/libnx/wrapper/switch/services/audctl.h b/src/libnx/wrapper/switch/services/audctl.h new file mode 100644 index 0000000..8eae337 --- /dev/null +++ b/src/libnx/wrapper/switch/services/audctl.h @@ -0,0 +1,68 @@ +/** + * @file audctl.h + * @brief Audio Control IPC wrapper. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef enum { + AudioTarget_Invalid = 0, + AudioTarget_Speaker = 1, + AudioTarget_Headphone = 2, + AudioTarget_Tv = 3, + AudioTarget_UsbOutputDevice = 4, +} AudioTarget; + +typedef enum { + AudioOutputMode_Invalid = 0, + AudioOutputMode_Pcm1ch = 1, + AudioOutputMode_Pcm2ch = 2, + AudioOutputMode_Pcm6ch = 3, + AudioOutputMode_PcmAuto = 4, +} AudioOutputMode; + +typedef enum { + AudioForceMutePolicy_Disable = 0, + AudioForceMutePolicy_SpeakerMuteOnHeadphoneUnplugged = 1, +} AudioForceMutePolicy; + +typedef enum { + AudioHeadphoneOutputLevelMode_Normal = 0, + AudioHeadphoneOutputLevelMode_HighPower = 1, +} AudioHeadphoneOutputLevelMode; + +Result audctlInitialize(void); +void audctlExit(void); +Service* audctlGetServiceSession(void); + +Result audctlGetTargetVolume(float* volume_out, AudioTarget target); +Result audctlSetTargetVolume(AudioTarget target, float volume); +Result audctlGetTargetVolumeMin(float* volume_out); +Result audctlGetTargetVolumeMax(float* volume_out); +Result audctlIsTargetMute(bool* mute_out, AudioTarget target); +Result audctlSetTargetMute(AudioTarget target, bool mute); +Result audctlIsTargetConnected(bool* connected_out, AudioTarget target); +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 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 audctlGetAudioOutputTargetForPlayReport(AudioTarget* target_out); ///< [3.0.0+] +Result audctlNotifyHeadphoneVolumeWarningDisplayedEvent(void); ///< [3.0.0+] +Result audctlSetSystemOutputMasterVolume(float volume); ///< [4.0.0+] +Result audctlGetSystemOutputMasterVolume(float* volume_out); ///< [4.0.0+] diff --git a/src/libnx/wrapper/switch/services/audctl.nim b/src/libnx/wrapper/switch/services/audctl.nim new file mode 100644 index 0000000..f97f53b --- /dev/null +++ b/src/libnx/wrapper/switch/services/audctl.nim @@ -0,0 +1,97 @@ +## * +## @file audctl.h +## @brief Audio Control IPC wrapper. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + AudioTarget* = enum + AudioTargetInvalid = 0, AudioTargetSpeaker = 1, AudioTargetHeadphone = 2, + AudioTargetTv = 3, AudioTargetUsbOutputDevice = 4 + AudioOutputMode* = enum + AudioOutputModeInvalid = 0, AudioOutputModePcm1ch = 1, AudioOutputModePcm2ch = 2, + AudioOutputModePcm6ch = 3, AudioOutputModePcmAuto = 4 + AudioForceMutePolicy* = enum + AudioForceMutePolicyDisable = 0, + AudioForceMutePolicySpeakerMuteOnHeadphoneUnplugged = 1 + AudioHeadphoneOutputLevelMode* = enum + AudioHeadphoneOutputLevelModeNormal = 0, + AudioHeadphoneOutputLevelModeHighPower = 1 + + + + + +proc audctlInitialize*(): Result {.cdecl, importc: "audctlInitialize".} +proc audctlExit*() {.cdecl, importc: "audctlExit".} +proc audctlGetServiceSession*(): ptr Service {.cdecl, + importc: "audctlGetServiceSession".} +proc audctlGetTargetVolume*(volumeOut: ptr cfloat; target: AudioTarget): Result {. + cdecl, importc: "audctlGetTargetVolume".} +proc audctlSetTargetVolume*(target: AudioTarget; volume: cfloat): Result {.cdecl, + importc: "audctlSetTargetVolume".} +proc audctlGetTargetVolumeMin*(volumeOut: ptr cfloat): Result {.cdecl, + importc: "audctlGetTargetVolumeMin".} +proc audctlGetTargetVolumeMax*(volumeOut: ptr cfloat): Result {.cdecl, + importc: "audctlGetTargetVolumeMax".} +proc audctlIsTargetMute*(muteOut: ptr bool; target: AudioTarget): Result {.cdecl, + importc: "audctlIsTargetMute".} +proc audctlSetTargetMute*(target: AudioTarget; mute: bool): Result {.cdecl, + importc: "audctlSetTargetMute".} +proc audctlIsTargetConnected*(connectedOut: ptr bool; target: AudioTarget): Result {. + cdecl, importc: "audctlIsTargetConnected".} +proc audctlSetDefaultTarget*(target: AudioTarget; fadeInNs: U64; fadeOutNs: U64): Result {. + cdecl, importc: "audctlSetDefaultTarget".} +proc audctlGetDefaultTarget*(targetOut: ptr AudioTarget): Result {.cdecl, + importc: "audctlGetDefaultTarget".} +proc audctlGetAudioOutputMode*(modeOut: ptr AudioOutputMode; target: AudioTarget): Result {. + cdecl, importc: "audctlGetAudioOutputMode".} +proc audctlSetAudioOutputMode*(target: AudioTarget; mode: AudioOutputMode): Result {. + cdecl, importc: "audctlSetAudioOutputMode".} +proc audctlSetForceMutePolicy*(policy: AudioForceMutePolicy): Result {.cdecl, + importc: "audctlSetForceMutePolicy".} +proc audctlGetForceMutePolicy*(policyOut: ptr AudioForceMutePolicy): Result {.cdecl, + importc: "audctlGetForceMutePolicy".} +proc audctlGetOutputModeSetting*(modeOut: ptr AudioOutputMode; target: AudioTarget): Result {. + cdecl, importc: "audctlGetOutputModeSetting".} +proc audctlSetOutputModeSetting*(target: AudioTarget; mode: AudioOutputMode): Result {. + cdecl, importc: "audctlSetOutputModeSetting".} +proc audctlSetOutputTarget*(target: AudioTarget): Result {.cdecl, + importc: "audctlSetOutputTarget".} +proc audctlSetInputTargetForceEnabled*(enable: bool): Result {.cdecl, + importc: "audctlSetInputTargetForceEnabled".} +proc audctlSetHeadphoneOutputLevelMode*(mode: AudioHeadphoneOutputLevelMode): Result {. + cdecl, importc: "audctlSetHeadphoneOutputLevelMode".} +## /< [3.0.0+] + +proc audctlGetHeadphoneOutputLevelMode*(modeOut: ptr AudioHeadphoneOutputLevelMode): Result {. + cdecl, importc: "audctlGetHeadphoneOutputLevelMode".} +## /< [3.0.0+] + +proc audctlAcquireAudioVolumeUpdateEventForPlayReport*(eventOut: ptr Event): Result {. + cdecl, importc: "audctlAcquireAudioVolumeUpdateEventForPlayReport".} +## /< [3.0.0+] + +proc audctlAcquireAudioOutputDeviceUpdateEventForPlayReport*(eventOut: ptr Event): Result {. + cdecl, importc: "audctlAcquireAudioOutputDeviceUpdateEventForPlayReport".} +## /< [3.0.0+] + +proc audctlGetAudioOutputTargetForPlayReport*(targetOut: ptr AudioTarget): Result {. + cdecl, importc: "audctlGetAudioOutputTargetForPlayReport".} +## /< [3.0.0+] + +proc audctlNotifyHeadphoneVolumeWarningDisplayedEvent*(): Result {.cdecl, + importc: "audctlNotifyHeadphoneVolumeWarningDisplayedEvent".} +## /< [3.0.0+] + +proc audctlSetSystemOutputMasterVolume*(volume: cfloat): Result {.cdecl, + importc: "audctlSetSystemOutputMasterVolume".} +## /< [4.0.0+] + +proc audctlGetSystemOutputMasterVolume*(volumeOut: ptr cfloat): Result {.cdecl, + importc: "audctlGetSystemOutputMasterVolume".} +## /< [4.0.0+] diff --git a/src/libnx/wrapper/switch/services/auddev.h b/src/libnx/wrapper/switch/services/auddev.h new file mode 100644 index 0000000..015b186 --- /dev/null +++ b/src/libnx/wrapper/switch/services/auddev.h @@ -0,0 +1,25 @@ +/** + * @file auddev.h + * @brief IAudioDevice IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" + +/// Initialize IAudioDevice. +Result auddevInitialize(void); + +/// Exit IAudioDevice. +void auddevExit(void); + +/// Gets the Service object for IAudioDevice. +Service* auddevGetServiceSession(void); + +Result auddevListAudioDeviceName(AudioDeviceName *DeviceNames, s32 max_names, s32 *total_names); +Result auddevSetAudioDeviceOutputVolume(const AudioDeviceName *DeviceName, float volume); +Result auddevGetAudioDeviceOutputVolume(const AudioDeviceName *DeviceName, float *volume); + diff --git a/src/libnx/wrapper/switch/services/auddev.nim b/src/libnx/wrapper/switch/services/auddev.nim new file mode 100644 index 0000000..1ac9146 --- /dev/null +++ b/src/libnx/wrapper/switch/services/auddev.nim @@ -0,0 +1,29 @@ +## * +## @file auddev.h +## @brief IAudioDevice IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../audio/audio, ../sf/service + +## / Initialize IAudioDevice. + +proc auddevInitialize*(): Result {.cdecl, importc: "auddevInitialize".} +## / Exit IAudioDevice. + +proc auddevExit*() {.cdecl, importc: "auddevExit".} +## / Gets the Service object for IAudioDevice. + +proc auddevGetServiceSession*(): ptr Service {.cdecl, + importc: "auddevGetServiceSession".} +proc auddevListAudioDeviceName*(deviceNames: ptr AudioDeviceName; maxNames: S32; + totalNames: ptr S32): Result {.cdecl, + importc: "auddevListAudioDeviceName".} +proc auddevSetAudioDeviceOutputVolume*(deviceName: ptr AudioDeviceName; + volume: cfloat): Result {.cdecl, + importc: "auddevSetAudioDeviceOutputVolume".} +proc auddevGetAudioDeviceOutputVolume*(deviceName: ptr AudioDeviceName; + volume: ptr cfloat): Result {.cdecl, + importc: "auddevGetAudioDeviceOutputVolume".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/audin.h b/src/libnx/wrapper/switch/services/audin.h new file mode 100644 index 0000000..fbc245a --- /dev/null +++ b/src/libnx/wrapper/switch/services/audin.h @@ -0,0 +1,74 @@ +/** + * @file audin.h + * @brief Audio input service. + * @author hexkyz + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" + +typedef enum { + AudioInState_Started = 0, + AudioInState_Stopped = 1, +} AudioInState; + +/// Audio input buffer format +typedef struct AudioInBuffer AudioInBuffer; + +struct AudioInBuffer +{ + AudioInBuffer* next; ///< Next buffer. (Unused) + void* buffer; ///< Sample buffer (aligned to 0x1000 bytes). + u64 buffer_size; ///< Sample buffer size (aligned to 0x1000 bytes). + u64 data_size; ///< Size of data inside the buffer. + u64 data_offset; ///< Offset of data inside the buffer. (Unused?) +}; + +/// Initialize audin. +Result audinInitialize(void); + +/// Exit audin. +void audinExit(void); + +/// Gets the Service object for the actual audin service session. +Service* audinGetServiceSession(void); + +/// Gets the Service object for IAudioIn. +Service* audinGetServiceSession_AudioIn(void); + +Result audinListAudioIns(char *DeviceNames, s32 count, u32 *DeviceNamesCount); +Result audinOpenAudioIn(const char *DeviceNameIn, char *DeviceNameOut, u32 SampleRateIn, u32 ChannelCountIn, u32 *SampleRateOut, u32 *ChannelCountOut, PcmFormat *Format, AudioInState *State); +Result audinGetAudioInState(AudioInState *State); +Result audinStartAudioIn(void); +Result audinStopAudioIn(void); + +/// Submits an \ref AudioInBuffer for capturing. +Result audinAppendAudioInBuffer(AudioInBuffer *Buffer); + +Result audinGetReleasedAudioInBuffer(AudioInBuffer **Buffer, u32 *ReleasedBuffersCount); +Result audinContainsAudioInBuffer(AudioInBuffer *Buffer, bool *ContainsBuffer); + +/** + * @brief Submits an audio sample data buffer for capturing and waits for it to finish capturing. + * @brief Uses \ref audinAppendAudioInBuffer and \ref audinWaitCaptureFinish internally. + * @param source AudioInBuffer containing the buffer to hold the captured sample data. + * @param released AudioInBuffer to receive the captured buffer after being released. + */ +Result audinCaptureBuffer(AudioInBuffer *source, AudioInBuffer **released); + +/** + * @brief Waits for audio capture to finish. + * @param released AudioInBuffer to receive the first captured buffer after being released. + * @param released_count Pointer to receive the number of captured buffers. + * @param timeout Timeout value, use UINT64_MAX to wait until all finished. + */ +Result audinWaitCaptureFinish(AudioInBuffer **released, u32* released_count, u64 timeout); + +/// These return the state associated with the currently active audio input device. +u32 audinGetSampleRate(void); ///< Supported sample rate (48000Hz). +u32 audinGetChannelCount(void); ///< Supported channel count (2 channels). +PcmFormat audinGetPcmFormat(void); ///< Supported PCM format (Int16). +AudioInState audinGetDeviceState(void); ///< Initial device state (stopped). diff --git a/src/libnx/wrapper/switch/services/audin.nim b/src/libnx/wrapper/switch/services/audin.nim new file mode 100644 index 0000000..92b9c7b --- /dev/null +++ b/src/libnx/wrapper/switch/services/audin.nim @@ -0,0 +1,106 @@ +## * +## @file audin.h +## @brief Audio input service. +## @author hexkyz +## @copyright libnx Authors +## + +import + ../types, ../audio/audio, ../sf/service + +type + AudioInState* = enum + AudioInStateStarted = 0, AudioInStateStopped = 1 + + +## / Audio input buffer format + +type + AudioInBuffer* {.bycopy.} = object + next*: ptr AudioInBuffer ## /< Next buffer. (Unused) + buffer*: pointer ## /< Sample buffer (aligned to 0x1000 bytes). + bufferSize*: U64 ## /< Sample buffer size (aligned to 0x1000 bytes). + dataSize*: U64 ## /< Size of data inside the buffer. + dataOffset*: U64 ## /< Offset of data inside the buffer. (Unused?) + +proc audinInitialize*(): Result {.cdecl, importc: "audinInitialize".} +## / Initialize audin. + +proc audinExit*() {.cdecl, importc: "audinExit".} +## / Exit audin. + +proc audinGetServiceSession*(): ptr Service {.cdecl, + importc: "audinGetServiceSession".} +## / Gets the Service object for the actual audin service session. + +proc audinGetServiceSessionAudioIn*(): ptr Service {.cdecl, + importc: "audinGetServiceSession_AudioIn".} +## / Gets the Service object for IAudioIn. + +proc audinListAudioIns*(deviceNames: cstring; count: S32; deviceNamesCount: ptr U32): Result {. + cdecl, importc: "audinListAudioIns".} +## + +proc audinOpenAudioIn*(deviceNameIn: cstring; deviceNameOut: cstring; + sampleRateIn: U32; channelCountIn: U32; + sampleRateOut: ptr U32; channelCountOut: ptr U32; + format: ptr PcmFormat; state: ptr AudioInState): Result {.cdecl, + importc: "audinOpenAudioIn".} +## + +proc audinGetAudioInState*(state: ptr AudioInState): Result {.cdecl, + importc: "audinGetAudioInState".} +## + +proc audinStartAudioIn*(): Result {.cdecl, importc: "audinStartAudioIn".} +## + +proc audinStopAudioIn*(): Result {.cdecl, importc: "audinStopAudioIn".} +## + +proc audinAppendAudioInBuffer*(buffer: ptr AudioInBuffer): Result {.cdecl, + importc: "audinAppendAudioInBuffer".} +## / Submits an \ref AudioInBuffer for capturing. + +proc audinGetReleasedAudioInBuffer*(buffer: ptr ptr AudioInBuffer; + releasedBuffersCount: ptr U32): Result {.cdecl, + importc: "audinGetReleasedAudioInBuffer".} +## + +proc audinContainsAudioInBuffer*(buffer: ptr AudioInBuffer; containsBuffer: ptr bool): Result {. + cdecl, importc: "audinContainsAudioInBuffer".} +## + +proc audinCaptureBuffer*(source: ptr AudioInBuffer; released: ptr ptr AudioInBuffer): Result {. + cdecl, importc: "audinCaptureBuffer".} +## * +## @brief Submits an audio sample data buffer for capturing and waits for it to finish capturing. +## @brief Uses \ref audinAppendAudioInBuffer and \ref audinWaitCaptureFinish internally. +## @param source AudioInBuffer containing the buffer to hold the captured sample data. +## @param released AudioInBuffer to receive the captured buffer after being released. +## + +proc audinWaitCaptureFinish*(released: ptr ptr AudioInBuffer; releasedCount: ptr U32; + timeout: U64): Result {.cdecl, + importc: "audinWaitCaptureFinish".} +## * +## @brief Waits for audio capture to finish. +## @param released AudioInBuffer to receive the first captured buffer after being released. +## @param released_count Pointer to receive the number of captured buffers. +## @param timeout Timeout value, use UINT64_MAX to wait until all finished. +## + + +## / These return the state associated with the currently active audio input device. + +proc audinGetSampleRate*(): U32 {.cdecl, importc: "audinGetSampleRate".} +## /< Supported sample rate (48000Hz). + +proc audinGetChannelCount*(): U32 {.cdecl, importc: "audinGetChannelCount".} +## /< Supported channel count (2 channels). + +proc audinGetPcmFormat*(): PcmFormat {.cdecl, importc: "audinGetPcmFormat".} +## /< Supported PCM format (Int16). + +proc audinGetDeviceState*(): AudioInState {.cdecl, importc: "audinGetDeviceState".} +## /< Initial device state (stopped). diff --git a/src/libnx/wrapper/switch/services/audout.h b/src/libnx/wrapper/switch/services/audout.h new file mode 100644 index 0000000..8a49a9b --- /dev/null +++ b/src/libnx/wrapper/switch/services/audout.h @@ -0,0 +1,85 @@ +/** + * @file audout.h + * @brief Audio output service. + * @author hexkyz + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" + +typedef enum { + AudioOutState_Started = 0, + AudioOutState_Stopped = 1, +} AudioOutState; + +/// Audio output buffer format +typedef struct AudioOutBuffer AudioOutBuffer; + +struct AudioOutBuffer +{ + AudioOutBuffer* next; ///< Next buffer. (Unused) + void* buffer; ///< Sample buffer (aligned to 0x1000 bytes). + u64 buffer_size; ///< Sample buffer size (aligned to 0x1000 bytes). + u64 data_size; ///< Size of data inside the buffer. + u64 data_offset; ///< Offset of data inside the buffer. (Unused?) +}; + +/// Initialize audout. +Result audoutInitialize(void); + +/// Exit audout. +void audoutExit(void); + +/// Gets the Service object for the actual audout service session. +Service* audoutGetServiceSession(void); + +/// Gets the Service object for IAudioOut. +Service* audoutGetServiceSession_AudioOut(void); + +Result audoutListAudioOuts(char *DeviceNames, s32 count, u32 *DeviceNamesCount); +Result audoutOpenAudioOut(const char *DeviceNameIn, char *DeviceNameOut, u32 SampleRateIn, u32 ChannelCountIn, u32 *SampleRateOut, u32 *ChannelCountOut, PcmFormat *Format, AudioOutState *State); +Result audoutGetAudioOutState(AudioOutState *State); +Result audoutStartAudioOut(void); +Result audoutStopAudioOut(void); + +/// Submits an \ref AudioOutBuffer for playing. +Result audoutAppendAudioOutBuffer(AudioOutBuffer *Buffer); + +Result audoutGetReleasedAudioOutBuffer(AudioOutBuffer **Buffer, u32 *ReleasedBuffersCount); +Result audoutContainsAudioOutBuffer(AudioOutBuffer *Buffer, bool *ContainsBuffer); + +/// Only available with [4.0.0+]. +Result audoutGetAudioOutBufferCount(u32 *count); +/// Only available with [4.0.0+]. +Result audoutGetAudioOutPlayedSampleCount(u64 *count); +/// Only available with [4.0.0+]. +Result audoutFlushAudioOutBuffers(bool *flushed); +/// Only available with [6.0.0+]. +Result audoutSetAudioOutVolume(float volume); +/// Only available with [6.0.0+]. +Result audoutGetAudioOutVolume(float *volume); + +/** + * @brief Submits an audio sample data buffer for playing and waits for it to finish playing. + * @brief Uses \ref audoutAppendAudioOutBuffer and \ref audoutWaitPlayFinish internally. + * @param source AudioOutBuffer containing the source sample data to be played. + * @param released AudioOutBuffer to receive the played buffer after being released. + */ +Result audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer **released); + +/** + * @brief Waits for audio playback to finish. + * @param released AudioOutBuffer to receive the first played buffer after being released. + * @param released_count Pointer to receive the number of played buffers. + * @param timeout Timeout value, use UINT64_MAX to wait until all finished. + */ +Result audoutWaitPlayFinish(AudioOutBuffer **released, u32* released_count, u64 timeout); + +/// These return the state associated with the currently active audio output device. +u32 audoutGetSampleRate(void); ///< Supported sample rate (48000Hz). +u32 audoutGetChannelCount(void); ///< Supported channel count (2 channels). +PcmFormat audoutGetPcmFormat(void); ///< Supported PCM format (Int16). +AudioOutState audoutGetDeviceState(void); ///< Initial device state (stopped). diff --git a/src/libnx/wrapper/switch/services/audout.nim b/src/libnx/wrapper/switch/services/audout.nim new file mode 100644 index 0000000..31b7cbf --- /dev/null +++ b/src/libnx/wrapper/switch/services/audout.nim @@ -0,0 +1,127 @@ +## * +## @file audout.h +## @brief Audio output service. +## @author hexkyz +## @copyright libnx Authors +## + +import + ../types, ../audio/audio, ../sf/service + +type + AudioOutState* = enum + AudioOutStateStarted = 0, AudioOutStateStopped = 1 + + +## / Audio output buffer format + +type + AudioOutBuffer* {.bycopy.} = object + next*: ptr AudioOutBuffer ## /< Next buffer. (Unused) + buffer*: pointer ## /< Sample buffer (aligned to 0x1000 bytes). + bufferSize*: U64 ## /< Sample buffer size (aligned to 0x1000 bytes). + dataSize*: U64 ## /< Size of data inside the buffer. + dataOffset*: U64 ## /< Offset of data inside the buffer. (Unused?) + +proc audoutInitialize*(): Result {.cdecl, importc: "audoutInitialize".} +## / Initialize audout. + +proc audoutExit*() {.cdecl, importc: "audoutExit".} +## / Exit audout. + +proc audoutGetServiceSession*(): ptr Service {.cdecl, + importc: "audoutGetServiceSession".} +## / Gets the Service object for the actual audout service session. + +proc audoutGetServiceSessionAudioOut*(): ptr Service {.cdecl, + importc: "audoutGetServiceSession_AudioOut".} +## / Gets the Service object for IAudioOut. + +proc audoutListAudioOuts*(deviceNames: cstring; count: S32; deviceNamesCount: ptr U32): Result {. + cdecl, importc: "audoutListAudioOuts".} +## + +proc audoutOpenAudioOut*(deviceNameIn: cstring; deviceNameOut: cstring; + sampleRateIn: U32; channelCountIn: U32; + sampleRateOut: ptr U32; channelCountOut: ptr U32; + format: ptr PcmFormat; state: ptr AudioOutState): Result {. + cdecl, importc: "audoutOpenAudioOut".} +## + +proc audoutGetAudioOutState*(state: ptr AudioOutState): Result {.cdecl, + importc: "audoutGetAudioOutState".} +## + +proc audoutStartAudioOut*(): Result {.cdecl, importc: "audoutStartAudioOut".} +## + +proc audoutStopAudioOut*(): Result {.cdecl, importc: "audoutStopAudioOut".} +## + +proc audoutAppendAudioOutBuffer*(buffer: ptr AudioOutBuffer): Result {.cdecl, + importc: "audoutAppendAudioOutBuffer".} +## / Submits an \ref AudioOutBuffer for playing. + +proc audoutGetReleasedAudioOutBuffer*(buffer: ptr ptr AudioOutBuffer; + releasedBuffersCount: ptr U32): Result {.cdecl, + importc: "audoutGetReleasedAudioOutBuffer".} +## + +proc audoutContainsAudioOutBuffer*(buffer: ptr AudioOutBuffer; + containsBuffer: ptr bool): Result {.cdecl, + importc: "audoutContainsAudioOutBuffer".} +## + +proc audoutGetAudioOutBufferCount*(count: ptr U32): Result {.cdecl, + importc: "audoutGetAudioOutBufferCount".} +## / Only available with [4.0.0+]. + +proc audoutGetAudioOutPlayedSampleCount*(count: ptr U64): Result {.cdecl, + importc: "audoutGetAudioOutPlayedSampleCount".} +## / Only available with [4.0.0+]. + +proc audoutFlushAudioOutBuffers*(flushed: ptr bool): Result {.cdecl, + importc: "audoutFlushAudioOutBuffers".} +## / Only available with [4.0.0+]. + +proc audoutSetAudioOutVolume*(volume: cfloat): Result {.cdecl, + importc: "audoutSetAudioOutVolume".} +## / Only available with [6.0.0+]. + +proc audoutGetAudioOutVolume*(volume: ptr cfloat): Result {.cdecl, + importc: "audoutGetAudioOutVolume".} +## / Only available with [6.0.0+]. + +proc audoutPlayBuffer*(source: ptr AudioOutBuffer; released: ptr ptr AudioOutBuffer): Result {. + cdecl, importc: "audoutPlayBuffer".} +## * +## @brief Submits an audio sample data buffer for playing and waits for it to finish playing. +## @brief Uses \ref audoutAppendAudioOutBuffer and \ref audoutWaitPlayFinish internally. +## @param source AudioOutBuffer containing the source sample data to be played. +## @param released AudioOutBuffer to receive the played buffer after being released. +## + +proc audoutWaitPlayFinish*(released: ptr ptr AudioOutBuffer; releasedCount: ptr U32; + timeout: U64): Result {.cdecl, + importc: "audoutWaitPlayFinish".} +## * +## @brief Waits for audio playback to finish. +## @param released AudioOutBuffer to receive the first played buffer after being released. +## @param released_count Pointer to receive the number of played buffers. +## @param timeout Timeout value, use UINT64_MAX to wait until all finished. +## + + +## / These return the state associated with the currently active audio output device. + +proc audoutGetSampleRate*(): U32 {.cdecl, importc: "audoutGetSampleRate".} +## /< Supported sample rate (48000Hz). + +proc audoutGetChannelCount*(): U32 {.cdecl, importc: "audoutGetChannelCount".} +## /< Supported channel count (2 channels). + +proc audoutGetPcmFormat*(): PcmFormat {.cdecl, importc: "audoutGetPcmFormat".} +## /< Supported PCM format (Int16). + +proc audoutGetDeviceState*(): AudioOutState {.cdecl, importc: "audoutGetDeviceState".} +## /< Initial device state (stopped). diff --git a/src/libnx/wrapper/switch/services/audrec.h b/src/libnx/wrapper/switch/services/audrec.h new file mode 100644 index 0000000..a6e3f17 --- /dev/null +++ b/src/libnx/wrapper/switch/services/audrec.h @@ -0,0 +1,50 @@ +/** + * @file audrec.h + * @brief Audio Recorder IPC wrapper. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef struct { + u64 released_ns; + u64 next_buffer_ptr; + u64 sample_buffer_ptr; + u64 sample_buffer_capacity; + u64 data_size; + u64 data_offset; +} FinalOutputRecorderBuffer; + +typedef struct { + u32 sample_rate; + u32 channel_count; +} FinalOutputRecorderParameter; + +typedef struct { + u32 sample_rate; + u32 channel_count; + u32 sample_format; + u32 state; +} FinalOutputRecorderParameterInternal; + +typedef struct { + Service s; +} AudrecRecorder; + +Result audrecInitialize(void); +void audrecExit(void); +Service* audrecGetServiceSession(void); + +Result audrecOpenFinalOutputRecorder(AudrecRecorder* recorder_out, FinalOutputRecorderParameter* param_in, u64 aruid, FinalOutputRecorderParameterInternal* param_out); + +Result audrecRecorderStart(AudrecRecorder* recorder); +Result audrecRecorderStop(AudrecRecorder* recorder); +Result audrecRecorderRegisterBufferEvent(AudrecRecorder* recorder, Event* out_event); +Result audrecRecorderAppendFinalOutputRecorderBuffer(AudrecRecorder* recorder, u64 buffer_client_ptr, FinalOutputRecorderBuffer* param); +Result audrecRecorderGetReleasedFinalOutputRecorderBuffers(AudrecRecorder* recorder, u64* out_buffers, u64* inout_count, u64* out_released); +void audrecRecorderClose(AudrecRecorder* recorder); diff --git a/src/libnx/wrapper/switch/services/audrec.nim b/src/libnx/wrapper/switch/services/audrec.nim new file mode 100644 index 0000000..3982533 --- /dev/null +++ b/src/libnx/wrapper/switch/services/audrec.nim @@ -0,0 +1,56 @@ +## * +## @file audrec.h +## @brief Audio Recorder IPC wrapper. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + FinalOutputRecorderBuffer* {.bycopy.} = object + releasedNs*: U64 + nextBufferPtr*: U64 + sampleBufferPtr*: U64 + sampleBufferCapacity*: U64 + dataSize*: U64 + dataOffset*: U64 + + FinalOutputRecorderParameter* {.bycopy.} = object + sampleRate*: U32 + channelCount*: U32 + + FinalOutputRecorderParameterInternal* {.bycopy.} = object + sampleRate*: U32 + channelCount*: U32 + sampleFormat*: U32 + state*: U32 + + AudrecRecorder* {.bycopy.} = object + s*: Service + + +proc audrecInitialize*(): Result {.cdecl, importc: "audrecInitialize".} +proc audrecExit*() {.cdecl, importc: "audrecExit".} +proc audrecGetServiceSession*(): ptr Service {.cdecl, + importc: "audrecGetServiceSession".} +proc audrecOpenFinalOutputRecorder*(recorderOut: ptr AudrecRecorder; + paramIn: ptr FinalOutputRecorderParameter; + aruid: U64; paramOut: ptr FinalOutputRecorderParameterInternal): Result {. + cdecl, importc: "audrecOpenFinalOutputRecorder".} +proc audrecRecorderStart*(recorder: ptr AudrecRecorder): Result {.cdecl, + importc: "audrecRecorderStart".} +proc audrecRecorderStop*(recorder: ptr AudrecRecorder): Result {.cdecl, + importc: "audrecRecorderStop".} +proc audrecRecorderRegisterBufferEvent*(recorder: ptr AudrecRecorder; + outEvent: ptr Event): Result {.cdecl, + importc: "audrecRecorderRegisterBufferEvent".} +proc audrecRecorderAppendFinalOutputRecorderBuffer*(recorder: ptr AudrecRecorder; + bufferClientPtr: U64; param: ptr FinalOutputRecorderBuffer): Result {.cdecl, + importc: "audrecRecorderAppendFinalOutputRecorderBuffer".} +proc audrecRecorderGetReleasedFinalOutputRecorderBuffers*( + recorder: ptr AudrecRecorder; outBuffers: ptr U64; inoutCount: ptr U64; + outReleased: ptr U64): Result {.cdecl, importc: "audrecRecorderGetReleasedFinalOutputRecorderBuffers".} +proc audrecRecorderClose*(recorder: ptr AudrecRecorder) {.cdecl, + importc: "audrecRecorderClose".} diff --git a/src/libnx/wrapper/switch/services/audren.h b/src/libnx/wrapper/switch/services/audren.h new file mode 100644 index 0000000..3af6ad5 --- /dev/null +++ b/src/libnx/wrapper/switch/services/audren.h @@ -0,0 +1,332 @@ +/** + * @file audren.h + * @brief Audio renderer service. + * @author fincs + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../audio/audio.h" +#include "../sf/service.h" + +#define AUDREN_TIMER_FREQ_HZ 200.0f +#define AUDREN_TIMER_PERIOD_MS 5.0f +#define AUDREN_SAMPLES_PER_FRAME_32KHZ 160 +#define AUDREN_SAMPLES_PER_FRAME_48KHZ 240 + +#define AUDREN_INPUT_PARAM_ALIGNMENT 0x1000 +#define AUDREN_OUTPUT_PARAM_ALIGNMENT 0x10 +#define AUDREN_MEMPOOL_ALIGNMENT 0x1000 +#define AUDREN_BUFFER_ALIGNMENT 0x40 + +#define AUDREN_REVISION_1 0x31564552 // REV1 [1.0.0+] +#define AUDREN_REVISION_2 0x32564552 // REV2 [2.0.0+] +#define AUDREN_REVISION_3 0x33564552 // REV3 [3.0.0+] +#define AUDREN_REVISION_4 0x34564552 // REV4 [4.0.0+] +#define AUDREN_REVISION_5 0x35564552 // REV5 [6.0.0+] +#define AUDREN_REVISION_6 0x36564552 // REV6 [6.1.0+] + +#define AUDREN_NODEID(_a,_b,_c) ((((u32)(_a) & 0xF) << 28) | (((u32)(_b) & 0xFFF) << 16) | ((u32)(_c) & 0xFFFF)) +#define AUDREN_FINAL_MIX_ID 0 +#define AUDREN_UNUSED_MIX_ID 0x7FFFFFFF +#define AUDREN_UNUSED_SPLITTER_ID 0xFFFFFFFF + +#define AUDREN_DEFAULT_DEVICE_NAME "MainAudioOut" + +typedef enum { + AudioRendererOutputRate_32kHz, + AudioRendererOutputRate_48kHz, +} AudioRendererOutputRate; + +typedef struct { + AudioRendererOutputRate output_rate; + int num_voices; + int num_effects; + int num_sinks; + int num_mix_objs; + int num_mix_buffers; +} AudioRendererConfig; + +/* +Input buffer layout: + +AudioRendererUpdateDataHeader +AudioRendererBehaviorInfoIn +AudioRendererMemPoolInfoIn * mempool_count +AudioRendererChannelInfoIn * channel_count +AudioRendererVoiceInfoIn * voice_count +(effects would go here) +(splitters would go here) +AudioRendererMixInfoIn * mix_count (i.e. submix_count+1) +AudioRendererSinkInfoIn * sink_count +AudioRendererPerformanceBufferInfoIn +*/ + +/* +Output buffer layout: + +AudioRendererUpdateDataHeader +AudioRendererMemPoolInfoOut * mempool_count +AudioRendererVoiceInfoOut * voice_count +(effects would go here) +AudioRendererSinkInfoOut * sink_count +AudioRendererPerformanceBufferInfoOut +AudioRendererBehaviorInfoOut +*/ + +typedef struct { + u32 revision; + u32 behavior_sz; + u32 mempools_sz; + u32 voices_sz; + u32 channels_sz; + u32 effects_sz; + u32 mixes_sz; + u32 sinks_sz; + u32 perfmgr_sz; + u32 _padding[6]; + u32 total_sz; +} AudioRendererUpdateDataHeader; + +typedef struct { + u32 revision; + u32 _padding1; + u64 flags; +} AudioRendererBehaviorInfoIn; + +typedef struct { + u64 unknown[20]; + u64 _padding1[2]; +} AudioRendererBehaviorInfoOut; + +typedef enum { + AudioRendererMemPoolState_Invalid, + AudioRendererMemPoolState_New, + AudioRendererMemPoolState_RequestDetach, + AudioRendererMemPoolState_Detached, + AudioRendererMemPoolState_RequestAttach, + AudioRendererMemPoolState_Attached, + AudioRendererMemPoolState_Released, +} AudioRendererMemPoolState; + +typedef struct { + const void* address; + u64 size; + AudioRendererMemPoolState state; + u32 _padding2[3]; +} AudioRendererMemPoolInfoIn; + +typedef struct +{ + AudioRendererMemPoolState new_state; + u32 _padding2[3]; +} AudioRendererMemPoolInfoOut; + +typedef struct { + u32 id; + float mix[24]; + bool is_used; + u8 _padding1[11]; +} AudioRendererChannelInfoIn; + +typedef struct { + bool enable; + u8 _padding; + s16 numerator[3]; + s16 denominator[2]; +} AudioRendererBiquadFilter; + +typedef struct { + u16 coefficients[16]; +} AudioRendererAdpcmParameters; + +typedef struct { + u16 index; + s16 history0; + s16 history1; +} AudioRendererAdpcmContext; + +typedef struct { + const void* address; + u64 size; + s32 start_sample_offset; + s32 end_sample_offset; + bool is_looping; + bool end_of_stream; + bool sent_to_server; + u8 _padding1[5]; + const void* context_addr; + u64 context_sz; + u64 _padding2; +} AudioRendererWaveBuf; + +typedef enum { + AudioRendererVoicePlayState_Started, + AudioRendererVoicePlayState_Stopped, + AudioRendererVoicePlayState_Paused, +} AudioRendererVoicePlayState; + +typedef struct { + u32 id; + u32 node_id; + bool is_new; + bool is_used; + AudioRendererVoicePlayState state : 8; + PcmFormat sample_format : 8; + u32 sample_rate; + u32 priority; + u32 sorting_order; + u32 channel_count; + float pitch; + float volume; + AudioRendererBiquadFilter biquads[2]; + u32 wavebuf_count; + s16 wavebuf_head; + u16 _padding1; + u32 _padding2; + const void* extra_params_ptr; + u64 extra_params_sz; + u32 dest_mix_id; + u32 dest_splitter_id; + AudioRendererWaveBuf wavebufs[4]; + u32 channel_ids[6]; + u8 _padding3[24]; +} AudioRendererVoiceInfoIn; + +typedef struct { + u64 played_sample_count; + u32 num_wavebufs_consumed; + u32 voice_drops_count; +} AudioRendererVoiceInfoOut; + +typedef struct { + float volume; + u32 sample_rate; + u32 buffer_count; + bool is_used; + u8 _padding1[3]; + u32 mix_id; + u32 _padding2; + u32 node_id; + u32 _padding3[2]; + float mix[24][24]; // [src_index][dest_index] + u32 dest_mix_id; + u32 dest_splitter_id; + u32 _padding4; +} AudioRendererMixInfoIn; + +typedef struct { + u8 coefficients[16]; +} AudioRendererDownMixParameters; + +typedef enum { + AudioRendererSinkType_Invalid, + AudioRendererSinkType_Device, + AudioRendererSinkType_CircularBuffer, +} AudioRendererSinkType; + +typedef struct { + char name[255]; + u8 _padding1; + u32 input_count; + u8 inputs[6]; + u8 _padding2; + bool downmix_params_enabled; + AudioRendererDownMixParameters downmix_params; +} AudioRendererDeviceSinkInfoIn; + +typedef struct { + void* buffer_ptr; + u32 buffer_sz; + u32 input_count; + u32 sample_count; + u32 last_read_offset; + PcmFormat sample_format; + u8 inputs[6]; + u8 _padding2[6]; +} AudioRendererCircularBufferSinkInfoIn; + +typedef struct { + AudioRendererSinkType type : 8; + bool is_used; + u8 _padding1[2]; + u32 node_id; + u64 _padding2[3]; + union { + AudioRendererDeviceSinkInfoIn device_sink; + AudioRendererCircularBufferSinkInfoIn circular_buffer_sink; + }; +} AudioRendererSinkInfoIn; + +typedef struct { + u32 last_written_offset; + u32 unk1; + u64 unk2; + u64 _padding1[2]; +} AudioRendererSinkInfoOut; + +typedef struct { + u32 detail_target; + u32 _padding1[3]; +} AudioRendererPerformanceBufferInfoIn; + +typedef struct { + u32 written_sz; + u32 _padding1[3]; +} AudioRendererPerformanceBufferInfoOut; + +static inline u32 audrenGetRevision(void) +{ + extern u32 g_audrenRevision; + return g_audrenRevision; +} + +NX_CONSTEXPR int audrenGetMemPoolCount(const AudioRendererConfig* config) +{ + return config->num_effects + 4 * config->num_voices; +} + +NX_CONSTEXPR size_t audrenGetInputParamSize(const AudioRendererConfig* config) +{ + size_t size = 0; + size += sizeof(AudioRendererUpdateDataHeader); + size += sizeof(AudioRendererBehaviorInfoIn); + size += sizeof(AudioRendererMemPoolInfoIn) * audrenGetMemPoolCount(config); + size += sizeof(AudioRendererChannelInfoIn) * config->num_voices; + size += sizeof(AudioRendererVoiceInfoIn) * config->num_voices; + // todo: effects, splitters + size += sizeof(AudioRendererMixInfoIn) * config->num_mix_objs; + size += sizeof(AudioRendererSinkInfoIn) * config->num_sinks; + size += sizeof(AudioRendererPerformanceBufferInfoIn); + return size; +} + +NX_CONSTEXPR size_t audrenGetOutputParamSize(const AudioRendererConfig* config) +{ + size_t size = 0; + size += sizeof(AudioRendererUpdateDataHeader); + size += sizeof(AudioRendererMemPoolInfoOut) * audrenGetMemPoolCount(config); + size += sizeof(AudioRendererVoiceInfoOut) * config->num_voices; + // todo: effects + size += sizeof(AudioRendererSinkInfoOut) * config->num_sinks; + size += sizeof(AudioRendererPerformanceBufferInfoOut); + size += sizeof(AudioRendererBehaviorInfoOut); + return size; +} + +/// Initialize audren. +Result audrenInitialize(const AudioRendererConfig* config); + +/// Exit audren. +void audrenExit(void); + +/// Gets the Service object for IAudioRenderer. +Service* audrenGetServiceSession_AudioRenderer(void); + +void audrenWaitFrame(void); +Result audrenGetState(u32* out_state); +Result audrenRequestUpdateAudioRenderer(const void* in_param_buf, size_t in_param_buf_size, void* out_param_buf, size_t out_param_buf_size, void* perf_buf, size_t perf_buf_size); +Result audrenStartAudioRenderer(void); +Result audrenStopAudioRenderer(void); +Result audrenSetAudioRendererRenderingTimeLimit(int percent); diff --git a/src/libnx/wrapper/switch/services/audren.nim b/src/libnx/wrapper/switch/services/audren.nim new file mode 100644 index 0000000..dacf64e --- /dev/null +++ b/src/libnx/wrapper/switch/services/audren.nim @@ -0,0 +1,306 @@ +## * +## @file audren.h +## @brief Audio renderer service. +## @author fincs +## @copyright libnx Authors +## + +import + ../types, ../audio/audio, ../sf/service + +const + AUDREN_TIMER_FREQ_HZ* = 200.0f + AUDREN_TIMER_PERIOD_MS* = 5.0f + AUDREN_SAMPLES_PER_FRAME_32KHZ* = 160 + AUDREN_SAMPLES_PER_FRAME_48KHZ* = 240 + AUDREN_INPUT_PARAM_ALIGNMENT* = 0x1000 + AUDREN_OUTPUT_PARAM_ALIGNMENT* = 0x10 + AUDREN_MEMPOOL_ALIGNMENT* = 0x1000 + AUDREN_BUFFER_ALIGNMENT* = 0x40 + AUDREN_REVISION_1* = 0x31564552 ## REV1 [1.0.0+] + AUDREN_REVISION_2* = 0x32564552 ## REV2 [2.0.0+] + AUDREN_REVISION_3* = 0x33564552 ## REV3 [3.0.0+] + AUDREN_REVISION_4* = 0x34564552 ## REV4 [4.0.0+] + AUDREN_REVISION_5* = 0x35564552 ## REV5 [6.0.0+] + AUDREN_REVISION_6* = 0x36564552 ## REV6 [6.1.0+] + +template audren_Nodeid*(a, b, c: untyped): untyped = + ((((u32)(a) and 0xF) shl 28) or (((u32)(b) and 0xFFF) shl 16) or ((u32)(c) and 0xFFFF)) + +const + AUDREN_FINAL_MIX_ID* = 0 + AUDREN_UNUSED_MIX_ID* = 0x7FFFFFFF + AUDREN_UNUSED_SPLITTER_ID* = 0xFFFFFFFF + AUDREN_DEFAULT_DEVICE_NAME* = "MainAudioOut" + +type + AudioRendererOutputRate* = enum + AudioRendererOutputRate32kHz, AudioRendererOutputRate48kHz + AudioRendererConfig* {.bycopy.} = object + outputRate*: AudioRendererOutputRate + numVoices*: cint + numEffects*: cint + numSinks*: cint + numMixObjs*: cint + numMixBuffers*: cint + + + +## +## Input buffer layout: +## +## AudioRendererUpdateDataHeader +## AudioRendererBehaviorInfoIn +## AudioRendererMemPoolInfoIn * mempool_count +## AudioRendererChannelInfoIn * channel_count +## AudioRendererVoiceInfoIn * voice_count +## (effects would go here) +## (splitters would go here) +## AudioRendererMixInfoIn * mix_count (i.e. submix_count+1) +## AudioRendererSinkInfoIn * sink_count +## AudioRendererPerformanceBufferInfoIn +## +## +## Output buffer layout: +## +## AudioRendererUpdateDataHeader +## AudioRendererMemPoolInfoOut * mempool_count +## AudioRendererVoiceInfoOut * voice_count +## (effects would go here) +## AudioRendererSinkInfoOut * sink_count +## AudioRendererPerformanceBufferInfoOut +## AudioRendererBehaviorInfoOut +## + +type + INNER_C_UNION_audren_2* {.bycopy, union.} = object + deviceSink*: AudioRendererDeviceSinkInfoIn + circularBufferSink*: AudioRendererCircularBufferSinkInfoIn + + AudioRendererUpdateDataHeader* {.bycopy.} = object + revision*: U32 + behaviorSz*: U32 + mempoolsSz*: U32 + voicesSz*: U32 + channelsSz*: U32 + effectsSz*: U32 + mixesSz*: U32 + sinksSz*: U32 + perfmgrSz*: U32 + padding*: array[6, U32] + totalSz*: U32 + + AudioRendererBehaviorInfoIn* {.bycopy.} = object + revision*: U32 + padding1*: U32 + flags*: U64 + + AudioRendererBehaviorInfoOut* {.bycopy.} = object + unknown*: array[20, U64] + padding1*: array[2, U64] + + AudioRendererMemPoolState* = enum + AudioRendererMemPoolStateInvalid, AudioRendererMemPoolStateNew, + AudioRendererMemPoolStateRequestDetach, AudioRendererMemPoolStateDetached, + AudioRendererMemPoolStateRequestAttach, AudioRendererMemPoolStateAttached, + AudioRendererMemPoolStateReleased + AudioRendererMemPoolInfoIn* {.bycopy.} = object + address*: pointer + size*: U64 + state*: AudioRendererMemPoolState + padding2*: array[3, U32] + + AudioRendererMemPoolInfoOut* {.bycopy.} = object + newState*: AudioRendererMemPoolState + padding2*: array[3, U32] + + AudioRendererChannelInfoIn* {.bycopy.} = object + id*: U32 + mix*: array[24, cfloat] + isUsed*: bool + padding1*: array[11, U8] + + AudioRendererBiquadFilter* {.bycopy.} = object + enable*: bool + padding*: U8 + numerator*: array[3, S16] + denominator*: array[2, S16] + + AudioRendererAdpcmParameters* {.bycopy.} = object + coefficients*: array[16, U16] + + AudioRendererAdpcmContext* {.bycopy.} = object + index*: U16 + history0*: S16 + history1*: S16 + + AudioRendererWaveBuf* {.bycopy.} = object + address*: pointer + size*: U64 + startSampleOffset*: S32 + endSampleOffset*: S32 + isLooping*: bool + endOfStream*: bool + sentToServer*: bool + padding1*: array[5, U8] + contextAddr*: pointer + contextSz*: U64 + padding2*: U64 + + AudioRendererVoicePlayState* = enum + AudioRendererVoicePlayStateStarted, AudioRendererVoicePlayStateStopped, + AudioRendererVoicePlayStatePaused + AudioRendererVoiceInfoIn* {.bycopy.} = object + id*: U32 + nodeId*: U32 + isNew*: bool + isUsed*: bool + state* {.bitsize: 8.}: AudioRendererVoicePlayState + sampleFormat* {.bitsize: 8.}: PcmFormat + sampleRate*: U32 + priority*: U32 + sortingOrder*: U32 + channelCount*: U32 + pitch*: cfloat + volume*: cfloat + biquads*: array[2, AudioRendererBiquadFilter] + wavebufCount*: U32 + wavebufHead*: S16 + padding1*: U16 + padding2*: U32 + extraParamsPtr*: pointer + extraParamsSz*: U64 + destMixId*: U32 + destSplitterId*: U32 + wavebufs*: array[4, AudioRendererWaveBuf] + channelIds*: array[6, U32] + padding3*: array[24, U8] + + AudioRendererVoiceInfoOut* {.bycopy.} = object + playedSampleCount*: U64 + numWavebufsConsumed*: U32 + voiceDropsCount*: U32 + + AudioRendererMixInfoIn* {.bycopy.} = object + volume*: cfloat + sampleRate*: U32 + bufferCount*: U32 + isUsed*: bool + padding1*: array[3, U8] + mixId*: U32 + padding2*: U32 + nodeId*: U32 + padding3*: array[2, U32] + mix*: array[24, array[24, cfloat]] ## [src_index][dest_index] + destMixId*: U32 + destSplitterId*: U32 + padding4*: U32 + + AudioRendererDownMixParameters* {.bycopy.} = object + coefficients*: array[16, U8] + + AudioRendererSinkType* = enum + AudioRendererSinkTypeInvalid, AudioRendererSinkTypeDevice, + AudioRendererSinkTypeCircularBuffer + AudioRendererDeviceSinkInfoIn* {.bycopy.} = object + name*: array[255, char] + padding1*: U8 + inputCount*: U32 + inputs*: array[6, U8] + padding2*: U8 + downmixParamsEnabled*: bool + downmixParams*: AudioRendererDownMixParameters + + AudioRendererCircularBufferSinkInfoIn* {.bycopy.} = object + bufferPtr*: pointer + bufferSz*: U32 + inputCount*: U32 + sampleCount*: U32 + lastReadOffset*: U32 + sampleFormat*: PcmFormat + inputs*: array[6, U8] + padding2*: array[6, U8] + + AudioRendererSinkInfoIn* {.bycopy.} = object + `type`* {.bitsize: 8.}: AudioRendererSinkType + isUsed*: bool + padding1*: array[2, U8] + nodeId*: U32 + padding2*: array[3, U64] + anoAudren3*: INNER_C_UNION_audren_2 + + AudioRendererSinkInfoOut* {.bycopy.} = object + lastWrittenOffset*: U32 + unk1*: U32 + unk2*: U64 + padding1*: array[2, U64] + + AudioRendererPerformanceBufferInfoIn* {.bycopy.} = object + detailTarget*: U32 + padding1*: array[3, U32] + + AudioRendererPerformanceBufferInfoOut* {.bycopy.} = object + writtenSz*: U32 + padding1*: array[3, U32] + + + + + +proc audrenGetRevision*(): U32 {.inline, cdecl.} = + var gAudrenRevision: U32 + return gAudrenRevision + +proc audrenGetMemPoolCount*(config: ptr AudioRendererConfig): cint {.inline, cdecl.} = + return config.numEffects + 4 * config.numVoices + +proc audrenGetInputParamSize*(config: ptr AudioRendererConfig): csize_t {.inline, cdecl.} = + var size: csize_t = 0 + inc(size, sizeof((AudioRendererUpdateDataHeader))) + inc(size, sizeof((AudioRendererBehaviorInfoIn))) + inc(size, sizeof((AudioRendererMemPoolInfoIn)) * + audrenGetMemPoolCount(config)) + inc(size, sizeof((AudioRendererChannelInfoIn)) * config.numVoices) + inc(size, sizeof((AudioRendererVoiceInfoIn)) * config.numVoices) + ## todo: effects, splitters + inc(size, sizeof((AudioRendererMixInfoIn)) * config.numMixObjs) + inc(size, sizeof((AudioRendererSinkInfoIn)) * config.numSinks) + inc(size, sizeof((AudioRendererPerformanceBufferInfoIn))) + return size + +proc audrenGetOutputParamSize*(config: ptr AudioRendererConfig): csize_t {.inline, cdecl.} = + var size: csize_t = 0 + inc(size, sizeof((AudioRendererUpdateDataHeader))) + inc(size, sizeof((AudioRendererMemPoolInfoOut)) * + audrenGetMemPoolCount(config)) + inc(size, sizeof((AudioRendererVoiceInfoOut)) * config.numVoices) + ## todo: effects + inc(size, sizeof((AudioRendererSinkInfoOut)) * config.numSinks) + inc(size, sizeof((AudioRendererPerformanceBufferInfoOut))) + inc(size, sizeof((AudioRendererBehaviorInfoOut))) + return size + + +proc audrenInitialize*(config: ptr AudioRendererConfig): Result {.cdecl, + importc: "audrenInitialize".} +## / Initialize audren. + +proc audrenExit*() {.cdecl, importc: "audrenExit".} +## / Exit audren. + +proc audrenGetServiceSessionAudioRenderer*(): ptr Service {.cdecl, + importc: "audrenGetServiceSession_AudioRenderer".} +## / Gets the Service object for IAudioRenderer. +proc audrenWaitFrame*() {.cdecl, importc: "audrenWaitFrame".} +proc audrenGetState*(outState: ptr U32): Result {.cdecl, importc: "audrenGetState".} +proc audrenRequestUpdateAudioRenderer*(inParamBuf: pointer; + inParamBufSize: csize_t; + outParamBuf: pointer; + outParamBufSize: csize_t; perfBuf: pointer; + perfBufSize: csize_t): Result {.cdecl, + importc: "audrenRequestUpdateAudioRenderer".} +proc audrenStartAudioRenderer*(): Result {.cdecl, + importc: "audrenStartAudioRenderer".} +proc audrenStopAudioRenderer*(): Result {.cdecl, importc: "audrenStopAudioRenderer".} +proc audrenSetAudioRendererRenderingTimeLimit*(percent: cint): Result {.cdecl, + importc: "audrenSetAudioRendererRenderingTimeLimit".} diff --git a/src/libnx/wrapper/switch/services/avm.h b/src/libnx/wrapper/switch/services/avm.h new file mode 100644 index 0000000..1ad59f4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/avm.h @@ -0,0 +1,45 @@ +/** + * @file avm.h + * @brief AVM services IPC wrapper. Only available on [6.0.0+]. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../sf/service.h" + +typedef struct { + u64 application_id; + u32 version; + u32 required; +} AvmVersionListEntry; + +typedef struct { + u64 application_id; + u32 version; +} AvmRequiredVersionEntry; + +typedef struct { + Service s; +} AvmVersionListImporter; + +Result avmInitialize(void); +void avmExit(void); + +Service *avmGetServiceSession(void); + +Result avmGetHighestAvailableVersion(u64 id_1, u64 id_2, u32 *version); +Result avmGetHighestRequiredVersion(u64 id_1, u64 id_2, u32 *version); +Result avmGetVersionListEntry(u64 application_id, AvmVersionListEntry *entry); +Result avmGetVersionListImporter(AvmVersionListImporter *out); +Result avmGetLaunchRequiredVersion(u64 application_id, u32 *version); +Result avmUpgradeLaunchRequiredVersion(u64 application_id, u32 version); +Result avmPushLaunchVersion(u64 application_id, u32 version); +Result avmListVersionList(AvmVersionListEntry *buffer, size_t count, u32 *out); +Result avmListRequiredVersion(AvmRequiredVersionEntry *buffer, size_t count, u32 *out); + +void avmVersionListImporterClose(AvmVersionListImporter *srv); +Result avmVersionListImporterSetTimestamp(AvmVersionListImporter *srv, u64 timestamp); +Result avmVersionListImporterSetData(AvmVersionListImporter *srv, const AvmVersionListEntry *entries, u32 count); +Result avmVersionListImporterFlush(AvmVersionListImporter *srv); diff --git a/src/libnx/wrapper/switch/services/avm.nim b/src/libnx/wrapper/switch/services/avm.nim new file mode 100644 index 0000000..7da906e --- /dev/null +++ b/src/libnx/wrapper/switch/services/avm.nim @@ -0,0 +1,57 @@ +## * +## @file avm.h +## @brief AVM services IPC wrapper. Only available on [6.0.0+]. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + AvmVersionListEntry* {.bycopy.} = object + applicationId*: U64 + version*: U32 + required*: U32 + + AvmRequiredVersionEntry* {.bycopy.} = object + applicationId*: U64 + version*: U32 + + AvmVersionListImporter* {.bycopy.} = object + s*: Service + + +proc avmInitialize*(): Result {.cdecl, importc: "avmInitialize".} +proc avmExit*() {.cdecl, importc: "avmExit".} +proc avmGetServiceSession*(): ptr Service {.cdecl, importc: "avmGetServiceSession".} +proc avmGetHighestAvailableVersion*(id1: U64; id2: U64; version: ptr U32): Result {. + cdecl, importc: "avmGetHighestAvailableVersion".} +proc avmGetHighestRequiredVersion*(id1: U64; id2: U64; version: ptr U32): Result {.cdecl, + importc: "avmGetHighestRequiredVersion".} +proc avmGetVersionListEntry*(applicationId: U64; entry: ptr AvmVersionListEntry): Result {. + cdecl, importc: "avmGetVersionListEntry".} +proc avmGetVersionListImporter*(`out`: ptr AvmVersionListImporter): Result {.cdecl, + importc: "avmGetVersionListImporter".} +proc avmGetLaunchRequiredVersion*(applicationId: U64; version: ptr U32): Result {. + cdecl, importc: "avmGetLaunchRequiredVersion".} +proc avmUpgradeLaunchRequiredVersion*(applicationId: U64; version: U32): Result {. + cdecl, importc: "avmUpgradeLaunchRequiredVersion".} +proc avmPushLaunchVersion*(applicationId: U64; version: U32): Result {.cdecl, + importc: "avmPushLaunchVersion".} +proc avmListVersionList*(buffer: ptr AvmVersionListEntry; count: csize_t; + `out`: ptr U32): Result {.cdecl, + importc: "avmListVersionList".} +proc avmListRequiredVersion*(buffer: ptr AvmRequiredVersionEntry; count: csize_t; + `out`: ptr U32): Result {.cdecl, + importc: "avmListRequiredVersion".} +proc avmVersionListImporterClose*(srv: ptr AvmVersionListImporter) {.cdecl, + importc: "avmVersionListImporterClose".} +proc avmVersionListImporterSetTimestamp*(srv: ptr AvmVersionListImporter; + timestamp: U64): Result {.cdecl, + importc: "avmVersionListImporterSetTimestamp".} +proc avmVersionListImporterSetData*(srv: ptr AvmVersionListImporter; + entries: ptr AvmVersionListEntry; count: U32): Result {. + cdecl, importc: "avmVersionListImporterSetData".} +proc avmVersionListImporterFlush*(srv: ptr AvmVersionListImporter): Result {.cdecl, + importc: "avmVersionListImporterFlush".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/bpc.h b/src/libnx/wrapper/switch/services/bpc.h new file mode 100644 index 0000000..3a67fcb --- /dev/null +++ b/src/libnx/wrapper/switch/services/bpc.h @@ -0,0 +1,28 @@ +/** + * @file bpc.h + * @brief Board power control (bpc) service IPC wrapper. + * @author XorTroll, SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + BpcSleepButtonState_Held = 0, + BpcSleepButtonState_Released = 1, +} BpcSleepButtonState; + +/// Initialize bpc. +Result bpcInitialize(void); + +/// Exit bpc. +void bpcExit(void); + +/// Gets the Service object for the actual bpc service session. +Service* bpcGetServiceSession(void); + +Result bpcShutdownSystem(void); +Result bpcRebootSystem(void); +Result bpcGetSleepButtonState(BpcSleepButtonState *out); ///< [2.0.0-13.2.1] +Result bpcGetPowerButton(bool* out_is_pushed); ///< [6.0.0+] diff --git a/src/libnx/wrapper/switch/services/bpc.nim b/src/libnx/wrapper/switch/services/bpc.nim new file mode 100644 index 0000000..157c9a8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/bpc.nim @@ -0,0 +1,33 @@ +## * +## @file bpc.h +## @brief Board power control (bpc) service IPC wrapper. +## @author XorTroll, SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + BpcSleepButtonState* = enum + BpcSleepButtonStateHeld = 0, BpcSleepButtonStateReleased = 1 + + +## / Initialize bpc. + +proc bpcInitialize*(): Result {.cdecl, importc: "bpcInitialize".} +## / Exit bpc. + +proc bpcExit*() {.cdecl, importc: "bpcExit".} +## / Gets the Service object for the actual bpc service session. + +proc bpcGetServiceSession*(): ptr Service {.cdecl, importc: "bpcGetServiceSession".} +proc bpcShutdownSystem*(): Result {.cdecl, importc: "bpcShutdownSystem".} +proc bpcRebootSystem*(): Result {.cdecl, importc: "bpcRebootSystem".} +proc bpcGetSleepButtonState*(`out`: ptr BpcSleepButtonState): Result {.cdecl, + importc: "bpcGetSleepButtonState".} +## /< [2.0.0-13.2.1] + +proc bpcGetPowerButton*(outIsPushed: ptr bool): Result {.cdecl, + importc: "bpcGetPowerButton".} +## /< [6.0.0+] diff --git a/src/libnx/wrapper/switch/services/bsd.h b/src/libnx/wrapper/switch/services/bsd.h new file mode 100644 index 0000000..80958a9 --- /dev/null +++ b/src/libnx/wrapper/switch/services/bsd.h @@ -0,0 +1,84 @@ +/** + * @file bsd.h + * @brief BSD sockets (bsd:u/s) service IPC wrapper. Please use the standard interface instead. + * @author plutoo + * @author TuxSH + * @copyright libnx Authors + */ +#pragma once +#include // for socklen_t +#include // for fd_set +#include // for struct pollfd, ndfs_t + +#include "../types.h" +#include "../kernel/tmem.h" +#include "../sf/service.h" + +/// Configuration structure for bsdInitalize +typedef struct { + u32 version; ///< Observed 1 on [2.0.0+] LibAppletWeb, 2 on [3.0.0+]. + + void *tmem_buffer; ///< User-provided buffer to use as backing for transfer memory. If NULL, a buffer will be allocated automatically. Must be large enough and page-aligned. + size_t tmem_buffer_size; ///< Size of the user-provided transfer memory backing buffer. Must be large enough and page-aligned. + + u32 tcp_tx_buf_size; ///< Size of the TCP transfer (send) buffer (initial or fixed). + u32 tcp_rx_buf_size; ///< Size of the TCP receive buffer (initial or fixed). + u32 tcp_tx_buf_max_size; ///< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + u32 tcp_rx_buf_max_size; ///< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + + u32 udp_tx_buf_size; ///< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + u32 udp_rx_buf_size; ///< Size of the UDP receive buffer (typically 0xA500 bytes). + + u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). +} BsdInitConfig; + +extern __thread Result g_bsdResult; ///< Last Switch "result", per-thread +extern __thread int g_bsdErrno; ///< Last errno, per-thread + +/// Fetch the default configuration for bsdInitialize. +const BsdInitConfig *bsdGetDefaultInitConfig(void); + +/// Initialize the BSD service. +Result bsdInitialize(const BsdInitConfig *config, u32 num_sessions, u32 service_type); + +/// Exit the BSD service. +void bsdExit(void); + +/// Gets the Service object for the actual BSD service session. +Service* bsdGetServiceSession(void); + +/// Creates a socket. +int bsdSocket(int domain, int type, int protocol); +/// Like @ref bsdSocket but the newly created socket is immediately shut down. +int bsdSocketExempt(int domain, int type, int protocol); +int bsdOpen(const char *pathname, int flags); +int bsdSelect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); +int bsdPoll(struct pollfd *fds, nfds_t nfds, int timeout); +int bsdSysctl(const int *name, unsigned int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); +ssize_t bsdRecv(int sockfd, void *buf, size_t len, int flags); +ssize_t bsdRecvFrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); +ssize_t bsdSend(int sockfd, const void* buf, size_t len, int flags); +ssize_t bsdSendTo(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); +int bsdAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int bsdConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int bsdGetPeerName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdGetSockName(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int bsdGetSockOpt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); +int bsdListen(int sockfd, int backlog); +/// Made non-variadic for convenience. +int bsdIoctl(int fd, int request, void *data); +/// Made non-variadic for convenience. +int bsdFcntl(int fd, int cmd, int flags); +int bsdSetSockOpt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); +int bsdShutdown(int sockfd, int how); +int bsdShutdownAllSockets(int how); +ssize_t bsdWrite(int fd, const void *buf, size_t count); +ssize_t bsdRead(int fd, void *buf, size_t count); +int bsdClose(int fd); +/// Duplicate a socket (bsd:s). +int bsdDuplicateSocket(int sockfd); +int bsdRecvMMsg(int sockfd, void *buf, size_t size, unsigned int vlen, int flags, struct timespec *timeout); +int bsdSendMMsg(int sockfd, void *buf, size_t size, unsigned int vlen, int flags); + +// TODO: Reverse-engineer GetResourceStatistics. diff --git a/src/libnx/wrapper/switch/services/bsd.nim b/src/libnx/wrapper/switch/services/bsd.nim new file mode 100644 index 0000000..137054e --- /dev/null +++ b/src/libnx/wrapper/switch/services/bsd.nim @@ -0,0 +1,120 @@ +## * +## @file bsd.h +## @brief BSD sockets (bsd:u/s) service IPC wrapper. Please use the standard interface instead. +## @author plutoo +## @author TuxSH +## @copyright libnx Authors +## + +import + ../types, ../kernel/tmem, ../sf/service + +## / Configuration structure for bsdInitalize + +type + BsdInitConfig* {.bycopy.} = object + version*: U32 ## /< Observed 1 on [2.0.0+] LibAppletWeb, 2 on [3.0.0+]. + tmemBuffer*: pointer ## /< User-provided buffer to use as backing for transfer memory. If NULL, a buffer will be allocated automatically. Must be large enough and page-aligned. + tmemBufferSize*: csize_t ## /< Size of the user-provided transfer memory backing buffer. Must be large enough and page-aligned. + tcpTxBufSize*: U32 ## /< Size of the TCP transfer (send) buffer (initial or fixed). + tcpRxBufSize*: U32 ## /< Size of the TCP receive buffer (initial or fixed). + tcpTxBufMaxSize*: U32 ## /< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + tcpRxBufMaxSize*: U32 ## /< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + udpTxBufSize*: U32 ## /< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + udpRxBufSize*: U32 ## /< Size of the UDP receive buffer (typically 0xA500 bytes). + sbEfficiency*: U32 ## /< Number of buffers for each socket (standard values range from 1 to 8). + +type + SockAddr* = object + FdSet* = object + TimeVal* = object + NfdsT* = uint + PollFd* = object + SockLenT* = uint32 + TimeSpec* = object + tv_sec: clong + tv_nsec: clong + +var gBsdResult* {.importc: "g_bsdResult".}: Result + +## /< Last Switch "result", per-thread + +var gBsdErrno* {.importc: "g_bsdErrno".}: cint + +## /< Last errno, per-thread +## / Fetch the default configuration for bsdInitialize. + +proc bsdGetDefaultInitConfig*(): ptr BsdInitConfig {.cdecl, + importc: "bsdGetDefaultInitConfig".} +## / Initialize the BSD service. + +proc bsdInitialize*(config: ptr BsdInitConfig; numSessions: U32; serviceType: U32): Result {. + cdecl, importc: "bsdInitialize".} +## / Exit the BSD service. + +proc bsdExit*() {.cdecl, importc: "bsdExit".} +## / Gets the Service object for the actual BSD service session. + +proc bsdGetServiceSession*(): ptr Service {.cdecl, importc: "bsdGetServiceSession".} +## / Creates a socket. + +proc bsdSocket*(domain: cint; `type`: cint; protocol: cint): cint {.cdecl, + importc: "bsdSocket".} +## / Like @ref bsdSocket but the newly created socket is immediately shut down. + +proc bsdSocketExempt*(domain: cint; `type`: cint; protocol: cint): cint {.cdecl, + importc: "bsdSocketExempt".} +proc bsdOpen*(pathname: cstring; flags: cint): cint {.cdecl, importc: "bsdOpen".} +proc bsdSelect*(nfds: cint; readfds: ptr FdSet; writefds: ptr FdSet; + exceptfds: ptr FdSet; timeout: ptr Timeval): cint {.cdecl, + importc: "bsdSelect".} +proc bsdPoll*(fds: ptr Pollfd; nfds: NfdsT; timeout: cint): cint {.cdecl, + importc: "bsdPoll".} +proc bsdSysctl*(name: ptr cint; namelen: cuint; oldp: pointer; oldlenp: ptr csize_t; + newp: pointer; newlen: csize_t): cint {.cdecl, importc: "bsdSysctl".} +proc bsdRecv*(sockfd: cint; buf: pointer; len: csize_t; flags: cint): SsizeT {.cdecl, + importc: "bsdRecv".} +proc bsdRecvFrom*(sockfd: cint; buf: pointer; len: csize_t; flags: cint; + srcAddr: ptr Sockaddr; addrlen: ptr SocklenT): SsizeT {.cdecl, + importc: "bsdRecvFrom".} +proc bsdSend*(sockfd: cint; buf: pointer; len: csize_t; flags: cint): SsizeT {.cdecl, + importc: "bsdSend".} +proc bsdSendTo*(sockfd: cint; buf: pointer; len: csize_t; flags: cint; + destAddr: ptr Sockaddr; addrlen: SocklenT): SsizeT {.cdecl, + importc: "bsdSendTo".} +proc bsdAccept*(sockfd: cint; `addr`: ptr Sockaddr; addrlen: ptr SocklenT): cint {.cdecl, + importc: "bsdAccept".} +proc bsdBind*(sockfd: cint; `addr`: ptr Sockaddr; addrlen: SocklenT): cint {.cdecl, + importc: "bsdBind".} +proc bsdConnect*(sockfd: cint; `addr`: ptr Sockaddr; addrlen: SocklenT): cint {.cdecl, + importc: "bsdConnect".} +proc bsdGetPeerName*(sockfd: cint; `addr`: ptr Sockaddr; addrlen: ptr SocklenT): cint {. + cdecl, importc: "bsdGetPeerName".} +proc bsdGetSockName*(sockfd: cint; `addr`: ptr Sockaddr; addrlen: ptr SocklenT): cint {. + cdecl, importc: "bsdGetSockName".} +proc bsdGetSockOpt*(sockfd: cint; level: cint; optname: cint; optval: pointer; + optlen: ptr SocklenT): cint {.cdecl, importc: "bsdGetSockOpt".} +proc bsdListen*(sockfd: cint; backlog: cint): cint {.cdecl, importc: "bsdListen".} +## / Made non-variadic for convenience. + +proc bsdIoctl*(fd: cint; request: cint; data: pointer): cint {.cdecl, importc: "bsdIoctl".} +## / Made non-variadic for convenience. + +proc bsdFcntl*(fd: cint; cmd: cint; flags: cint): cint {.cdecl, importc: "bsdFcntl".} +proc bsdSetSockOpt*(sockfd: cint; level: cint; optname: cint; optval: pointer; + optlen: SocklenT): cint {.cdecl, importc: "bsdSetSockOpt".} +proc bsdShutdown*(sockfd: cint; how: cint): cint {.cdecl, importc: "bsdShutdown".} +proc bsdShutdownAllSockets*(how: cint): cint {.cdecl, + importc: "bsdShutdownAllSockets".} +proc bsdWrite*(fd: cint; buf: pointer; count: csize_t): SsizeT {.cdecl, + importc: "bsdWrite".} +proc bsdRead*(fd: cint; buf: pointer; count: csize_t): SsizeT {.cdecl, importc: "bsdRead".} +proc bsdClose*(fd: cint): cint {.cdecl, importc: "bsdClose".} +## / Duplicate a socket (bsd:s). + +proc bsdDuplicateSocket*(sockfd: cint): cint {.cdecl, importc: "bsdDuplicateSocket".} +proc bsdRecvMMsg*(sockfd: cint; buf: pointer; size: csize_t; vlen: cuint; flags: cint; + timeout: ptr Timespec): cint {.cdecl, importc: "bsdRecvMMsg".} +proc bsdSendMMsg*(sockfd: cint; buf: pointer; size: csize_t; vlen: cuint; flags: cint): cint {. + cdecl, importc: "bsdSendMMsg".} +## TODO: Reverse-engineer GetResourceStatistics. diff --git a/src/libnx/wrapper/switch/services/bt.h b/src/libnx/wrapper/switch/services/bt.h new file mode 100644 index 0000000..3fc8d3f --- /dev/null +++ b/src/libnx/wrapper/switch/services/bt.h @@ -0,0 +1,132 @@ +/** + * @file bt.h + * @brief Bluetooth user (bt) service IPC wrapper. + * @note See also btdev. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/btdrv.h" +#include "../sf/service.h" + +/// Initialize bt. Only available on [5.0.0+]. +Result btInitialize(void); + +/// Exit bt. +void btExit(void); + +/// Gets the Service object for the actual bt service session. +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 + */ +Result btLeClientReadCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, u8 unk); + +/** + * @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 + */ +Result btLeClientReadDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, u8 unk); + +/** + * @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] buffer Input buffer. + * @param[in] size Input buffer size, must be <=0x258. + * @param[in] unk Unknown + * @param[in] flag Flag + */ +Result btLeClientWriteCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size, u8 unk, bool flag); + +/** + * @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] buffer Input buffer. + * @param[in] size Input buffer size, must be <=0x258. + * @param[in] unk Unknown + */ +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); + +/** + * @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 + */ +Result btLeClientRegisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1); + +/** + * @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 + */ +Result btLeClientDeregisterNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1); + +/** + * @brief SetLeResponse + * @param[in] unk Unknown + * @param[in] uuid0 \ref BtdrvGattAttributeUuid + * @param[in] uuid1 \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); + +/** + * @brief LeSendIndication + * @param[in] unk Unknown + * @param[in] uuid0 \ref BtdrvGattAttributeUuid + * @param[in] uuid1 \ref BtdrvGattAttributeUuid + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size, clamped to max size 0x258. + * @param[in] flag Flag + */ +Result btLeSendIndication(u8 unk, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, const void* buffer, size_t size, bool flag); + +/** + * @brief GetLeEventInfo + * @note This is identical to \ref btdrvGetLeHidEventInfo except different state is used. + * @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. + */ +Result btGetLeEventInfo(void* buffer, size_t size, u32 *type); + +/** + * @brief RegisterBleEvent + * @note This is identical to \ref btdrvRegisterBleHidEvent except different state is used. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btRegisterBleEvent(Event* out_event); + diff --git a/src/libnx/wrapper/switch/services/bt.nim b/src/libnx/wrapper/switch/services/bt.nim new file mode 100644 index 0000000..cb390ea --- /dev/null +++ b/src/libnx/wrapper/switch/services/bt.nim @@ -0,0 +1,153 @@ +## * +## @file bt.h +## @brief Bluetooth user (bt) service IPC wrapper. +## @note See also btdev. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service, ../services/btdrv_types + +proc btInitialize*(): Result {.cdecl, importc: "btInitialize".} +## / Initialize bt. Only available on [5.0.0+]. + +proc btExit*() {.cdecl, importc: "btExit".} +## / Exit bt. + +proc btGetServiceSession*(): ptr Service {.cdecl, importc: "btGetServiceSession".} +## / Gets the Service object for the actual bt service session. + +proc btLeClientReadCharacteristic*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; unk: U8): Result {. + cdecl, importc: "btLeClientReadCharacteristic".} +## * +## @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 +## + +proc btLeClientReadDescriptor*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + id2: ptr BtdrvGattId; unk: U8): Result {.cdecl, + importc: "btLeClientReadDescriptor".} +## * +## @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 +## + +proc btLeClientWriteCharacteristic*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + buffer: pointer; size: csize_t; unk: U8; flag: bool): Result {. + cdecl, importc: "btLeClientWriteCharacteristic".} +## * +## @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] buffer Input buffer. +## @param[in] size Input buffer size, must be <=0x258. +## @param[in] unk Unknown +## @param[in] flag Flag +## + +proc btLeClientWriteDescriptor*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + id2: ptr BtdrvGattId; buffer: pointer; size: csize_t; + unk: U8): Result {.cdecl, + importc: "btLeClientWriteDescriptor".} +## * +## @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] buffer Input buffer. +## @param[in] size Input buffer size, must be <=0x258. +## @param[in] unk Unknown +## + +proc btLeClientRegisterNotification*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId): Result {. + cdecl, importc: "btLeClientRegisterNotification".} +## * +## @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 +## + +proc btLeClientDeregisterNotification*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId): Result {. + cdecl, importc: "btLeClientDeregisterNotification".} +## * +## @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 +## + +proc btSetLeResponse*(unk: U8; uuid0: ptr BtdrvGattAttributeUuid; + uuid1: ptr BtdrvGattAttributeUuid; buffer: pointer; + size: csize_t): Result {.cdecl, importc: "btSetLeResponse".} +## * +## @brief SetLeResponse +## @param[in] unk Unknown +## @param[in] uuid0 \ref BtdrvGattAttributeUuid +## @param[in] uuid1 \ref BtdrvGattAttributeUuid +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size, must be <=0x258. +## + +proc btLeSendIndication*(unk: U8; uuid0: ptr BtdrvGattAttributeUuid; + uuid1: ptr BtdrvGattAttributeUuid; buffer: pointer; + size: csize_t; flag: bool): Result {.cdecl, + importc: "btLeSendIndication".} +## * +## @brief LeSendIndication +## @param[in] unk Unknown +## @param[in] uuid0 \ref BtdrvGattAttributeUuid +## @param[in] uuid1 \ref BtdrvGattAttributeUuid +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size, clamped to max size 0x258. +## @param[in] flag Flag +## + +proc btGetLeEventInfo*(buffer: pointer; size: csize_t; `type`: ptr U32): Result {.cdecl, + importc: "btGetLeEventInfo".} +## * +## @brief GetLeEventInfo +## @note This is identical to \ref btdrvGetLeHidEventInfo except different state is used. +## @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. +## + +proc btRegisterBleEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btRegisterBleEvent".} +## * +## @brief RegisterBleEvent +## @note This is identical to \ref btdrvRegisterBleHidEvent except different state is used. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + diff --git a/src/libnx/wrapper/switch/services/btdrv.h b/src/libnx/wrapper/switch/services/btdrv.h new file mode 100644 index 0000000..48bd71c --- /dev/null +++ b/src/libnx/wrapper/switch/services/btdrv.h @@ -0,0 +1,1528 @@ +/** + * @file btdrv.h + * @brief Bluetooth driver (btdrv) service IPC wrapper. + * @author yellows8, ndeadly + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/btdrv_types.h" +#include "../services/set.h" +#include "../sf/service.h" + +/// Data for \ref btdrvGetEventInfo. The data stored here depends on the \ref BtdrvEventType. +typedef struct { + union { + u8 data[0x400]; ///< Raw data. + + struct { + u32 val; ///< Value + } type0; ///< ::BtdrvEventTypeOld_Unknown0 + + struct { + union { + struct { + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvAddress addr; ///< Device address. + u8 reserved_xFF[0x10]; ///< Reserved + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 unk_x112[0x4]; ///< Set to fixed value u32 0x1. + u8 reserved_x116[0xFA]; ///< Reserved + u8 reserved_x210[0x5C]; ///< Reserved + char name2[0xF9]; ///< Device name, NUL-terminated string. Same as name above, except starting at index 1. + u8 rssi[0x4]; ///< s32 RSSI + u8 name3[0x4]; ///< Two bytes which are the same as name[11-12]. + u8 reserved_x36D[0x10]; ///< Reserved + } v1; ///< [1.0.0-11.0.1] + + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 reserved[0x6]; ///< Reserved + } v12; ///< [12.0.0+] + }; + } inquiry_device; ///< ::BtdrvEventType_InquiryDevice + + struct { + union { + struct { + BtdrvInquiryStatus status; ///< \ref BtdrvInquiryStatus + } v1; ///< [1.0.0-11.0.1] + + struct { + u8 status; ///< \ref BtdrvInquiryStatus + u8 pad[3]; ///< Padding + u32 service_mask; ///< Services value from \ref btdrvStartInquiry when starting, otherwise this is value 0. + } v12; ///< [12.0.0+] + }; + } inquiry_status; ///< ::BtdrvEventType_InquiryStatus + + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + } pairing_pin_code_request; ///< ::BtdrvEventType_PairingPinCodeRequest + + struct { + union { + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 pad[2]; ///< Padding + u32 type; ///< 0 = SSP confirm request, 3 = SSP passkey notification. + s32 passkey; ///< Passkey, only set when the above field is value 3. + } v1; ///< [1.0.0-11.0.1] + + struct { + BtdrvAddress addr; ///< Device address. + char name[0xF9]; ///< Device name, NUL-terminated string. + BtdrvClassOfDevice class_of_device; ///< Class of Device. + u8 flag; ///< bool flag for Just Works. With SSP passkey notification this is always 0. + u8 pad; ///< Padding + s32 passkey; ///< Passkey + } v12; ///< [12.0.0+] + }; + } ssp_request; ///< ::BtdrvEventType_SspRequest + + struct { + union { + struct { + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + u32 status; ///< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). + u32 type; ///< \ref BtdrvConnectionEventType + } v1; ///< [1.0.0-8.1.1] + + struct { + u32 status; ///< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + u32 type; ///< \ref BtdrvConnectionEventType + } v9; ///< [9.0.0-11.0.1] + + struct { + u32 type; ///< \ref BtdrvConnectionEventType + BtdrvAddress addr; ///< Device address. + u8 reserved[0xfe]; ///< Reserved + } v12; ///< [12.0.0+] + }; + } connection; ///< ::BtdrvEventType_Connection + + struct { + BtdrvAddress addr; ///< Device address. + u8 status; ///< Status flag: 1 = success, 0 = failure. + u8 value; ///< Tsi value, when the above indicates success. + } tsi; ///< ::BtdrvEventType_Tsi + + struct { + BtdrvAddress addr; ///< Device address. + u8 status; ///< Status flag: 1 = success, 0 = failure. + u8 value; ///< Input bool value from \ref btdrvEnableBurstMode, when the above indicates success. + } burst_mode; ///< ::BtdrvEventType_BurstMode + + struct { + BtdrvAddress addr; ///< Device address. + u8 status; ///< Status flag: 1 = success, 0 = failure. + u8 flag; ///< Bool flag, when the above indicates success. + } set_zero_retransmission; ///< ::BtdrvEventType_SetZeroRetransmission + + struct { + u8 status; ///< Status flag: 1 = success, 0 = failure. + u8 pad[0x3]; ///< Padding + u32 count; ///< Count value. + } pending_connections; ///< ::BtdrvEventType_PendingConnections + + struct { + BtdrvAddress addr; ///< Device address. + u8 status; ///< Status flag: 1 = success, 0 = failure. + } move_to_secondary_piconet; ///< ::BtdrvEventType_MoveToSecondaryPiconet + + struct { + u16 reason; ///< \ref BtdrvFatalReason + } bluetooth_crash; ///< ::BtdrvEventType_BluetoothCrash + }; +} BtdrvEventInfo; + +/// Data for \ref btdrvGetHidEventInfo. The data stored here depends on the \ref BtdrvHidEventType. +typedef struct { + union { + u8 data[0x480]; ///< Raw data. + + struct { + union { + struct { + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus + } v1; ///< [1.0.0-11.0.1] + + struct { + BtdrvHidConnectionStatus status; ///< \ref BtdrvHidConnectionStatus + BtdrvAddress addr; ///< Device address. + } v12; ///< [12.0.0+] + }; + } connection; ///< ::BtdrvHidEventType_Connection + + struct { + u32 type; ///< \ref BtdrvExtEventType, controls which data is stored below. + + union { + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + } set_tsi; ///< ::BtdrvExtEventType_SetTsi + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + } exit_tsi; ///< ::BtdrvExtEventType_ExitTsi + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + } set_burst_mode; ///< ::BtdrvExtEventType_SetBurstMode + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + } exit_burst_mode; ///< ::BtdrvExtEventType_ExitBurstMode + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + u8 flag; ///< Flag + } set_zero_retransmission; ///< ::BtdrvExtEventType_SetZeroRetransmission + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Unused + u8 pad[2]; ///< Padding + u32 count; ///< Count value. + } pending_connections; ///< ::BtdrvExtEventType_PendingConnections + + struct { + u32 status; ///< 0 for success, non-zero for error. + BtdrvAddress addr; ///< Device address. + } move_to_secondary_piconet; ///< ::BtdrvExtEventType_MoveToSecondaryPiconet + }; + } ext; ///< ::BtdrvHidEventType_Ext [1.0.0-11.0.1] + }; +} BtdrvHidEventInfo; + +/// Data for \ref btdrvGetHidReportEventInfo. The data stored here depends on the \ref BtdrvHidEventType. +typedef struct { + union { + u8 data[0x480]; ///< Raw data. + + struct { + union { + struct { + struct { + BtdrvAddress addr; + u8 pad[2]; + u32 res; + u32 size; + } hdr; + u8 unused[0x3]; ///< Unused + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 unused2[0x3]; ///< Unused + BtdrvHidData report; + } v1; ///< [1.0.0-6.2.0] + + struct { + u8 unused[0x3]; ///< Unused + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 unused2[0x3]; ///< Unused + BtdrvHidData report; + } v7; ///< [7.0.0-8.1.1] + + struct { + u32 res; ///< Always 0. + u8 unk_x4; ///< Always 0. + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 pad; ///< Padding + BtdrvHidReport report; + } v9; ///< [9.0.0+] + }; + } data_report; ///< ::BtdrvHidEventType_DataReport + + struct { + union { + u8 rawdata[0xC]; ///< Raw data. + + struct { + u32 res; ///< 0 = success, non-zero = error. + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 pad[2]; ///< Padding + }; + }; + } set_report; ///< ::BtdrvHidEventType_SetReport + + struct { + union { + union { + u8 rawdata[0x290]; ///< Raw data. + + struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 pad[2]; ///< Padding + u32 res; ///< Unknown. hid-sysmodule only uses the below data when this field is 0. + BtdrvHidData report; ///< \ref BtdrvHidData + u8 pad2[2]; ///< Padding + }; + } v1; ///< [1.0.0-8.1.1] + + union { + u8 rawdata[0x2C8]; ///< Raw data. + + struct { + u32 res; ///< Unknown. hid-sysmodule only uses the below report when this field is 0. + BtdrvAddress addr; ///< \ref BtdrvAddress + BtdrvHidReport report; ///< \ref BtdrvHidReport + }; + } v9; ///< [9.0.0+] + }; + } get_report; ///< ::BtdrvHidEventType_GetReport + }; +} BtdrvHidReportEventInfo; + +/// The raw sharedmem data for HidReportEventInfo. +typedef struct { + struct { + u8 type; ///< \ref BtdrvHidEventType + u8 pad[7]; + u64 tick; + u64 size; + } hdr; + + BtdrvHidReportEventInfo data; +} BtdrvHidReportEventInfoBufferData; + +/// Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType. +typedef union { + struct { + u32 status; ///< Status: 0 = AV connection closed, 1 = AV connection opened, 2 = failed to open AV connection. + BtdrvAddress addr; ///< Device address. + u8 pad[2]; ///< Padding + } connection; ///< ::BtdrvAudioEventType_Connection +} BtdrvAudioEventInfo; + +/// CircularBuffer +typedef struct { + Mutex mutex; + void* event_type; ///< Not set with sharedmem. + u8 data[0x2710]; + s32 write_offset; + s32 read_offset; + u64 utilization; + char name[0x11]; + u8 initialized; +} BtdrvCircularBuffer; + +/// Data for \ref btdrvGetBleManagedEventInfo. The data stored here depends on the \ref BtdrvBleEventType. +typedef struct { + union { + u8 data[0x400]; + + struct { + u32 status; + u8 handle; + u8 registered; + } type0; + + struct { + u32 status; + u32 conn_id; + u32 unk_x8; + u32 unk_xC; + } type2; + + struct { + u32 conn_id; + u16 min_interval; + u16 max_interval; + u16 slave_latency; + u16 timeout_multiplier; + } type3; ///< Connection params? + + struct { + u32 status; + u8 unk_x4; + u8 unk_x5; + u8 unk_x6; + u8 unk_x7; + u32 conn_id; + BtdrvAddress address; + u16 unk_x12; + } type4; ///< Connection status? + + struct { + u32 status; + u8 unk_x4; + u8 unk_x5; + u8 unk_x6; + BtdrvAddress address; + BtdrvBleAdvertisementData adv[10]; + u8 count; + u32 unk_x144; + } type6; ///< Scan result? + + struct { + u32 status; + u32 conn_id; + } type7; + + struct { + u32 status; + u8 interface; + u8 unk_x5; + u16 unk_x6; + u32 unk_x8; + BtdrvGattAttributeUuid svc_uuid; + BtdrvGattAttributeUuid char_uuid; + BtdrvGattAttributeUuid descr_uuid; + u16 size; + u8 data[0x202]; + } type8; ///< Notification? + + struct { + u32 status; + u32 conn_id; + u32 unk_x8; + u8 unk_xC[0x140]; + } type9; + + struct { + u32 status; + u32 conn_id; + u8 unk_x8[0x24]; + u32 unk_x2C; + u8 unk_x30[0x11c]; + } type10; + + struct { + u32 status; + u32 conn_id; + u16 unk_x8; + } type11; + + struct { + u8 unk_x0[0x218]; + } type13; + }; +} BtdrvBleEventInfo; + +/// Initialize btdrv. +Result btdrvInitialize(void); + +/// Exit btdrv. +void btdrvExit(void); + +/// Gets the Service object for the actual btdrv service session. +Service* btdrvGetServiceSession(void); + +/** + * @brief InitializeBluetooth + * @note This is used by btm-sysmodule, this should not be used by other processes. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btdrvInitializeBluetooth(Event* out_event); + +/** + * @brief EnableBluetooth + * @note This is used by btm-sysmodule. + */ +Result btdrvEnableBluetooth(void); + +/** + * @brief DisableBluetooth + * @note This is used by btm-sysmodule. + */ +Result btdrvDisableBluetooth(void); + +/** + * @brief FinalizeBluetooth + * @note This is not used by btm-sysmodule, this should not be used by other processes. + */ +Result btdrvFinalizeBluetooth(void); + +/** + * @brief GetAdapterProperties [1.0.0-11.0.1] + * @param[out] properties \ref BtdrvAdapterPropertyOld + */ +Result btdrvLegacyGetAdapterProperties(BtdrvAdapterPropertyOld *properties); + +/** + * @brief GetAdapterProperties [12.0.0+] + * @param[out] properties \ref BtdrvAdapterPropertySet + */ +Result btdrvGetAdapterProperties(BtdrvAdapterPropertySet *properties); + +/** + * @brief GetAdapterProperty [1.0.0-11.0.1] + * @param[in] type \ref BtdrvBluetoothPropertyType + * @param[out] buffer Output buffer, see \ref BtdrvBluetoothPropertyType for the contents. + * @param[in] size Output buffer size. + */ +Result btdrvLegacyGetAdapterProperty(BtdrvBluetoothPropertyType type, void* buffer, size_t size); + +/** + * @brief GetAdapterProperty [12.0.0+] + * @param[in] type \ref BtdrvAdapterPropertyType + * @param[in] property \ref BtdrvAdapterProperty + */ +Result btdrvGetAdapterProperty(BtdrvAdapterPropertyType type, BtdrvAdapterProperty *property); + +/** + * @brief SetAdapterProperty [1.0.0-11.0.1] + * @param[in] type \ref BtdrvBluetoothPropertyType + * @param[in] buffer Input buffer, see \ref BtdrvBluetoothPropertyType for the contents. + * @param[in] size Input buffer size. + */ +Result btdrvLegacySetAdapterProperty(BtdrvBluetoothPropertyType type, const void* buffer, size_t size); + +/** + * @brief SetAdapterProperty [12.0.0+] + * @param[in] type \ref BtdrvAdapterPropertyType + * @param[in] property \ref BtdrvAdapterProperty + */ +Result btdrvSetAdapterProperty(BtdrvAdapterPropertyType type, const BtdrvAdapterProperty *property); + +/** + * @brief StartInquiry [1.0.0-11.0.1]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. Inquiry will automatically stop in 10.24 seconds. + * @note This is used by btm-sysmodule. + */ +Result btdrvLegacyStartInquiry(void); + +/** + * @brief StartInquiry [12.0.0+]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. + * @param[in] services Bitfield of allowed services. When -1 the original defaults from pre-12.0.0 are used. + * @param[in] duration Inquiry duration in nanoseconds. + * @note This is used by btm-sysmodule. + */ +Result btdrvStartInquiry(u32 services, s64 duration); + +/** + * @brief This stops Inquiry which was started by \ref btdrvStartInquiry, if it's still active. + * @note This is used by btm-sysmodule. + */ +Result btdrvStopInquiry(void); + +/** + * @brief CreateBond + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] type TransportType + */ +Result btdrvCreateBond(BtdrvAddress addr, u32 type); + +/** + * @brief RemoveBond + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvRemoveBond(BtdrvAddress addr); + +/** + * @brief CancelBond + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvCancelBond(BtdrvAddress addr); + +/** + * @brief RespondToPinRequest [1.0.0-11.0.1] + * @note The official sysmodule only uses the input \ref BtdrvAddress. + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + * @param[in] pin_code \ref BtdrvBluetoothPinCode + * @param[in] length Length of pin_code + */ +Result btdrvLegacyRespondToPinRequest(BtdrvAddress addr, bool flag, const BtdrvBluetoothPinCode *pin_code, u8 length); + +/** + * @brief RespondToPinRequest [12.0.0+] + * @param[in] addr \ref BtdrvAddress + * @param[in] pin_code \ref BtdrvPinCode + */ +Result btdrvRespondToPinRequest(BtdrvAddress addr, const BtdrvPinCode *pin_code); + +/** + * @brief RespondToSspRequest + * @note The official sysmodule only uses the input \ref BtdrvAddress and the flag. + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] variant BluetoothSspVariant + * @param[in] accept Whether the request is accepted. + * @param[in] passkey Passkey. + */ +Result btdrvRespondToSspRequest(BtdrvAddress addr, u32 variant, bool accept, u32 passkey); + +/** + * @brief GetEventInfo + * @note This is used by btm-sysmodule. + * @param[out] buffer Output buffer, see \ref BtdrvEventInfo. + * @param[in] size Output buffer size. + * @param[out] type Output BtdrvEventType. + */ +Result btdrvGetEventInfo(void* buffer, size_t size, BtdrvEventType *type); + +/** + * @brief InitializeHid + * @note This is used by btm-sysmodule, this should not be used by other processes. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btdrvInitializeHid(Event* out_event); + +/** + * @brief OpenHidConnection + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvOpenHidConnection(BtdrvAddress addr); + +/** + * @brief CloseHidConnection + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvCloseHidConnection(BtdrvAddress addr); + +/** + * @brief This sends a HID DATA transaction packet with report-type Output. + * @param[in] addr \ref BtdrvAddress + * @param[in] buffer Input \ref BtdrvHidReport, on pre-9.0.0 this is \ref BtdrvHidData. + */ +Result btdrvWriteHidData(BtdrvAddress addr, const BtdrvHidReport *buffer); + +/** + * @brief WriteHidData2 + * @param[in] addr \ref BtdrvAddress + * @param[in] buffer Input buffer, same as the buffer for \ref btdrvWriteHidData. + * @param[in] size Input buffer size. + */ +Result btdrvWriteHidData2(BtdrvAddress addr, const void* buffer, size_t size); + +/** + * @brief This sends a HID SET_REPORT transaction packet. + * @param[in] addr \ref BtdrvAddress + * @param[in] type \ref BtdrvBluetoothHhReportType + * @param[in] buffer Input \ref BtdrvHidReport, on pre-9.0.0 this is \ref BtdrvHidData. + */ +Result btdrvSetHidReport(BtdrvAddress addr, BtdrvBluetoothHhReportType type, const BtdrvHidReport *buffer); + +/** + * @brief This sends a HID GET_REPORT transaction packet. + * @param[in] addr \ref BtdrvAddress + * @param[in] report_id This is sent in the packet for the Report Id, when non-zero. + * @param[in] type \ref BtdrvBluetoothHhReportType + */ +Result btdrvGetHidReport(BtdrvAddress addr, u8 report_id, BtdrvBluetoothHhReportType type); + +/** + * @brief TriggerConnection + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] unk [9.0.0+] Unknown + */ +Result btdrvTriggerConnection(BtdrvAddress addr, u16 unk); + +/** + * @brief AddPairedDeviceInfo + * @note This is used by btm-sysmodule. + * @param[in] settings \ref SetSysBluetoothDevicesSettings + */ +Result btdrvAddPairedDeviceInfo(const SetSysBluetoothDevicesSettings *settings); + +/** + * @brief GetPairedDeviceInfo + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[out] settings \ref SetSysBluetoothDevicesSettings + */ +Result btdrvGetPairedDeviceInfo(BtdrvAddress addr, SetSysBluetoothDevicesSettings *settings); + +/** + * @brief FinalizeHid + * @note This is not used by btm-sysmodule, this should not be used by other processes. + */ +Result btdrvFinalizeHid(void); + +/** + * @brief GetHidEventInfo + * @note This is used by btm-sysmodule. + * @param[out] buffer Output buffer, see \ref BtdrvHidEventInfo. + * @param[in] size Output buffer size. + * @param[out] type \ref BtdrvHidEventType, always ::BtdrvHidEventType_Connection or ::BtdrvHidEventType_Ext. + */ +Result btdrvGetHidEventInfo(void* buffer, size_t size, BtdrvHidEventType *type); + +/** + * @brief SetTsi + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] tsi Tsi: non-value-0xFF to Set, value 0xFF to Exit. See also \ref BtmTsiMode. + */ +Result btdrvSetTsi(BtdrvAddress addr, u8 tsi); + +/** + * @brief EnableBurstMode + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag: true = Set, false = Exit. + */ +Result btdrvEnableBurstMode(BtdrvAddress addr, bool flag); + +/** + * @brief SetZeroRetransmission + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). + * @note This is used by btm-sysmodule. + * @param[in] addr \ref BtdrvAddress + * @param[in] report_ids Input buffer containing an array of u8s. + * @param[in] count Total u8s in the input buffer. This can be 0, the max is 5. + */ +Result btdrvSetZeroRetransmission(BtdrvAddress addr, u8 *report_ids, u8 count); + +/** + * @brief EnableMcMode + * @note This is used by btm-sysmodule. + * @param[in] flag Flag + */ +Result btdrvEnableMcMode(bool flag); + +/** + * @brief EnableLlrScan + * @note This is used by btm-sysmodule. + */ +Result btdrvEnableLlrScan(void); + +/** + * @brief DisableLlrScan + * @note This is used by btm-sysmodule. + */ +Result btdrvDisableLlrScan(void); + +/** + * @brief EnableRadio + * @note This is used by btm-sysmodule. + * @param[in] flag Flag + */ +Result btdrvEnableRadio(bool flag); + +/** + * @brief SetVisibility + * @note This is used by btm-sysmodule. + * @param[in] inquiry_scan Controls Inquiry Scan, whether the device can be discovered during Inquiry. + * @param[in] page_scan Controls Page Scan, whether the device accepts connections. + */ +Result btdrvSetVisibility(bool inquiry_scan, bool page_scan); + +/** + * @brief EnableTbfcScan + * @note Only available on [4.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] flag Flag + */ +Result btdrvEnableTbfcScan(bool flag); + +/** + * @brief RegisterHidReportEvent + * @note This also does sharedmem init/handling if needed, on [7.0.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. This is signaled when data is available with \ref btdrvGetHidReportEventInfo. + */ +Result btdrvRegisterHidReportEvent(Event* out_event); + +/** + * @brief GetHidReportEventInfo + * @note \ref btdrvRegisterHidReportEvent must be used before this, on [7.0.0+]. + * @note This is used by hid-sysmodule. When used by other processes, hid/user-process will conflict. No events will be received by that user-process, or it will be corrupted, etc. + * @note [7.0.0+] When data isn't available, the type is set to ::BtdrvHidEventType_Data, with the buffer cleared to all-zero. + * @param[out] buffer Output buffer, see \ref BtdrvHidReportEventInfo. + * @param[in] size Output buffer size. + * @oaram[out] type \ref BtdrvHidEventType + */ +Result btdrvGetHidReportEventInfo(void* buffer, size_t size, BtdrvHidEventType *type); + +/// Gets the SharedMemory addr for HidReportEventInfo (\ref BtdrvCircularBuffer), only valid when \ref btdrvRegisterHidReportEvent was previously used, on [7.0.0+]. +void* btdrvGetHidReportEventInfoSharedmemAddr(void); + +/** + * @brief GetLatestPlr + * @param[out] out Output \ref BtdrvPlrList, on pre-9.0.0 this is \ref BtdrvPlrStatistics. + */ +Result btdrvGetLatestPlr(BtdrvPlrList *out); + +/** + * @brief GetPendingConnections + * @note The output data will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). + * @note This is used by btm-sysmodule. + * @note Only available on [3.0.0+]. + */ +Result btdrvGetPendingConnections(void); + +/** + * @brief GetChannelMap + * @note Only available on [3.0.0+]. + * @param[out] out \ref BtdrvChannelMapList + */ +Result btdrvGetChannelMap(BtdrvChannelMapList *out); + +/** + * @brief EnableTxPowerBoostSetting + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result btdrvEnableTxPowerBoostSetting(bool flag); + +/** + * @brief IsTxPowerBoostSettingEnabled + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result btdrvIsTxPowerBoostSettingEnabled(bool *out); + +/** + * @brief EnableAfhSetting + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result btdrvEnableAfhSetting(bool flag); + +/** + * @brief IsAfhSettingEnabled + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result btdrvIsAfhSettingEnabled(bool *out); + +/** + * @brief InitializeBle + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btdrvInitializeBle(Event* out_event); + +/** + * @brief EnableBle + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + */ +Result btdrvEnableBle(void); + +/** + * @brief DisableBle + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + */ +Result btdrvDisableBle(void); + +/** + * @brief FinalizeBle + * @note Only available on [5.0.0+]. + */ +Result btdrvFinalizeBle(void); + +/** + * @brief SetBleVisibility + * @note Only available on [5.0.0+]. + * @param[in] discoverable Whether the BLE device is discoverable. + * @param[in] connectable Whether the BLE device is connectable. + */ +Result btdrvSetBleVisibility(bool discoverable, bool connectable); + +/** + * @brief SetLeConnectionParameter + * @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleConnectionParameter. + * @param[in] param \ref BtdrvLeConnectionParams + */ +Result btdrvSetLeConnectionParameter(const BtdrvLeConnectionParams *param); + +/** + * @brief SetBleConnectionParameter + * @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeConnectionParameter. + * @param[in] addr \ref BtdrvAddress + * @param[in] param \ref BtdrvBleConnectionParameter + * @param[in] flag Flag + */ +Result btdrvSetBleConnectionParameter(BtdrvAddress addr, const BtdrvBleConnectionParameter *param, bool flag); + +/** + * @brief SetLeDefaultConnectionParameter + * @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleDefaultConnectionParameter. + * @param[in] param \ref BtdrvLeConnectionParams + */ +Result btdrvSetLeDefaultConnectionParameter(const BtdrvLeConnectionParams *param); + +/** + * @brief SetBleDefaultConnectionParameter + * @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeDefaultConnectionParameter. + * @param[in] param \ref BtdrvBleConnectionParameter + */ +Result btdrvSetBleDefaultConnectionParameter(const BtdrvBleConnectionParameter *param); + +/** + * @brief SetBleAdvertiseData + * @note Only available on [5.0.0+]. + * @param[in] data \ref BtdrvBleAdvertisePacketData + */ +Result btdrvSetBleAdvertiseData(const BtdrvBleAdvertisePacketData *data); + +/** + * @brief SetBleAdvertiseParameter + * @note Only available on [5.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] unk0 Unknown + * @param[in] unk1 Unknown + */ +Result btdrvSetBleAdvertiseParameter(BtdrvAddress addr, u16 unk0, u16 unk1); + +/** + * @brief StartBleScan + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + */ +Result btdrvStartBleScan(void); + +/** + * @brief StopBleScan + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + */ +Result btdrvStopBleScan(void); + +/** + * @brief AddBleScanFilterCondition + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] filter \ref BtdrvBleAdvertiseFilter + */ +Result btdrvAddBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter); + +/** + * @brief DeleteBleScanFilterCondition + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] filter \ref BtdrvBleAdvertiseFilter + */ +Result btdrvDeleteBleScanFilterCondition(const BtdrvBleAdvertiseFilter *filter); + +/** + * @brief DeleteBleScanFilter + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + */ +Result btdrvDeleteBleScanFilter(u8 unk); + +/** + * @brief ClearBleScanFilters + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + */ +Result btdrvClearBleScanFilters(void); + +/** + * @brief EnableBleScanFilter + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] flag Flag + */ +Result btdrvEnableBleScanFilter(bool flag); + +/** + * @brief RegisterGattClient + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvRegisterGattClient(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief UnregisterGattClient + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + */ +Result btdrvUnregisterGattClient(u8 unk); + +/** + * @brief UnregisterAllGattClients + * @note Only available on [5.0.0+]. + */ +Result btdrvUnregisterAllGattClients(void); + +/** + * @brief ConnectGattServer + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] unk Unknown + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + * @param[in] AppletResourceUserId AppletResourceUserId + */ +Result btdrvConnectGattServer(u8 unk, BtdrvAddress addr, bool flag, u64 AppletResourceUserId); + +/** + * @brief CancelConnectGattServer + * @note Only available on [5.1.0+]. + * @note This is used by btm-sysmodule. + * @param[in] unk Unknown + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + */ +Result btdrvCancelConnectGattServer(u8 unk, BtdrvAddress addr, bool flag); + +/** + * @brief DisconnectGattServer + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] unk Unknown + */ +Result btdrvDisconnectGattServer(u32 unk); + +/** + * @brief GetGattAttribute + * @note Only available on [5.0.0+]. + * @param[in] addr \ref BtdrvAddress, only used on pre-9.0.0. + * @param[in] unk Unknown + */ +Result btdrvGetGattAttribute(BtdrvAddress addr, u32 unk); + +/** + * @brief GetGattService + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvGetGattService(u32 unk, const BtdrvGattAttributeUuid *uuid); + +/** + * @brief ConfigureAttMtu + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] unk Unknown + * @param[in] mtu MTU + */ +Result btdrvConfigureAttMtu(u32 unk, u16 mtu); + +/** + * @brief RegisterGattServer + * @note Only available on [5.0.0+]. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvRegisterGattServer(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief UnregisterGattServer + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + */ +Result btdrvUnregisterGattServer(u8 unk); + +/** + * @brief ConnectGattClient + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + */ +Result btdrvConnectGattClient(u8 unk, BtdrvAddress addr, bool flag); + +/** + * @brief DisconnectGattClient + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] addr \ref BtdrvAddress, only used on pre-9.0.0. + */ +Result btdrvDisconnectGattClient(u8 unk, BtdrvAddress addr); + +/** + * @brief AddGattService + * @note Only available on [5.0.0+]. + * @param[in] unk0 Unknown + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[in] unk1 Unknown + * @param[in] flag Flag + */ +Result btdrvAddGattService(u8 unk0, const BtdrvGattAttributeUuid *uuid, u8 unk1, bool flag); + +/** + * @brief EnableGattService + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvEnableGattService(u8 unk, const BtdrvGattAttributeUuid *uuid); + +/** + * @brief AddGattCharacteristic + * @note Only available on [5.0.0+]. + * @param[in] unk0 Unknown + * @param[in] uuid0 \ref BtdrvGattAttributeUuid + * @param[in] uuid1 \ref BtdrvGattAttributeUuid + * @param[in] unk1 Unknown + * @param[in] unk2 Unknown + */ +Result btdrvAddGattCharacteristic(u8 unk0, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, u8 unk1, u16 unk2); + +/** + * @brief AddGattDescriptor + * @note Only available on [5.0.0+]. + * @param[in] unk0 Unknown + * @param[in] uuid0 \ref BtdrvGattAttributeUuid + * @param[in] uuid1 \ref BtdrvGattAttributeUuid + * @param[in] unk1 Unknown + */ +Result btdrvAddGattDescriptor(u8 unk0, const BtdrvGattAttributeUuid *uuid0, const BtdrvGattAttributeUuid *uuid1, u16 unk1); + +/** + * @brief GetBleManagedEventInfo + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[out] buffer Output buffer. 0x400-bytes from state is written here. + * @param[in] size Output buffer size. + * @oaram[out] type Output BtdrvBleEventType. + */ +Result btdrvGetBleManagedEventInfo(void* buffer, size_t size, BtdrvBleEventType *type); + +/** + * @brief GetGattFirstCharacteristic + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] id \ref BtdrvGattId + * @param[in] flag Flag + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] out_property Output Property. + * @param[out] out_char_id Output CharacteristicId \ref BtdrvGattId + */ +Result btdrvGetGattFirstCharacteristic(u32 unk, const BtdrvGattId *id, bool flag, const BtdrvGattAttributeUuid *uuid, u8 *out_property, BtdrvGattId *out_char_id); + +/** + * @brief GetGattNextCharacteristic + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] id0 \ref BtdrvGattId + * @param[in] flag Flag + * @param[in] id1 \ref BtdrvGattId + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] out_property Output Property. + * @param[out] out_char_id Output CharacteristicId \ref BtdrvGattId + */ +Result btdrvGetGattNextCharacteristic(u32 unk, const BtdrvGattId *id0, bool flag, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, u8 *out_property, BtdrvGattId *out_char_id); + +/** + * @brief GetGattFirstDescriptor + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] id0 \ref BtdrvGattId + * @param[in] flag Flag + * @param[in] id1 \ref BtdrvGattId + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] out_desc_id Output DescriptorId \ref BtdrvGattId + */ +Result btdrvGetGattFirstDescriptor(u32 unk, const BtdrvGattId *id0, bool flag, const BtdrvGattId *id1, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *out_desc_id); + +/** + * @brief GetGattNextDescriptor + * @note Only available on [5.0.0+]. + * @param[in] unk Unknown + * @param[in] id0 \ref BtdrvGattId + * @param[in] flag Flag + * @param[in] id1 \ref BtdrvGattId + * @param[in] id2 \ref BtdrvGattId + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] out_desc_id Output DescriptorId \ref BtdrvGattId + */ +Result btdrvGetGattNextDescriptor(u32 unk, const BtdrvGattId *id0, bool flag, const BtdrvGattId *id1, const BtdrvGattId *id2, const BtdrvGattAttributeUuid *uuid, BtdrvGattId *out_desc_id); + +/** + * @brief RegisterGattManagedDataPath + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvRegisterGattManagedDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief UnregisterGattManagedDataPath + * @note Only available on [5.0.0+]. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvUnregisterGattManagedDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief RegisterGattHidDataPath + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvRegisterGattHidDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief UnregisterGattHidDataPath + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvUnregisterGattHidDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief RegisterGattDataPath + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvRegisterGattDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief UnregisterGattDataPath + * @note Only available on [5.0.0+]. + * @note This is used by btm-sysmodule. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btdrvUnregisterGattDataPath(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief ReadGattCharacteristic + * @note Only available on [5.0.0+]. + * @param[in] connection_handle ConnectionHandle + * @param[in] primary_service PrimaryService + * @param[in] id0 \ref BtdrvGattId + * @param[in] id1 \ref BtdrvGattId + * @param[in] unk Unknown + */ +Result btdrvReadGattCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, u8 unk); + +/** + * @brief ReadGattDescriptor + * @note Only available on [5.0.0+]. + * @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 + */ +Result btdrvReadGattDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, u8 unk); + +/** + * @brief WriteGattCharacteristic + * @note Only available on [5.0.0+]. + * @param[in] connection_handle ConnectionHandle + * @param[in] primary_service PrimaryService + * @param[in] id0 \ref BtdrvGattId + * @param[in] id1 \ref BtdrvGattId + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size, must be <=0x258. + * @param[in] unk Unknown + * @param[in] flag Flag + */ +Result btdrvWriteGattCharacteristic(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const void* buffer, size_t size, u8 unk, bool flag); + +/** + * @brief WriteGattDescriptor + * @note Only available on [5.0.0+]. + * @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] buffer Input buffer. + * @param[in] size Input buffer size, must be <=0x258. + * @param[in] unk Unknown + */ +Result btdrvWriteGattDescriptor(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1, const BtdrvGattId *id2, const void* buffer, size_t size, u8 unk); + +/** + * @brief RegisterGattNotification + * @note Only available on [5.0.0+]. + * @param[in] connection_handle ConnectionHandle + * @param[in] primary_service PrimaryService + * @param[in] id0 \ref BtdrvGattId + * @param[in] id1 \ref BtdrvGattId + */ +Result btdrvRegisterGattNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1); + +/** + * @brief UnregisterGattNotification + * @note Only available on [5.0.0+]. + * @param[in] connection_handle ConnectionHandle + * @param[in] primary_service PrimaryService + * @param[in] id0 \ref BtdrvGattId + * @param[in] id1 \ref BtdrvGattId + */ +Result btdrvUnregisterGattNotification(u32 connection_handle, bool primary_service, const BtdrvGattId *id0, const BtdrvGattId *id1); + +/** + * @brief GetLeHidEventInfo + * @note Only available on [5.0.0+]. + * @note The state used by this is reset after writing the data to output. + * @param[out] buffer Output buffer. 0x400-bytes from state is written here. See \ref BtdrvLeEventInfo. + * @param[in] size Output buffer size. + * @oaram[out] type Output BleEventType. + */ +Result btdrvGetLeHidEventInfo(void* buffer, size_t size, u32 *type); + +/** + * @brief RegisterBleHidEvent + * @note Only available on [5.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 btdrvRegisterBleHidEvent(Event* out_event); + +/** + * @brief SetBleScanParameter + * @note Only available on [5.1.0+]. + * @note This is used by btm-sysmodule. + * @param[in] unk0 Unknown + * @param[in] unk1 Unknown + */ +Result btdrvSetBleScanParameter(u16 unk0, u16 unk1); + +/** + * @brief MoveToSecondaryPiconet + * @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). + * @note Only available on [10.0.0+]. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvMoveToSecondaryPiconet(BtdrvAddress addr); + +/** + * @brief IsBluetoothEnabled + * @note Only available on [12.0.0+]. + * @param[out] out Output flag. + */ +Result btdrvIsBluetoothEnabled(bool *out); + +/** + * @brief AcquireAudioEvent + * @note Only available on [12.0.0+]. + * @param[out] out_event Output Event. + * @param[in] autoclear Event autoclear. + */ +Result btdrvAcquireAudioEvent(Event* out_event, bool autoclear); + +/** + * @brief GetAudioEventInfo + * @note Only available on [12.0.0+]. + * @param[out] buffer Output buffer, see \ref BtdrvAudioEventInfo. + * @param[in] size Output buffer size. + * @param[out] type \ref BtdrvAudioEventType. + */ +Result btdrvGetAudioEventInfo(void* buffer, size_t size, BtdrvAudioEventType *type); + +/** + * @brief OpenAudioConnection + * @note Only available on [12.0.0+]. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvOpenAudioConnection(BtdrvAddress addr); + +/** + * @brief CloseAudioConnection + * @note Only available on [12.0.0+]. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvCloseAudioConnection(BtdrvAddress addr); + +/** + * @brief OpenAudioOut + * @note Only available on [12.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[out] audio_handle Audio handle. + */ +Result btdrvOpenAudioOut(BtdrvAddress addr, u32 *audio_handle); + +/** + * @brief CloseAudioOut + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + */ +Result btdrvCloseAudioOut(u32 audio_handle); + +/** + * @brief StartAudioOut + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[in] pcm_param \ref BtdrvPcmParameter + * @param[in] in_latency Input latency in nanoseconds. + * @param[out] out_latency Output latency in nanoseconds. + * @param[out] out1 Unknown output. + */ +Result btdrvStartAudioOut(u32 audio_handle, const BtdrvPcmParameter *pcm_param, s64 in_latency, s64 *out_latency, u64 *out1); + +/** + * @brief StopAudioOut + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + */ +Result btdrvStopAudioOut(u32 audio_handle); + +/** + * @brief GetAudioOutState + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[out] out \ref BtdrvAudioOutState + */ +Result btdrvGetAudioOutState(u32 audio_handle, BtdrvAudioOutState *out); + +/** + * @brief GetAudioOutFeedingCodec + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[out] out \ref BtdrvAudioCodec + */ +Result btdrvGetAudioOutFeedingCodec(u32 audio_handle, BtdrvAudioCodec *out); + +/** + * @brief GetAudioOutFeedingParameter + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[out] out \ref BtdrvPcmParameter + */ +Result btdrvGetAudioOutFeedingParameter(u32 audio_handle, BtdrvPcmParameter *out); + +/** + * @brief AcquireAudioOutStateChangedEvent + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[out] out_event Output Event. + * @param[in] autoclear Event autoclear. + */ +Result btdrvAcquireAudioOutStateChangedEvent(u32 audio_handle, Event* out_event, bool autoclear); + +/** + * @brief AcquireAudioOutBufferAvailableEvent + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[out] out_event Output Event. + * @param[in] autoclear Event autoclear. + */ +Result btdrvAcquireAudioOutBufferAvailableEvent(u32 audio_handle, Event* out_event, bool autoclear); + +/** + * @brief SendAudioData + * @note Only available on [12.0.0+]. + * @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + * @param[out] Output transferred size. This is always either 0 (error occured) or the buffer size. + */ +Result btdrvSendAudioData(u32 audio_handle, const void* buffer, size_t size, u64 *transferred_size); + +/** + * @brief AcquireAudioControlInputStateChangedEvent + * @note Only available on [12.0.0+]. + * @param[out] out_event Output Event. + * @param[in] autoclear Event autoclear. + */ +Result btdrvAcquireAudioControlInputStateChangedEvent(Event* out_event, bool autoclear); + +/** + * @brief GetAudioControlInputState + * @note Only available on [12.0.0+]. + * @param[out] states Output array of \ref BtdrvAudioControlButtonState. + * @param[in] count Size of the states array in entries, the maximum is 0xF. + * @param[out] total_out Total output entries. + */ +Result btdrvGetAudioControlInputState(BtdrvAudioControlButtonState *states, s32 count, s32 *total_out); + +/** + * @brief AcquireAudioConnectionStateChangedEvent + * @note Only available on [12.0.0-13.2.1]. + * @param[out] out_event Output Event. + * @param[in] autoclear Event autoclear. + */ +Result btdrvAcquireAudioConnectionStateChangedEvent(Event* out_event, bool autoclear); + +/** + * @brief GetConnectedAudioDevice + * @note Only available on [12.0.0-13.2.1]. + * @param[out] addrs Output array of \ref BtdrvAddress. + * @param[in] count Size of the addrs array in entries, the maximum is 0x8. + * @param[out] total_out Total output entries. + */ +Result btdrvGetConnectedAudioDevice(BtdrvAddress *addrs, s32 count, s32 *total_out); + +/** + * @brief CloseAudioControlInput + * @note Only available on [13.0.0+]. + * @param[in] addr \ref BtdrvAddress + */ +Result btdrvCloseAudioControlInput(BtdrvAddress addr); + +/** + * @brief RegisterAudioControlNotification + * @note Only available on [13.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] event_type AvrcEventType + */ +Result btdrvRegisterAudioControlNotification(BtdrvAddress addr, u32 event_type); + +/** + * @brief SendAudioControlPassthroughCommand + * @note Only available on [13.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] op_id AvrcOperationId + * @param[in] state_type AvrcStateType + */ +Result btdrvSendAudioControlPassthroughCommand(BtdrvAddress addr, u32 op_id, u32 state_type); + +/** + * @brief SendAudioControlSetAbsoluteVolumeCommand + * @note Only available on [13.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] val Input value + */ +Result btdrvSendAudioControlSetAbsoluteVolumeCommand(BtdrvAddress addr, s32 val); + +/** + * @brief IsManufacturingMode + * @note Only available on [5.0.0+]. + * @param[out] out Output flag. + */ +Result btdrvIsManufacturingMode(bool *out); + +/** + * @brief EmulateBluetoothCrash + * @note Only available on [7.0.0+]. + * @param[in] reason \ref BtdrvFatalReason + */ +Result btdrvEmulateBluetoothCrash(BtdrvFatalReason reason); + +/** + * @brief GetBleChannelMap + * @note Only available on [9.0.0+]. + * @param[out] out \ref BtdrvChannelMapList + */ +Result btdrvGetBleChannelMap(BtdrvChannelMapList *out); + +///@name CircularBuffer +///@{ + +/** + * @brief Read + * @note Used by \ref btdrvGetHidReportEventInfo on [7.0.0+]. + * @param c \ref BtdrvCircularBuffer + */ +void* btdrvCircularBufferRead(BtdrvCircularBuffer *c); + +/** + * @brief Free + * @note Used by \ref btdrvGetHidReportEventInfo on [7.0.0+]. + * @param c \ref BtdrvCircularBuffer + */ +bool btdrvCircularBufferFree(BtdrvCircularBuffer *c); + +///@} + diff --git a/src/libnx/wrapper/switch/services/btdrv.nim b/src/libnx/wrapper/switch/services/btdrv.nim new file mode 100644 index 0000000..a83d1c0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btdrv.nim @@ -0,0 +1,1728 @@ +## * +## @file btdrv.h +## @brief Bluetooth driver (btdrv) service IPC wrapper. +## @author yellows8, ndeadly +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/btdrv_types, ../services/set, ../sf/service, ../kernel/mutex + +## / Data for \ref btdrvGetEventInfo. The data stored here depends on the \ref BtdrvEventType. + +type + INNER_C_STRUCT_btdrv_32* {.bycopy.} = object + val*: U32 ## /< Value + + INNER_C_STRUCT_btdrv_35* {.bycopy.} = object + name*: array[0xF9, char] ## /< Device name, NUL-terminated string. + `addr`*: BtdrvAddress ## /< Device address. + reservedXFF*: array[0x10, U8] ## /< Reserved + classOfDevice*: BtdrvClassOfDevice ## /< Class of Device. + unkX112*: array[0x4, U8] ## /< Set to fixed value u32 0x1. + reservedX116*: array[0xFA, U8] ## /< Reserved + reservedX210*: array[0x5C, U8] ## /< Reserved + name2*: array[0xF9, char] ## /< Device name, NUL-terminated string. Same as name above, except starting at index 1. + rssi*: array[0x4, U8] ## /< s32 RSSI + name3*: array[0x4, U8] ## /< Two bytes which are the same as name[11-12]. + reservedX36D*: array[0x10, U8] ## /< Reserved + + INNER_C_STRUCT_btdrv_36* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + name*: array[0xF9, char] ## /< Device name, NUL-terminated string. + classOfDevice*: BtdrvClassOfDevice ## /< Class of Device. + reserved*: array[0x6, U8] ## /< Reserved + + INNER_C_UNION_btdrv_34* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_35 ## /< [1.0.0-11.0.1] + v12*: INNER_C_STRUCT_btdrv_36 ## /< [12.0.0+] + + INNER_C_STRUCT_btdrv_33* {.bycopy.} = object + anoBtdrv37*: INNER_C_UNION_btdrv_34 + + INNER_C_STRUCT_btdrv_40* {.bycopy.} = object + status*: BtdrvInquiryStatus ## /< \ref BtdrvInquiryStatus + + INNER_C_STRUCT_btdrv_41* {.bycopy.} = object + status*: U8 ## /< \ref BtdrvInquiryStatus + pad*: array[3, U8] ## /< Padding + serviceMask*: U32 ## /< Services value from \ref btdrvStartInquiry when starting, otherwise this is value 0. + + INNER_C_UNION_btdrv_39* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_40 ## /< [1.0.0-11.0.1] + v12*: INNER_C_STRUCT_btdrv_41 ## /< [12.0.0+] + + INNER_C_STRUCT_btdrv_38* {.bycopy.} = object + anoBtdrv42*: INNER_C_UNION_btdrv_39 + + INNER_C_STRUCT_btdrv_43* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + name*: array[0xF9, char] ## /< Device name, NUL-terminated string. + classOfDevice*: BtdrvClassOfDevice ## /< Class of Device. + + INNER_C_STRUCT_btdrv_46* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + name*: array[0xF9, char] ## /< Device name, NUL-terminated string. + classOfDevice*: BtdrvClassOfDevice ## /< Class of Device. + pad*: array[2, U8] ## /< Padding + `type`*: U32 ## /< 0 = SSP confirm request, 3 = SSP passkey notification. + passkey*: S32 ## /< Passkey, only set when the above field is value 3. + + INNER_C_STRUCT_btdrv_47* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + name*: array[0xF9, char] ## /< Device name, NUL-terminated string. + classOfDevice*: BtdrvClassOfDevice ## /< Class of Device. + flag*: U8 ## /< bool flag for Just Works. With SSP passkey notification this is always 0. + pad*: U8 ## /< Padding + passkey*: S32 ## /< Passkey + + INNER_C_UNION_btdrv_45* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_46 ## /< [1.0.0-11.0.1] + v12*: INNER_C_STRUCT_btdrv_47 ## /< [12.0.0+] + + INNER_C_STRUCT_btdrv_44* {.bycopy.} = object + anoBtdrv48*: INNER_C_UNION_btdrv_45 + + INNER_C_STRUCT_btdrv_51* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + pad*: array[2, U8] ## /< Padding + status*: U32 ## /< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). + `type`*: U32 ## /< \ref BtdrvConnectionEventType + + INNER_C_STRUCT_btdrv_52* {.bycopy.} = object + status*: U32 ## /< Status, always 0 except with ::BtdrvConnectionEventType_Status: 2 = ACL Link is now Resumed, 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). + `addr`*: BtdrvAddress ## /< Device address. + pad*: array[2, U8] ## /< Padding + `type`*: U32 ## /< \ref BtdrvConnectionEventType + + INNER_C_STRUCT_btdrv_53* {.bycopy.} = object + `type`*: U32 ## /< \ref BtdrvConnectionEventType + `addr`*: BtdrvAddress ## /< Device address. + reserved*: array[0xfe, U8] ## /< Reserved + + INNER_C_UNION_btdrv_50* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_51 ## /< [1.0.0-8.1.1] + v9*: INNER_C_STRUCT_btdrv_52 ## /< [9.0.0-11.0.1] + v12*: INNER_C_STRUCT_btdrv_53 ## /< [12.0.0+] + + INNER_C_STRUCT_btdrv_49* {.bycopy.} = object + anoBtdrv54*: INNER_C_UNION_btdrv_50 + + INNER_C_STRUCT_btdrv_55* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + status*: U8 ## /< Status flag: 1 = success, 0 = failure. + value*: U8 ## /< Tsi value, when the above indicates success. + + INNER_C_STRUCT_btdrv_56* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + status*: U8 ## /< Status flag: 1 = success, 0 = failure. + value*: U8 ## /< Input bool value from \ref btdrvEnableBurstMode, when the above indicates success. + + INNER_C_STRUCT_btdrv_57* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + status*: U8 ## /< Status flag: 1 = success, 0 = failure. + flag*: U8 ## /< Bool flag, when the above indicates success. + + INNER_C_STRUCT_btdrv_58* {.bycopy.} = object + status*: U8 ## /< Status flag: 1 = success, 0 = failure. + pad*: array[0x3, U8] ## /< Padding + count*: U32 ## /< Count value. + + INNER_C_STRUCT_btdrv_59* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + status*: U8 ## /< Status flag: 1 = success, 0 = failure. + + INNER_C_STRUCT_btdrv_60* {.bycopy.} = object + reason*: U16 ## /< \ref BtdrvFatalReason + + INNER_C_UNION_btdrv_31* {.bycopy, union.} = object + data*: array[0x400, U8] ## /< Raw data. + type0*: INNER_C_STRUCT_btdrv_32 ## /< ::BtdrvEventTypeOld_Unknown0 + inquiryDevice*: INNER_C_STRUCT_btdrv_33 ## /< ::BtdrvEventType_InquiryDevice + inquiryStatus*: INNER_C_STRUCT_btdrv_38 ## /< ::BtdrvEventType_InquiryStatus + pairingPinCodeRequest*: INNER_C_STRUCT_btdrv_43 ## /< ::BtdrvEventType_PairingPinCodeRequest + sspRequest*: INNER_C_STRUCT_btdrv_44 ## /< ::BtdrvEventType_SspRequest + connection*: INNER_C_STRUCT_btdrv_49 ## /< ::BtdrvEventType_Connection + tsi*: INNER_C_STRUCT_btdrv_55 ## /< ::BtdrvEventType_Tsi + burstMode*: INNER_C_STRUCT_btdrv_56 ## /< ::BtdrvEventType_BurstMode + setZeroRetransmission*: INNER_C_STRUCT_btdrv_57 ## /< ::BtdrvEventType_SetZeroRetransmission + pendingConnections*: INNER_C_STRUCT_btdrv_58 ## /< ::BtdrvEventType_PendingConnections + moveToSecondaryPiconet*: INNER_C_STRUCT_btdrv_59 ## /< ::BtdrvEventType_MoveToSecondaryPiconet + bluetoothCrash*: INNER_C_STRUCT_btdrv_60 ## /< ::BtdrvEventType_BluetoothCrash + + BtdrvEventInfo* {.bycopy.} = object + anoBtdrv61*: INNER_C_UNION_btdrv_31 + + +## / Data for \ref btdrvGetHidEventInfo. The data stored here depends on the \ref BtdrvHidEventType. + +type + INNER_C_STRUCT_btdrv_82* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Device address. + pad*: array[2, U8] ## /< Padding + status*: BtdrvHidConnectionStatus ## /< \ref BtdrvHidConnectionStatus + + INNER_C_STRUCT_btdrv_83* {.bycopy.} = object + status*: BtdrvHidConnectionStatus ## /< \ref BtdrvHidConnectionStatus + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_UNION_btdrv_81* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_82 ## /< [1.0.0-11.0.1] + v12*: INNER_C_STRUCT_btdrv_83 ## /< [12.0.0+] + + INNER_C_STRUCT_btdrv_80* {.bycopy.} = object + anoBtdrv84*: INNER_C_UNION_btdrv_81 + + INNER_C_STRUCT_btdrv_87* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_STRUCT_btdrv_88* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_STRUCT_btdrv_89* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_STRUCT_btdrv_90* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_STRUCT_btdrv_91* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + pad*: array[2, U8] ## /< Padding + flag*: U8 ## /< Flag + + INNER_C_STRUCT_btdrv_92* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Unused + pad*: array[2, U8] ## /< Padding + count*: U32 ## /< Count value. + + INNER_C_STRUCT_btdrv_93* {.bycopy.} = object + status*: U32 ## /< 0 for success, non-zero for error. + `addr`*: BtdrvAddress ## /< Device address. + + INNER_C_UNION_btdrv_86* {.bycopy, union.} = object + setTsi*: INNER_C_STRUCT_btdrv_87 ## /< ::BtdrvExtEventType_SetTsi + exitTsi*: INNER_C_STRUCT_btdrv_88 ## /< ::BtdrvExtEventType_ExitTsi + setBurstMode*: INNER_C_STRUCT_btdrv_89 ## /< ::BtdrvExtEventType_SetBurstMode + exitBurstMode*: INNER_C_STRUCT_btdrv_90 ## /< ::BtdrvExtEventType_ExitBurstMode + setZeroRetransmission*: INNER_C_STRUCT_btdrv_91 ## /< ::BtdrvExtEventType_SetZeroRetransmission + pendingConnections*: INNER_C_STRUCT_btdrv_92 ## /< ::BtdrvExtEventType_PendingConnections + moveToSecondaryPiconet*: INNER_C_STRUCT_btdrv_93 ## /< ::BtdrvExtEventType_MoveToSecondaryPiconet + + INNER_C_STRUCT_btdrv_85* {.bycopy.} = object + `type`*: U32 ## /< \ref BtdrvExtEventType, controls which data is stored below. + anoBtdrv94*: INNER_C_UNION_btdrv_86 + + INNER_C_UNION_btdrv_79* {.bycopy, union.} = object + data*: array[0x480, U8] ## /< Raw data. + connection*: INNER_C_STRUCT_btdrv_80 ## /< ::BtdrvHidEventType_Connection + ext*: INNER_C_STRUCT_btdrv_85 ## /< ::BtdrvHidEventType_Ext [1.0.0-11.0.1] + + BtdrvHidEventInfo* {.bycopy.} = object + anoBtdrv95*: INNER_C_UNION_btdrv_79 + + +## / Data for \ref btdrvGetHidReportEventInfo. The data stored here depends on the \ref BtdrvHidEventType. + +type + INNER_C_STRUCT_btdrv_123* {.bycopy.} = object + `addr`*: BtdrvAddress + pad*: array[2, U8] + res*: U32 + size*: U32 + + INNER_C_STRUCT_btdrv_122* {.bycopy.} = object + hdr*: INNER_C_STRUCT_btdrv_123 + unused*: array[0x3, U8] ## /< Unused + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + unused2*: array[0x3, U8] ## /< Unused + report*: BtdrvHidData + + INNER_C_STRUCT_btdrv_124* {.bycopy.} = object + unused*: array[0x3, U8] ## /< Unused + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + unused2*: array[0x3, U8] ## /< Unused + report*: BtdrvHidData + + INNER_C_STRUCT_btdrv_125* {.bycopy.} = object + res*: U32 ## /< Always 0. + unkX4*: U8 ## /< Always 0. + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + pad*: U8 ## /< Padding + report*: BtdrvHidReport + + INNER_C_UNION_btdrv_121* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btdrv_122 ## /< [1.0.0-6.2.0] + v7*: INNER_C_STRUCT_btdrv_124 ## /< [7.0.0-8.1.1] + v9*: INNER_C_STRUCT_btdrv_125 ## /< [9.0.0+] + + INNER_C_STRUCT_btdrv_120* {.bycopy.} = object + anoBtdrv126*: INNER_C_UNION_btdrv_121 + + INNER_C_STRUCT_btdrv_129* {.bycopy.} = object + res*: U32 ## /< 0 = success, non-zero = error. + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + pad*: array[2, U8] ## /< Padding + + INNER_C_UNION_btdrv_128* {.bycopy, union.} = object + rawdata*: array[0xC, U8] ## /< Raw data. + anoBtdrv130*: INNER_C_STRUCT_btdrv_129 + + INNER_C_STRUCT_btdrv_127* {.bycopy.} = object + anoBtdrv131*: INNER_C_UNION_btdrv_128 + + INNER_C_STRUCT_btdrv_135* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + pad*: array[2, U8] ## /< Padding + res*: U32 ## /< Unknown. hid-sysmodule only uses the below data when this field is 0. + report*: BtdrvHidData ## /< \ref BtdrvHidData + pad2*: array[2, U8] ## /< Padding + + INNER_C_UNION_btdrv_134* {.bycopy, union.} = object + rawdata*: array[0x290, U8] ## /< Raw data. + anoBtdrv136*: INNER_C_STRUCT_btdrv_135 + + INNER_C_STRUCT_btdrv_138* {.bycopy.} = object + res*: U32 ## /< Unknown. hid-sysmodule only uses the below report when this field is 0. + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + report*: BtdrvHidReport ## /< \ref BtdrvHidReport + + INNER_C_UNION_btdrv_137* {.bycopy, union.} = object + rawdata*: array[0x2C8, U8] ## /< Raw data. + anoBtdrv139*: INNER_C_STRUCT_btdrv_138 + + INNER_C_UNION_btdrv_133* {.bycopy, union.} = object + v1*: INNER_C_UNION_btdrv_134 ## /< [1.0.0-8.1.1] + v9*: INNER_C_UNION_btdrv_137 ## /< [9.0.0+] + + INNER_C_STRUCT_btdrv_132* {.bycopy.} = object + anoBtdrv140*: INNER_C_UNION_btdrv_133 + + INNER_C_UNION_btdrv_119* {.bycopy, union.} = object + data*: array[0x480, U8] ## /< Raw data. + dataReport*: INNER_C_STRUCT_btdrv_120 ## /< ::BtdrvHidEventType_DataReport + setReport*: INNER_C_STRUCT_btdrv_127 ## /< ::BtdrvHidEventType_SetReport + getReport*: INNER_C_STRUCT_btdrv_132 ## /< ::BtdrvHidEventType_GetReport + + BtdrvHidReportEventInfo* {.bycopy.} = object + anoBtdrv141*: INNER_C_UNION_btdrv_119 + + +## / The raw sharedmem data for HidReportEventInfo. + +type + INNER_C_STRUCT_btdrv_143* {.bycopy.} = object + `type`*: U8 ## /< \ref BtdrvHidEventType + pad*: array[7, U8] + tick*: U64 + size*: U64 + + BtdrvHidReportEventInfoBufferData* {.bycopy.} = object + hdr*: INNER_C_STRUCT_btdrv_143 + data*: BtdrvHidReportEventInfo + + +## / Data for \ref btdrvGetAudioEventInfo. The data stored here depends on the \ref BtdrvAudioEventType. + +type + INNER_C_STRUCT_btdrv_145* {.bycopy.} = object + status*: U32 ## /< Status: 0 = AV connection closed, 1 = AV connection opened, 2 = failed to open AV connection. + `addr`*: BtdrvAddress ## /< Device address. + pad*: array[2, U8] ## /< Padding + + BtdrvAudioEventInfo* {.bycopy, union.} = object + connection*: INNER_C_STRUCT_btdrv_145 ## /< ::BtdrvAudioEventType_Connection + + +## / CircularBuffer + +type + BtdrvCircularBuffer* {.bycopy.} = object + mutex*: Mutex + eventType*: pointer ## /< Not set with sharedmem. + data*: array[0x2710, U8] + writeOffset*: S32 + readOffset*: S32 + utilization*: U64 + name*: array[0x11, char] + initialized*: U8 + + +## / Data for \ref btdrvGetBleManagedEventInfo. The data stored here depends on the \ref BtdrvBleEventType. + +type + INNER_C_STRUCT_btdrv_160* {.bycopy.} = object + status*: U32 + handle*: U8 + registered*: U8 + + INNER_C_STRUCT_btdrv_161* {.bycopy.} = object + status*: U32 + connId*: U32 + unkX8*: U32 + unkXC*: U32 + + INNER_C_STRUCT_btdrv_162* {.bycopy.} = object + connId*: U32 + minInterval*: U16 + maxInterval*: U16 + slaveLatency*: U16 + timeoutMultiplier*: U16 + + INNER_C_STRUCT_btdrv_163* {.bycopy.} = object + status*: U32 + unkX4*: U8 + unkX5*: U8 + unkX6*: U8 + unkX7*: U8 + connId*: U32 + address*: BtdrvAddress + unkX12*: U16 + + INNER_C_STRUCT_btdrv_164* {.bycopy.} = object + status*: U32 + unkX4*: U8 + unkX5*: U8 + unkX6*: U8 + address*: BtdrvAddress + adv*: array[10, BtdrvBleAdvertisementData] + count*: U8 + unkX144*: U32 + + INNER_C_STRUCT_btdrv_165* {.bycopy.} = object + status*: U32 + connId*: U32 + + INNER_C_STRUCT_btdrv_166* {.bycopy.} = object + status*: U32 + `interface`*: U8 + unkX5*: U8 + unkX6*: U16 + unkX8*: U32 + svcUuid*: BtdrvGattAttributeUuid + charUuid*: BtdrvGattAttributeUuid + descrUuid*: BtdrvGattAttributeUuid + size*: U16 + data*: array[0x202, U8] + + INNER_C_STRUCT_btdrv_167* {.bycopy.} = object + status*: U32 + connId*: U32 + unkX8*: U32 + unkXC*: array[0x140, U8] + + INNER_C_STRUCT_btdrv_168* {.bycopy.} = object + status*: U32 + connId*: U32 + unkX8*: array[0x24, U8] + unkX2C*: U32 + unkX30*: array[0x11c, U8] + + INNER_C_STRUCT_btdrv_169* {.bycopy.} = object + status*: U32 + connId*: U32 + unkX8*: U16 + + INNER_C_STRUCT_btdrv_170* {.bycopy.} = object + unkX0*: array[0x218, U8] + + INNER_C_UNION_btdrv_159* {.bycopy, union.} = object + data*: array[0x400, U8] + type0*: INNER_C_STRUCT_btdrv_160 + type2*: INNER_C_STRUCT_btdrv_161 + type3*: INNER_C_STRUCT_btdrv_162 ## /< Connection params? + type4*: INNER_C_STRUCT_btdrv_163 ## /< Connection status? + type6*: INNER_C_STRUCT_btdrv_164 ## /< Scan result? + type7*: INNER_C_STRUCT_btdrv_165 + type8*: INNER_C_STRUCT_btdrv_166 ## /< Notification? + type9*: INNER_C_STRUCT_btdrv_167 + type10*: INNER_C_STRUCT_btdrv_168 + type11*: INNER_C_STRUCT_btdrv_169 + type13*: INNER_C_STRUCT_btdrv_170 + + BtdrvBleEventInfo* {.bycopy.} = object + anoBtdrv171*: INNER_C_UNION_btdrv_159 + +proc btdrvInitialize*(): Result {.cdecl, importc: "btdrvInitialize".} +## / Initialize btdrv. + +proc btdrvExit*() {.cdecl, importc: "btdrvExit".} +## / Exit btdrv. + +proc btdrvGetServiceSession*(): ptr Service {.cdecl, + importc: "btdrvGetServiceSession".} +## / Gets the Service object for the actual btdrv service session. + +proc btdrvInitializeBluetooth*(outEvent: ptr Event): Result {.cdecl, + importc: "btdrvInitializeBluetooth".} +## * +## @brief InitializeBluetooth +## @note This is used by btm-sysmodule, this should not be used by other processes. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btdrvEnableBluetooth*(): Result {.cdecl, importc: "btdrvEnableBluetooth".} +## * +## @brief EnableBluetooth +## @note This is used by btm-sysmodule. +## + +proc btdrvDisableBluetooth*(): Result {.cdecl, importc: "btdrvDisableBluetooth".} +## * +## @brief DisableBluetooth +## @note This is used by btm-sysmodule. +## + +proc btdrvFinalizeBluetooth*(): Result {.cdecl, importc: "btdrvFinalizeBluetooth".} +## * +## @brief FinalizeBluetooth +## @note This is not used by btm-sysmodule, this should not be used by other processes. +## + +proc btdrvLegacyGetAdapterProperties*(properties: ptr BtdrvAdapterPropertyOld): Result {. + cdecl, importc: "btdrvLegacyGetAdapterProperties".} +## * +## @brief GetAdapterProperties [1.0.0-11.0.1] +## @param[out] properties \ref BtdrvAdapterPropertyOld +## + +proc btdrvGetAdapterProperties*(properties: ptr BtdrvAdapterPropertySet): Result {. + cdecl, importc: "btdrvGetAdapterProperties".} +## * +## @brief GetAdapterProperties [12.0.0+] +## @param[out] properties \ref BtdrvAdapterPropertySet +## + +proc btdrvLegacyGetAdapterProperty*(`type`: BtdrvBluetoothPropertyType; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "btdrvLegacyGetAdapterProperty".} +## * +## @brief GetAdapterProperty [1.0.0-11.0.1] +## @param[in] type \ref BtdrvBluetoothPropertyType +## @param[out] buffer Output buffer, see \ref BtdrvBluetoothPropertyType for the contents. +## @param[in] size Output buffer size. +## + +proc btdrvGetAdapterProperty*(`type`: BtdrvAdapterPropertyType; + property: ptr BtdrvAdapterProperty): Result {.cdecl, + importc: "btdrvGetAdapterProperty".} +## * +## @brief GetAdapterProperty [12.0.0+] +## @param[in] type \ref BtdrvAdapterPropertyType +## @param[in] property \ref BtdrvAdapterProperty +## + +proc btdrvLegacySetAdapterProperty*(`type`: BtdrvBluetoothPropertyType; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "btdrvLegacySetAdapterProperty".} +## * +## @brief SetAdapterProperty [1.0.0-11.0.1] +## @param[in] type \ref BtdrvBluetoothPropertyType +## @param[in] buffer Input buffer, see \ref BtdrvBluetoothPropertyType for the contents. +## @param[in] size Input buffer size. +## + +proc btdrvSetAdapterProperty*(`type`: BtdrvAdapterPropertyType; + property: ptr BtdrvAdapterProperty): Result {.cdecl, + importc: "btdrvSetAdapterProperty".} +## * +## @brief SetAdapterProperty [12.0.0+] +## @param[in] type \ref BtdrvAdapterPropertyType +## @param[in] property \ref BtdrvAdapterProperty +## + +proc btdrvLegacyStartInquiry*(): Result {.cdecl, importc: "btdrvLegacyStartInquiry".} +## * +## @brief StartInquiry [1.0.0-11.0.1]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. Inquiry will automatically stop in 10.24 seconds. +## @note This is used by btm-sysmodule. +## + +proc btdrvStartInquiry*(services: U32; duration: S64): Result {.cdecl, + importc: "btdrvStartInquiry".} +## * +## @brief StartInquiry [12.0.0+]. This starts Inquiry, the output data will be available via \ref btdrvGetEventInfo. +## @param[in] services Bitfield of allowed services. When -1 the original defaults from pre-12.0.0 are used. +## @param[in] duration Inquiry duration in nanoseconds. +## @note This is used by btm-sysmodule. +## + +proc btdrvStopInquiry*(): Result {.cdecl, importc: "btdrvStopInquiry".} +## * +## @brief This stops Inquiry which was started by \ref btdrvStartInquiry, if it's still active. +## @note This is used by btm-sysmodule. +## + +proc btdrvCreateBond*(`addr`: BtdrvAddress; `type`: U32): Result {.cdecl, + importc: "btdrvCreateBond".} +## * +## @brief CreateBond +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] type TransportType +## + +proc btdrvRemoveBond*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvRemoveBond".} +## * +## @brief RemoveBond +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvCancelBond*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvCancelBond".} +## * +## @brief CancelBond +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvLegacyRespondToPinRequest*(`addr`: BtdrvAddress; flag: bool; + pinCode: ptr BtdrvBluetoothPinCode; length: U8): Result {. + cdecl, importc: "btdrvLegacyRespondToPinRequest".} +## * +## @brief RespondToPinRequest [1.0.0-11.0.1] +## @note The official sysmodule only uses the input \ref BtdrvAddress. +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## @param[in] pin_code \ref BtdrvBluetoothPinCode +## @param[in] length Length of pin_code +## + +proc btdrvRespondToPinRequest*(`addr`: BtdrvAddress; pinCode: ptr BtdrvPinCode): Result {. + cdecl, importc: "btdrvRespondToPinRequest".} +## * +## @brief RespondToPinRequest [12.0.0+] +## @param[in] addr \ref BtdrvAddress +## @param[in] pin_code \ref BtdrvPinCode +## + +proc btdrvRespondToSspRequest*(`addr`: BtdrvAddress; variant: U32; accept: bool; + passkey: U32): Result {.cdecl, + importc: "btdrvRespondToSspRequest".} +## * +## @brief RespondToSspRequest +## @note The official sysmodule only uses the input \ref BtdrvAddress and the flag. +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] variant BluetoothSspVariant +## @param[in] accept Whether the request is accepted. +## @param[in] passkey Passkey. +## + +proc btdrvGetEventInfo*(buffer: pointer; size: csize_t; `type`: ptr BtdrvEventType): Result {. + cdecl, importc: "btdrvGetEventInfo".} +## * +## @brief GetEventInfo +## @note This is used by btm-sysmodule. +## @param[out] buffer Output buffer, see \ref BtdrvEventInfo. +## @param[in] size Output buffer size. +## @param[out] type Output BtdrvEventType. +## + +proc btdrvInitializeHid*(outEvent: ptr Event): Result {.cdecl, + importc: "btdrvInitializeHid".} +## * +## @brief InitializeHid +## @note This is used by btm-sysmodule, this should not be used by other processes. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btdrvOpenHidConnection*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvOpenHidConnection".} +## * +## @brief OpenHidConnection +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvCloseHidConnection*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvCloseHidConnection".} +## * +## @brief CloseHidConnection +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvWriteHidData*(`addr`: BtdrvAddress; buffer: ptr BtdrvHidReport): Result {. + cdecl, importc: "btdrvWriteHidData".} +## * +## @brief This sends a HID DATA transaction packet with report-type Output. +## @param[in] addr \ref BtdrvAddress +## @param[in] buffer Input \ref BtdrvHidReport, on pre-9.0.0 this is \ref BtdrvHidData. +## + +proc btdrvWriteHidData2*(`addr`: BtdrvAddress; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "btdrvWriteHidData2".} +## * +## @brief WriteHidData2 +## @param[in] addr \ref BtdrvAddress +## @param[in] buffer Input buffer, same as the buffer for \ref btdrvWriteHidData. +## @param[in] size Input buffer size. +## + +proc btdrvSetHidReport*(`addr`: BtdrvAddress; `type`: BtdrvBluetoothHhReportType; + buffer: ptr BtdrvHidReport): Result {.cdecl, + importc: "btdrvSetHidReport".} +## * +## @brief This sends a HID SET_REPORT transaction packet. +## @param[in] addr \ref BtdrvAddress +## @param[in] type \ref BtdrvBluetoothHhReportType +## @param[in] buffer Input \ref BtdrvHidReport, on pre-9.0.0 this is \ref BtdrvHidData. +## + +proc btdrvGetHidReport*(`addr`: BtdrvAddress; reportId: U8; + `type`: BtdrvBluetoothHhReportType): Result {.cdecl, + importc: "btdrvGetHidReport".} +## * +## @brief This sends a HID GET_REPORT transaction packet. +## @param[in] addr \ref BtdrvAddress +## @param[in] report_id This is sent in the packet for the Report Id, when non-zero. +## @param[in] type \ref BtdrvBluetoothHhReportType +## + +proc btdrvTriggerConnection*(`addr`: BtdrvAddress; unk: U16): Result {.cdecl, + importc: "btdrvTriggerConnection".} +## * +## @brief TriggerConnection +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] unk [9.0.0+] Unknown +## + +proc btdrvAddPairedDeviceInfo*(settings: ptr SetSysBluetoothDevicesSettings): Result {. + cdecl, importc: "btdrvAddPairedDeviceInfo".} +## * +## @brief AddPairedDeviceInfo +## @note This is used by btm-sysmodule. +## @param[in] settings \ref SetSysBluetoothDevicesSettings +## + +proc btdrvGetPairedDeviceInfo*(`addr`: BtdrvAddress; + settings: ptr SetSysBluetoothDevicesSettings): Result {. + cdecl, importc: "btdrvGetPairedDeviceInfo".} +## * +## @brief GetPairedDeviceInfo +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[out] settings \ref SetSysBluetoothDevicesSettings +## + +proc btdrvFinalizeHid*(): Result {.cdecl, importc: "btdrvFinalizeHid".} +## * +## @brief FinalizeHid +## @note This is not used by btm-sysmodule, this should not be used by other processes. +## + +proc btdrvGetHidEventInfo*(buffer: pointer; size: csize_t; + `type`: ptr BtdrvHidEventType): Result {.cdecl, + importc: "btdrvGetHidEventInfo".} +## * +## @brief GetHidEventInfo +## @note This is used by btm-sysmodule. +## @param[out] buffer Output buffer, see \ref BtdrvHidEventInfo. +## @param[in] size Output buffer size. +## @param[out] type \ref BtdrvHidEventType, always ::BtdrvHidEventType_Connection or ::BtdrvHidEventType_Ext. +## + +proc btdrvSetTsi*(`addr`: BtdrvAddress; tsi: U8): Result {.cdecl, + importc: "btdrvSetTsi".} +## * +## @brief SetTsi +## @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] tsi Tsi: non-value-0xFF to Set, value 0xFF to Exit. See also \ref BtmTsiMode. +## + +proc btdrvEnableBurstMode*(`addr`: BtdrvAddress; flag: bool): Result {.cdecl, + importc: "btdrvEnableBurstMode".} +## * +## @brief EnableBurstMode +## @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag: true = Set, false = Exit. +## + +proc btdrvSetZeroRetransmission*(`addr`: BtdrvAddress; reportIds: ptr U8; count: U8): Result {. + cdecl, importc: "btdrvSetZeroRetransmission".} +## * +## @brief SetZeroRetransmission +## @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). +## @note This is used by btm-sysmodule. +## @param[in] addr \ref BtdrvAddress +## @param[in] report_ids Input buffer containing an array of u8s. +## @param[in] count Total u8s in the input buffer. This can be 0, the max is 5. +## + +proc btdrvEnableMcMode*(flag: bool): Result {.cdecl, importc: "btdrvEnableMcMode".} +## * +## @brief EnableMcMode +## @note This is used by btm-sysmodule. +## @param[in] flag Flag +## + +proc btdrvEnableLlrScan*(): Result {.cdecl, importc: "btdrvEnableLlrScan".} +## * +## @brief EnableLlrScan +## @note This is used by btm-sysmodule. +## + +proc btdrvDisableLlrScan*(): Result {.cdecl, importc: "btdrvDisableLlrScan".} +## * +## @brief DisableLlrScan +## @note This is used by btm-sysmodule. +## + +proc btdrvEnableRadio*(flag: bool): Result {.cdecl, importc: "btdrvEnableRadio".} +## * +## @brief EnableRadio +## @note This is used by btm-sysmodule. +## @param[in] flag Flag +## + +proc btdrvSetVisibility*(inquiryScan: bool; pageScan: bool): Result {.cdecl, + importc: "btdrvSetVisibility".} +## * +## @brief SetVisibility +## @note This is used by btm-sysmodule. +## @param[in] inquiry_scan Controls Inquiry Scan, whether the device can be discovered during Inquiry. +## @param[in] page_scan Controls Page Scan, whether the device accepts connections. +## + +proc btdrvEnableTbfcScan*(flag: bool): Result {.cdecl, importc: "btdrvEnableTbfcScan".} +## * +## @brief EnableTbfcScan +## @note Only available on [4.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] flag Flag +## + +proc btdrvRegisterHidReportEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdrvRegisterHidReportEvent".} +## * +## @brief RegisterHidReportEvent +## @note This also does sharedmem init/handling if needed, on [7.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. This is signaled when data is available with \ref btdrvGetHidReportEventInfo. +## + +proc btdrvGetHidReportEventInfo*(buffer: pointer; size: csize_t; + `type`: ptr BtdrvHidEventType): Result {.cdecl, + importc: "btdrvGetHidReportEventInfo".} +## * +## @brief GetHidReportEventInfo +## @note \ref btdrvRegisterHidReportEvent must be used before this, on [7.0.0+]. +## @note This is used by hid-sysmodule. When used by other processes, hid/user-process will conflict. No events will be received by that user-process, or it will be corrupted, etc. +## @note [7.0.0+] When data isn't available, the type is set to ::BtdrvHidEventType_Data, with the buffer cleared to all-zero. +## @param[out] buffer Output buffer, see \ref BtdrvHidReportEventInfo. +## @param[in] size Output buffer size. +## @oaram[out] type \ref BtdrvHidEventType +## + +proc btdrvGetHidReportEventInfoSharedmemAddr*(): pointer {.cdecl, + importc: "btdrvGetHidReportEventInfoSharedmemAddr".} +## / Gets the SharedMemory addr for HidReportEventInfo (\ref BtdrvCircularBuffer), only valid when \ref btdrvRegisterHidReportEvent was previously used, on [7.0.0+]. + +proc btdrvGetLatestPlr*(`out`: ptr BtdrvPlrList): Result {.cdecl, + importc: "btdrvGetLatestPlr".} +## * +## @brief GetLatestPlr +## @param[out] out Output \ref BtdrvPlrList, on pre-9.0.0 this is \ref BtdrvPlrStatistics. +## + +proc btdrvGetPendingConnections*(): Result {.cdecl, + importc: "btdrvGetPendingConnections".} +## * +## @brief GetPendingConnections +## @note The output data will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). +## @note This is used by btm-sysmodule. +## @note Only available on [3.0.0+]. +## + +proc btdrvGetChannelMap*(`out`: ptr BtdrvChannelMapList): Result {.cdecl, + importc: "btdrvGetChannelMap".} +## * +## @brief GetChannelMap +## @note Only available on [3.0.0+]. +## @param[out] out \ref BtdrvChannelMapList +## + +proc btdrvEnableTxPowerBoostSetting*(flag: bool): Result {.cdecl, + importc: "btdrvEnableTxPowerBoostSetting".} +## * +## @brief EnableTxPowerBoostSetting +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc btdrvIsTxPowerBoostSettingEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "btdrvIsTxPowerBoostSettingEnabled".} +## * +## @brief IsTxPowerBoostSettingEnabled +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc btdrvEnableAfhSetting*(flag: bool): Result {.cdecl, + importc: "btdrvEnableAfhSetting".} +## * +## @brief EnableAfhSetting +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc btdrvIsAfhSettingEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "btdrvIsAfhSettingEnabled".} +## * +## @brief IsAfhSettingEnabled +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc btdrvInitializeBle*(outEvent: ptr Event): Result {.cdecl, + importc: "btdrvInitializeBle".} +## * +## @brief InitializeBle +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btdrvEnableBle*(): Result {.cdecl, importc: "btdrvEnableBle".} +## * +## @brief EnableBle +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## + +proc btdrvDisableBle*(): Result {.cdecl, importc: "btdrvDisableBle".} +## * +## @brief DisableBle +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## + +proc btdrvFinalizeBle*(): Result {.cdecl, importc: "btdrvFinalizeBle".} +## * +## @brief FinalizeBle +## @note Only available on [5.0.0+]. +## + +proc btdrvSetBleVisibility*(discoverable: bool; connectable: bool): Result {.cdecl, + importc: "btdrvSetBleVisibility".} +## * +## @brief SetBleVisibility +## @note Only available on [5.0.0+]. +## @param[in] discoverable Whether the BLE device is discoverable. +## @param[in] connectable Whether the BLE device is connectable. +## + +proc btdrvSetLeConnectionParameter*(param: ptr BtdrvLeConnectionParams): Result {. + cdecl, importc: "btdrvSetLeConnectionParameter".} +## * +## @brief SetLeConnectionParameter +## @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleConnectionParameter. +## @param[in] param \ref BtdrvLeConnectionParams +## + +proc btdrvSetBleConnectionParameter*(`addr`: BtdrvAddress; + param: ptr BtdrvBleConnectionParameter; + flag: bool): Result {.cdecl, + importc: "btdrvSetBleConnectionParameter".} +## * +## @brief SetBleConnectionParameter +## @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeConnectionParameter. +## @param[in] addr \ref BtdrvAddress +## @param[in] param \ref BtdrvBleConnectionParameter +## @param[in] flag Flag +## + +proc btdrvSetLeDefaultConnectionParameter*(param: ptr BtdrvLeConnectionParams): Result {. + cdecl, importc: "btdrvSetLeDefaultConnectionParameter".} +## * +## @brief SetLeDefaultConnectionParameter +## @note Only available on [5.0.0-8.1.1]. This is the older version of \ref btdrvSetBleDefaultConnectionParameter. +## @param[in] param \ref BtdrvLeConnectionParams +## + +proc btdrvSetBleDefaultConnectionParameter*( + param: ptr BtdrvBleConnectionParameter): Result {.cdecl, + importc: "btdrvSetBleDefaultConnectionParameter".} +## * +## @brief SetBleDefaultConnectionParameter +## @note Only available on [9.0.0+]. This is the newer version of \ref btdrvSetLeDefaultConnectionParameter. +## @param[in] param \ref BtdrvBleConnectionParameter +## + +proc btdrvSetBleAdvertiseData*(data: ptr BtdrvBleAdvertisePacketData): Result {. + cdecl, importc: "btdrvSetBleAdvertiseData".} +## * +## @brief SetBleAdvertiseData +## @note Only available on [5.0.0+]. +## @param[in] data \ref BtdrvBleAdvertisePacketData +## + +proc btdrvSetBleAdvertiseParameter*(`addr`: BtdrvAddress; unk0: U16; unk1: U16): Result {. + cdecl, importc: "btdrvSetBleAdvertiseParameter".} +## * +## @brief SetBleAdvertiseParameter +## @note Only available on [5.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] unk0 Unknown +## @param[in] unk1 Unknown +## + +proc btdrvStartBleScan*(): Result {.cdecl, importc: "btdrvStartBleScan".} +## * +## @brief StartBleScan +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## + +proc btdrvStopBleScan*(): Result {.cdecl, importc: "btdrvStopBleScan".} +## * +## @brief StopBleScan +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## + +proc btdrvAddBleScanFilterCondition*(filter: ptr BtdrvBleAdvertiseFilter): Result {. + cdecl, importc: "btdrvAddBleScanFilterCondition".} +## * +## @brief AddBleScanFilterCondition +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] filter \ref BtdrvBleAdvertiseFilter +## + +proc btdrvDeleteBleScanFilterCondition*(filter: ptr BtdrvBleAdvertiseFilter): Result {. + cdecl, importc: "btdrvDeleteBleScanFilterCondition".} +## * +## @brief DeleteBleScanFilterCondition +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] filter \ref BtdrvBleAdvertiseFilter +## + +proc btdrvDeleteBleScanFilter*(unk: U8): Result {.cdecl, + importc: "btdrvDeleteBleScanFilter".} +## * +## @brief DeleteBleScanFilter +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## + +proc btdrvClearBleScanFilters*(): Result {.cdecl, + importc: "btdrvClearBleScanFilters".} +## * +## @brief ClearBleScanFilters +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## + +proc btdrvEnableBleScanFilter*(flag: bool): Result {.cdecl, + importc: "btdrvEnableBleScanFilter".} +## * +## @brief EnableBleScanFilter +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] flag Flag +## + +proc btdrvRegisterGattClient*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvRegisterGattClient".} +## * +## @brief RegisterGattClient +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvUnregisterGattClient*(unk: U8): Result {.cdecl, + importc: "btdrvUnregisterGattClient".} +## * +## @brief UnregisterGattClient +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## + +proc btdrvUnregisterAllGattClients*(): Result {.cdecl, + importc: "btdrvUnregisterAllGattClients".} +## * +## @brief UnregisterAllGattClients +## @note Only available on [5.0.0+]. +## + +proc btdrvConnectGattServer*(unk: U8; `addr`: BtdrvAddress; flag: bool; + appletResourceUserId: U64): Result {.cdecl, + importc: "btdrvConnectGattServer".} +## * +## @brief ConnectGattServer +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] unk Unknown +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## @param[in] AppletResourceUserId AppletResourceUserId +## + +proc btdrvCancelConnectGattServer*(unk: U8; `addr`: BtdrvAddress; flag: bool): Result {. + cdecl, importc: "btdrvCancelConnectGattServer".} +## * +## @brief CancelConnectGattServer +## @note Only available on [5.1.0+]. +## @note This is used by btm-sysmodule. +## @param[in] unk Unknown +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## + +proc btdrvDisconnectGattServer*(unk: U32): Result {.cdecl, + importc: "btdrvDisconnectGattServer".} +## * +## @brief DisconnectGattServer +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] unk Unknown +## + +proc btdrvGetGattAttribute*(`addr`: BtdrvAddress; unk: U32): Result {.cdecl, + importc: "btdrvGetGattAttribute".} +## * +## @brief GetGattAttribute +## @note Only available on [5.0.0+]. +## @param[in] addr \ref BtdrvAddress, only used on pre-9.0.0. +## @param[in] unk Unknown +## + +proc btdrvGetGattService*(unk: U32; uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvGetGattService".} +## * +## @brief GetGattService +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvConfigureAttMtu*(unk: U32; mtu: U16): Result {.cdecl, + importc: "btdrvConfigureAttMtu".} +## * +## @brief ConfigureAttMtu +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] unk Unknown +## @param[in] mtu MTU +## + +proc btdrvRegisterGattServer*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvRegisterGattServer".} +## * +## @brief RegisterGattServer +## @note Only available on [5.0.0+]. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvUnregisterGattServer*(unk: U8): Result {.cdecl, + importc: "btdrvUnregisterGattServer".} +## * +## @brief UnregisterGattServer +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## + +proc btdrvConnectGattClient*(unk: U8; `addr`: BtdrvAddress; flag: bool): Result {.cdecl, + importc: "btdrvConnectGattClient".} +## * +## @brief ConnectGattClient +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## + +proc btdrvDisconnectGattClient*(unk: U8; `addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvDisconnectGattClient".} +## * +## @brief DisconnectGattClient +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] addr \ref BtdrvAddress, only used on pre-9.0.0. +## + +proc btdrvAddGattService*(unk0: U8; uuid: ptr BtdrvGattAttributeUuid; unk1: U8; + flag: bool): Result {.cdecl, importc: "btdrvAddGattService".} +## * +## @brief AddGattService +## @note Only available on [5.0.0+]. +## @param[in] unk0 Unknown +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[in] unk1 Unknown +## @param[in] flag Flag +## + +proc btdrvEnableGattService*(unk: U8; uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdrvEnableGattService".} +## * +## @brief EnableGattService +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvAddGattCharacteristic*(unk0: U8; uuid0: ptr BtdrvGattAttributeUuid; + uuid1: ptr BtdrvGattAttributeUuid; unk1: U8; + unk2: U16): Result {.cdecl, + importc: "btdrvAddGattCharacteristic".} +## * +## @brief AddGattCharacteristic +## @note Only available on [5.0.0+]. +## @param[in] unk0 Unknown +## @param[in] uuid0 \ref BtdrvGattAttributeUuid +## @param[in] uuid1 \ref BtdrvGattAttributeUuid +## @param[in] unk1 Unknown +## @param[in] unk2 Unknown +## + +proc btdrvAddGattDescriptor*(unk0: U8; uuid0: ptr BtdrvGattAttributeUuid; + uuid1: ptr BtdrvGattAttributeUuid; unk1: U16): Result {. + cdecl, importc: "btdrvAddGattDescriptor".} +## * +## @brief AddGattDescriptor +## @note Only available on [5.0.0+]. +## @param[in] unk0 Unknown +## @param[in] uuid0 \ref BtdrvGattAttributeUuid +## @param[in] uuid1 \ref BtdrvGattAttributeUuid +## @param[in] unk1 Unknown +## + +proc btdrvGetBleManagedEventInfo*(buffer: pointer; size: csize_t; + `type`: ptr BtdrvBleEventType): Result {.cdecl, + importc: "btdrvGetBleManagedEventInfo".} +## * +## @brief GetBleManagedEventInfo +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[out] buffer Output buffer. 0x400-bytes from state is written here. +## @param[in] size Output buffer size. +## @oaram[out] type Output BtdrvBleEventType. +## + +proc btdrvGetGattFirstCharacteristic*(unk: U32; id: ptr BtdrvGattId; flag: bool; + uuid: ptr BtdrvGattAttributeUuid; + outProperty: ptr U8; + outCharId: ptr BtdrvGattId): Result {.cdecl, + importc: "btdrvGetGattFirstCharacteristic".} +## * +## @brief GetGattFirstCharacteristic +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] id \ref BtdrvGattId +## @param[in] flag Flag +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] out_property Output Property. +## @param[out] out_char_id Output CharacteristicId \ref BtdrvGattId +## + +proc btdrvGetGattNextCharacteristic*(unk: U32; id0: ptr BtdrvGattId; flag: bool; + id1: ptr BtdrvGattId; + uuid: ptr BtdrvGattAttributeUuid; + outProperty: ptr U8; outCharId: ptr BtdrvGattId): Result {. + cdecl, importc: "btdrvGetGattNextCharacteristic".} +## * +## @brief GetGattNextCharacteristic +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] id0 \ref BtdrvGattId +## @param[in] flag Flag +## @param[in] id1 \ref BtdrvGattId +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] out_property Output Property. +## @param[out] out_char_id Output CharacteristicId \ref BtdrvGattId +## + +proc btdrvGetGattFirstDescriptor*(unk: U32; id0: ptr BtdrvGattId; flag: bool; + id1: ptr BtdrvGattId; + uuid: ptr BtdrvGattAttributeUuid; + outDescId: ptr BtdrvGattId): Result {.cdecl, + importc: "btdrvGetGattFirstDescriptor".} +## * +## @brief GetGattFirstDescriptor +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] id0 \ref BtdrvGattId +## @param[in] flag Flag +## @param[in] id1 \ref BtdrvGattId +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] out_desc_id Output DescriptorId \ref BtdrvGattId +## + +proc btdrvGetGattNextDescriptor*(unk: U32; id0: ptr BtdrvGattId; flag: bool; + id1: ptr BtdrvGattId; id2: ptr BtdrvGattId; + uuid: ptr BtdrvGattAttributeUuid; + outDescId: ptr BtdrvGattId): Result {.cdecl, + importc: "btdrvGetGattNextDescriptor".} +## * +## @brief GetGattNextDescriptor +## @note Only available on [5.0.0+]. +## @param[in] unk Unknown +## @param[in] id0 \ref BtdrvGattId +## @param[in] flag Flag +## @param[in] id1 \ref BtdrvGattId +## @param[in] id2 \ref BtdrvGattId +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] out_desc_id Output DescriptorId \ref BtdrvGattId +## + +proc btdrvRegisterGattManagedDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdrvRegisterGattManagedDataPath".} +## * +## @brief RegisterGattManagedDataPath +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvUnregisterGattManagedDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdrvUnregisterGattManagedDataPath".} +## * +## @brief UnregisterGattManagedDataPath +## @note Only available on [5.0.0+]. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvRegisterGattHidDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvRegisterGattHidDataPath".} +## * +## @brief RegisterGattHidDataPath +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvUnregisterGattHidDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btdrvUnregisterGattHidDataPath".} +## * +## @brief UnregisterGattHidDataPath +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvRegisterGattDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvRegisterGattDataPath".} +## * +## @brief RegisterGattDataPath +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvUnregisterGattDataPath*(uuid: ptr BtdrvGattAttributeUuid): Result {.cdecl, + importc: "btdrvUnregisterGattDataPath".} +## * +## @brief UnregisterGattDataPath +## @note Only available on [5.0.0+]. +## @note This is used by btm-sysmodule. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btdrvReadGattCharacteristic*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; unk: U8): Result {. + cdecl, importc: "btdrvReadGattCharacteristic".} +## * +## @brief ReadGattCharacteristic +## @note Only available on [5.0.0+]. +## @param[in] connection_handle ConnectionHandle +## @param[in] primary_service PrimaryService +## @param[in] id0 \ref BtdrvGattId +## @param[in] id1 \ref BtdrvGattId +## @param[in] unk Unknown +## + +proc btdrvReadGattDescriptor*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + id2: ptr BtdrvGattId; unk: U8): Result {.cdecl, + importc: "btdrvReadGattDescriptor".} +## * +## @brief ReadGattDescriptor +## @note Only available on [5.0.0+]. +## @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 +## + +proc btdrvWriteGattCharacteristic*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + buffer: pointer; size: csize_t; unk: U8; flag: bool): Result {. + cdecl, importc: "btdrvWriteGattCharacteristic".} +## * +## @brief WriteGattCharacteristic +## @note Only available on [5.0.0+]. +## @param[in] connection_handle ConnectionHandle +## @param[in] primary_service PrimaryService +## @param[in] id0 \ref BtdrvGattId +## @param[in] id1 \ref BtdrvGattId +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size, must be <=0x258. +## @param[in] unk Unknown +## @param[in] flag Flag +## + +proc btdrvWriteGattDescriptor*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId; + id2: ptr BtdrvGattId; buffer: pointer; size: csize_t; + unk: U8): Result {.cdecl, + importc: "btdrvWriteGattDescriptor".} +## * +## @brief WriteGattDescriptor +## @note Only available on [5.0.0+]. +## @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] buffer Input buffer. +## @param[in] size Input buffer size, must be <=0x258. +## @param[in] unk Unknown +## + +proc btdrvRegisterGattNotification*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId): Result {. + cdecl, importc: "btdrvRegisterGattNotification".} +## * +## @brief RegisterGattNotification +## @note Only available on [5.0.0+]. +## @param[in] connection_handle ConnectionHandle +## @param[in] primary_service PrimaryService +## @param[in] id0 \ref BtdrvGattId +## @param[in] id1 \ref BtdrvGattId +## + +proc btdrvUnregisterGattNotification*(connectionHandle: U32; primaryService: bool; + id0: ptr BtdrvGattId; id1: ptr BtdrvGattId): Result {. + cdecl, importc: "btdrvUnregisterGattNotification".} +## * +## @brief UnregisterGattNotification +## @note Only available on [5.0.0+]. +## @param[in] connection_handle ConnectionHandle +## @param[in] primary_service PrimaryService +## @param[in] id0 \ref BtdrvGattId +## @param[in] id1 \ref BtdrvGattId +## + +proc btdrvGetLeHidEventInfo*(buffer: pointer; size: csize_t; `type`: ptr U32): Result {. + cdecl, importc: "btdrvGetLeHidEventInfo".} +## * +## @brief GetLeHidEventInfo +## @note Only available on [5.0.0+]. +## @note The state used by this is reset after writing the data to output. +## @param[out] buffer Output buffer. 0x400-bytes from state is written here. See \ref BtdrvLeEventInfo. +## @param[in] size Output buffer size. +## @oaram[out] type Output BleEventType. +## + +proc btdrvRegisterBleHidEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btdrvRegisterBleHidEvent".} +## * +## @brief RegisterBleHidEvent +## @note Only available on [5.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btdrvSetBleScanParameter*(unk0: U16; unk1: U16): Result {.cdecl, + importc: "btdrvSetBleScanParameter".} +## * +## @brief SetBleScanParameter +## @note Only available on [5.1.0+]. +## @note This is used by btm-sysmodule. +## @param[in] unk0 Unknown +## @param[in] unk1 Unknown +## + +proc btdrvMoveToSecondaryPiconet*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvMoveToSecondaryPiconet".} +## * +## @brief MoveToSecondaryPiconet +## @note The response will be available via \ref btdrvGetHidEventInfo ([12.0.0+] \ref btdrvGetEventInfo). +## @note Only available on [10.0.0+]. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvIsBluetoothEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "btdrvIsBluetoothEnabled".} +## * +## @brief IsBluetoothEnabled +## @note Only available on [12.0.0+]. +## @param[out] out Output flag. +## + +proc btdrvAcquireAudioEvent*(outEvent: ptr Event; autoclear: bool): Result {.cdecl, + importc: "btdrvAcquireAudioEvent".} +## * +## @brief AcquireAudioEvent +## @note Only available on [12.0.0+]. +## @param[out] out_event Output Event. +## @param[in] autoclear Event autoclear. +## + +proc btdrvGetAudioEventInfo*(buffer: pointer; size: csize_t; + `type`: ptr BtdrvAudioEventType): Result {.cdecl, + importc: "btdrvGetAudioEventInfo".} +## * +## @brief GetAudioEventInfo +## @note Only available on [12.0.0+]. +## @param[out] buffer Output buffer, see \ref BtdrvAudioEventInfo. +## @param[in] size Output buffer size. +## @param[out] type \ref BtdrvAudioEventType. +## + +proc btdrvOpenAudioConnection*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvOpenAudioConnection".} +## * +## @brief OpenAudioConnection +## @note Only available on [12.0.0+]. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvCloseAudioConnection*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvCloseAudioConnection".} +## * +## @brief CloseAudioConnection +## @note Only available on [12.0.0+]. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvOpenAudioOut*(`addr`: BtdrvAddress; audioHandle: ptr U32): Result {.cdecl, + importc: "btdrvOpenAudioOut".} +## * +## @brief OpenAudioOut +## @note Only available on [12.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[out] audio_handle Audio handle. +## + +proc btdrvCloseAudioOut*(audioHandle: U32): Result {.cdecl, + importc: "btdrvCloseAudioOut".} +## * +## @brief CloseAudioOut +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## + +proc btdrvStartAudioOut*(audioHandle: U32; pcmParam: ptr BtdrvPcmParameter; + inLatency: S64; outLatency: ptr S64; out1: ptr U64): Result {. + cdecl, importc: "btdrvStartAudioOut".} +## * +## @brief StartAudioOut +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[in] pcm_param \ref BtdrvPcmParameter +## @param[in] in_latency Input latency in nanoseconds. +## @param[out] out_latency Output latency in nanoseconds. +## @param[out] out1 Unknown output. +## + +proc btdrvStopAudioOut*(audioHandle: U32): Result {.cdecl, + importc: "btdrvStopAudioOut".} +## * +## @brief StopAudioOut +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## + +proc btdrvGetAudioOutState*(audioHandle: U32; `out`: ptr BtdrvAudioOutState): Result {. + cdecl, importc: "btdrvGetAudioOutState".} +## * +## @brief GetAudioOutState +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[out] out \ref BtdrvAudioOutState +## + +proc btdrvGetAudioOutFeedingCodec*(audioHandle: U32; `out`: ptr BtdrvAudioCodec): Result {. + cdecl, importc: "btdrvGetAudioOutFeedingCodec".} +## * +## @brief GetAudioOutFeedingCodec +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[out] out \ref BtdrvAudioCodec +## + +proc btdrvGetAudioOutFeedingParameter*(audioHandle: U32; + `out`: ptr BtdrvPcmParameter): Result {.cdecl, + importc: "btdrvGetAudioOutFeedingParameter".} +## * +## @brief GetAudioOutFeedingParameter +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[out] out \ref BtdrvPcmParameter +## + +proc btdrvAcquireAudioOutStateChangedEvent*(audioHandle: U32; outEvent: ptr Event; + autoclear: bool): Result {.cdecl, + importc: "btdrvAcquireAudioOutStateChangedEvent".} +## * +## @brief AcquireAudioOutStateChangedEvent +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[out] out_event Output Event. +## @param[in] autoclear Event autoclear. +## + +proc btdrvAcquireAudioOutBufferAvailableEvent*(audioHandle: U32; + outEvent: ptr Event; autoclear: bool): Result {.cdecl, + importc: "btdrvAcquireAudioOutBufferAvailableEvent".} +## * +## @brief AcquireAudioOutBufferAvailableEvent +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[out] out_event Output Event. +## @param[in] autoclear Event autoclear. +## + +proc btdrvSendAudioData*(audioHandle: U32; buffer: pointer; size: csize_t; + transferredSize: ptr U64): Result {.cdecl, + importc: "btdrvSendAudioData".} +## * +## @brief SendAudioData +## @note Only available on [12.0.0+]. +## @param[in] audio_handle Audio handle from \ref btdrvOpenAudioOut. +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## @param[out] Output transferred size. This is always either 0 (error occured) or the buffer size. +## + +proc btdrvAcquireAudioControlInputStateChangedEvent*(outEvent: ptr Event; + autoclear: bool): Result {.cdecl, importc: "btdrvAcquireAudioControlInputStateChangedEvent".} +## * +## @brief AcquireAudioControlInputStateChangedEvent +## @note Only available on [12.0.0+]. +## @param[out] out_event Output Event. +## @param[in] autoclear Event autoclear. +## + +proc btdrvGetAudioControlInputState*(states: ptr BtdrvAudioControlButtonState; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "btdrvGetAudioControlInputState".} +## * +## @brief GetAudioControlInputState +## @note Only available on [12.0.0+]. +## @param[out] states Output array of \ref BtdrvAudioControlButtonState. +## @param[in] count Size of the states array in entries, the maximum is 0xF. +## @param[out] total_out Total output entries. +## + +proc btdrvAcquireAudioConnectionStateChangedEvent*(outEvent: ptr Event; + autoclear: bool): Result {.cdecl, importc: "btdrvAcquireAudioConnectionStateChangedEvent".} +## * +## @brief AcquireAudioConnectionStateChangedEvent +## @note Only available on [12.0.0-13.2.1]. +## @param[out] out_event Output Event. +## @param[in] autoclear Event autoclear. +## + +proc btdrvGetConnectedAudioDevice*(addrs: ptr BtdrvAddress; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "btdrvGetConnectedAudioDevice".} +## * +## @brief GetConnectedAudioDevice +## @note Only available on [12.0.0-13.2.1]. +## @param[out] addrs Output array of \ref BtdrvAddress. +## @param[in] count Size of the addrs array in entries, the maximum is 0x8. +## @param[out] total_out Total output entries. +## + +proc btdrvCloseAudioControlInput*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btdrvCloseAudioControlInput".} +## * +## @brief CloseAudioControlInput +## @note Only available on [13.0.0+]. +## @param[in] addr \ref BtdrvAddress +## + +proc btdrvRegisterAudioControlNotification*(`addr`: BtdrvAddress; eventType: U32): Result {. + cdecl, importc: "btdrvRegisterAudioControlNotification".} +## * +## @brief RegisterAudioControlNotification +## @note Only available on [13.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] event_type AvrcEventType +## + +proc btdrvSendAudioControlPassthroughCommand*(`addr`: BtdrvAddress; opId: U32; + stateType: U32): Result {.cdecl, + importc: "btdrvSendAudioControlPassthroughCommand".} +## * +## @brief SendAudioControlPassthroughCommand +## @note Only available on [13.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] op_id AvrcOperationId +## @param[in] state_type AvrcStateType +## + +proc btdrvSendAudioControlSetAbsoluteVolumeCommand*(`addr`: BtdrvAddress; val: S32): Result {. + cdecl, importc: "btdrvSendAudioControlSetAbsoluteVolumeCommand".} +## * +## @brief SendAudioControlSetAbsoluteVolumeCommand +## @note Only available on [13.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] val Input value +## + +proc btdrvIsManufacturingMode*(`out`: ptr bool): Result {.cdecl, + importc: "btdrvIsManufacturingMode".} +## * +## @brief IsManufacturingMode +## @note Only available on [5.0.0+]. +## @param[out] out Output flag. +## + +proc btdrvEmulateBluetoothCrash*(reason: BtdrvFatalReason): Result {.cdecl, + importc: "btdrvEmulateBluetoothCrash".} +## * +## @brief EmulateBluetoothCrash +## @note Only available on [7.0.0+]. +## @param[in] reason \ref BtdrvFatalReason +## + +proc btdrvGetBleChannelMap*(`out`: ptr BtdrvChannelMapList): Result {.cdecl, + importc: "btdrvGetBleChannelMap".} +## * +## @brief GetBleChannelMap +## @note Only available on [9.0.0+]. +## @param[out] out \ref BtdrvChannelMapList +## + +proc btdrvCircularBufferRead*(c: ptr BtdrvCircularBuffer): pointer {.cdecl, + importc: "btdrvCircularBufferRead".} +## /@name CircularBuffer +## /@{ +## * +## @brief Read +## @note Used by \ref btdrvGetHidReportEventInfo on [7.0.0+]. +## @param c \ref BtdrvCircularBuffer +## + +proc btdrvCircularBufferFree*(c: ptr BtdrvCircularBuffer): bool {.cdecl, + importc: "btdrvCircularBufferFree".} +## * +## @brief Free +## @note Used by \ref btdrvGetHidReportEventInfo on [7.0.0+]. +## @param c \ref BtdrvCircularBuffer +## + +## /@} diff --git a/src/libnx/wrapper/switch/services/btdrv_types.h b/src/libnx/wrapper/switch/services/btdrv_types.h new file mode 100644 index 0000000..a5fb580 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btdrv_types.h @@ -0,0 +1,349 @@ +/** + * @file btdrv_types.h + * @brief Bluetooth driver (btdrv) service types (see btdrv.h for the rest). + * @author yellows8, ndeadly + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// BluetoothPropertyType [1.0.0-11.0.1] +typedef enum { + BtdrvBluetoothPropertyType_Name = 1, ///< Name. String, max length 0xF8 excluding NUL-terminator. + BtdrvBluetoothPropertyType_Address = 2, ///< \ref BtdrvAddress + BtdrvBluetoothPropertyType_Unknown3 = 3, ///< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress. + BtdrvBluetoothPropertyType_ClassOfDevice = 5, ///< 3-bytes, Class of Device. + BtdrvBluetoothPropertyType_FeatureSet = 6, ///< 1-byte, FeatureSet. The default is value 0x68. +} BtdrvBluetoothPropertyType; + +/// AdapterPropertyType [12.0.0+] +typedef enum { + BtdrvAdapterPropertyType_Address = 0, ///< \ref BtdrvAddress + BtdrvAdapterPropertyType_Name = 1, ///< Name. String, max length 0xF8 excluding NUL-terminator. + BtdrvAdapterPropertyType_ClassOfDevice = 2, ///< 3-bytes, Class of Device. + BtdrvAdapterPropertyType_Unknown3 = 3, ///< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress. +} BtdrvAdapterPropertyType; + +/// EventType +typedef enum { + ///< BtdrvEventType_* should be used on [12.0.0+] + BtdrvEventType_InquiryDevice = 0, ///< Device found during Inquiry. + BtdrvEventType_InquiryStatus = 1, ///< Inquiry status changed. + BtdrvEventType_PairingPinCodeRequest = 2, ///< Pairing PIN code request. + BtdrvEventType_SspRequest = 3, ///< SSP confirm request / SSP passkey notification. + BtdrvEventType_Connection = 4, ///< Connection + BtdrvEventType_Tsi = 5, ///< SetTsi (\ref btdrvSetTsi) + BtdrvEventType_BurstMode = 6, ///< SetBurstMode (\ref btdrvEnableBurstMode) + BtdrvEventType_SetZeroRetransmission = 7, ///< \ref btdrvSetZeroRetransmission + BtdrvEventType_PendingConnections = 8, ///< \ref btdrvGetPendingConnections + BtdrvEventType_MoveToSecondaryPiconet = 9, ///< \ref btdrvMoveToSecondaryPiconet + BtdrvEventType_BluetoothCrash = 10, ///< BluetoothCrash + + ///< BtdrvEventTypeOld_* should be used on [1.0.0-11.0.1] + BtdrvEventTypeOld_Unknown0 = 0, ///< Unused + BtdrvEventTypeOld_InquiryDevice = 3, ///< Device found during Inquiry. + BtdrvEventTypeOld_InquiryStatus = 4, ///< Inquiry status changed. + BtdrvEventTypeOld_PairingPinCodeRequest = 5, ///< Pairing PIN code request. + BtdrvEventTypeOld_SspRequest = 6, ///< SSP confirm request / SSP passkey notification. + BtdrvEventTypeOld_Connection = 7, ///< Connection + BtdrvEventTypeOld_BluetoothCrash = 13, ///< BluetoothCrash +} BtdrvEventType; + +/// BtdrvInquiryStatus +typedef enum { + BtdrvInquiryStatus_Stopped = 0, ///< Inquiry stopped. + BtdrvInquiryStatus_Started = 1, ///< Inquiry started. +} BtdrvInquiryStatus; + +/// ConnectionEventType +typedef enum { + BtdrvConnectionEventType_Status = 0, ///< BtdrvEventInfo::connection::status + BtdrvConnectionEventType_SspConfirmRequest = 1, ///< SSP confirm request. + BtdrvConnectionEventType_Suspended = 2, ///< ACL Link is now Suspended. +} BtdrvConnectionEventType; + +/// ExtEventType [1.0.0-11.0.1] +typedef enum { + BtdrvExtEventType_SetTsi = 0, ///< SetTsi (\ref btdrvSetTsi) + BtdrvExtEventType_ExitTsi = 1, ///< ExitTsi (\ref btdrvSetTsi) + BtdrvExtEventType_SetBurstMode = 2, ///< SetBurstMode (\ref btdrvEnableBurstMode) + BtdrvExtEventType_ExitBurstMode = 3, ///< ExitBurstMode (\ref btdrvEnableBurstMode) + BtdrvExtEventType_SetZeroRetransmission = 4, ///< \ref btdrvSetZeroRetransmission + BtdrvExtEventType_PendingConnections = 5, ///< \ref btdrvGetPendingConnections + BtdrvExtEventType_MoveToSecondaryPiconet = 6, ///< \ref btdrvMoveToSecondaryPiconet +} BtdrvExtEventType; + +/// BluetoothHhReportType +/// Bit0-1 directly control the HID bluetooth transaction report-type value. +/// Bit2-3: these directly control the Parameter Reserved field for SetReport, for GetReport these control the Parameter Reserved and Size bits. +typedef enum { + BtdrvBluetoothHhReportType_Other = 0, ///< Other + BtdrvBluetoothHhReportType_Input = 1, ///< Input + BtdrvBluetoothHhReportType_Output = 2, ///< Output + BtdrvBluetoothHhReportType_Feature = 3, ///< Feature +} BtdrvBluetoothHhReportType; + +/// HidEventType +typedef enum { + ///< BtdrvHidEventType_* should be used on [12.0.0+] + BtdrvHidEventType_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventType_Data = 1, ///< DATA report on the Interrupt channel. + BtdrvHidEventType_SetReport = 2, ///< Response to SET_REPORT. + BtdrvHidEventType_GetReport = 3, ///< Response to GET_REPORT. + + ///< BtdrvHidEventTypeOld_* should be used on [1.0.0-11.0.1] + BtdrvHidEventTypeOld_Connection = 0, ///< Connection. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventTypeOld_Data = 4, ///< DATA report on the Interrupt channel. + BtdrvHidEventTypeOld_Ext = 7, ///< Response for extensions. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventTypeOld_SetReport = 8, ///< Response to SET_REPORT. + BtdrvHidEventTypeOld_GetReport = 9, ///< Response to GET_REPORT. +} BtdrvHidEventType; + +/// HidConnectionStatus [12.0.0+] +typedef enum { + ///< BtdrvHidConnectionStatus_* should be used on [12.0.0+] + BtdrvHidConnectionStatus_Closed = 0, + BtdrvHidConnectionStatus_Opened = 1, + BtdrvHidConnectionStatus_Failed = 2, + + ///< BtdrvHidConnectionStatusOld_* should be used on [1.0.0-11.0.1] + BtdrvHidConnectionStatusOld_Opened = 0, + BtdrvHidConnectionStatusOld_Closed = 2, + BtdrvHidConnectionStatusOld_Failed = 8, +} BtdrvHidConnectionStatus; + +/// This determines the u16 data to write into a CircularBuffer. +typedef enum { + BtdrvFatalReason_Invalid = 0, ///< Only for \ref BtdrvEventInfo: invalid. + BtdrvFatalReason_Unknown1 = 1, ///< Can only be triggered by \ref btdrvEmulateBluetoothCrash, not triggered by the sysmodule otherwise. + BtdrvFatalReason_CommandTimeout = 2, ///< HCI command timeout. + BtdrvFatalReason_HardwareError = 3, ///< HCI event HCI_Hardware_Error occurred. + BtdrvFatalReason_Enable = 7, ///< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field. + BtdrvFatalReason_Audio = 9, ///< [12.0.0+] Only for \ref BtdrvEventInfo: triggered by Audio cmds in some cases. +} BtdrvFatalReason; + +/// BleEventType +typedef enum { + BtdrvBleEventType_Unknown0 = 0, ///< Unknown. + BtdrvBleEventType_Unknown1 = 1, ///< Unknown. + BtdrvBleEventType_Unknown2 = 2, ///< Unknown. + BtdrvBleEventType_Unknown3 = 3, ///< Unknown. + BtdrvBleEventType_Unknown4 = 4, ///< Unknown. + BtdrvBleEventType_Unknown5 = 5, ///< Unknown. + BtdrvBleEventType_Unknown6 = 6, ///< Unknown. + BtdrvBleEventType_Unknown7 = 7, ///< Unknown. + BtdrvBleEventType_Unknown8 = 8, ///< Unknown. + BtdrvBleEventType_Unknown9 = 9, ///< Unknown. + BtdrvBleEventType_Unknown10 = 10, ///< Unknown. + BtdrvBleEventType_Unknown11 = 11, ///< Unknown. + BtdrvBleEventType_Unknown12 = 12, ///< Unknown. + BtdrvBleEventType_Unknown13 = 13, ///< Unknown. +} BtdrvBleEventType; + +/// AudioEventType +typedef enum { + BtdrvAudioEventType_None = 0, ///< None + BtdrvAudioEventType_Connection = 1, ///< Connection +} BtdrvAudioEventType; + +/// AudioOutState +typedef enum { + BtdrvAudioOutState_Stopped = 0, ///< Stopped + BtdrvAudioOutState_Started = 1, ///< Started +} BtdrvAudioOutState; + +/// AudioCodec +typedef enum { + BtdrvAudioCodec_Pcm = 0, ///< Raw PCM +} BtdrvAudioCodec; + +/// Address +typedef struct { + u8 address[0x6]; ///< Address +} BtdrvAddress; + +/// ClassOfDevice +typedef struct { + u8 class_of_device[0x3]; ///< ClassOfDevice +} BtdrvClassOfDevice; + +/// AdapterProperty [1.0.0-11.0.1] +typedef struct { + BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address. + BtdrvClassOfDevice class_of_device; ///< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. + char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized). + u8 feature_set; ///< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet). +} BtdrvAdapterPropertyOld; + +/// AdapterProperty [12.0.0+] +typedef struct { + u8 type; ///< \ref BtdrvAdapterPropertyType + u8 size; ///< Data size. + u8 data[0x100]; ///< Data (above size), as specified by the type. +} BtdrvAdapterProperty; + +/// AdapterPropertySet [12.0.0+] +typedef struct { + BtdrvAddress addr; ///< Same as the data for ::BtdrvBluetoothPropertyType_Address. + BtdrvClassOfDevice class_of_device; ///< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. + char name[0xF9]; ///< Same as the data for ::BtdrvBluetoothPropertyType_Name. +} BtdrvAdapterPropertySet; + +/// BluetoothPinCode [1.0.0-11.0.1] +typedef struct { + char code[0x10]; ///< PinCode +} BtdrvBluetoothPinCode; + +/// BtdrvPinCode [12.0.0+] +typedef struct { + char code[0x10]; ///< PinCode + u8 length; ///< Length +} BtdrvPinCode; + +/// HidData [1.0.0-8.1.1] +typedef struct { + u16 size; ///< Size of data. + u8 data[0x280]; ///< Data +} BtdrvHidData; + +/// HidReport [9.0.0+]. +typedef struct { + u16 size; ///< Size of data. + u8 data[0x2BC]; ///< Data +} BtdrvHidReport; + +/// PlrStatistics +typedef struct { + u8 unk_x0[0x84]; ///< Unknown +} BtdrvPlrStatistics; + +/// PlrList +typedef struct { + u8 unk_x0[0xA4]; ///< Unknown +} BtdrvPlrList; + +/// ChannelMapList +typedef struct { + u8 unk_x0[0x88]; ///< Unknown +} BtdrvChannelMapList; + +/// LeConnectionParams +typedef struct { + u8 unk_x0[0x14]; ///< Unknown +} BtdrvLeConnectionParams; + +/// BleConnectionParameter +typedef struct { + u8 unk_x0[0xC]; ///< Unknown +} BtdrvBleConnectionParameter; + +/// BtdrvBleAdvertisePacketDataEntry +typedef struct { + u16 unk_x0; ///< Unknown + u8 unused[0x12]; ///< Unused +} BtdrvBleAdvertisePacketDataEntry; + +/// BleAdvertisePacketData +typedef struct { + u32 unk_x0; ///< Unknown + u8 unk_x4; ///< Unknown + u8 size0; ///< Size of the data at unk_x6. + u8 unk_x6[0x1F]; ///< Unknown, see size0. + u8 pad[3]; ///< Padding + u8 count; ///< Total array entries, see entries. + u8 pad2[7]; ///< Padding + BtdrvBleAdvertisePacketDataEntry entries[0x5]; ///< \ref BtdrvBleAdvertisePacketDataEntry + u8 pad3[0x10]; ///< Padding + u8 size2; ///< Size of the data at unk_xA8. + u8 unk_xA5; ///< Unknown + u8 pad4[2]; ///< Padding + u8 unk_xA8[0x1F]; ///< Unknown, see size2. + u8 unk_xC7; ///< Unknown + u8 unk_xC8; ///< Unknown + u8 pad5[3]; ///< Padding +} BtdrvBleAdvertisePacketData; + +typedef struct { + u8 length; + u8 type; + u8 value[0x1d]; +} BtdrvBleAdvertisementData; + +/// BleAdvertiseFilter +typedef struct { + u8 unk_x0[0x3E]; ///< Unknown +} BtdrvBleAdvertiseFilter; + +/// BleAdvertisePacketParameter +typedef struct { + u8 data[0x8]; ///< Unknown +} BtdrvBleAdvertisePacketParameter; + +/// BleScanResult +typedef struct { + u8 unk_x0; ///< Unknown + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 unk_x7[0x139]; ///< Unknown + s32 unk_x140; ///< Unknown + s32 unk_x144; ///< Unknown +} BtdrvBleScanResult; + +/// BleConnectionInfo +typedef struct { + u32 connection_handle; ///< ConnectionHandle, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid. + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 pad[2]; ///< Padding +} BtdrvBleConnectionInfo; + +/// GattAttributeUuid +typedef struct { + u32 size; ///< UUID size, must be 0x2, 0x4, or 0x10. + u8 uuid[0x10]; ///< UUID with the above size. +} BtdrvGattAttributeUuid; + +/// GattId +typedef struct { + u8 instance_id; ///< InstanceId + u8 pad[3]; ///< Padding + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid +} BtdrvGattId; + +/// LeEventInfo +typedef struct { + u32 unk_x0; ///< Unknown + u32 unk_x4; ///< Unknown + u8 unk_x8; ///< Unknown + u8 pad[3]; ///< Padding + BtdrvGattAttributeUuid uuid0; ///< \ref BtdrvGattAttributeUuid + BtdrvGattAttributeUuid uuid1; ///< \ref BtdrvGattAttributeUuid + BtdrvGattAttributeUuid uuid2; ///< \ref BtdrvGattAttributeUuid + u16 size; ///< Size of the below data. + u8 data[0x3B6]; ///< Data. +} BtdrvLeEventInfo; + +/// BleClientGattOperationInfo +typedef struct { + u8 unk_x0; ///< Converted from BtdrvLeEventInfo::unk_x0. + u8 pad[3]; ///< Padding + u32 unk_x4; ///< BtdrvLeEventInfo::unk_x4 + u8 unk_x8; ///< BtdrvLeEventInfo::unk_x8 + u8 pad2[3]; ///< Padding + BtdrvGattAttributeUuid uuid0; ///< BtdrvLeEventInfo::uuid0 + BtdrvGattAttributeUuid uuid1; ///< BtdrvLeEventInfo::uuid1 + BtdrvGattAttributeUuid uuid2; ///< BtdrvLeEventInfo::uuid2 + u64 size; ///< BtdrvLeEventInfo::size + u8 data[0x200]; ///< BtdrvLeEventInfo::data +} BtdrvBleClientGattOperationInfo; + +/// PcmParameter +typedef struct { + u32 unk_x0; ///< Must be 0-3. Controls number of channels: 0 = mono, non-zero = stereo. + s32 sample_rate; ///< Sample rate. Must be one of the following: 16000, 32000, 44100, 48000. + u32 bits_per_sample; ///< Bits per sample. Must be 8 or 16. +} BtdrvPcmParameter; + +/// AudioControlButtonState +typedef struct { + u8 unk_x0[0x10]; ///< Unknown +} BtdrvAudioControlButtonState; + diff --git a/src/libnx/wrapper/switch/services/btdrv_types.nim b/src/libnx/wrapper/switch/services/btdrv_types.nim new file mode 100644 index 0000000..86abe28 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btdrv_types.nim @@ -0,0 +1,422 @@ +## * +## @file btdrv_types.h +## @brief Bluetooth driver (btdrv) service types (see btdrv.h for the rest). +## @author yellows8, ndeadly +## @copyright libnx Authors +## + +import + ../types + +## / BluetoothPropertyType [1.0.0-11.0.1] + +type + BtdrvBluetoothPropertyType* = enum + BtdrvBluetoothPropertyTypeName = 1, ## /< Name. String, max length 0xF8 excluding NUL-terminator. + BtdrvBluetoothPropertyTypeAddress = 2, ## /< \ref BtdrvAddress + BtdrvBluetoothPropertyTypeUnknown3 = 3, ## /< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress. + BtdrvBluetoothPropertyTypeClassOfDevice = 5, ## /< 3-bytes, Class of Device. + BtdrvBluetoothPropertyTypeFeatureSet = 6 ## /< 1-byte, FeatureSet. The default is value 0x68. + + +## / AdapterPropertyType [12.0.0+] + +type + BtdrvAdapterPropertyType* = enum + BtdrvAdapterPropertyTypeAddress = 0, ## /< \ref BtdrvAddress + BtdrvAdapterPropertyTypeName = 1, ## /< Name. String, max length 0xF8 excluding NUL-terminator. + BtdrvAdapterPropertyTypeClassOfDevice = 2, ## /< 3-bytes, Class of Device. + BtdrvAdapterPropertyTypeUnknown3 = 3 ## /< Only available with \ref btdrvSetAdapterProperty. Unknown, \ref BtdrvAddress. + + +## / EventType + +type ## /< BtdrvEventType_* should be used on [12.0.0+] + BtdrvEventType* = enum + BtdrvEventTypeInquiryDevice = 0, ## /< Device found during Inquiry. + BtdrvEventTypeInquiryStatus = 1, ## /< Inquiry status changed. + BtdrvEventTypePairingPinCodeRequest = 2, ## /< Pairing PIN code request. + BtdrvEventTypeSspRequest = 3, ## /< SSP confirm request / SSP passkey notification. + BtdrvEventTypeConnection = 4, ## /< Connection + BtdrvEventTypeTsi = 5, ## /< SetTsi (\ref btdrvSetTsi) + BtdrvEventTypeBurstMode = 6, ## /< SetBurstMode (\ref btdrvEnableBurstMode) + BtdrvEventTypeSetZeroRetransmission = 7, ## /< \ref btdrvSetZeroRetransmission + BtdrvEventTypePendingConnections = 8, ## /< \ref btdrvGetPendingConnections + BtdrvEventTypeMoveToSecondaryPiconet = 9, ## /< \ref btdrvMoveToSecondaryPiconet + BtdrvEventTypeBluetoothCrash = 10, ## /< BluetoothCrash + ## /< BtdrvEventTypeOld_* should be used on [1.0.0-11.0.1] + BtdrvEventTypeOldBluetoothCrash = 13 ## /< BluetoothCrash + +const + BtdrvEventTypeOldUnknown0* = BtdrvEventTypeInquiryDevice + BtdrvEventTypeOldInquiryDevice* = BtdrvEventTypeSspRequest + BtdrvEventTypeOldInquiryStatus* = BtdrvEventTypeConnection + BtdrvEventTypeOldPairingPinCodeRequest* = BtdrvEventTypeTsi + BtdrvEventTypeOldSspRequest* = BtdrvEventTypeBurstMode + BtdrvEventTypeOldConnection* = BtdrvEventTypeSetZeroRetransmission + +## / BtdrvInquiryStatus + +type + BtdrvInquiryStatus* = enum + BtdrvInquiryStatusStopped = 0, ## /< Inquiry stopped. + BtdrvInquiryStatusStarted = 1 ## /< Inquiry started. + + +## / ConnectionEventType + +type + BtdrvConnectionEventType* = enum + BtdrvConnectionEventTypeStatus = 0, ## /< BtdrvEventInfo::connection::status + BtdrvConnectionEventTypeSspConfirmRequest = 1, ## /< SSP confirm request. + BtdrvConnectionEventTypeSuspended = 2 ## /< ACL Link is now Suspended. + + +## / ExtEventType [1.0.0-11.0.1] + +type + BtdrvExtEventType* = enum + BtdrvExtEventTypeSetTsi = 0, ## /< SetTsi (\ref btdrvSetTsi) + BtdrvExtEventTypeExitTsi = 1, ## /< ExitTsi (\ref btdrvSetTsi) + BtdrvExtEventTypeSetBurstMode = 2, ## /< SetBurstMode (\ref btdrvEnableBurstMode) + BtdrvExtEventTypeExitBurstMode = 3, ## /< ExitBurstMode (\ref btdrvEnableBurstMode) + BtdrvExtEventTypeSetZeroRetransmission = 4, ## /< \ref btdrvSetZeroRetransmission + BtdrvExtEventTypePendingConnections = 5, ## /< \ref btdrvGetPendingConnections + BtdrvExtEventTypeMoveToSecondaryPiconet = 6 ## /< \ref btdrvMoveToSecondaryPiconet + + +## / BluetoothHhReportType +## / Bit0-1 directly control the HID bluetooth transaction report-type value. +## / Bit2-3: these directly control the Parameter Reserved field for SetReport, for GetReport these control the Parameter Reserved and Size bits. + +type + BtdrvBluetoothHhReportType* = enum + BtdrvBluetoothHhReportTypeOther = 0, ## /< Other + BtdrvBluetoothHhReportTypeInput = 1, ## /< Input + BtdrvBluetoothHhReportTypeOutput = 2, ## /< Output + BtdrvBluetoothHhReportTypeFeature = 3 ## /< Feature + + +## / HidEventType + +type ## /< BtdrvHidEventType_* should be used on [12.0.0+] + BtdrvHidEventType* = enum + BtdrvHidEventTypeConnection = 0, ## /< Connection. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventTypeData = 1, ## /< DATA report on the Interrupt channel. + BtdrvHidEventTypeSetReport = 2, ## /< Response to SET_REPORT. + BtdrvHidEventTypeGetReport = 3, ## /< Response to GET_REPORT. + ## /< BtdrvHidEventTypeOld_* should be used on [1.0.0-11.0.1] + BtdrvHidEventTypeOldData = 4, ## /< DATA report on the Interrupt channel. + BtdrvHidEventTypeOldExt = 7, ## /< Response for extensions. Only used with \ref btdrvGetHidEventInfo. + BtdrvHidEventTypeOldSetReport = 8, ## /< Response to SET_REPORT. + BtdrvHidEventTypeOldGetReport = 9 ## /< Response to GET_REPORT. + +const + BtdrvHidEventTypeOldConnection* = BtdrvHidEventTypeConnection + +## / HidConnectionStatus [12.0.0+] + +type ## /< BtdrvHidConnectionStatus_* should be used on [12.0.0+] + BtdrvHidConnectionStatus* = enum + BtdrvHidConnectionStatusClosed = 0, BtdrvHidConnectionStatusOpened = 1, BtdrvHidConnectionStatusFailed = 2, ## /< BtdrvHidConnectionStatusOld_* should be used on [1.0.0-11.0.1] + BtdrvHidConnectionStatusOldFailed = 8 + +const + BtdrvHidConnectionStatusOldOpened* = BtdrvHidConnectionStatusClosed + BtdrvHidConnectionStatusOldClosed* = BtdrvHidConnectionStatusFailed + +## / This determines the u16 data to write into a CircularBuffer. + +type + BtdrvFatalReason* = enum + BtdrvFatalReasonInvalid = 0, ## /< Only for \ref BtdrvEventInfo: invalid. + BtdrvFatalReasonUnknown1 = 1, ## /< Can only be triggered by \ref btdrvEmulateBluetoothCrash, not triggered by the sysmodule otherwise. + BtdrvFatalReasonCommandTimeout = 2, ## /< HCI command timeout. + BtdrvFatalReasonHardwareError = 3, ## /< HCI event HCI_Hardware_Error occurred. + BtdrvFatalReasonEnable = 7, ## /< Only for \ref BtdrvEventInfo: triggered after enabling bluetooth, depending on the value of a global state field. + BtdrvFatalReasonAudio = 9 ## /< [12.0.0+] Only for \ref BtdrvEventInfo: triggered by Audio cmds in some cases. + + +## / BleEventType + +type + BtdrvBleEventType* = enum + BtdrvBleEventTypeUnknown0 = 0, ## /< Unknown. + BtdrvBleEventTypeUnknown1 = 1, ## /< Unknown. + BtdrvBleEventTypeUnknown2 = 2, ## /< Unknown. + BtdrvBleEventTypeUnknown3 = 3, ## /< Unknown. + BtdrvBleEventTypeUnknown4 = 4, ## /< Unknown. + BtdrvBleEventTypeUnknown5 = 5, ## /< Unknown. + BtdrvBleEventTypeUnknown6 = 6, ## /< Unknown. + BtdrvBleEventTypeUnknown7 = 7, ## /< Unknown. + BtdrvBleEventTypeUnknown8 = 8, ## /< Unknown. + BtdrvBleEventTypeUnknown9 = 9, ## /< Unknown. + BtdrvBleEventTypeUnknown10 = 10, ## /< Unknown. + BtdrvBleEventTypeUnknown11 = 11, ## /< Unknown. + BtdrvBleEventTypeUnknown12 = 12, ## /< Unknown. + BtdrvBleEventTypeUnknown13 = 13 ## /< Unknown. + + +## / AudioEventType + +type + BtdrvAudioEventType* = enum + BtdrvAudioEventTypeNone = 0, ## /< None + BtdrvAudioEventTypeConnection = 1 ## /< Connection + + +## / AudioOutState + +type + BtdrvAudioOutState* = enum + BtdrvAudioOutStateStopped = 0, ## /< Stopped + BtdrvAudioOutStateStarted = 1 ## /< Started + + +## / AudioCodec + +type + BtdrvAudioCodec* = enum + BtdrvAudioCodecPcm = 0 ## /< Raw PCM + + +## / Address + +type + BtdrvAddress* {.bycopy.} = object + address*: array[0x6, U8] ## /< Address + + +## / ClassOfDevice + +type + BtdrvClassOfDevice* {.bycopy.} = object + classOfDevice*: array[0x3, U8] ## /< ClassOfDevice + + +## / AdapterProperty [1.0.0-11.0.1] + +type + BtdrvAdapterPropertyOld* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Same as the data for ::BtdrvBluetoothPropertyType_Address. + classOfDevice*: BtdrvClassOfDevice ## /< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. + name*: array[0xF9, char] ## /< Same as the data for ::BtdrvBluetoothPropertyType_Name (last byte is not initialized). + featureSet*: U8 ## /< Set to hard-coded value 0x68 (same as the data for ::BtdrvBluetoothPropertyType_FeatureSet). + + +## / AdapterProperty [12.0.0+] + +type + BtdrvAdapterProperty* {.bycopy.} = object + `type`*: U8 ## /< \ref BtdrvAdapterPropertyType + size*: U8 ## /< Data size. + data*: array[0x100, U8] ## /< Data (above size), as specified by the type. + + +## / AdapterPropertySet [12.0.0+] + +type + BtdrvAdapterPropertySet* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Same as the data for ::BtdrvBluetoothPropertyType_Address. + classOfDevice*: BtdrvClassOfDevice ## /< Same as the data for ::BtdrvBluetoothPropertyType_ClassOfDevice. + name*: array[0xF9, char] ## /< Same as the data for ::BtdrvBluetoothPropertyType_Name. + + +## / BluetoothPinCode [1.0.0-11.0.1] + +type + BtdrvBluetoothPinCode* {.bycopy.} = object + code*: array[0x10, char] ## /< PinCode + + +## / BtdrvPinCode [12.0.0+] + +type + BtdrvPinCode* {.bycopy.} = object + code*: array[0x10, char] ## /< PinCode + length*: U8 ## /< Length + + +## / HidData [1.0.0-8.1.1] + +type + BtdrvHidData* {.bycopy.} = object + size*: U16 ## /< Size of data. + data*: array[0x280, U8] ## /< Data + + +## / HidReport [9.0.0+]. + +type + BtdrvHidReport* {.bycopy.} = object + size*: U16 ## /< Size of data. + data*: array[0x2BC, U8] ## /< Data + + +## / PlrStatistics + +type + BtdrvPlrStatistics* {.bycopy.} = object + unkX0*: array[0x84, U8] ## /< Unknown + + +## / PlrList + +type + BtdrvPlrList* {.bycopy.} = object + unkX0*: array[0xA4, U8] ## /< Unknown + + +## / ChannelMapList + +type + BtdrvChannelMapList* {.bycopy.} = object + unkX0*: array[0x88, U8] ## /< Unknown + + +## / LeConnectionParams + +type + BtdrvLeConnectionParams* {.bycopy.} = object + unkX0*: array[0x14, U8] ## /< Unknown + + +## / BleConnectionParameter + +type + BtdrvBleConnectionParameter* {.bycopy.} = object + unkX0*: array[0xC, U8] ## /< Unknown + + +## / BtdrvBleAdvertisePacketDataEntry + +type + BtdrvBleAdvertisePacketDataEntry* {.bycopy.} = object + unkX0*: U16 ## /< Unknown + unused*: array[0x12, U8] ## /< Unused + + +## / BleAdvertisePacketData + +type + BtdrvBleAdvertisePacketData* {.bycopy.} = object + unkX0*: U32 ## /< Unknown + unkX4*: U8 ## /< Unknown + size0*: U8 ## /< Size of the data at unk_x6. + unkX6*: array[0x1F, U8] ## /< Unknown, see size0. + pad*: array[3, U8] ## /< Padding + count*: U8 ## /< Total array entries, see entries. + pad2*: array[7, U8] ## /< Padding + entries*: array[0x5, BtdrvBleAdvertisePacketDataEntry] ## /< \ref BtdrvBleAdvertisePacketDataEntry + pad3*: array[0x10, U8] ## /< Padding + size2*: U8 ## /< Size of the data at unk_xA8. + unkXA5*: U8 ## /< Unknown + pad4*: array[2, U8] ## /< Padding + unkXA8*: array[0x1F, U8] ## /< Unknown, see size2. + unkXC7*: U8 ## /< Unknown + unkXC8*: U8 ## /< Unknown + pad5*: array[3, U8] ## /< Padding + + BtdrvBleAdvertisementData* {.bycopy.} = object + length*: U8 + `type`*: U8 + value*: array[0x1d, U8] + + +## / BleAdvertiseFilter + +type + BtdrvBleAdvertiseFilter* {.bycopy.} = object + unkX0*: array[0x3E, U8] ## /< Unknown + + +## / BleAdvertisePacketParameter + +type + BtdrvBleAdvertisePacketParameter* {.bycopy.} = object + data*: array[0x8, U8] ## /< Unknown + + +## / BleScanResult + +type + BtdrvBleScanResult* {.bycopy.} = object + unkX0*: U8 ## /< Unknown + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + unkX7*: array[0x139, U8] ## /< Unknown + unkX140*: S32 ## /< Unknown + unkX144*: S32 ## /< Unknown + + +## / BleConnectionInfo + +type + BtdrvBleConnectionInfo* {.bycopy.} = object + connectionHandle*: U32 ## /< ConnectionHandle, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid. + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + pad*: array[2, U8] ## /< Padding + + +## / GattAttributeUuid + +type + BtdrvGattAttributeUuid* {.bycopy.} = object + size*: U32 ## /< UUID size, must be 0x2, 0x4, or 0x10. + uuid*: array[0x10, U8] ## /< UUID with the above size. + + +## / GattId + +type + BtdrvGattId* {.bycopy.} = object + instanceId*: U8 ## /< InstanceId + pad*: array[3, U8] ## /< Padding + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + + +## / LeEventInfo + +type + BtdrvLeEventInfo* {.bycopy.} = object + unkX0*: U32 ## /< Unknown + unkX4*: U32 ## /< Unknown + unkX8*: U8 ## /< Unknown + pad*: array[3, U8] ## /< Padding + uuid0*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + uuid1*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + uuid2*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + size*: U16 ## /< Size of the below data. + data*: array[0x3B6, U8] ## /< Data. + + +## / BleClientGattOperationInfo + +type + BtdrvBleClientGattOperationInfo* {.bycopy.} = object + unkX0*: U8 ## /< Converted from BtdrvLeEventInfo::unk_x0. + pad*: array[3, U8] ## /< Padding + unkX4*: U32 ## /< BtdrvLeEventInfo::unk_x4 + unkX8*: U8 ## /< BtdrvLeEventInfo::unk_x8 + pad2*: array[3, U8] ## /< Padding + uuid0*: BtdrvGattAttributeUuid ## /< BtdrvLeEventInfo::uuid0 + uuid1*: BtdrvGattAttributeUuid ## /< BtdrvLeEventInfo::uuid1 + uuid2*: BtdrvGattAttributeUuid ## /< BtdrvLeEventInfo::uuid2 + size*: U64 ## /< BtdrvLeEventInfo::size + data*: array[0x200, U8] ## /< BtdrvLeEventInfo::data + + +## / PcmParameter + +type + BtdrvPcmParameter* {.bycopy.} = object + unkX0*: U32 ## /< Must be 0-3. Controls number of channels: 0 = mono, non-zero = stereo. + sampleRate*: S32 ## /< Sample rate. Must be one of the following: 16000, 32000, 44100, 48000. + bitsPerSample*: U32 ## /< Bits per sample. Must be 8 or 16. + + +## / AudioControlButtonState + +type + BtdrvAudioControlButtonState* {.bycopy.} = object + unkX0*: array[0x10, U8] ## /< Unknown + diff --git a/src/libnx/wrapper/switch/services/btm.h b/src/libnx/wrapper/switch/services/btm.h new file mode 100644 index 0000000..8db496e --- /dev/null +++ b/src/libnx/wrapper/switch/services/btm.h @@ -0,0 +1,491 @@ +/** + * @file btm.h + * @brief btm service IPC wrapper. + * @note See also: https://switchbrew.org/wiki/BTM_services + * @author yellows8 + */ +#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. +Result btmInitialize(void); + +/// Exit btm. +void btmExit(void); + +/// Gets the Service object for the actual btm service session. +Service* btmGetServiceSession(void); + +/** + * @brief GetState + * @param[out] out \ref BtmState + */ +Result btmGetState(BtmState *out); + +/** + * @brief GetHostDeviceProperty + * @param[out] out \ref BtmHostDeviceProperty + */ +Result btmGetHostDeviceProperty(BtmHostDeviceProperty *out); + +/** + * @brief AcquireDeviceConditionEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmAcquireDeviceConditionEvent(Event* out_event); + +/** + * @brief GetDeviceCondition [1.0.0-12.1.0] + * @param[out] out \ref BtmDeviceCondition + */ +Result btmLegacyGetDeviceCondition(BtmDeviceCondition *out); + +/** + * @brief GetDeviceCondition [13.0.0+] + * @param[in] profile \ref BtmProfile, when not ::BtmProfile_None entries are only returned which match this profile. + * @param[out] out \ref BtmConnectedDeviceV13 + * @param[in] count Size of the out array in entries. + * @param[out] total_out Total output entries. + */ +Result btmGetDeviceCondition(BtmProfile profile, BtmConnectedDeviceV13 *out, size_t count, s32 *total_out); + +/** + * @brief SetBurstMode + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + */ +Result btmSetBurstMode(BtdrvAddress addr, bool flag); + +/** + * @brief SetSlotMode + * @param[in] list \ref BtmDeviceSlotModeList + */ +Result btmSetSlotMode(const BtmDeviceSlotModeList *list); + +/** + * @brief SetBluetoothMode + * @note Only available on pre-9.0.0. + * @param[in] mode \ref BtmBluetoothMode + */ +Result btmSetBluetoothMode(BtmBluetoothMode mode); + +/** + * @brief SetWlanMode + * @param[in] mode \ref BtmWlanMode + */ +Result btmSetWlanMode(BtmWlanMode mode); + +/** + * @brief AcquireDeviceInfoEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmAcquireDeviceInfoEvent(Event* out_event); + +/** + * @brief GetDeviceInfo [1.0.0-12.1.0] + * @param[out] out \ref BtmDeviceInfoList + */ +Result btmLegacyGetDeviceInfo(BtmDeviceInfoList *out); + +/** + * @brief GetDeviceInfo [13.0.0+] + * @param[in] profile \ref BtmProfile, when not ::BtmProfile_None entries are only returned which match this profile. + * @param[out] out \ref BtmDeviceInfoV13 + * @param[in] count Size of the out array in entries. + * @param[out] total_out Total output entries. + */ +Result btmGetDeviceInfo(BtmProfile profile, BtmDeviceInfoV13 *out, size_t count, s32 *total_out); + +/** + * @brief AddDeviceInfo + * @param[in] info \ref BtmDeviceInfo + */ +Result btmAddDeviceInfo(const BtmDeviceInfo *info); + +/** + * @brief RemoveDeviceInfo + * @param[in] addr \ref BtdrvAddress + */ +Result btmRemoveDeviceInfo(BtdrvAddress addr); + +/** + * @brief IncreaseDeviceInfoOrder + * @param[in] addr \ref BtdrvAddress + */ +Result btmIncreaseDeviceInfoOrder(BtdrvAddress addr); + +/** + * @brief LlrNotify + * @param[in] addr \ref BtdrvAddress + * @param[in] unk [9.0.0+] Unknown + */ +Result btmLlrNotify(BtdrvAddress addr, s32 unk); + +/** + * @brief EnableRadio + */ +Result btmEnableRadio(void); + +/** + * @brief DisableRadio + */ +Result btmDisableRadio(void); + +/** + * @brief HidDisconnect + * @param[in] addr \ref BtdrvAddress + */ +Result btmHidDisconnect(BtdrvAddress addr); + +/** + * @brief HidSetRetransmissionMode + * @param[in] addr \ref BtdrvAddress + * @param[in] list \ref BtmZeroRetransmissionList + */ +Result btmHidSetRetransmissionMode(BtdrvAddress addr, const BtmZeroRetransmissionList *list); + +/** + * @brief AcquireAwakeReqEvent + * @note Only available on [2.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 btmAcquireAwakeReqEvent(Event* out_event); + + +/** + * @brief AcquireLlrStateEvent + * @note Only available on [4.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 btmAcquireLlrStateEvent(Event* out_event); + +/** + * @brief IsLlrStarted + * @note Only available on [4.0.0+]. + * @param[out] out Output flag. + */ +Result btmIsLlrStarted(bool *out); + +/** + * @brief EnableSlotSaving + * @note Only available on [4.0.0+]. + * @param[in] flag Flag + */ +Result btmEnableSlotSaving(bool flag); + +/** + * @brief ProtectDeviceInfo + * @note Only available on [5.0.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Flag + */ +Result btmProtectDeviceInfo(BtdrvAddress addr, bool flag); + +/** + * @brief AcquireBleScanEvent + * @note Only available on [5.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 btmAcquireBleScanEvent(Event* out_event); + +/** + * @brief GetBleScanParameterGeneral + * @note Only available on [5.1.0+]. + * @param[in] parameter_id Must be value 0x1 or 0xFFFF. + * @param[out] out \ref BtdrvBleAdvertisePacketParameter + */ +Result btmGetBleScanParameterGeneral(u16 parameter_id, BtdrvBleAdvertisePacketParameter *out); + +/** + * @brief GetBleScanParameterSmartDevice + * @note Only available on [5.1.0+]. + * @param[in] parameter_id Must be value 0x2. + * @param[out] out \ref BtdrvGattAttributeUuid. The first 4-bytes is always 0. + */ +Result btmGetBleScanParameterSmartDevice(u16 parameter_id, BtdrvGattAttributeUuid *out); + +/** + * @brief StartBleScanForGeneral + * @note Only available on [5.1.0+]. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmStartBleScanForGeneral(BtdrvBleAdvertisePacketParameter param); + +/** + * @brief StopBleScanForGeneral + * @note Only available on [5.1.0+]. + */ +Result btmStopBleScanForGeneral(void); + +/** + * @brief GetBleScanResultsForGeneral + * @note Only available on [5.1.0+]. + * @param[out] results Output array of \ref BtdrvBleScanResult. + * @param[in] count Size of the results array in entries. The max is 10. + * @param[out] total_out Total output entries. + */ +Result btmGetBleScanResultsForGeneral(BtdrvBleScanResult *results, u8 count, u8 *total_out); + +/** + * @brief StartBleScanForPaired + * @note Only available on [5.1.0+]. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmStartBleScanForPaired(BtdrvBleAdvertisePacketParameter param); + +/** + * @brief StopBleScanForPaired + * @note Only available on [5.1.0+]. + */ +Result btmStopBleScanForPaired(void); + +/** + * @brief StartBleScanForSmartDevice + * @note Only available on [5.1.0+]. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btmStartBleScanForSmartDevice(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief StopBleScanForSmartDevice + * @note Only available on [5.1.0+]. + */ +Result btmStopBleScanForSmartDevice(void); + +/** + * @brief GetBleScanResultsForSmartDevice + * @note Only available on [5.1.0+]. + * @param[out] results Output array of \ref BtdrvBleScanResult. + * @param[in] count Size of the results array in entries. The max is 10. + * @param[out] total_out Total output entries. + */ +Result btmGetBleScanResultsForSmartDevice(BtdrvBleScanResult *results, u8 count, u8 *total_out); + +/** + * @brief AcquireBleConnectionEvent + * @note Only available on [5.1.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmAcquireBleConnectionEvent(Event* out_event); + +/** + * @brief BleConnect + * @note Only available on [5.0.0+]. + * @note The \ref BtdrvAddress must not be already connected. A maximum of 4 devices can be connected. + * @param[in] addr \ref BtdrvAddress + */ +Result btmBleConnect(BtdrvAddress addr); + +/** + * @brief BleOverrideConnection + * @note Only available on [5.1.0+]. + * @param[in] id Same as \ref btmBleDisconnect. + */ +Result btmBleOverrideConnection(u32 id); + +/** + * @brief BleDisconnect + * @note Only available on [5.0.0+]. + * @param[in] connection_handle This must match a BtdrvBleConnectionInfo::id from \ref btmBleGetConnectionState. [5.1.0+] 0xFFFFFFFF is invalid. + */ +Result btmBleDisconnect(u32 connection_handle); + +/** + * @brief BleGetConnectionState + * @note Only available on [5.0.0+]. + * @param[out] info Output array of \ref BtdrvBleConnectionInfo. + * @param[in] count Size of the info array in entries. Other cmds which use this internally use count=4. + * @param[out] total_out Total output entries. + */ +Result btmBleGetConnectionState(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out); + +/** + * @brief BleGetGattClientConditionList + * @note Only available on [5.0.0+]. + * @param[out] list \ref BtmGattClientConditionList + */ +Result btmBleGetGattClientConditionList(BtmGattClientConditionList *list); + +/** + * @brief AcquireBlePairingEvent + * @note Only available on [5.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 btmAcquireBlePairingEvent(Event* out_event); + +/** + * @brief BlePairDevice + * @note Only available on [5.1.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmBlePairDevice(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleUnpairDeviceOnBoth + * @note Only available on [5.1.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmBleUnpairDeviceOnBoth(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleUnPairDevice + * @note Only available on [5.1.0+]. + * @param[in] addr \ref BtdrvAddress + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmBleUnPairDevice(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleGetPairedAddresses + * @note Only available on [5.1.0+]. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + * @param[out] addrs Output array of \ref BtdrvAddress. + * @param[in] count Size of the addrs array in entries. + * @param[out] total_out Total output entries. The max is 10. + */ +Result btmBleGetPairedAddresses(BtdrvBleAdvertisePacketParameter param, BtdrvAddress *addrs, u8 count, u8 *total_out); + +/** + * @brief AcquireBleServiceDiscoveryEvent + * @note Only available on [5.1.0+]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmAcquireBleServiceDiscoveryEvent(Event* out_event); + +/** + * @brief GetGattServices + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[out] services Output array of \ref BtmGattService. + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmGetGattServices(u32 connection_handle, BtmGattService *services, u8 count, u8 *total_out); + +/** + * @brief Same as \ref btmGetGattServices except this only returns the \ref BtmGattService which matches the input \ref BtdrvGattAttributeUuid. + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] service \ref BtmGattService + * @param[out] flag Whether a \ref BtmGattService was returned. + */ +Result btmGetGattService(u32 connection_handle, const BtdrvGattAttributeUuid *uuid, BtmGattService *service, bool *flag); + +/** + * @brief Same as \ref btmGetGattServices except this only returns \ref BtmGattService entries where various checks pass with u16 fields. + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] service_handle ServiceHandle + * @param[out] services \ref BtmGattService + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] out Output value. + */ +Result btmGetGattIncludedServices(u32 connection_handle, u16 service_handle, BtmGattService *services, u8 count, u8 *out); + +/** + * @brief This is similar to \ref btmGetGattIncludedServices except this only returns 1 \ref BtmGattService. + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] attribute_handle AttributeHandle + * @param[out] service \ref BtmGattService + * @param[out] flag Whether a \ref BtmGattService was returned. + */ +Result btmGetBelongingService(u32 connection_handle, u16 attribute_handle, BtmGattService *service, bool *flag); + +/** + * @brief GetGattCharacteristics + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] service_handle This controls which \ref BtmGattCharacteristic entries to return. + * @param[out] characteristics \ref BtmGattCharacteristic + * @param[in] count Size of the characteristics array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmGetGattCharacteristics(u32 connection_handle, u16 service_handle, BtmGattCharacteristic *characteristics, u8 count, u8 *total_out); + +/** + * @brief GetGattDescriptors + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] char_handle Characteristic handle. This controls which \ref BtmGattDescriptor entries to return. + * @param[out] descriptors \ref BtmGattDescriptor + * @param[in] count Size of the descriptors array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmGetGattDescriptors(u32 connection_handle, u16 char_handle, BtmGattDescriptor *descriptors, u8 count, u8 *total_out); + +/** + * @brief AcquireBleMtuConfigEvent + * @note Only available on [5.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 btmAcquireBleMtuConfigEvent(Event* out_event); + +/** + * @brief ConfigureBleMtu + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[in] mtu MTU + */ +Result btmConfigureBleMtu(u32 connection_handle, u16 mtu); + +/** + * @brief GetBleMtu + * @note Only available on [5.0.0+]. + * @param[in] connection_handle Same as \ref btmBleDisconnect. + * @param[out] out Output MTU. + */ +Result btmGetBleMtu(u32 connection_handle, u16 *out); + +/** + * @brief RegisterBleGattDataPath + * @note Only available on [5.0.0+]. + * @param[in] path \ref BtmBleDataPath + */ +Result btmRegisterBleGattDataPath(const BtmBleDataPath *path); + +/** + * @brief UnregisterBleGattDataPath + * @note Only available on [5.0.0+]. + * @param[in] path \ref BtmBleDataPath + */ +Result btmUnregisterBleGattDataPath(const BtmBleDataPath *path); + +/** + * @brief RegisterAppletResourceUserId + * @note Only available on [5.0.0+]. + * @param[in] AppletResourceUserId AppletResourceUserId + * @param[in] unk Unknown + */ +Result btmRegisterAppletResourceUserId(u64 AppletResourceUserId, u32 unk); + +/** + * @brief UnregisterAppletResourceUserId + * @note Only available on [5.0.0+]. + * @param[in] AppletResourceUserId AppletResourceUserId + */ +Result btmUnregisterAppletResourceUserId(u64 AppletResourceUserId); + +/** + * @brief SetAppletResourceUserId + * @note Only available on [5.0.0+]. + * @param[in] AppletResourceUserId AppletResourceUserId + */ +Result btmSetAppletResourceUserId(u64 AppletResourceUserId); + diff --git a/src/libnx/wrapper/switch/services/btm.nim b/src/libnx/wrapper/switch/services/btm.nim new file mode 100644 index 0000000..9e3cf63 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btm.nim @@ -0,0 +1,562 @@ +## * +## @file btm.h +## @brief btm service IPC wrapper. +## @note See also: https://switchbrew.org/wiki/BTM_services +## @author yellows8 +## + +import + ../types, ../kernel/event, ../services/btdrv_types, ../services/btm_types, + ../sf/service +proc btmInitialize*(): Result {.cdecl, importc: "btmInitialize".} +## / Initialize btm. + +proc btmExit*() {.cdecl, importc: "btmExit".} +## / Exit btm. + +proc btmGetServiceSession*(): ptr Service {.cdecl, importc: "btmGetServiceSession".} +## / Gets the Service object for the actual btm service session. + +proc btmGetState*(`out`: ptr BtmState): Result {.cdecl, importc: "btmGetState".} +## * +## @brief GetState +## @param[out] out \ref BtmState +## + +proc btmGetHostDeviceProperty*(`out`: ptr BtmHostDeviceProperty): Result {.cdecl, + importc: "btmGetHostDeviceProperty".} +## * +## @brief GetHostDeviceProperty +## @param[out] out \ref BtmHostDeviceProperty +## + +proc btmAcquireDeviceConditionEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireDeviceConditionEvent".} +## * +## @brief AcquireDeviceConditionEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmLegacyGetDeviceCondition*(`out`: ptr BtmDeviceCondition): Result {.cdecl, + importc: "btmLegacyGetDeviceCondition".} +## * +## @brief GetDeviceCondition [1.0.0-12.1.0] +## @param[out] out \ref BtmDeviceCondition +## + +proc btmGetDeviceCondition*(profile: BtmProfile; `out`: ptr BtmConnectedDeviceV13; + count: csize_t; totalOut: ptr S32): Result {.cdecl, + importc: "btmGetDeviceCondition".} +## * +## @brief GetDeviceCondition [13.0.0+] +## @param[in] profile \ref BtmProfile, when not ::BtmProfile_None entries are only returned which match this profile. +## @param[out] out \ref BtmConnectedDeviceV13 +## @param[in] count Size of the out array in entries. +## @param[out] total_out Total output entries. +## + +proc btmSetBurstMode*(`addr`: BtdrvAddress; flag: bool): Result {.cdecl, + importc: "btmSetBurstMode".} +## * +## @brief SetBurstMode +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## + +proc btmSetSlotMode*(list: ptr BtmDeviceSlotModeList): Result {.cdecl, + importc: "btmSetSlotMode".} +## * +## @brief SetSlotMode +## @param[in] list \ref BtmDeviceSlotModeList +## + +proc btmSetBluetoothMode*(mode: BtmBluetoothMode): Result {.cdecl, + importc: "btmSetBluetoothMode".} +## * +## @brief SetBluetoothMode +## @note Only available on pre-9.0.0. +## @param[in] mode \ref BtmBluetoothMode +## + +proc btmSetWlanMode*(mode: BtmWlanMode): Result {.cdecl, importc: "btmSetWlanMode".} +## * +## @brief SetWlanMode +## @param[in] mode \ref BtmWlanMode +## + +proc btmAcquireDeviceInfoEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireDeviceInfoEvent".} +## * +## @brief AcquireDeviceInfoEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmLegacyGetDeviceInfo*(`out`: ptr BtmDeviceInfoList): Result {.cdecl, + importc: "btmLegacyGetDeviceInfo".} +## * +## @brief GetDeviceInfo [1.0.0-12.1.0] +## @param[out] out \ref BtmDeviceInfoList +## + +proc btmGetDeviceInfo*(profile: BtmProfile; `out`: ptr BtmDeviceInfoV13; + count: csize_t; totalOut: ptr S32): Result {.cdecl, + importc: "btmGetDeviceInfo".} +## * +## @brief GetDeviceInfo [13.0.0+] +## @param[in] profile \ref BtmProfile, when not ::BtmProfile_None entries are only returned which match this profile. +## @param[out] out \ref BtmDeviceInfoV13 +## @param[in] count Size of the out array in entries. +## @param[out] total_out Total output entries. +## + +proc btmAddDeviceInfo*(info: ptr BtmDeviceInfo): Result {.cdecl, + importc: "btmAddDeviceInfo".} +## * +## @brief AddDeviceInfo +## @param[in] info \ref BtmDeviceInfo +## + +proc btmRemoveDeviceInfo*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btmRemoveDeviceInfo".} +## * +## @brief RemoveDeviceInfo +## @param[in] addr \ref BtdrvAddress +## + +proc btmIncreaseDeviceInfoOrder*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btmIncreaseDeviceInfoOrder".} +## * +## @brief IncreaseDeviceInfoOrder +## @param[in] addr \ref BtdrvAddress +## + +proc btmLlrNotify*(`addr`: BtdrvAddress; unk: S32): Result {.cdecl, + importc: "btmLlrNotify".} +## * +## @brief LlrNotify +## @param[in] addr \ref BtdrvAddress +## @param[in] unk [9.0.0+] Unknown +## + +proc btmEnableRadio*(): Result {.cdecl, importc: "btmEnableRadio".} +## * +## @brief EnableRadio +## + +proc btmDisableRadio*(): Result {.cdecl, importc: "btmDisableRadio".} +## * +## @brief DisableRadio +## + +proc btmHidDisconnect*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "btmHidDisconnect".} +## * +## @brief HidDisconnect +## @param[in] addr \ref BtdrvAddress +## + +proc btmHidSetRetransmissionMode*(`addr`: BtdrvAddress; + list: ptr BtmZeroRetransmissionList): Result {. + cdecl, importc: "btmHidSetRetransmissionMode".} +## * +## @brief HidSetRetransmissionMode +## @param[in] addr \ref BtdrvAddress +## @param[in] list \ref BtmZeroRetransmissionList +## + +proc btmAcquireAwakeReqEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireAwakeReqEvent".} +## * +## @brief AcquireAwakeReqEvent +## @note Only available on [2.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmAcquireLlrStateEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireLlrStateEvent".} +## * +## @brief AcquireLlrStateEvent +## @note Only available on [4.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmIsLlrStarted*(`out`: ptr bool): Result {.cdecl, importc: "btmIsLlrStarted".} +## * +## @brief IsLlrStarted +## @note Only available on [4.0.0+]. +## @param[out] out Output flag. +## + +proc btmEnableSlotSaving*(flag: bool): Result {.cdecl, importc: "btmEnableSlotSaving".} +## * +## @brief EnableSlotSaving +## @note Only available on [4.0.0+]. +## @param[in] flag Flag +## + +proc btmProtectDeviceInfo*(`addr`: BtdrvAddress; flag: bool): Result {.cdecl, + importc: "btmProtectDeviceInfo".} +## * +## @brief ProtectDeviceInfo +## @note Only available on [5.0.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Flag +## + +proc btmAcquireBleScanEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireBleScanEvent".} +## * +## @brief AcquireBleScanEvent +## @note Only available on [5.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmGetBleScanParameterGeneral*(parameterId: U16; + `out`: ptr BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmGetBleScanParameterGeneral".} +## * +## @brief GetBleScanParameterGeneral +## @note Only available on [5.1.0+]. +## @param[in] parameter_id Must be value 0x1 or 0xFFFF. +## @param[out] out \ref BtdrvBleAdvertisePacketParameter +## + +proc btmGetBleScanParameterSmartDevice*(parameterId: U16; + `out`: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btmGetBleScanParameterSmartDevice".} +## * +## @brief GetBleScanParameterSmartDevice +## @note Only available on [5.1.0+]. +## @param[in] parameter_id Must be value 0x2. +## @param[out] out \ref BtdrvGattAttributeUuid. The first 4-bytes is always 0. +## + +proc btmStartBleScanForGeneral*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmStartBleScanForGeneral".} +## * +## @brief StartBleScanForGeneral +## @note Only available on [5.1.0+]. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmStopBleScanForGeneral*(): Result {.cdecl, + importc: "btmStopBleScanForGeneral".} +## * +## @brief StopBleScanForGeneral +## @note Only available on [5.1.0+]. +## + +proc btmGetBleScanResultsForGeneral*(results: ptr BtdrvBleScanResult; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmGetBleScanResultsForGeneral".} +## * +## @brief GetBleScanResultsForGeneral +## @note Only available on [5.1.0+]. +## @param[out] results Output array of \ref BtdrvBleScanResult. +## @param[in] count Size of the results array in entries. The max is 10. +## @param[out] total_out Total output entries. +## + +proc btmStartBleScanForPaired*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmStartBleScanForPaired".} +## * +## @brief StartBleScanForPaired +## @note Only available on [5.1.0+]. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmStopBleScanForPaired*(): Result {.cdecl, importc: "btmStopBleScanForPaired".} +## * +## @brief StopBleScanForPaired +## @note Only available on [5.1.0+]. +## + +proc btmStartBleScanForSmartDevice*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btmStartBleScanForSmartDevice".} +## * +## @brief StartBleScanForSmartDevice +## @note Only available on [5.1.0+]. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btmStopBleScanForSmartDevice*(): Result {.cdecl, + importc: "btmStopBleScanForSmartDevice".} +## * +## @brief StopBleScanForSmartDevice +## @note Only available on [5.1.0+]. +## + +proc btmGetBleScanResultsForSmartDevice*(results: ptr BtdrvBleScanResult; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmGetBleScanResultsForSmartDevice".} +## * +## @brief GetBleScanResultsForSmartDevice +## @note Only available on [5.1.0+]. +## @param[out] results Output array of \ref BtdrvBleScanResult. +## @param[in] count Size of the results array in entries. The max is 10. +## @param[out] total_out Total output entries. +## + +proc btmAcquireBleConnectionEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireBleConnectionEvent".} +## * +## @brief AcquireBleConnectionEvent +## @note Only available on [5.1.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmBleConnect*(`addr`: BtdrvAddress): Result {.cdecl, importc: "btmBleConnect".} +## * +## @brief BleConnect +## @note Only available on [5.0.0+]. +## @note The \ref BtdrvAddress must not be already connected. A maximum of 4 devices can be connected. +## @param[in] addr \ref BtdrvAddress +## + +proc btmBleOverrideConnection*(id: U32): Result {.cdecl, + importc: "btmBleOverrideConnection".} +## * +## @brief BleOverrideConnection +## @note Only available on [5.1.0+]. +## @param[in] id Same as \ref btmBleDisconnect. +## + +proc btmBleDisconnect*(connectionHandle: U32): Result {.cdecl, + importc: "btmBleDisconnect".} +## * +## @brief BleDisconnect +## @note Only available on [5.0.0+]. +## @param[in] connection_handle This must match a BtdrvBleConnectionInfo::id from \ref btmBleGetConnectionState. [5.1.0+] 0xFFFFFFFF is invalid. +## + +proc btmBleGetConnectionState*(info: ptr BtdrvBleConnectionInfo; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmBleGetConnectionState".} +## * +## @brief BleGetConnectionState +## @note Only available on [5.0.0+]. +## @param[out] info Output array of \ref BtdrvBleConnectionInfo. +## @param[in] count Size of the info array in entries. Other cmds which use this internally use count=4. +## @param[out] total_out Total output entries. +## + +proc btmBleGetGattClientConditionList*(list: ptr BtmGattClientConditionList): Result {. + cdecl, importc: "btmBleGetGattClientConditionList".} +## * +## @brief BleGetGattClientConditionList +## @note Only available on [5.0.0+]. +## @param[out] list \ref BtmGattClientConditionList +## + +proc btmAcquireBlePairingEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireBlePairingEvent".} +## * +## @brief AcquireBlePairingEvent +## @note Only available on [5.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmBlePairDevice*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btmBlePairDevice".} +## * +## @brief BlePairDevice +## @note Only available on [5.1.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmBleUnpairDeviceOnBoth*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmBleUnpairDeviceOnBoth".} +## * +## @brief BleUnpairDeviceOnBoth +## @note Only available on [5.1.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmBleUnPairDevice*(`addr`: BtdrvAddress; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btmBleUnPairDevice".} +## * +## @brief BleUnPairDevice +## @note Only available on [5.1.0+]. +## @param[in] addr \ref BtdrvAddress +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmBleGetPairedAddresses*(param: BtdrvBleAdvertisePacketParameter; + addrs: ptr BtdrvAddress; count: U8; totalOut: ptr U8): Result {. + cdecl, importc: "btmBleGetPairedAddresses".} +## * +## @brief BleGetPairedAddresses +## @note Only available on [5.1.0+]. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## @param[out] addrs Output array of \ref BtdrvAddress. +## @param[in] count Size of the addrs array in entries. +## @param[out] total_out Total output entries. The max is 10. +## + +proc btmAcquireBleServiceDiscoveryEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireBleServiceDiscoveryEvent".} +## * +## @brief AcquireBleServiceDiscoveryEvent +## @note Only available on [5.1.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmGetGattServices*(connectionHandle: U32; services: ptr BtmGattService; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btmGetGattServices".} +## * +## @brief GetGattServices +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[out] services Output array of \ref BtmGattService. +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmGetGattService*(connectionHandle: U32; uuid: ptr BtdrvGattAttributeUuid; + service: ptr BtmGattService; flag: ptr bool): Result {.cdecl, + importc: "btmGetGattService".} +## * +## @brief Same as \ref btmGetGattServices except this only returns the \ref BtmGattService which matches the input \ref BtdrvGattAttributeUuid. +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] service \ref BtmGattService +## @param[out] flag Whether a \ref BtmGattService was returned. +## + +proc btmGetGattIncludedServices*(connectionHandle: U32; serviceHandle: U16; + services: ptr BtmGattService; count: U8; + `out`: ptr U8): Result {.cdecl, + importc: "btmGetGattIncludedServices".} +## * +## @brief Same as \ref btmGetGattServices except this only returns \ref BtmGattService entries where various checks pass with u16 fields. +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] service_handle ServiceHandle +## @param[out] services \ref BtmGattService +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] out Output value. +## + +proc btmGetBelongingService*(connectionHandle: U32; attributeHandle: U16; + service: ptr BtmGattService; flag: ptr bool): Result {. + cdecl, importc: "btmGetBelongingService".} +## * +## @brief This is similar to \ref btmGetGattIncludedServices except this only returns 1 \ref BtmGattService. +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] attribute_handle AttributeHandle +## @param[out] service \ref BtmGattService +## @param[out] flag Whether a \ref BtmGattService was returned. +## + +proc btmGetGattCharacteristics*(connectionHandle: U32; serviceHandle: U16; + characteristics: ptr BtmGattCharacteristic; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btmGetGattCharacteristics".} +## * +## @brief GetGattCharacteristics +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] service_handle This controls which \ref BtmGattCharacteristic entries to return. +## @param[out] characteristics \ref BtmGattCharacteristic +## @param[in] count Size of the characteristics array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmGetGattDescriptors*(connectionHandle: U32; charHandle: U16; + descriptors: ptr BtmGattDescriptor; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmGetGattDescriptors".} +## * +## @brief GetGattDescriptors +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] char_handle Characteristic handle. This controls which \ref BtmGattDescriptor entries to return. +## @param[out] descriptors \ref BtmGattDescriptor +## @param[in] count Size of the descriptors array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmAcquireBleMtuConfigEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmAcquireBleMtuConfigEvent".} +## * +## @brief AcquireBleMtuConfigEvent +## @note Only available on [5.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmConfigureBleMtu*(connectionHandle: U32; mtu: U16): Result {.cdecl, + importc: "btmConfigureBleMtu".} +## * +## @brief ConfigureBleMtu +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[in] mtu MTU +## + +proc btmGetBleMtu*(connectionHandle: U32; `out`: ptr U16): Result {.cdecl, + importc: "btmGetBleMtu".} +## * +## @brief GetBleMtu +## @note Only available on [5.0.0+]. +## @param[in] connection_handle Same as \ref btmBleDisconnect. +## @param[out] out Output MTU. +## + +proc btmRegisterBleGattDataPath*(path: ptr BtmBleDataPath): Result {.cdecl, + importc: "btmRegisterBleGattDataPath".} +## * +## @brief RegisterBleGattDataPath +## @note Only available on [5.0.0+]. +## @param[in] path \ref BtmBleDataPath +## + +proc btmUnregisterBleGattDataPath*(path: ptr BtmBleDataPath): Result {.cdecl, + importc: "btmUnregisterBleGattDataPath".} +## * +## @brief UnregisterBleGattDataPath +## @note Only available on [5.0.0+]. +## @param[in] path \ref BtmBleDataPath +## + +proc btmRegisterAppletResourceUserId*(appletResourceUserId: U64; unk: U32): Result {. + cdecl, importc: "btmRegisterAppletResourceUserId".} +## * +## @brief RegisterAppletResourceUserId +## @note Only available on [5.0.0+]. +## @param[in] AppletResourceUserId AppletResourceUserId +## @param[in] unk Unknown +## + +proc btmUnregisterAppletResourceUserId*(appletResourceUserId: U64): Result {.cdecl, + importc: "btmUnregisterAppletResourceUserId".} +## * +## @brief UnregisterAppletResourceUserId +## @note Only available on [5.0.0+]. +## @param[in] AppletResourceUserId AppletResourceUserId +## + +proc btmSetAppletResourceUserId*(appletResourceUserId: U64): Result {.cdecl, + importc: "btmSetAppletResourceUserId".} +## * +## @brief SetAppletResourceUserId +## @note Only available on [5.0.0+]. +## @param[in] AppletResourceUserId AppletResourceUserId +## + diff --git a/src/libnx/wrapper/switch/services/btm_types.h b/src/libnx/wrapper/switch/services/btm_types.h new file mode 100644 index 0000000..078c790 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btm_types.h @@ -0,0 +1,299 @@ +/** + * @file btm_types.h + * @brief btm service types. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// BtmState +typedef enum { + BtmState_NotInitialized = 0, ///< NotInitialized + BtmState_RadioOff = 1, ///< RadioOff + BtmState_MinorSlept = 2, ///< MinorSlept + BtmState_RadioOffMinorSlept = 3, ///< RadioOffMinorSlept + BtmState_Slept = 4, ///< Slept + BtmState_RadioOffSlept = 5, ///< RadioOffSlept + BtmState_Initialized = 6, ///< Initialized + BtmState_Working = 7, ///< Working +} BtmState; + +/// BluetoothMode +typedef enum { + BtmBluetoothMode_Dynamic2Slot = 0, ///< Dynamic2Slot + BtmBluetoothMode_StaticJoy = 1, ///< StaticJoy +} BtmBluetoothMode; + +/// WlanMode +typedef enum { + BtmWlanMode_Local4 = 0, ///< Local4 + BtmWlanMode_Local8 = 1, ///< Local8 + BtmWlanMode_None = 2, ///< None +} BtmWlanMode; + +/// TsiMode +typedef enum { + BtmTsiMode_0Fd3Td3Si10 = 0, ///< 0Fd3Td3Si10 + BtmTsiMode_1Fd1Td1Si5 = 1, ///< 1Fd1Td1Si5 + BtmTsiMode_2Fd1Td3Si10 = 2, ///< 2Fd1Td3Si10 + BtmTsiMode_3Fd1Td5Si15 = 3, ///< 3Fd1Td5Si15 + BtmTsiMode_4Fd3Td1Si10 = 4, ///< 4Fd3Td1Si10 + BtmTsiMode_5Fd3Td3Si15 = 5, ///< 5Fd3Td3Si15 + BtmTsiMode_6Fd5Td1Si15 = 6, ///< 6Fd5Td1Si15 + BtmTsiMode_7Fd1Td3Si15 = 7, ///< 7Fd1Td3Si15 + BtmTsiMode_8Fd3Td1Si15 = 8, ///< 8Fd3Td1Si15 + BtmTsiMode_9Fd1Td1Si10 = 9, ///< 9Fd1Td1Si10 + BtmTsiMode_10Fd1Td1Si15 = 10, ///< 10Fd1Td1Si15 + BtmTsiMode_Active = 255, ///< Active +} BtmTsiMode; + +/// SlotMode +typedef enum { + BtmSlotMode_2 = 0, ///< 2 + BtmSlotMode_4 = 1, ///< 4 + BtmSlotMode_6 = 2, ///< 6 + BtmSlotMode_Active = 3, ///< Active +} BtmSlotMode; + +/// Profile +typedef enum { + BtmProfile_None = 0, ///< None + BtmProfile_Hid = 1, ///< Hid +} BtmProfile; + +/// BdName +typedef struct { + char name[0x20]; ///< Name string. +} BtmBdName; + +/// ClassOfDevice +typedef struct { + u8 class_of_device[0x3]; ///< ClassOfDevice +} BtmClassOfDevice; + +/// LinkKey +typedef struct { + u8 link_key[0x10]; ///< LinkKey +} BtmLinkKey; + +/// HidDeviceInfo +typedef struct { + u16 vid; ///< Vid + u16 pid; ///< Pid +} BtmHidDeviceInfo; + +/// HostDeviceProperty +typedef struct { + union { + struct { + BtdrvAddress addr; ///< Same as BtdrvAdapterProperty::addr. + BtmClassOfDevice class_of_device; ///< Same as BtdrvAdapterProperty::class_of_device. + BtmBdName name; ///< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + u8 feature_set; ///< Same as BtdrvAdapterProperty::feature_set. + } v1; ///< [1.0.0-12.1.0] + + struct { + BtdrvAddress addr; ///< Same as BtdrvAdapterProperty::addr. + BtmClassOfDevice class_of_device; ///< Same as BtdrvAdapterProperty::class_of_device. + char name[0xF9]; ///< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + u8 feature_set; ///< Same as BtdrvAdapterProperty::feature_set. + } v13; ///< [13.0.0+] + }; +} BtmHostDeviceProperty; + +/// BtmConnectedDevice [1.0.0-12.1.0] +typedef struct { + BtdrvAddress address; + u8 pad[2]; + u32 unk_x8; + char name[0x20]; + u8 unk_x2C[0x1C]; + u16 vid; + u16 pid; + u8 unk_x4C[0x20]; +} BtmConnectedDeviceV1; + +/// BtmConnectedDevice [13.0.0+] +typedef struct { + BtdrvAddress address; + u8 pad[2]; + u32 profile; ///< \ref BtmProfile + u8 unk_xC[0x40]; + char name[0x20]; + u8 unk_x6C[0xD9]; + u8 pad2[3]; +} BtmConnectedDeviceV13; + +/// DeviceCondition [1.0.0-5.0.2] +typedef struct { + u32 unk_x0; + u32 unk_x4; + u8 unk_x8; + u8 unk_x9; + u8 max_count; + u8 connected_count; + BtmConnectedDeviceV1 devices[8]; +} BtmDeviceConditionV100; + +/// DeviceCondition [5.1.0-7.0.1] +typedef struct { + u32 unk_x0; + u32 unk_x4; + u8 unk_x8; + u8 unk_x9[2]; + u8 max_count; + u8 connected_count; + u8 pad[3]; + BtmConnectedDeviceV1 devices[8]; +} BtmDeviceConditionV510; + +/// DeviceCondition [8.0.0-8.1.1] +typedef struct { + u32 unk_x0; + u32 unk_x4; + u8 unk_x8; + u8 unk_x9; + u8 max_count; + u8 connected_count; + BtmConnectedDeviceV1 devices[8]; +} BtmDeviceConditionV800; + +/// DeviceCondition [9.0.0-12.1.0] +typedef struct { + u32 unk_x0; + u8 unk_x4; + u8 unk_x5; + u8 max_count; + u8 connected_count; + BtmConnectedDeviceV1 devices[8]; +} BtmDeviceConditionV900; + +/// DeviceCondition [1.0.0-12.1.0] +typedef union { + BtmDeviceConditionV100 v100; + BtmDeviceConditionV510 v510; + BtmDeviceConditionV800 v800; + BtmDeviceConditionV900 v900; +} BtmDeviceCondition; + +/// DeviceSlotMode +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + u8 reserved[2]; ///< Reserved + u32 slot_mode; ///< \ref BtmSlotMode +} BtmDeviceSlotMode; + +/// DeviceSlotModeList +typedef struct { + u8 device_count; ///< DeviceCount + u8 reserved[3]; ///< Reserved + BtmDeviceSlotMode devices[8]; ///< Array of \ref BtmDeviceSlotMode with the above count. +} BtmDeviceSlotModeList; + +/// DeviceInfo [1.0.0-12.1.0] +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + BtmClassOfDevice class_of_device; ///< ClassOfDevice + BtmBdName name; ///< BdName + BtmLinkKey link_key; ///< LinkKey + u8 reserved[3]; ///< Reserved + u32 profile; ///< \ref BtmProfile + union { + u8 data[0x4]; ///< Empty (Profile = None) + BtmHidDeviceInfo hid_device_info; ///< \ref BtmHidDeviceInfo (Profile = Hid) + } profile_info; + u8 reserved2[0x1C]; ///< Reserved +} BtmDeviceInfoV1; + +/// DeviceInfo [13.0.0+] +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + BtmClassOfDevice class_of_device; ///< ClassOfDevice + BtmLinkKey link_key; ///< LinkKey + u8 reserved[3]; ///< Reserved + u32 profile; ///< \ref BtmProfile + union { + u8 data[0x4]; ///< Empty (Profile = None) + BtmHidDeviceInfo hid_device_info; ///< \ref BtmHidDeviceInfo (Profile = Hid) + } profile_info; + u8 reserved2[0x1C]; ///< Reserved + char name[0xF9]; ///< Name + u8 pad[3]; ///< Padding +} BtmDeviceInfoV13; + +/// DeviceInfo [1.0.0-13.0.0] +typedef union { + BtmDeviceInfoV1 v1; + BtmDeviceInfoV13 v13; +} BtmDeviceInfo; + +/// DeviceInfoList +typedef struct { + u8 device_count; ///< DeviceCount + u8 reserved[3]; ///< Reserved + BtmDeviceInfoV1 devices[10]; ///< Array of \ref BtmDeviceInfoV1 with the above count. +} BtmDeviceInfoList; + +/// DeviceProperty +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + BtmClassOfDevice class_of_device; ///< ClassOfDevice + BtmBdName name; ///< BdName +} BtmDeviceProperty; + +/// DevicePropertyList +typedef struct { + u8 device_count; ///< DeviceCount + BtmDeviceProperty devices[15]; ///< Array of \ref BtmDeviceProperty. +} BtmDevicePropertyList; + +/// ZeroRetransmissionList +typedef struct { + u8 enabled_report_id_count; ///< EnabledReportIdCount + u8 enabled_report_id[0x10]; ///< Array of EnabledReportId. +} BtmZeroRetransmissionList; + +/// GattClientConditionList +typedef struct { + u8 unk_x0[0x74]; ///< Unknown +} BtmGattClientConditionList; + +/// GattService +typedef struct { + u8 unk_x0[0x4]; ///< Unknown + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid + u16 handle; ///< Handle + u8 unk_x1A[0x2]; ///< Unknown + u16 instance_id; ///< InstanceId + u16 end_group_handle; ///< EndGroupHandle + u8 primary_service; ///< PrimaryService + u8 pad[3]; ///< Padding +} BtmGattService; + +/// GattCharacteristic +typedef struct { + u8 unk_x0[0x4]; ///< Unknown + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid + u16 handle; ///< Handle + u8 unk_x1A[0x2]; ///< Unknown + u16 instance_id; ///< InstanceId + u8 properties; ///< Properties + u8 unk_x1F[0x5]; ///< Unknown +} BtmGattCharacteristic; + +/// GattDescriptor +typedef struct { + u8 unk_x0[0x4]; ///< Unknown + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid + u16 handle; ///< Handle + u8 unk_x1A[0x6]; ///< Unknown +} BtmGattDescriptor; + +/// BleDataPath +typedef struct { + u8 unk_x0; ///< Unknown + u8 pad[3]; ///< Padding + BtdrvGattAttributeUuid uuid; ///< \ref BtdrvGattAttributeUuid +} BtmBleDataPath; + diff --git a/src/libnx/wrapper/switch/services/btm_types.nim b/src/libnx/wrapper/switch/services/btm_types.nim new file mode 100644 index 0000000..a639f63 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btm_types.nim @@ -0,0 +1,367 @@ +## * +## @file btm_types.h +## @brief btm service types. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, btdrv_types + +## / BtmState + +type + BtmState* = enum + BtmStateNotInitialized = 0, ## /< NotInitialized + BtmStateRadioOff = 1, ## /< RadioOff + BtmStateMinorSlept = 2, ## /< MinorSlept + BtmStateRadioOffMinorSlept = 3, ## /< RadioOffMinorSlept + BtmStateSlept = 4, ## /< Slept + BtmStateRadioOffSlept = 5, ## /< RadioOffSlept + BtmStateInitialized = 6, ## /< Initialized + BtmStateWorking = 7 ## /< Working + + +## / BluetoothMode + +type + BtmBluetoothMode* = enum + BtmBluetoothModeDynamic2Slot = 0, ## /< Dynamic2Slot + BtmBluetoothModeStaticJoy = 1 ## /< StaticJoy + + +## / WlanMode + +type + BtmWlanMode* = enum + BtmWlanModeLocal4 = 0, ## /< Local4 + BtmWlanModeLocal8 = 1, ## /< Local8 + BtmWlanModeNone = 2 ## /< None + + +## / TsiMode + +type + BtmTsiMode* = enum + BtmTsiMode0Fd3Td3Si10 = 0, ## /< 0Fd3Td3Si10 + BtmTsiMode1Fd1Td1Si5 = 1, ## /< 1Fd1Td1Si5 + BtmTsiMode2Fd1Td3Si10 = 2, ## /< 2Fd1Td3Si10 + BtmTsiMode3Fd1Td5Si15 = 3, ## /< 3Fd1Td5Si15 + BtmTsiMode4Fd3Td1Si10 = 4, ## /< 4Fd3Td1Si10 + BtmTsiMode5Fd3Td3Si15 = 5, ## /< 5Fd3Td3Si15 + BtmTsiMode6Fd5Td1Si15 = 6, ## /< 6Fd5Td1Si15 + BtmTsiMode7Fd1Td3Si15 = 7, ## /< 7Fd1Td3Si15 + BtmTsiMode8Fd3Td1Si15 = 8, ## /< 8Fd3Td1Si15 + BtmTsiMode9Fd1Td1Si10 = 9, ## /< 9Fd1Td1Si10 + BtmTsiMode10Fd1Td1Si15 = 10, ## /< 10Fd1Td1Si15 + BtmTsiModeActive = 255 ## /< Active + + +## / SlotMode + +type + BtmSlotMode* = enum + BtmSlotMode2 = 0, ## /< 2 + BtmSlotMode4 = 1, ## /< 4 + BtmSlotMode6 = 2, ## /< 6 + BtmSlotModeActive = 3 ## /< Active + + +## / Profile + +type + BtmProfile* = enum + BtmProfileNone = 0, ## /< None + BtmProfileHid = 1 ## /< Hid + + +## / BdName + +type + BtmBdName* {.bycopy.} = object + name*: array[0x20, char] ## /< Name string. + + +## / ClassOfDevice + +type + BtmClassOfDevice* {.bycopy.} = object + classOfDevice*: array[0x3, U8] ## /< ClassOfDevice + + +## / LinkKey + +type + BtmLinkKey* {.bycopy.} = object + linkKey*: array[0x10, U8] ## /< LinkKey + + +## / HidDeviceInfo + +type + BtmHidDeviceInfo* {.bycopy.} = object + vid*: U16 ## /< Vid + pid*: U16 ## /< Pid + + +## / HostDeviceProperty + +type + INNER_C_STRUCT_btm_types_5* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Same as BtdrvAdapterProperty::addr. + classOfDevice*: BtmClassOfDevice ## /< Same as BtdrvAdapterProperty::class_of_device. + name*: BtmBdName ## /< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + featureSet*: U8 ## /< Same as BtdrvAdapterProperty::feature_set. + + INNER_C_STRUCT_btm_types_6* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< Same as BtdrvAdapterProperty::addr. + classOfDevice*: BtmClassOfDevice ## /< Same as BtdrvAdapterProperty::class_of_device. + name*: array[0xF9, char] ## /< Same as BtdrvAdapterProperty::name (except the last byte which is always zero). + featureSet*: U8 ## /< Same as BtdrvAdapterProperty::feature_set. + + INNER_C_UNION_btm_types_4* {.bycopy, union.} = object + v1*: INNER_C_STRUCT_btm_types_5 ## /< [1.0.0-12.1.0] + v13*: INNER_C_STRUCT_btm_types_6 ## /< [13.0.0+] + + BtmHostDeviceProperty* {.bycopy.} = object + anoBtmTypes7*: INNER_C_UNION_btm_types_4 + + +## / BtmConnectedDevice [1.0.0-12.1.0] + +type + BtmConnectedDeviceV1* {.bycopy.} = object + address*: BtdrvAddress + pad*: array[2, U8] + unkX8*: U32 + name*: array[0x20, char] + unkX2C*: array[0x1C, U8] + vid*: U16 + pid*: U16 + unkX4C*: array[0x20, U8] + + +## / BtmConnectedDevice [13.0.0+] + +type + BtmConnectedDeviceV13* {.bycopy.} = object + address*: BtdrvAddress + pad*: array[2, U8] + profile*: U32 ## /< \ref BtmProfile + unkXC*: array[0x40, U8] + name*: array[0x20, char] + unkX6C*: array[0xD9, U8] + pad2*: array[3, U8] + + +## / DeviceCondition [1.0.0-5.0.2] + +type + BtmDeviceConditionV100* {.bycopy.} = object + unkX0*: U32 + unkX4*: U32 + unkX8*: U8 + unkX9*: U8 + maxCount*: U8 + connectedCount*: U8 + devices*: array[8, BtmConnectedDeviceV1] + + +## / DeviceCondition [5.1.0-7.0.1] + +type + BtmDeviceConditionV510* {.bycopy.} = object + unkX0*: U32 + unkX4*: U32 + unkX8*: U8 + unkX9*: array[2, U8] + maxCount*: U8 + connectedCount*: U8 + pad*: array[3, U8] + devices*: array[8, BtmConnectedDeviceV1] + + +## / DeviceCondition [8.0.0-8.1.1] + +type + BtmDeviceConditionV800* {.bycopy.} = object + unkX0*: U32 + unkX4*: U32 + unkX8*: U8 + unkX9*: U8 + maxCount*: U8 + connectedCount*: U8 + devices*: array[8, BtmConnectedDeviceV1] + + +## / DeviceCondition [9.0.0-12.1.0] + +type + BtmDeviceConditionV900* {.bycopy.} = object + unkX0*: U32 + unkX4*: U8 + unkX5*: U8 + maxCount*: U8 + connectedCount*: U8 + devices*: array[8, BtmConnectedDeviceV1] + + +## / DeviceCondition [1.0.0-12.1.0] + +type + BtmDeviceCondition* {.bycopy, union.} = object + v100*: BtmDeviceConditionV100 + v510*: BtmDeviceConditionV510 + v800*: BtmDeviceConditionV800 + v900*: BtmDeviceConditionV900 + + +## / DeviceSlotMode + +type + BtmDeviceSlotMode* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + reserved*: array[2, U8] ## /< Reserved + slotMode*: U32 ## /< \ref BtmSlotMode + + +## / DeviceSlotModeList + +type + BtmDeviceSlotModeList* {.bycopy.} = object + deviceCount*: U8 ## /< DeviceCount + reserved*: array[3, U8] ## /< Reserved + devices*: array[8, BtmDeviceSlotMode] ## /< Array of \ref BtmDeviceSlotMode with the above count. + + +## / DeviceInfo [1.0.0-12.1.0] + +type + INNER_C_UNION_btm_types_9* {.bycopy, union.} = object + data*: array[0x4, U8] ## /< Empty (Profile = None) + hidDeviceInfo*: BtmHidDeviceInfo ## /< \ref BtmHidDeviceInfo (Profile = Hid) + + BtmDeviceInfoV1* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + classOfDevice*: BtmClassOfDevice ## /< ClassOfDevice + name*: BtmBdName ## /< BdName + linkKey*: BtmLinkKey ## /< LinkKey + reserved*: array[3, U8] ## /< Reserved + profile*: U32 ## /< \ref BtmProfile + profileInfo*: INNER_C_UNION_btm_types_9 + reserved2*: array[0x1C, U8] ## /< Reserved + + +## / DeviceInfo [13.0.0+] + +type + INNER_C_UNION_btm_types_11* {.bycopy, union.} = object + data*: array[0x4, U8] ## /< Empty (Profile = None) + hidDeviceInfo*: BtmHidDeviceInfo ## /< \ref BtmHidDeviceInfo (Profile = Hid) + + BtmDeviceInfoV13* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + classOfDevice*: BtmClassOfDevice ## /< ClassOfDevice + linkKey*: BtmLinkKey ## /< LinkKey + reserved*: array[3, U8] ## /< Reserved + profile*: U32 ## /< \ref BtmProfile + profileInfo*: INNER_C_UNION_btm_types_11 + reserved2*: array[0x1C, U8] ## /< Reserved + name*: array[0xF9, char] ## /< Name + pad*: array[3, U8] ## /< Padding + + +## / DeviceInfo [1.0.0-13.0.0] + +type + BtmDeviceInfo* {.bycopy, union.} = object + v1*: BtmDeviceInfoV1 + v13*: BtmDeviceInfoV13 + + +## / DeviceInfoList + +type + BtmDeviceInfoList* {.bycopy.} = object + deviceCount*: U8 ## /< DeviceCount + reserved*: array[3, U8] ## /< Reserved + devices*: array[10, BtmDeviceInfoV1] ## /< Array of \ref BtmDeviceInfoV1 with the above count. + + +## / DeviceProperty + +type + BtmDeviceProperty* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + classOfDevice*: BtmClassOfDevice ## /< ClassOfDevice + name*: BtmBdName ## /< BdName + + +## / DevicePropertyList + +type + BtmDevicePropertyList* {.bycopy.} = object + deviceCount*: U8 ## /< DeviceCount + devices*: array[15, BtmDeviceProperty] ## /< Array of \ref BtmDeviceProperty. + + +## / ZeroRetransmissionList + +type + BtmZeroRetransmissionList* {.bycopy.} = object + enabledReportIdCount*: U8 ## /< EnabledReportIdCount + enabledReportId*: array[0x10, U8] ## /< Array of EnabledReportId. + + +## / GattClientConditionList + +type + BtmGattClientConditionList* {.bycopy.} = object + unkX0*: array[0x74, U8] ## /< Unknown + + +## / GattService + +type + BtmGattService* {.bycopy.} = object + unkX0*: array[0x4, U8] ## /< Unknown + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + handle*: U16 ## /< Handle + unkX1A*: array[0x2, U8] ## /< Unknown + instanceId*: U16 ## /< InstanceId + endGroupHandle*: U16 ## /< EndGroupHandle + primaryService*: U8 ## /< PrimaryService + pad*: array[3, U8] ## /< Padding + + +## / GattCharacteristic + +type + BtmGattCharacteristic* {.bycopy.} = object + unkX0*: array[0x4, U8] ## /< Unknown + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + handle*: U16 ## /< Handle + unkX1A*: array[0x2, U8] ## /< Unknown + instanceId*: U16 ## /< InstanceId + properties*: U8 ## /< Properties + unkX1F*: array[0x5, U8] ## /< Unknown + + +## / GattDescriptor + +type + BtmGattDescriptor* {.bycopy.} = object + unkX0*: array[0x4, U8] ## /< Unknown + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + handle*: U16 ## /< Handle + unkX1A*: array[0x6, U8] ## /< Unknown + + +## / BleDataPath + +type + BtmBleDataPath* {.bycopy.} = object + unkX0*: U8 ## /< Unknown + pad*: array[3, U8] ## /< Padding + uuid*: BtdrvGattAttributeUuid ## /< \ref BtdrvGattAttributeUuid + diff --git a/src/libnx/wrapper/switch/services/btmsys.h b/src/libnx/wrapper/switch/services/btmsys.h new file mode 100644 index 0000000..ee9af1d --- /dev/null +++ b/src/libnx/wrapper/switch/services/btmsys.h @@ -0,0 +1,82 @@ +/** + * @file btmsys.h + * @brief btm:sys (btm system) service IPC wrapper. + * @author yellows8 + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +/// Initialize btm:sys. +Result btmsysInitialize(void); + +/// Exit btm:sys. +void btmsysExit(void); + +/// Gets the Service object for the actual btm:sys service session. This object must be closed by the user once finished using cmds with this. +Result btmsysGetServiceSession(Service* srv_out); + +/// Gets the Service object for IBtmSystemCore. +Service* btmsysGetServiceSession_IBtmSystemCore(void); + +/** + * @brief StartGamepadPairing + */ +Result btmsysStartGamepadPairing(void); + +/** + * @brief CancelGamepadPairing + */ +Result btmsysCancelGamepadPairing(void); + +/** + * @brief ClearGamepadPairingDatabase + */ +Result btmsysClearGamepadPairingDatabase(void); + +/** + * @brief GetPairedGamepadCount + * @param[out] out Output count. + */ +Result btmsysGetPairedGamepadCount(u8 *out); + +/** + * @brief EnableRadio + */ +Result btmsysEnableRadio(void); + +/** + * @brief DisableRadio + */ +Result btmsysDisableRadio(void); + +/** + * @brief GetRadioOnOff + * @param[out] out Output flag. + */ +Result btmsysGetRadioOnOff(bool *out); + +/** + * @brief AcquireRadioEvent + * @note Only available on [3.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 btmsysAcquireRadioEvent(Event* out_event); + +/** + * @brief AcquireGamepadPairingEvent + * @note Only available on [3.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 btmsysAcquireGamepadPairingEvent(Event* out_event); + +/** + * @brief IsGamepadPairingStarted + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result btmsysIsGamepadPairingStarted(bool *out); + diff --git a/src/libnx/wrapper/switch/services/btmsys.nim b/src/libnx/wrapper/switch/services/btmsys.nim new file mode 100644 index 0000000..3004973 --- /dev/null +++ b/src/libnx/wrapper/switch/services/btmsys.nim @@ -0,0 +1,91 @@ +## * +## @file btmsys.h +## @brief btm:sys (btm system) service IPC wrapper. +## @author yellows8 +## + +import + ../types, ../kernel/event, ../sf/service + +## / Initialize btm:sys. + +proc btmsysInitialize*(): Result {.cdecl, importc: "btmsysInitialize".} +## / Exit btm:sys. + +proc btmsysExit*() {.cdecl, importc: "btmsysExit".} +## / Gets the Service object for the actual btm:sys service session. This object must be closed by the user once finished using cmds with this. + +proc btmsysGetServiceSession*(srvOut: ptr Service): Result {.cdecl, + importc: "btmsysGetServiceSession".} +## / Gets the Service object for IBtmSystemCore. + +proc btmsysGetServiceSessionIBtmSystemCore*(): ptr Service {.cdecl, + importc: "btmsysGetServiceSession_IBtmSystemCore".} +## * +## @brief StartGamepadPairing +## + +proc btmsysStartGamepadPairing*(): Result {.cdecl, + importc: "btmsysStartGamepadPairing".} +## * +## @brief CancelGamepadPairing +## + +proc btmsysCancelGamepadPairing*(): Result {.cdecl, + importc: "btmsysCancelGamepadPairing".} +## * +## @brief ClearGamepadPairingDatabase +## + +proc btmsysClearGamepadPairingDatabase*(): Result {.cdecl, + importc: "btmsysClearGamepadPairingDatabase".} +## * +## @brief GetPairedGamepadCount +## @param[out] out Output count. +## + +proc btmsysGetPairedGamepadCount*(`out`: ptr U8): Result {.cdecl, + importc: "btmsysGetPairedGamepadCount".} +## * +## @brief EnableRadio +## + +proc btmsysEnableRadio*(): Result {.cdecl, importc: "btmsysEnableRadio".} +## * +## @brief DisableRadio +## + +proc btmsysDisableRadio*(): Result {.cdecl, importc: "btmsysDisableRadio".} +## * +## @brief GetRadioOnOff +## @param[out] out Output flag. +## + +proc btmsysGetRadioOnOff*(`out`: ptr bool): Result {.cdecl, + importc: "btmsysGetRadioOnOff".} +## * +## @brief AcquireRadioEvent +## @note Only available on [3.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmsysAcquireRadioEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmsysAcquireRadioEvent".} +## * +## @brief AcquireGamepadPairingEvent +## @note Only available on [3.0.0+]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmsysAcquireGamepadPairingEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmsysAcquireGamepadPairingEvent".} +## * +## @brief IsGamepadPairingStarted +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc btmsysIsGamepadPairingStarted*(`out`: ptr bool): Result {.cdecl, + importc: "btmsysIsGamepadPairingStarted".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/btmu.h b/src/libnx/wrapper/switch/services/btmu.h new file mode 100644 index 0000000..04a70cf --- /dev/null +++ b/src/libnx/wrapper/switch/services/btmu.h @@ -0,0 +1,290 @@ +/** + * @file btmu.h + * @brief btm:u (btm user) service IPC wrapper. + * @note Only available on [5.0.0+]. + * @note See also btdev. + * @note See also: https://switchbrew.org/wiki/BTM_services + * @author yellows8 + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/btdrv_types.h" +#include "../services/btm.h" +#include "../sf/service.h" + +/// Initialize btm:u. +Result btmuInitialize(void); + +/// Exit btm:u. +void btmuExit(void); + +/// Gets the Service object for the actual btm:u service session. This object must be closed by the user once finished using cmds with this. +Result btmuGetServiceSession(Service* srv_out); + +/// Gets the Service object for IBtmUserCore. +Service* btmuGetServiceSession_IBtmUserCore(void); + +/** + * @brief AcquireBleScanEvent + * @note This is similar to \ref btmAcquireBleScanEvent. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmuAcquireBleScanEvent(Event* out_event); + +/** + * @brief GetBleScanFilterParameter + * @note This is the same as \ref btmGetBleScanParameterGeneral. + * @param[in] parameter_id Must be value 0x1 or 0xFFFF. + * @param[out] out \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuGetBleScanFilterParameter(u16 parameter_id, BtdrvBleAdvertisePacketParameter *out); + +/** + * @brief GetBleScanFilterParameter2 + * @note This is the same as \ref btmGetBleScanParameterSmartDevice. + * @param[in] parameter_id Must be value 0x2. + * @param[out] out \ref BtdrvGattAttributeUuid. The first 4-bytes is always 0. + */ +Result btmuGetBleScanFilterParameter2(u16 parameter_id, BtdrvGattAttributeUuid *out); + +/** + * @brief StartBleScanForGeneral + * @note This is similar to \ref btmStartBleScanForGeneral. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuStartBleScanForGeneral(BtdrvBleAdvertisePacketParameter param); + +/** + * @brief StopBleScanForGeneral + * @note This is similar to \ref btmStopBleScanForGeneral. + */ +Result btmuStopBleScanForGeneral(void); + +/** + * @brief GetBleScanResultsForGeneral + * @note This is similar to \ref btmGetBleScanResultsForGeneral. + * @param[out] results Output array of \ref BtdrvBleScanResult. + * @param[in] count Size of the results array in entries. The max is 10. + * @param[out] total_out Total output entries. + */ +Result btmuGetBleScanResultsForGeneral(BtdrvBleScanResult *results, u8 count, u8 *total_out); + +/** + * @brief StartBleScanForPaired + * @note This is similar to \ref btmStartBleScanForPaired. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuStartBleScanForPaired(BtdrvBleAdvertisePacketParameter param); + +/** + * @brief StopBleScanForPaired + * @note This is similar to \ref btmStopBleScanForPaired. + */ +Result btmuStopBleScanForPaired(void); + +/** + * @brief StartBleScanForSmartDevice + * @note This is similar to \ref btmStartBleScanForSmartDevice. + * @param[in] uuid \ref BtdrvGattAttributeUuid + */ +Result btmuStartBleScanForSmartDevice(const BtdrvGattAttributeUuid *uuid); + +/** + * @brief StopBleScanForSmartDevice + * @note This is similar to \ref btmStopBleScanForSmartDevice. + */ +Result btmuStopBleScanForSmartDevice(void); + +/** + * @brief GetBleScanResultsForSmartDevice + * @note This is similar to \ref btmGetBleScanResultsForSmartDevice. + * @param[out] results Output array of \ref BtdrvBleScanResult. + * @param[in] count Size of the results array in entries. The max is 10. + * @param[out] total_out Total output entries. + */ +Result btmuGetBleScanResultsForSmartDevice(BtdrvBleScanResult *results, u8 count, u8 *total_out); + +/** + * @brief AcquireBleConnectionEvent + * @note This is similar to \ref btmAcquireBleConnectionEvent. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmuAcquireBleConnectionEvent(Event* out_event); + +/** + * @brief BleConnect + * @note This is similar to \ref btmBleConnect. + * @param[in] addr \ref BtdrvAddress + */ +Result btmuBleConnect(BtdrvAddress addr); + +/** + * @brief BleDisconnect + * @note This is similar to \ref btmBleDisconnect. + * @param[in] connection_handle This must match a BtdrvBleConnectionInfo::connection_handle from \ref btmuBleGetConnectionState. [5.1.0+] 0xFFFFFFFF is invalid. + */ +Result btmuBleDisconnect(u32 connection_handle); + +/** + * @brief BleGetConnectionState + * @note This is similar to \ref btmBleGetConnectionState. + * @param[out] info Output array of \ref BtdrvBleConnectionInfo. + * @param[in] count Size of the info array in entries. Other cmds which use this internally use count=4. + * @param[out] total_out Total output entries. + */ +Result btmuBleGetConnectionState(BtdrvBleConnectionInfo *info, u8 count, u8 *total_out); + +/** + * @brief AcquireBlePairingEvent + * @note This is similar to \ref btmAcquireBlePairingEvent. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmuAcquireBlePairingEvent(Event* out_event); + +/** + * @brief BlePairDevice + * @note This is similar to \ref btmBlePairDevice. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuBlePairDevice(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleUnPairDevice + * @note This is similar to \ref btmBleUnpairDeviceOnBoth. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuBleUnPairDevice(u32 connection_handle, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleUnPairDevice2 + * @note This is similar to \ref btmBleUnPairDevice. + * @param[in] addr \ref BtdrvAddress + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + */ +Result btmuBleUnPairDevice2(BtdrvAddress addr, BtdrvBleAdvertisePacketParameter param); + +/** + * @brief BleGetPairedDevices + * @note This is similar to \ref btmBleGetPairedAddresses. + * @param[in] param \ref BtdrvBleAdvertisePacketParameter + * @param[out] addrs Output array of \ref BtdrvAddress. + * @param[in] count Size of the addrs array in entries. + * @param[out] total_out Total output entries. The max is 10. + */ +Result btmuBleGetPairedDevices(BtdrvBleAdvertisePacketParameter param, BtdrvAddress *addrs, u8 count, u8 *total_out); + +/** + * @brief AcquireBleServiceDiscoveryEvent + * @note This is similar to \ref btmAcquireBleServiceDiscoveryEvent. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmuAcquireBleServiceDiscoveryEvent(Event* out_event); + +/** + * @brief GetGattServices + * @note This is similar to \ref btmGetGattServices. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[out] services Output array of \ref BtmGattService. + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmuGetGattServices(u32 connection_handle, BtmGattService *services, u8 count, u8 *total_out); + +/** + * @brief Same as \ref btmuGetGattServices except this only returns the \ref BtmGattService which matches the input \ref BtdrvGattAttributeUuid. + * @note This is similar to \ref btmGetGattService. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] uuid \ref BtdrvGattAttributeUuid + * @param[out] service \ref BtmGattService + * @param[out] flag Whether a \ref BtmGattService was returned. + */ +Result btmuGetGattService(u32 connection_handle, const BtdrvGattAttributeUuid *uuid, BtmGattService *service, bool *flag); + +/** + * @brief Same as \ref btmuGetGattServices except this only returns \ref BtmGattService entries where various checks pass with u16 fields. + * @note This is similar to \ref btmGetGattIncludedServices. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] service_handle ServiceHandle + * @param[out] services \ref BtmGattService + * @param[in] count Size of the services array in entries. The max is 100. + * @param[out] out Output value. + */ +Result btmuGetGattIncludedServices(u32 connection_handle, u16 service_handle, BtmGattService *services, u8 count, u8 *out); + +/** + * @brief This is similar to \ref btmuGetGattIncludedServices except this only returns 1 \ref BtmGattService. + * @note This is similar to \ref btmGetBelongingService. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] attribute_handle AttributeHandle + * @param[out] service \ref BtmGattService + * @param[out] flag Whether a \ref BtmGattService was returned. + */ +Result btmuGetBelongingGattService(u32 connection_handle, u16 attribute_handle, BtmGattService *service, bool *flag); + +/** + * @brief GetGattCharacteristics + * @note This is similar to \ref btmGetGattCharacteristics. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] service_handle This controls which \ref BtmGattCharacteristic entries to return. + * @param[out] characteristics \ref BtmGattCharacteristic + * @param[in] count Size of the characteristics array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmuGetGattCharacteristics(u32 connection_handle, u16 service_handle, BtmGattCharacteristic *characteristics, u8 count, u8 *total_out); + +/** + * @brief GetGattDescriptors + * @note This is similar to \ref btmGetGattDescriptors. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] char_handle Characteristic handle. This controls which \ref BtmGattDescriptor entries to return. + * @param[out] descriptors \ref BtmGattDescriptor + * @param[in] count Size of the descriptors array in entries. The max is 100. + * @param[out] total_out Total output entries. + */ +Result btmuGetGattDescriptors(u32 connection_handle, u16 char_handle, BtmGattDescriptor *descriptors, u8 count, u8 *total_out); + +/** + * @brief AcquireBleMtuConfigEvent + * @note This is similar to \ref btmAcquireBleMtuConfigEvent. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result btmuAcquireBleMtuConfigEvent(Event* out_event); + +/** + * @brief ConfigureBleMtu + * @note This is similar to \ref btmConfigureBleMtu. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[in] mtu MTU + */ +Result btmuConfigureBleMtu(u32 connection_handle, u16 mtu); + +/** + * @brief GetBleMtu + * @note This is similar to \ref btmGetBleMtu. + * @param[in] connection_handle Same as \ref btmuBleDisconnect. + * @param[out] out Output MTU. + */ +Result btmuGetBleMtu(u32 connection_handle, u16 *out); + +/** + * @brief RegisterBleGattDataPath + * @note This is similar to \ref btmRegisterBleGattDataPath. + * @param[in] path \ref BtmBleDataPath + */ +Result btmuRegisterBleGattDataPath(const BtmBleDataPath *path); + +/** + * @brief UnregisterBleGattDataPath + * @note This is similar to \ref btmUnregisterBleGattDataPath. + * @param[in] path \ref BtmBleDataPath + */ +Result btmuUnregisterBleGattDataPath(const BtmBleDataPath *path); + diff --git a/src/libnx/wrapper/switch/services/btmu.nim b/src/libnx/wrapper/switch/services/btmu.nim new file mode 100644 index 0000000..070ceff --- /dev/null +++ b/src/libnx/wrapper/switch/services/btmu.nim @@ -0,0 +1,336 @@ +## * +## @file btmu.h +## @brief btm:u (btm user) service IPC wrapper. +## @note Only available on [5.0.0+]. +## @note See also btdev. +## @note See also: https://switchbrew.org/wiki/BTM_services +## @author yellows8 +## + +import + ../types, ../kernel/event, ../services/btdrv_types, ../services/btm_types, ../sf/service +proc btmuInitialize*(): Result {.cdecl, importc: "btmuInitialize".} +## / Initialize btm:u. + +proc btmuExit*() {.cdecl, importc: "btmuExit".} +## / Exit btm:u. + +proc btmuGetServiceSession*(srvOut: ptr Service): Result {.cdecl, + importc: "btmuGetServiceSession".} +## / Gets the Service object for the actual btm:u service session. This object must be closed by the user once finished using cmds with this. + +proc btmuGetServiceSessionIBtmUserCore*(): ptr Service {.cdecl, + importc: "btmuGetServiceSession_IBtmUserCore".} +## / Gets the Service object for IBtmUserCore. + +proc btmuAcquireBleScanEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmuAcquireBleScanEvent".} +## * +## @brief AcquireBleScanEvent +## @note This is similar to \ref btmAcquireBleScanEvent. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmuGetBleScanFilterParameter*(parameterId: U16; + `out`: ptr BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmuGetBleScanFilterParameter".} +## * +## @brief GetBleScanFilterParameter +## @note This is the same as \ref btmGetBleScanParameterGeneral. +## @param[in] parameter_id Must be value 0x1 or 0xFFFF. +## @param[out] out \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuGetBleScanFilterParameter2*(parameterId: U16; + `out`: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btmuGetBleScanFilterParameter2".} +## * +## @brief GetBleScanFilterParameter2 +## @note This is the same as \ref btmGetBleScanParameterSmartDevice. +## @param[in] parameter_id Must be value 0x2. +## @param[out] out \ref BtdrvGattAttributeUuid. The first 4-bytes is always 0. +## + +proc btmuStartBleScanForGeneral*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmuStartBleScanForGeneral".} +## * +## @brief StartBleScanForGeneral +## @note This is similar to \ref btmStartBleScanForGeneral. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuStopBleScanForGeneral*(): Result {.cdecl, + importc: "btmuStopBleScanForGeneral".} +## * +## @brief StopBleScanForGeneral +## @note This is similar to \ref btmStopBleScanForGeneral. +## + +proc btmuGetBleScanResultsForGeneral*(results: ptr BtdrvBleScanResult; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmuGetBleScanResultsForGeneral".} +## * +## @brief GetBleScanResultsForGeneral +## @note This is similar to \ref btmGetBleScanResultsForGeneral. +## @param[out] results Output array of \ref BtdrvBleScanResult. +## @param[in] count Size of the results array in entries. The max is 10. +## @param[out] total_out Total output entries. +## + +proc btmuStartBleScanForPaired*(param: BtdrvBleAdvertisePacketParameter): Result {. + cdecl, importc: "btmuStartBleScanForPaired".} +## * +## @brief StartBleScanForPaired +## @note This is similar to \ref btmStartBleScanForPaired. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuStopBleScanForPaired*(): Result {.cdecl, + importc: "btmuStopBleScanForPaired".} +## * +## @brief StopBleScanForPaired +## @note This is similar to \ref btmStopBleScanForPaired. +## + +proc btmuStartBleScanForSmartDevice*(uuid: ptr BtdrvGattAttributeUuid): Result {. + cdecl, importc: "btmuStartBleScanForSmartDevice".} +## * +## @brief StartBleScanForSmartDevice +## @note This is similar to \ref btmStartBleScanForSmartDevice. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## + +proc btmuStopBleScanForSmartDevice*(): Result {.cdecl, + importc: "btmuStopBleScanForSmartDevice".} +## * +## @brief StopBleScanForSmartDevice +## @note This is similar to \ref btmStopBleScanForSmartDevice. +## + +proc btmuGetBleScanResultsForSmartDevice*(results: ptr BtdrvBleScanResult; + count: U8; totalOut: ptr U8): Result {.cdecl, importc: "btmuGetBleScanResultsForSmartDevice".} +## * +## @brief GetBleScanResultsForSmartDevice +## @note This is similar to \ref btmGetBleScanResultsForSmartDevice. +## @param[out] results Output array of \ref BtdrvBleScanResult. +## @param[in] count Size of the results array in entries. The max is 10. +## @param[out] total_out Total output entries. +## + +proc btmuAcquireBleConnectionEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmuAcquireBleConnectionEvent".} +## * +## @brief AcquireBleConnectionEvent +## @note This is similar to \ref btmAcquireBleConnectionEvent. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmuBleConnect*(`addr`: BtdrvAddress): Result {.cdecl, importc: "btmuBleConnect".} +## * +## @brief BleConnect +## @note This is similar to \ref btmBleConnect. +## @param[in] addr \ref BtdrvAddress +## + +proc btmuBleDisconnect*(connectionHandle: U32): Result {.cdecl, + importc: "btmuBleDisconnect".} +## * +## @brief BleDisconnect +## @note This is similar to \ref btmBleDisconnect. +## @param[in] connection_handle This must match a BtdrvBleConnectionInfo::connection_handle from \ref btmuBleGetConnectionState. [5.1.0+] 0xFFFFFFFF is invalid. +## + +proc btmuBleGetConnectionState*(info: ptr BtdrvBleConnectionInfo; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmuBleGetConnectionState".} +## * +## @brief BleGetConnectionState +## @note This is similar to \ref btmBleGetConnectionState. +## @param[out] info Output array of \ref BtdrvBleConnectionInfo. +## @param[in] count Size of the info array in entries. Other cmds which use this internally use count=4. +## @param[out] total_out Total output entries. +## + +proc btmuAcquireBlePairingEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmuAcquireBlePairingEvent".} +## * +## @brief AcquireBlePairingEvent +## @note This is similar to \ref btmAcquireBlePairingEvent. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmuBlePairDevice*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btmuBlePairDevice".} +## * +## @brief BlePairDevice +## @note This is similar to \ref btmBlePairDevice. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuBleUnPairDevice*(connectionHandle: U32; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btmuBleUnPairDevice".} +## * +## @brief BleUnPairDevice +## @note This is similar to \ref btmBleUnpairDeviceOnBoth. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuBleUnPairDevice2*(`addr`: BtdrvAddress; + param: BtdrvBleAdvertisePacketParameter): Result {.cdecl, + importc: "btmuBleUnPairDevice2".} +## * +## @brief BleUnPairDevice2 +## @note This is similar to \ref btmBleUnPairDevice. +## @param[in] addr \ref BtdrvAddress +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## + +proc btmuBleGetPairedDevices*(param: BtdrvBleAdvertisePacketParameter; + addrs: ptr BtdrvAddress; count: U8; totalOut: ptr U8): Result {. + cdecl, importc: "btmuBleGetPairedDevices".} +## * +## @brief BleGetPairedDevices +## @note This is similar to \ref btmBleGetPairedAddresses. +## @param[in] param \ref BtdrvBleAdvertisePacketParameter +## @param[out] addrs Output array of \ref BtdrvAddress. +## @param[in] count Size of the addrs array in entries. +## @param[out] total_out Total output entries. The max is 10. +## + +proc btmuAcquireBleServiceDiscoveryEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmuAcquireBleServiceDiscoveryEvent".} +## * +## @brief AcquireBleServiceDiscoveryEvent +## @note This is similar to \ref btmAcquireBleServiceDiscoveryEvent. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmuGetGattServices*(connectionHandle: U32; services: ptr BtmGattService; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btmuGetGattServices".} +## * +## @brief GetGattServices +## @note This is similar to \ref btmGetGattServices. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[out] services Output array of \ref BtmGattService. +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmuGetGattService*(connectionHandle: U32; uuid: ptr BtdrvGattAttributeUuid; + service: ptr BtmGattService; flag: ptr bool): Result {.cdecl, + importc: "btmuGetGattService".} +## * +## @brief Same as \ref btmuGetGattServices except this only returns the \ref BtmGattService which matches the input \ref BtdrvGattAttributeUuid. +## @note This is similar to \ref btmGetGattService. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] uuid \ref BtdrvGattAttributeUuid +## @param[out] service \ref BtmGattService +## @param[out] flag Whether a \ref BtmGattService was returned. +## + +proc btmuGetGattIncludedServices*(connectionHandle: U32; serviceHandle: U16; + services: ptr BtmGattService; count: U8; + `out`: ptr U8): Result {.cdecl, + importc: "btmuGetGattIncludedServices".} +## * +## @brief Same as \ref btmuGetGattServices except this only returns \ref BtmGattService entries where various checks pass with u16 fields. +## @note This is similar to \ref btmGetGattIncludedServices. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] service_handle ServiceHandle +## @param[out] services \ref BtmGattService +## @param[in] count Size of the services array in entries. The max is 100. +## @param[out] out Output value. +## + +proc btmuGetBelongingGattService*(connectionHandle: U32; attributeHandle: U16; + service: ptr BtmGattService; flag: ptr bool): Result {. + cdecl, importc: "btmuGetBelongingGattService".} +## * +## @brief This is similar to \ref btmuGetGattIncludedServices except this only returns 1 \ref BtmGattService. +## @note This is similar to \ref btmGetBelongingService. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] attribute_handle AttributeHandle +## @param[out] service \ref BtmGattService +## @param[out] flag Whether a \ref BtmGattService was returned. +## + +proc btmuGetGattCharacteristics*(connectionHandle: U32; serviceHandle: U16; + characteristics: ptr BtmGattCharacteristic; + count: U8; totalOut: ptr U8): Result {.cdecl, + importc: "btmuGetGattCharacteristics".} +## * +## @brief GetGattCharacteristics +## @note This is similar to \ref btmGetGattCharacteristics. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] service_handle This controls which \ref BtmGattCharacteristic entries to return. +## @param[out] characteristics \ref BtmGattCharacteristic +## @param[in] count Size of the characteristics array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmuGetGattDescriptors*(connectionHandle: U32; charHandle: U16; + descriptors: ptr BtmGattDescriptor; count: U8; + totalOut: ptr U8): Result {.cdecl, + importc: "btmuGetGattDescriptors".} +## * +## @brief GetGattDescriptors +## @note This is similar to \ref btmGetGattDescriptors. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] char_handle Characteristic handle. This controls which \ref BtmGattDescriptor entries to return. +## @param[out] descriptors \ref BtmGattDescriptor +## @param[in] count Size of the descriptors array in entries. The max is 100. +## @param[out] total_out Total output entries. +## + +proc btmuAcquireBleMtuConfigEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "btmuAcquireBleMtuConfigEvent".} +## * +## @brief AcquireBleMtuConfigEvent +## @note This is similar to \ref btmAcquireBleMtuConfigEvent. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc btmuConfigureBleMtu*(connectionHandle: U32; mtu: U16): Result {.cdecl, + importc: "btmuConfigureBleMtu".} +## * +## @brief ConfigureBleMtu +## @note This is similar to \ref btmConfigureBleMtu. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[in] mtu MTU +## + +proc btmuGetBleMtu*(connectionHandle: U32; `out`: ptr U16): Result {.cdecl, + importc: "btmuGetBleMtu".} +## * +## @brief GetBleMtu +## @note This is similar to \ref btmGetBleMtu. +## @param[in] connection_handle Same as \ref btmuBleDisconnect. +## @param[out] out Output MTU. +## + +proc btmuRegisterBleGattDataPath*(path: ptr BtmBleDataPath): Result {.cdecl, + importc: "btmuRegisterBleGattDataPath".} +## * +## @brief RegisterBleGattDataPath +## @note This is similar to \ref btmRegisterBleGattDataPath. +## @param[in] path \ref BtmBleDataPath +## + +proc btmuUnregisterBleGattDataPath*(path: ptr BtmBleDataPath): Result {.cdecl, + importc: "btmuUnregisterBleGattDataPath".} +## * +## @brief UnregisterBleGattDataPath +## @note This is similar to \ref btmUnregisterBleGattDataPath. +## @param[in] path \ref BtmBleDataPath +## + diff --git a/src/libnx/wrapper/switch/services/capmtp.h b/src/libnx/wrapper/switch/services/capmtp.h new file mode 100644 index 0000000..5936866 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capmtp.h @@ -0,0 +1,24 @@ +/** + * @file capmtp.h + * @brief capmtp service IPC wrapper. + * @note Only available on [11.0.0+]. + * @author Behemoth + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +Result capmtpInitialize(void* mem, size_t size, u32 app_count, u32 max_img, u32 max_vid, const char *other_name); +void capmtpExit(void); + +Service* capmtpGetRootServiceSession(void); +Service* capmtpGetServiceSession(void); + +Result capmtpStartCommandHandler(void); +Result capmtpStopCommandHandler(void); +bool capmtpIsRunning(void); +Event *capmtpGetConnectionEvent(void); +bool capmtpIsConnected(void); +Event *capmtpGetScanErrorEvent(void); +Result capmtpGetScanError(void); diff --git a/src/libnx/wrapper/switch/services/capmtp.nim b/src/libnx/wrapper/switch/services/capmtp.nim new file mode 100644 index 0000000..4d01701 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capmtp.nim @@ -0,0 +1,29 @@ +## * +## @file capmtp.h +## @brief capmtp service IPC wrapper. +## @note Only available on [11.0.0+]. +## @author Behemoth +## + +import + ../types, ../kernel/event, ../sf/service + +proc capmtpInitialize*(mem: pointer; size: csize_t; appCount: U32; maxImg: U32; + maxVid: U32; otherName: cstring): Result {.cdecl, + importc: "capmtpInitialize".} +proc capmtpExit*() {.cdecl, importc: "capmtpExit".} +proc capmtpGetRootServiceSession*(): ptr Service {.cdecl, + importc: "capmtpGetRootServiceSession".} +proc capmtpGetServiceSession*(): ptr Service {.cdecl, + importc: "capmtpGetServiceSession".} +proc capmtpStartCommandHandler*(): Result {.cdecl, + importc: "capmtpStartCommandHandler".} +proc capmtpStopCommandHandler*(): Result {.cdecl, + importc: "capmtpStopCommandHandler".} +proc capmtpIsRunning*(): bool {.cdecl, importc: "capmtpIsRunning".} +proc capmtpGetConnectionEvent*(): ptr Event {.cdecl, + importc: "capmtpGetConnectionEvent".} +proc capmtpIsConnected*(): bool {.cdecl, importc: "capmtpIsConnected".} +proc capmtpGetScanErrorEvent*(): ptr Event {.cdecl, + importc: "capmtpGetScanErrorEvent".} +proc capmtpGetScanError*(): Result {.cdecl, importc: "capmtpGetScanError".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/caps.h b/src/libnx/wrapper/switch/services/caps.h new file mode 100644 index 0000000..7604389 --- /dev/null +++ b/src/libnx/wrapper/switch/services/caps.h @@ -0,0 +1,232 @@ +/** + * @file caps.h + * @brief Common caps (caps:*) service IPC header. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/acc.h" + +/// ImageOrientation +typedef enum { + AlbumImageOrientation_Unknown0 = 0, ///< Unknown. Default. + AlbumImageOrientation_Unknown1 = 1, ///< Unknown. + AlbumImageOrientation_Unknown2 = 2, ///< Unknown. + AlbumImageOrientation_Unknown3 = 3, ///< Unknown. +} AlbumImageOrientation; + +/// AlbumReportOption +typedef enum { + AlbumReportOption_Disable = 0, ///< Don't display the screenshot-taken Overlay-applet notification. + AlbumReportOption_Enable = 1, ///< Display the screenshot-taken Overlay notification. +} AlbumReportOption; + +typedef enum { + CapsAlbumStorage_Nand = 0, ///< Nand + CapsAlbumStorage_Sd = 1, ///< Sd +} CapsAlbumStorage; + +/// ContentType +typedef enum { + CapsContentType_Screenshot = 0, ///< Album screenshots. + CapsContentType_Movie = 1, ///< Album videos. + CapsContentType_ExtraMovie = 3, ///< Videos recorded by the current host Application via \ref grcCreateMovieMaker. +} CapsContentType; + +/// ScreenShotAttribute +typedef struct { + u32 unk_x0; ///< Always set to 0 by official sw. + u32 orientation; ///< \ref AlbumImageOrientation + u32 unk_x8; ///< Always set to 0 by official sw. + u32 unk_xc; ///< Always set to 1 by official sw. + u8 unk_x10[0x30]; ///< Always set to 0 by official sw. +} CapsScreenShotAttribute; + +/// ScreenShotAttributeForApplication. Only unk_x0 is used by official sw. +typedef struct { + u32 unk_x0; ///< Unknown. + u8 unk_x4; ///< Unknown. + u8 unk_x5; ///< Unknown. + u8 unk_x6; ///< Unknown. + u8 pad; ///< Padding. + u32 unk_x8; ///< Unknown. + u32 unk_xc; ///< Unknown. + u32 unk_x10; ///< Unknown. + u32 unk_x14; ///< Unknown. + u32 unk_x18; ///< Unknown. + u32 unk_x1c; ///< Unknown. + u16 unk_x20; ///< Unknown. + u16 unk_x22; ///< Unknown. + u16 unk_x24; ///< Unknown. + u16 unk_x26; ///< Unknown. + u8 reserved[0x18]; ///< Always zero. +} CapsScreenShotAttributeForApplication; + +/// ScreenShotDecoderFlag +typedef enum { + CapsScreenShotDecoderFlag_None = 0, ///< No special processing. + CapsScreenShotDecoderFlag_EnableFancyUpsampling = BIT(0), ///< See libjpeg-turbo do_fancy_upsampling. + CapsScreenShotDecoderFlag_EnableBlockSmoothing = BIT(1), ///< See libjpeg-turbo do_block_smoothing. +} CapsScreenShotDecoderFlag; + +/// ScreenShotDecodeOption +typedef struct { + u64 flags; ///< Bitflags, see \ref CapsScreenShotDecoderFlag. + u64 reserved[0x3]; ///< Reserved. Unused by official sw. +} CapsScreenShotDecodeOption; + +/// AlbumFileDateTime. This corresponds to each field in the Album entry filename, prior to the "-": "YYYYMMDDHHMMSSII". +typedef struct { + u16 year; ///< Year. + u8 month; ///< Month. + u8 day; ///< Day of the month. + u8 hour; ///< Hour. + u8 minute; ///< Minute. + u8 second; ///< Second. + u8 id; ///< Unique ID for when there's multiple Album files with the same timestamp. +} CapsAlbumFileDateTime; + +/// AlbumEntryId +typedef struct { + u64 application_id; ///< ApplicationId + CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime + u8 storage; ///< \ref CapsAlbumStorage + u8 content; ///< \ref CapsAlbumFileContents + u8 pad_x12[0x6]; ///< padding +} CapsAlbumFileId; + +/// AlbumEntry +typedef struct { + u64 size; ///< Size. + CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId +} CapsAlbumEntry; + +/// ApplicationAlbumEntry +typedef struct { + union { + u8 data[0x20]; ///< Data. + + struct { + u8 unk_x0[0x20]; ///< aes256 with random key over \ref AlbumEntry. + } v0; ///< Pre-7.0.0 + + struct { + u64 size; ///< size of the entry + u64 hash; ///< aes256 with hardcoded key over \ref AlbumEntry. + CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime + u8 storage; ///< \ref CapsAlbumStorage + u8 content; ///< \ref CapsAlbumFileContents + u8 pad_x1a[0x5]; ///< padding + u8 unk_x1f; ///< Set to 1 by official software + } v1; ///< [7.0.0+] + }; +} CapsApplicationAlbumEntry; + +/// ApplicationAlbumFileEntry +typedef struct { + CapsApplicationAlbumEntry entry; ///< \ref CapsApplicationAlbumEntry + CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime + u64 unk_x28; ///< Unknown. +} CapsApplicationAlbumFileEntry; + +/// ApplicationData +typedef struct { + u8 userdata[0x400]; ///< UserData. + u32 size; ///< UserData size. +} CapsApplicationData; + +/// AlbumFileContents +typedef enum { + CapsAlbumFileContents_ScreenShot = 0, + CapsAlbumFileContents_Movie = 1, + CapsAlbumFileContents_ExtraScreenShot = 2, + CapsAlbumFileContents_ExtraMovie = 3, +} CapsAlbumFileContents; + +typedef enum { + CapsAlbumContentsUsageFlag_HasGreaterUsage = BIT(0), ///< Indicates that there are additional files not captured by the count/size fields of CapsAlbumContentsUsage + CapsAlbumContentsUsageFlag_IsUnknownContents = BIT(1), ///< Indicates that the file is not a known content type +} CapsAlbumContentsUsageFlag; + +typedef struct { + s64 count; ///< Count. + s64 size; ///< Size. Used storage space. + u32 flags; ///< \ref CapsAlbumContentsUsageFlag + u8 file_contents; ///< \ref CapsAlbumFileContents + u8 pad_x15[0x3]; ///< Unused +} CapsAlbumContentsUsage; + +typedef struct { + CapsAlbumContentsUsage usages[2]; ///< \ref CapsAlbumContentsUsage +} CapsAlbumUsage2; + +typedef struct { + CapsAlbumContentsUsage usages[3]; ///< \ref CapsAlbumContentsUsage +} CapsAlbumUsage3; + +typedef struct { + CapsAlbumContentsUsage usages[16]; ///< \ref CapsAlbumContentsUsage +} CapsAlbumUsage16; + +/// UserIdList +typedef struct { + AccountUid uids[ACC_USER_LIST_SIZE]; ///< \ref AccountUid + u8 count; ///< Total userIDs. + u8 pad[7]; ///< Padding. +} CapsUserIdList; + +/// LoadAlbumScreenShotImageOutputForApplication +typedef struct { + s64 width; ///< Width. Official sw copies this to a s32 output field. + s64 height; ///< Height. Official sw copies this to a s32 output field. + CapsScreenShotAttributeForApplication attr; ///< \ref CapsScreenShotAttributeForApplication + CapsApplicationData appdata; ///< \ref CapsApplicationData + u8 reserved[0xac]; ///< Unused. +} CapsLoadAlbumScreenShotImageOutputForApplication; + +/// LoadAlbumScreenShotImageOutput +typedef struct { + s64 width; ///< Width. Official sw copies this to a s32 output field. + s64 height; ///< Height. Official sw copies this to a s32 output field. + CapsScreenShotAttribute attr; ///< \ref CapsScreenShotAttribute + u8 unk_x50[0x400]; ///< Unused. +} CapsLoadAlbumScreenShotImageOutput; + +/// AlbumFileContentsFlag +typedef enum { + CapsAlbumFileContentsFlag_ScreenShot = BIT(0), ///< Query for ScreenShot files. + CapsAlbumFileContentsFlag_Movie = BIT(1), ///< Query for Movie files. +} CapsAlbumFileContentsFlag; + +/// AlbumCache +typedef struct { + u64 count; ///< Count + u64 unk_x8; ///< Unknown +} CapsAlbumCache; + +/// Gets the ShimLibraryVersion. +u64 capsGetShimLibraryVersion(void); + +/// Gets the default start_datetime. +static inline CapsAlbumFileDateTime capsGetDefaultStartDateTime(void) { + return (CapsAlbumFileDateTime){.year = 1970, .month = 1, .day = 1}; +} + +/// Gets the default end_datetime. +static inline CapsAlbumFileDateTime capsGetDefaultEndDateTime(void) { + return (CapsAlbumFileDateTime){.year = 3000, .month = 1, .day = 1}; +} + +/// Convert a \ref CapsApplicationAlbumFileEntry to \ref CapsApplicationAlbumEntry. +static inline void capsConvertApplicationAlbumFileEntryToApplicationAlbumEntry(CapsApplicationAlbumEntry *out, CapsApplicationAlbumFileEntry *in) { + *out = in->entry; +} + +/// Convert a \ref CapsApplicationAlbumEntry to \ref CapsApplicationAlbumFileEntry. Should only be used on [7.0.0+]. +static inline void capsConvertApplicationAlbumEntryToApplicationAlbumFileEntry(CapsApplicationAlbumFileEntry *out, CapsApplicationAlbumEntry *in) { + out->entry = *in; + out->datetime = in->v1.datetime; + out->unk_x28 = 0; +} + diff --git a/src/libnx/wrapper/switch/services/caps.nim b/src/libnx/wrapper/switch/services/caps.nim new file mode 100644 index 0000000..e8fe691 --- /dev/null +++ b/src/libnx/wrapper/switch/services/caps.nim @@ -0,0 +1,270 @@ +## * +## @file caps.h +## @brief Common caps (caps:*) service IPC header. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../services/acc + +## / ImageOrientation + +type + AlbumImageOrientation* = enum + AlbumImageOrientationUnknown0 = 0, ## /< Unknown. Default. + AlbumImageOrientationUnknown1 = 1, ## /< Unknown. + AlbumImageOrientationUnknown2 = 2, ## /< Unknown. + AlbumImageOrientationUnknown3 = 3 ## /< Unknown. + + +## / AlbumReportOption + +type + AlbumReportOption* = enum + AlbumReportOptionDisable = 0, ## /< Don't display the screenshot-taken Overlay-applet notification. + AlbumReportOptionEnable = 1 ## /< Display the screenshot-taken Overlay notification. + CapsAlbumStorage* = enum + CapsAlbumStorageNand = 0, ## /< Nand + CapsAlbumStorageSd = 1 ## /< Sd + + + +## / ContentType + +type + CapsContentType* = enum + CapsContentTypeScreenshot = 0, ## /< Album screenshots. + CapsContentTypeMovie = 1, ## /< Album videos. + CapsContentTypeExtraMovie = 3 ## /< Videos recorded by the current host Application via \ref grcCreateMovieMaker. + + +## / ScreenShotAttribute + +type + CapsScreenShotAttribute* {.bycopy.} = object + unkX0*: U32 ## /< Always set to 0 by official sw. + orientation*: U32 ## /< \ref AlbumImageOrientation + unkX8*: U32 ## /< Always set to 0 by official sw. + unkXc*: U32 ## /< Always set to 1 by official sw. + unkX10*: array[0x30, U8] ## /< Always set to 0 by official sw. + + +## / ScreenShotAttributeForApplication. Only unk_x0 is used by official sw. + +type + CapsScreenShotAttributeForApplication* {.bycopy.} = object + unkX0*: U32 ## /< Unknown. + unkX4*: U8 ## /< Unknown. + unkX5*: U8 ## /< Unknown. + unkX6*: U8 ## /< Unknown. + pad*: U8 ## /< Padding. + unkX8*: U32 ## /< Unknown. + unkXc*: U32 ## /< Unknown. + unkX10*: U32 ## /< Unknown. + unkX14*: U32 ## /< Unknown. + unkX18*: U32 ## /< Unknown. + unkX1c*: U32 ## /< Unknown. + unkX20*: U16 ## /< Unknown. + unkX22*: U16 ## /< Unknown. + unkX24*: U16 ## /< Unknown. + unkX26*: U16 ## /< Unknown. + reserved*: array[0x18, U8] ## /< Always zero. + + +## / ScreenShotDecoderFlag + +type + CapsScreenShotDecoderFlag* = enum + CapsScreenShotDecoderFlagNone = 0, ## /< No special processing. + CapsScreenShotDecoderFlagEnableFancyUpsampling = bit(0), ## /< See libjpeg-turbo do_fancy_upsampling. + CapsScreenShotDecoderFlagEnableBlockSmoothing = bit(1) ## /< See libjpeg-turbo do_block_smoothing. + + +## / ScreenShotDecodeOption + +type + CapsScreenShotDecodeOption* {.bycopy.} = object + flags*: U64 ## /< Bitflags, see \ref CapsScreenShotDecoderFlag. + reserved*: array[0x3, U64] ## /< Reserved. Unused by official sw. + + +## / AlbumFileDateTime. This corresponds to each field in the Album entry filename, prior to the "-": "YYYYMMDDHHMMSSII". + +type + CapsAlbumFileDateTime* {.bycopy.} = object + year*: U16 ## /< Year. + month*: U8 ## /< Month. + day*: U8 ## /< Day of the month. + hour*: U8 ## /< Hour. + minute*: U8 ## /< Minute. + second*: U8 ## /< Second. + id*: U8 ## /< Unique ID for when there's multiple Album files with the same timestamp. + + +## / AlbumEntryId + +type + CapsAlbumFileId* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId + datetime*: CapsAlbumFileDateTime ## /< \ref CapsAlbumFileDateTime + storage*: U8 ## /< \ref CapsAlbumStorage + content*: U8 ## /< \ref CapsAlbumFileContents + padX12*: array[0x6, U8] ## /< padding + + +## / AlbumEntry + +type + CapsAlbumEntry* {.bycopy.} = object + size*: U64 ## /< Size. + fileId*: CapsAlbumFileId ## /< \ref CapsAlbumFileId + + +## / ApplicationAlbumEntry + +type + INNER_C_STRUCT_caps_5* {.bycopy.} = object + unkX0*: array[0x20, U8] ## /< aes256 with random key over \ref AlbumEntry. + + INNER_C_STRUCT_caps_6* {.bycopy.} = object + size*: U64 ## /< size of the entry + hash*: U64 ## /< aes256 with hardcoded key over \ref AlbumEntry. + datetime*: CapsAlbumFileDateTime ## /< \ref CapsAlbumFileDateTime + storage*: U8 ## /< \ref CapsAlbumStorage + content*: U8 ## /< \ref CapsAlbumFileContents + padX1a*: array[0x5, U8] ## /< padding + unkX1f*: U8 ## /< Set to 1 by official software + + INNER_C_UNION_caps_4* {.bycopy, union.} = object + data*: array[0x20, U8] ## /< Data. + v0*: INNER_C_STRUCT_caps_5 ## /< Pre-7.0.0 + v1*: INNER_C_STRUCT_caps_6 ## /< [7.0.0+] + + CapsApplicationAlbumEntry* {.bycopy.} = object + anoCaps7*: INNER_C_UNION_caps_4 + +template data*(caae: CapsApplicationAlbumEntry): array[0x20, U8] = + caae.anoCaps7.data + +template v0*(caae: CapsApplicationAlbumEntry): INNER_C_STRUCT_caps_5 = + caae.anoCaps7.v0 + +template v1*(caae: CapsApplicationAlbumEntry): INNER_C_STRUCT_caps_6 = + caae.anoCaps7.v1 + + +## / ApplicationAlbumFileEntry + +type + CapsApplicationAlbumFileEntry* {.bycopy.} = object + entry*: CapsApplicationAlbumEntry ## /< \ref CapsApplicationAlbumEntry + datetime*: CapsAlbumFileDateTime ## /< \ref CapsAlbumFileDateTime + unkX28*: U64 ## /< Unknown. + + +## / ApplicationData + +type + CapsApplicationData* {.bycopy.} = object + userdata*: array[0x400, U8] ## /< UserData. + size*: U32 ## /< UserData size. + + +## / AlbumFileContents + +type + CapsAlbumFileContents* = enum + CapsAlbumFileContentsScreenShot = 0, CapsAlbumFileContentsMovie = 1, + CapsAlbumFileContentsExtraScreenShot = 2, CapsAlbumFileContentsExtraMovie = 3 + CapsAlbumContentsUsageFlag* = enum + CapsAlbumContentsUsageFlagHasGreaterUsage = bit(0), ## /< Indicates that there are additional files not captured by the count/size fields of CapsAlbumContentsUsage + CapsAlbumContentsUsageFlagIsUnknownContents = bit(1) ## /< Indicates that the file is not a known content type + CapsAlbumContentsUsage* {.bycopy.} = object + count*: S64 ## /< Count. + size*: S64 ## /< Size. Used storage space. + flags*: U32 ## /< \ref CapsAlbumContentsUsageFlag + fileContents*: U8 ## /< \ref CapsAlbumFileContents + padX15*: array[0x3, U8] ## /< Unused + + CapsAlbumUsage2* {.bycopy.} = object + usages*: array[2, CapsAlbumContentsUsage] ## /< \ref CapsAlbumContentsUsage + + CapsAlbumUsage3* {.bycopy.} = object + usages*: array[3, CapsAlbumContentsUsage] ## /< \ref CapsAlbumContentsUsage + + CapsAlbumUsage16* {.bycopy.} = object + usages*: array[16, CapsAlbumContentsUsage] ## /< \ref CapsAlbumContentsUsage + + + + +## / UserIdList + +type + CapsUserIdList* {.bycopy.} = object + uids*: array[Acc_User_List_Size, AccountUid] ## /< \ref AccountUid + count*: U8 ## /< Total userIDs. + pad*: array[7, U8] ## /< Padding. + + +## / LoadAlbumScreenShotImageOutputForApplication + +type + CapsLoadAlbumScreenShotImageOutputForApplication* {.bycopy.} = object + width*: S64 ## /< Width. Official sw copies this to a s32 output field. + height*: S64 ## /< Height. Official sw copies this to a s32 output field. + attr*: CapsScreenShotAttributeForApplication ## /< \ref CapsScreenShotAttributeForApplication + appdata*: CapsApplicationData ## /< \ref CapsApplicationData + reserved*: array[0xac, U8] ## /< Unused. + + +## / LoadAlbumScreenShotImageOutput + +type + CapsLoadAlbumScreenShotImageOutput* {.bycopy.} = object + width*: S64 ## /< Width. Official sw copies this to a s32 output field. + height*: S64 ## /< Height. Official sw copies this to a s32 output field. + attr*: CapsScreenShotAttribute ## /< \ref CapsScreenShotAttribute + unkX50*: array[0x400, U8] ## /< Unused. + + +## / AlbumFileContentsFlag + +type + CapsAlbumFileContentsFlag* = enum + CapsAlbumFileContentsFlagScreenShot = bit(0), ## /< Query for ScreenShot files. + CapsAlbumFileContentsFlagMovie = bit(1) ## /< Query for Movie files. + + +## / AlbumCache + +type + CapsAlbumCache* {.bycopy.} = object + count*: U64 ## /< Count + unkX8*: U64 ## /< Unknown + +proc capsGetShimLibraryVersion*(): U64 {.cdecl, importc: "capsGetShimLibraryVersion".} +## / Gets the ShimLibraryVersion. + +proc capsGetDefaultStartDateTime*(): CapsAlbumFileDateTime {.inline, cdecl.} = + ## / Gets the default start_datetime. + return CapsAlbumFileDateTime(year: 1970, month: 1, day: 1) + +proc capsGetDefaultEndDateTime*(): CapsAlbumFileDateTime {.inline, cdecl.} = + ## / Gets the default end_datetime. + return CapsAlbumFileDateTime(year: 3000,month: 1,day: 1) + +proc capsConvertApplicationAlbumFileEntryToApplicationAlbumEntry*( + `out`: ptr CapsApplicationAlbumEntry; `in`: ptr CapsApplicationAlbumFileEntry) {. + inline, cdecl.} = + ## / Convert a \ref CapsApplicationAlbumFileEntry to \ref CapsApplicationAlbumEntry. + `out`[] = `in`.entry + +proc capsConvertApplicationAlbumEntryToApplicationAlbumFileEntry*( + `out`: ptr CapsApplicationAlbumFileEntry; `in`: ptr CapsApplicationAlbumEntry) {. + inline, cdecl.} = + ## / Convert a \ref CapsApplicationAlbumEntry to \ref CapsApplicationAlbumFileEntry. Should only be used on [7.0.0+]. + `out`.entry = `in`[] + `out`.datetime = `in`[].v1.datetime + `out`.unkX28 = 0 diff --git a/src/libnx/wrapper/switch/services/capsa.h b/src/libnx/wrapper/switch/services/capsa.h new file mode 100644 index 0000000..7a5517b --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsa.h @@ -0,0 +1,414 @@ +/** + * @file capsa.h + * @brief Album Accessor (caps:a) service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" + +/// Initialize caps:a. +Result capsaInitialize(void); + +/// Exit caps:a. +void capsaExit(void); + +/// Gets the Service for caps:a. +Service* capsaGetServiceSession(void); + +/// Gets the Service for IAlbumAccessorSession, only initialized after \ref capsaOpenAlbumMovieStream was used (unaffected by using \ref capsaCloseAlbumMovieStream). +Service* capsaGetServiceSession_Accessor(void); + +/** + * @brief Gets the amount of files at a AlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] count Amount of files. + */ +Result capsaGetAlbumFileCount(CapsAlbumStorage storage, u64 *count); + +/** + * @brief Gets a listing of \ref CapsAlbumEntry, where the AlbumFile's storage matches the input one. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] out Total output entries. + * @param[out] entries Output array of \ref CapsAlbumEntry. + * @param[in] count Reserved entry count. + */ +Result capsaGetAlbumFileList(CapsAlbumStorage storage, u64 *out, CapsAlbumEntry *entries, u64 count); + +/** + * @brief Loads a file into the specified buffer. + * @param[in] file_id \ref CapsAlbumFileId + * @param[out] out_size Size of the AlbumFile. + * @param[out] filebuf File output buffer. + * @param[in] filebuf_size Size of the filebuf. + */ +Result capsaLoadAlbumFile(const CapsAlbumFileId *file_id, u64 *out_size, void* filebuf, u64 filebuf_size); + +/** + * @brief Deletes an AlbumFile corresponding to the specified \ref CapsAlbumFileId. + * @param[in] file_id \ref CapsAlbumFileId + */ +Result capsaDeleteAlbumFile(const CapsAlbumFileId *file_id); + +/** + * @brief Copies an AlbumFile to the specified \ref CapsAlbumStorage. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] dst_storage \ref CapsAlbumStorage + */ +Result capsaStorageCopyAlbumFile(const CapsAlbumFileId *file_id, CapsAlbumStorage dst_storage); + +/** + * @brief Gets the mount status of the specified \ref CapsAlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] is_mounted Boolean over whether the storage is mounted or not. + */ +Result capsaIsAlbumMounted(CapsAlbumStorage storage, bool *is_mounted); + +/** + * @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] out \ref CapsAlbumUsage2 + */ +Result capsaGetAlbumUsage(CapsAlbumStorage storage, CapsAlbumUsage2 *out); + +/** + * @brief Gets the size for the specified AlbumFile. + * @param[in] file_id \ref CapsAlbumFileId + * @param[out] size Size of the file. + */ +Result capsaGetAlbumFileSize(const CapsAlbumFileId *file_id, u64 *size); + +/** + * @brief Load the Thumbnail for the specified AlbumFile. + * @note Will always be 320x180. + * @param[in] file_id \ref CapsAlbumFileId + * @param[out] out_size Size of the Thumbnail. + * @param[out] image JPEG image output buffer. + * @param[in] image_size Image buffer size. + */ +Result capsaLoadAlbumFileThumbnail(const CapsAlbumFileId *file_id, u64 *out_size, void* image, u64 image_size); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @note Only available on [2.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[in] file_id \ref CapsAlbumFileId + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImage(u64 *width, u64 *height, const CapsAlbumFileId *file_id, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [2.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[in] file_id \ref CapsAlbumFileId + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotThumbnailImage(u64 *width, u64 *height, const CapsAlbumFileId *file_id, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load an \ref CapsAlbumEntry from a \ref CapsApplicationAlbumEntry and an ApplicationId. + * @note Only available on [2.0.0+]. + * @param[out] entry \ref CapsAlbumEntry + * @param[in] application_entry \ref CapsApplicationAlbumEntry + * @param[in] application_id ApplicationId + */ +Result capsaGetAlbumEntryFromApplicationAlbumEntry(CapsAlbumEntry *entry, const CapsApplicationAlbumEntry *application_entry, u64 application_id); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImageEx(u64 *width, u64 *height, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotThumbnailImageEx(u64 *width, u64 *height, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttribute + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImageEx0(u64 *width, u64 *height, CapsScreenShotAttribute *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. + * @note Only available on [4.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] out \ref CapsAlbumUsage3 + */ +Result capsaGetAlbumUsage3(CapsAlbumStorage storage, CapsAlbumUsage3 *out); + +/** + * @brief Returns the result for a AlbumStorage mount. + * @note Only available on [4.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capsaGetAlbumMountResult(CapsAlbumStorage storage); + +/** + * @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. + * @note Only available on [4.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] flags \ref CapsAlbumFileContentsFlag + * @param[out] out \ref CapsAlbumUsage16 + */ +Result capsaGetAlbumUsage16(CapsAlbumStorage storage, u8 flags, CapsAlbumUsage16 *out); + +/** + * @brief Returns the start and end of the Applet Id range. + * @note Only available on [6.0.0+]. + * @param[out] success Returns bool over whether the call was handled or not. + * @param[out] min Mimimum applet id. Always 0x0100000000001000 + * @param[out] max Maximum applet id. Always 0x0100000000001FFF + */ +Result capsaGetMinMaxAppletId(bool* success, u64* min, u64* max); + +/** + * @brief Gets the amount of files of the specified type at a AlbumStorage. + * @note Only available on [5.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] flags \ref CapsAlbumFileContentsFlag + * @param[out] count Amount of files. + */ +Result capsaGetAlbumFileCountEx0(CapsAlbumStorage storage, u8 flags, u64 *count); + +/** + * @brief Gets a listing of \ref CapsAlbumEntry, where the AlbumFile's storage and type matches the input one. + * @note Only available on [5.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] flags \ref CapsAlbumFileContentsFlag + * @param[out] out Total output entries. + * @param[out] entries Output array of \ref CapsAlbumEntry. + * @param[in] count Reserved entry count. + */ +Result capsaGetAlbumFileListEx0(CapsAlbumStorage storage, u8 flags, u64 *out, CapsAlbumEntry *entries, u64 count); + +/** + * @brief Returns the image from the last shown ScreenShot Overlay. + * @param[out] file_id \ref CapsAlbumFileId + * @param[out] out_size Size of the thumbnail image. Always 0x5100. + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. + */ +Result capsaGetLastOverlayScreenShotThumbnail(CapsAlbumFileId *file_id, u64 *out_size, void* image, u64 image_size); + +/** + * @brief Returns the image from the last shown Movie Overlay. + * @note Only available on [4.0.0+]. + * @param[out] file_id \ref CapsAlbumFileId + * @param[out] out_size Size of the thumbnail image. Always 0x5100. + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. + */ +Result capsaGetLastOverlayMovieThumbnail(CapsAlbumFileId *file_id, u64 *out_size, void* image, u64 image_size); + +/** + * @brief Gets the currently set autosaving storage. + * @note Wrapper around setsysGetPrimaryAlbumStorage but defaults to NAND if SD isn't available. + * @param[out] storage \ref CapsAlbumStorage + */ +Result capsaGetAutoSavingStorage(CapsAlbumStorage *storage); + +/** + * @brief Gets required size to copy all files from one Storage to another. + * @param[in] dst_storage \ref CapsAlbumStorage + * @param[in] src_storage \ref CapsAlbumStorage + * @param[out] out Required storage space size. + */ +Result capsaGetRequiredStorageSpaceSizeToCopyAll(CapsAlbumStorage dst_storage, CapsAlbumStorage src_storage, u64 *out); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [3.0.0+]. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttribute + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsLoadAlbumScreenShotThumbnailImageEx0(u64 *width, u64 *height, CapsScreenShotAttribute *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @note Only available on [4.0.0+]. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] out \ref CapsLoadAlbumScreenShotImageOutput + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @note Only available on [4.0.0+]. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] opts \ref CapsScreenShotDecodeOption + * @param[out] out \ref CapsLoadAlbumScreenShotImageOutput + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + */ +Result capsaLoadAlbumScreenShotThumbnailImageEx1(const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, CapsLoadAlbumScreenShotImageOutput *out, void* image, u64 image_size, void* workbuf, u64 workbuf_size); + +/** + * @brief Unmounts the specified AlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capsaForceAlbumUnmounted(CapsAlbumStorage storage); + +/** + * @brief Resets mount status for the specified AlbumStorage. + * @note Mounts the Storage if available. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capsaResetAlbumMountStatus(CapsAlbumStorage storage); + +/** + * @brief Refreshs Album Cache for the specified AlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capsaRefreshAlbumCache(CapsAlbumStorage storage); + +/** + * @brief Gets the AlbumCache of the specified AlbumStorage. + * @note Stubbed on [4.0.0+]. + * @note use \ref capsaGetAlbumCacheEx instead. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] cache \ref CapsAlbumCache + */ +Result capsaGetAlbumCache(CapsAlbumStorage storage, CapsAlbumCache *cache); + +/** + * @brief Gets the AlbumCache for the specified type of the specified AlbumStorage. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] contents \ref CapsAlbumFileContents + * @param[out] cache \ref CapsAlbumCache + */ +Result capsaGetAlbumCacheEx(CapsAlbumStorage storage, CapsAlbumFileContents contents, CapsAlbumCache *cache); + +/** + * @brief Load an \ref CapsAlbumEntry from a \ref CapsApplicationAlbumEntry and an AppletResourceUserId. + * @note Only available on [2.0.0+]. + * @param[out] entry \ref CapsAlbumEntry + * @param[in] application_entry \ref CapsApplicationAlbumEntry + */ +Result capsaGetAlbumEntryFromApplicationAlbumEntryAruid(CapsAlbumEntry *entry, const CapsApplicationAlbumEntry *application_entry); + +/** + * @brief Opens an AlbumMovieStream. + * @note This opens IAlbumAccessorSession if not previously opened, it's closed during \ref capsaExit. + * @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsAlbumFileId. + * @note Only available on [4.0.0+]. + * @param[out] stream Stream handle. + * @param[in] entry \ref CapsAlbumFileId + */ +Result capsaOpenAlbumMovieStream(u64 *stream, const CapsAlbumFileId *file_id); + +/** + * @brief Closes an AlbumMovieStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capsaCloseAlbumMovieStream(u64 stream); + +/** + * @brief Gets the data size of an AlbumMovieStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Size of the actual MP4, without the JPEG at the end. + */ +Result capsaGetAlbumMovieStreamSize(u64 stream, u64 *size); + +/** + * @brief Reads data from an AlbumMovieStream. + * @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. + * @note When offset(+size) goes beyond the size from \ref capsaGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capsaReadMovieDataFromAlbumMovieReadStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size); + +/** + * @brief Gets the BrokenReason for an AlbumMovieStream. + * @note Official sw doesn't use this. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capsaGetAlbumMovieReadStreamBrokenReason(u64 stream); + +/** + * @brief Gets the data size of an Image taken from an AlbumMovieStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Expected size of an Image. + */ +Result capsaGetAlbumMovieReadStreamImageDataSize(u64 stream, u64 *size); + +/** + * @brief Reads data of an Image taken from an AlbumMovieStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capsaReadImageDataFromAlbumMovieReadStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size); + +/** + * @brief Gets the file attribute of an AlbumMovieStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] attr \ref CapsScreenShotAttribute + */ +Result capsaReadFileAttributeFromAlbumMovieReadStream(u64 stream, CapsScreenShotAttribute *attr); diff --git a/src/libnx/wrapper/switch/services/capsa.nim b/src/libnx/wrapper/switch/services/capsa.nim new file mode 100644 index 0000000..b4bf429 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsa.nim @@ -0,0 +1,500 @@ +## * +## @file capsa.h +## @brief Album Accessor (caps:a) service IPC wrapper. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/caps + +## / Initialize caps:a. + +proc capsaInitialize*(): Result {.cdecl, importc: "capsaInitialize".} +## / Exit caps:a. + +proc capsaExit*() {.cdecl, importc: "capsaExit".} +## / Gets the Service for caps:a. + +proc capsaGetServiceSession*(): ptr Service {.cdecl, + importc: "capsaGetServiceSession".} +## / Gets the Service for IAlbumAccessorSession, only initialized after \ref capsaOpenAlbumMovieStream was used (unaffected by using \ref capsaCloseAlbumMovieStream). + +proc capsaGetServiceSessionAccessor*(): ptr Service {.cdecl, + importc: "capsaGetServiceSession_Accessor".} +## * +## @brief Gets the amount of files at a AlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] count Amount of files. +## + +proc capsaGetAlbumFileCount*(storage: CapsAlbumStorage; count: ptr U64): Result {. + cdecl, importc: "capsaGetAlbumFileCount".} +## * +## @brief Gets a listing of \ref CapsAlbumEntry, where the AlbumFile's storage matches the input one. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] out Total output entries. +## @param[out] entries Output array of \ref CapsAlbumEntry. +## @param[in] count Reserved entry count. +## + +proc capsaGetAlbumFileList*(storage: CapsAlbumStorage; `out`: ptr U64; + entries: ptr CapsAlbumEntry; count: U64): Result {.cdecl, + importc: "capsaGetAlbumFileList".} +## * +## @brief Loads a file into the specified buffer. +## @param[in] file_id \ref CapsAlbumFileId +## @param[out] out_size Size of the AlbumFile. +## @param[out] filebuf File output buffer. +## @param[in] filebuf_size Size of the filebuf. +## + +proc capsaLoadAlbumFile*(fileId: ptr CapsAlbumFileId; outSize: ptr U64; + filebuf: pointer; filebufSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumFile".} +## * +## @brief Deletes an AlbumFile corresponding to the specified \ref CapsAlbumFileId. +## @param[in] file_id \ref CapsAlbumFileId +## + +proc capsaDeleteAlbumFile*(fileId: ptr CapsAlbumFileId): Result {.cdecl, + importc: "capsaDeleteAlbumFile".} +## * +## @brief Copies an AlbumFile to the specified \ref CapsAlbumStorage. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] dst_storage \ref CapsAlbumStorage +## + +proc capsaStorageCopyAlbumFile*(fileId: ptr CapsAlbumFileId; + dstStorage: CapsAlbumStorage): Result {.cdecl, + importc: "capsaStorageCopyAlbumFile".} +## * +## @brief Gets the mount status of the specified \ref CapsAlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] is_mounted Boolean over whether the storage is mounted or not. +## + +proc capsaIsAlbumMounted*(storage: CapsAlbumStorage; isMounted: ptr bool): Result {. + cdecl, importc: "capsaIsAlbumMounted".} +## * +## @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] out \ref CapsAlbumUsage2 +## + +proc capsaGetAlbumUsage*(storage: CapsAlbumStorage; `out`: ptr CapsAlbumUsage2): Result {. + cdecl, importc: "capsaGetAlbumUsage".} +## * +## @brief Gets the size for the specified AlbumFile. +## @param[in] file_id \ref CapsAlbumFileId +## @param[out] size Size of the file. +## + +proc capsaGetAlbumFileSize*(fileId: ptr CapsAlbumFileId; size: ptr U64): Result {.cdecl, + importc: "capsaGetAlbumFileSize".} +## * +## @brief Load the Thumbnail for the specified AlbumFile. +## @note Will always be 320x180. +## @param[in] file_id \ref CapsAlbumFileId +## @param[out] out_size Size of the Thumbnail. +## @param[out] image JPEG image output buffer. +## @param[in] image_size Image buffer size. +## + +proc capsaLoadAlbumFileThumbnail*(fileId: ptr CapsAlbumFileId; outSize: ptr U64; + image: pointer; imageSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumFileThumbnail".} +## * +## @brief Load the ScreenShotImage for the specified AlbumFile. +## @note Only available on [2.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[in] file_id \ref CapsAlbumFileId +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotImage*(width: ptr U64; height: ptr U64; + fileId: ptr CapsAlbumFileId; image: pointer; + imageSize: U64; workbuf: pointer; + workbufSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumScreenShotImage".} +## * +## @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. +## @note Only available on [2.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[in] file_id \ref CapsAlbumFileId +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotThumbnailImage*(width: ptr U64; height: ptr U64; + fileId: ptr CapsAlbumFileId; image: pointer; imageSize: U64; workbuf: pointer; + workbufSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumScreenShotThumbnailImage".} +## * +## @brief Load an \ref CapsAlbumEntry from a \ref CapsApplicationAlbumEntry and an ApplicationId. +## @note Only available on [2.0.0+]. +## @param[out] entry \ref CapsAlbumEntry +## @param[in] application_entry \ref CapsApplicationAlbumEntry +## @param[in] application_id ApplicationId +## + +proc capsaGetAlbumEntryFromApplicationAlbumEntry*(entry: ptr CapsAlbumEntry; + applicationEntry: ptr CapsApplicationAlbumEntry; applicationId: U64): Result {. + cdecl, importc: "capsaGetAlbumEntryFromApplicationAlbumEntry".} +## * +## @brief Load the ScreenShotImage for the specified AlbumFile. +## @note Only available on [3.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotImageEx*(width: ptr U64; height: ptr U64; + fileId: ptr CapsAlbumFileId; + opts: ptr CapsScreenShotDecodeOption; + image: pointer; imageSize: U64; + workbuf: pointer; workbufSize: U64): Result {. + cdecl, importc: "capsaLoadAlbumScreenShotImageEx".} +## * +## @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. +## @note Only available on [3.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotThumbnailImageEx*(width: ptr U64; height: ptr U64; + fileId: ptr CapsAlbumFileId; opts: ptr CapsScreenShotDecodeOption; image: pointer; + imageSize: U64; workbuf: pointer; workbufSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumScreenShotThumbnailImageEx".} +## * +## @brief Load the ScreenShotImage for the specified AlbumFile. +## @note Only available on [3.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[out] attr \ref CapsScreenShotAttribute +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotImageEx0*(width: ptr U64; height: ptr U64; + attr: ptr CapsScreenShotAttribute; + fileId: ptr CapsAlbumFileId; + opts: ptr CapsScreenShotDecodeOption; + image: pointer; imageSize: U64; + workbuf: pointer; workbufSize: U64): Result {. + cdecl, importc: "capsaLoadAlbumScreenShotImageEx0".} +## * +## @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. +## @note Only available on [4.0.0+]. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] out \ref CapsAlbumUsage3 +## + +proc capsaGetAlbumUsage3*(storage: CapsAlbumStorage; `out`: ptr CapsAlbumUsage3): Result {. + cdecl, importc: "capsaGetAlbumUsage3".} +## * +## @brief Returns the result for a AlbumStorage mount. +## @note Only available on [4.0.0+]. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capsaGetAlbumMountResult*(storage: CapsAlbumStorage): Result {.cdecl, + importc: "capsaGetAlbumMountResult".} +## * +## @brief Returns the AlbumUsage for a specified \ref CapsAlbumStorage. +## @note Only available on [4.0.0+]. +## @param[in] storage \ref CapsAlbumStorage +## @param[in] flags \ref CapsAlbumFileContentsFlag +## @param[out] out \ref CapsAlbumUsage16 +## + +proc capsaGetAlbumUsage16*(storage: CapsAlbumStorage; flags: U8; + `out`: ptr CapsAlbumUsage16): Result {.cdecl, + importc: "capsaGetAlbumUsage16".} +## * +## @brief Returns the start and end of the Applet Id range. +## @note Only available on [6.0.0+]. +## @param[out] success Returns bool over whether the call was handled or not. +## @param[out] min Mimimum applet id. Always 0x0100000000001000 +## @param[out] max Maximum applet id. Always 0x0100000000001FFF +## + +proc capsaGetMinMaxAppletId*(success: ptr bool; min: ptr U64; max: ptr U64): Result {. + cdecl, importc: "capsaGetMinMaxAppletId".} +## * +## @brief Gets the amount of files of the specified type at a AlbumStorage. +## @note Only available on [5.0.0+]. +## @param[in] storage \ref CapsAlbumStorage +## @param[in] flags \ref CapsAlbumFileContentsFlag +## @param[out] count Amount of files. +## + +proc capsaGetAlbumFileCountEx0*(storage: CapsAlbumStorage; flags: U8; count: ptr U64): Result {. + cdecl, importc: "capsaGetAlbumFileCountEx0".} +## * +## @brief Gets a listing of \ref CapsAlbumEntry, where the AlbumFile's storage and type matches the input one. +## @note Only available on [5.0.0+]. +## @param[in] storage \ref CapsAlbumStorage +## @param[in] flags \ref CapsAlbumFileContentsFlag +## @param[out] out Total output entries. +## @param[out] entries Output array of \ref CapsAlbumEntry. +## @param[in] count Reserved entry count. +## + +proc capsaGetAlbumFileListEx0*(storage: CapsAlbumStorage; flags: U8; `out`: ptr U64; + entries: ptr CapsAlbumEntry; count: U64): Result {. + cdecl, importc: "capsaGetAlbumFileListEx0".} +## * +## @brief Returns the image from the last shown ScreenShot Overlay. +## @param[out] file_id \ref CapsAlbumFileId +## @param[out] out_size Size of the thumbnail image. Always 0x5100. +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. +## + +proc capsaGetLastOverlayScreenShotThumbnail*(fileId: ptr CapsAlbumFileId; + outSize: ptr U64; image: pointer; imageSize: U64): Result {.cdecl, + importc: "capsaGetLastOverlayScreenShotThumbnail".} +## * +## @brief Returns the image from the last shown Movie Overlay. +## @note Only available on [4.0.0+]. +## @param[out] file_id \ref CapsAlbumFileId +## @param[out] out_size Size of the thumbnail image. Always 0x5100. +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. +## + +proc capsaGetLastOverlayMovieThumbnail*(fileId: ptr CapsAlbumFileId; + outSize: ptr U64; image: pointer; + imageSize: U64): Result {.cdecl, + importc: "capsaGetLastOverlayMovieThumbnail".} +## * +## @brief Gets the currently set autosaving storage. +## @note Wrapper around setsysGetPrimaryAlbumStorage but defaults to NAND if SD isn't available. +## @param[out] storage \ref CapsAlbumStorage +## + +proc capsaGetAutoSavingStorage*(storage: ptr CapsAlbumStorage): Result {.cdecl, + importc: "capsaGetAutoSavingStorage".} +## * +## @brief Gets required size to copy all files from one Storage to another. +## @param[in] dst_storage \ref CapsAlbumStorage +## @param[in] src_storage \ref CapsAlbumStorage +## @param[out] out Required storage space size. +## + +proc capsaGetRequiredStorageSpaceSizeToCopyAll*(dstStorage: CapsAlbumStorage; + srcStorage: CapsAlbumStorage; `out`: ptr U64): Result {.cdecl, + importc: "capsaGetRequiredStorageSpaceSizeToCopyAll".} +## * +## @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. +## @note Only available on [3.0.0+]. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[out] attr \ref CapsScreenShotAttribute +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsLoadAlbumScreenShotThumbnailImageEx0*(width: ptr U64; height: ptr U64; + attr: ptr CapsScreenShotAttribute; fileId: ptr CapsAlbumFileId; + opts: ptr CapsScreenShotDecodeOption; image: pointer; imageSize: U64; + workbuf: pointer; workbufSize: U64): Result {.cdecl, + importc: "capsLoadAlbumScreenShotThumbnailImageEx0".} +## * +## @brief Load the ScreenShotImage for the specified AlbumFile. +## @note Only available on [4.0.0+]. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] out \ref CapsLoadAlbumScreenShotImageOutput +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotImageEx1*(fileId: ptr CapsAlbumFileId; + opts: ptr CapsScreenShotDecodeOption; `out`: ptr CapsLoadAlbumScreenShotImageOutput; + image: pointer; imageSize: U64; + workbuf: pointer; workbufSize: U64): Result {. + cdecl, importc: "capsaLoadAlbumScreenShotImageEx1".} +## * +## @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. +## @note Only available on [4.0.0+]. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] opts \ref CapsScreenShotDecodeOption +## @param[out] out \ref CapsLoadAlbumScreenShotImageOutput +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## + +proc capsaLoadAlbumScreenShotThumbnailImageEx1*(fileId: ptr CapsAlbumFileId; + opts: ptr CapsScreenShotDecodeOption; + `out`: ptr CapsLoadAlbumScreenShotImageOutput; image: pointer; imageSize: U64; + workbuf: pointer; workbufSize: U64): Result {.cdecl, + importc: "capsaLoadAlbumScreenShotThumbnailImageEx1".} +## * +## @brief Unmounts the specified AlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capsaForceAlbumUnmounted*(storage: CapsAlbumStorage): Result {.cdecl, + importc: "capsaForceAlbumUnmounted".} +## * +## @brief Resets mount status for the specified AlbumStorage. +## @note Mounts the Storage if available. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capsaResetAlbumMountStatus*(storage: CapsAlbumStorage): Result {.cdecl, + importc: "capsaResetAlbumMountStatus".} +## * +## @brief Refreshs Album Cache for the specified AlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capsaRefreshAlbumCache*(storage: CapsAlbumStorage): Result {.cdecl, + importc: "capsaRefreshAlbumCache".} +## * +## @brief Gets the AlbumCache of the specified AlbumStorage. +## @note Stubbed on [4.0.0+]. +## @note use \ref capsaGetAlbumCacheEx instead. +## @param[in] storage \ref CapsAlbumStorage +## @param[out] cache \ref CapsAlbumCache +## + +proc capsaGetAlbumCache*(storage: CapsAlbumStorage; cache: ptr CapsAlbumCache): Result {. + cdecl, importc: "capsaGetAlbumCache".} +## * +## @brief Gets the AlbumCache for the specified type of the specified AlbumStorage. +## @param[in] storage \ref CapsAlbumStorage +## @param[in] contents \ref CapsAlbumFileContents +## @param[out] cache \ref CapsAlbumCache +## + +proc capsaGetAlbumCacheEx*(storage: CapsAlbumStorage; + contents: CapsAlbumFileContents; + cache: ptr CapsAlbumCache): Result {.cdecl, + importc: "capsaGetAlbumCacheEx".} +## * +## @brief Load an \ref CapsAlbumEntry from a \ref CapsApplicationAlbumEntry and an AppletResourceUserId. +## @note Only available on [2.0.0+]. +## @param[out] entry \ref CapsAlbumEntry +## @param[in] application_entry \ref CapsApplicationAlbumEntry +## + +proc capsaGetAlbumEntryFromApplicationAlbumEntryAruid*(entry: ptr CapsAlbumEntry; + applicationEntry: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "capsaGetAlbumEntryFromApplicationAlbumEntryAruid".} +## * +## @brief Opens an AlbumMovieStream. +## @note This opens IAlbumAccessorSession if not previously opened, it's closed during \ref capsaExit. +## @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsAlbumFileId. +## @note Only available on [4.0.0+]. +## @param[out] stream Stream handle. +## @param[in] entry \ref CapsAlbumFileId +## + +proc capsaOpenAlbumMovieStream*(stream: ptr U64; fileId: ptr CapsAlbumFileId): Result {. + cdecl, importc: "capsaOpenAlbumMovieStream".} +## * +## @brief Closes an AlbumMovieStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capsaCloseAlbumMovieStream*(stream: U64): Result {.cdecl, + importc: "capsaCloseAlbumMovieStream".} +## * +## @brief Gets the data size of an AlbumMovieStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Size of the actual MP4, without the JPEG at the end. +## + +proc capsaGetAlbumMovieStreamSize*(stream: U64; size: ptr U64): Result {.cdecl, + importc: "capsaGetAlbumMovieStreamSize".} +## * +## @brief Reads data from an AlbumMovieStream. +## @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. +## @note When offset(+size) goes beyond the size from \ref capsaGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capsaReadMovieDataFromAlbumMovieReadStream*(stream: U64; offset: S64; + buffer: pointer; size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "capsaReadMovieDataFromAlbumMovieReadStream".} +## * +## @brief Gets the BrokenReason for an AlbumMovieStream. +## @note Official sw doesn't use this. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capsaGetAlbumMovieReadStreamBrokenReason*(stream: U64): Result {.cdecl, + importc: "capsaGetAlbumMovieReadStreamBrokenReason".} +## * +## @brief Gets the data size of an Image taken from an AlbumMovieStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Expected size of an Image. +## + +proc capsaGetAlbumMovieReadStreamImageDataSize*(stream: U64; size: ptr U64): Result {. + cdecl, importc: "capsaGetAlbumMovieReadStreamImageDataSize".} +## * +## @brief Reads data of an Image taken from an AlbumMovieStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capsaReadImageDataFromAlbumMovieReadStream*(stream: U64; offset: S64; + buffer: pointer; size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "capsaReadImageDataFromAlbumMovieReadStream".} +## * +## @brief Gets the file attribute of an AlbumMovieStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] attr \ref CapsScreenShotAttribute +## + +proc capsaReadFileAttributeFromAlbumMovieReadStream*(stream: U64; + attr: ptr CapsScreenShotAttribute): Result {.cdecl, + importc: "capsaReadFileAttributeFromAlbumMovieReadStream".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capsc.h b/src/libnx/wrapper/switch/services/capsc.h new file mode 100644 index 0000000..c348022 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsc.h @@ -0,0 +1,333 @@ +/** + * @file capsc.h + * @brief Album Control (caps:c) service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" + +/// Initialize caps:c +Result capscInitialize(void); + +/// Exit caps:c. +void capscExit(void); + +/// Gets the Service for caps:c. +Service* capscGetServiceSession(void); + +/** + * @brief Notify the service that a storage is now available. + * @note This will result in capsrv mounting the image directory on that storage medium. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capscNotifyAlbumStorageIsAvailable(CapsAlbumStorage storage); + +/** + * @brief Notify the service that a storage is now unavailable. + * @note This will result in capsrv unmounting the image directory on that storage medium. + * @param[in] storage \ref CapsAlbumStorage + */ +Result capscNotifyAlbumStorageIsUnAvailable(CapsAlbumStorage storage); + +/** + * @brief Register an applet for later usage. + * @note Called at application launch by the system. + * @note Will generate a random AES-256 key for this application for use on Shim-Version 0. + * @note Only available on [2.0.0+]. + * @param[in] appletResourceUserId AppletResourceUserId. + * @param[in] application_id ApplicationId. + */ +Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id); + +/** + * @brief Unregister an applet. + * @note Called at application exit by the system. + * @note Only available on [2.0.0+]. + * @param[in] appletResourceUserId AppletResourceUserId. + * @param[in] application_id ApplicationId. + */ +Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id); + +/** + * @brief Get an ApplicationId that corresponds to an AppletResourceUserId. + * @note Returns value set by \ref capscRegisterAppletResourceUserId. + * @note Only available on [2.0.0+]. + * @param[out] application_id ApplicationId. + * @param[in] appletResourceUserId AppletResourceUserId. + */ +Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid); + +/** + * @brief Checks whether an ApplicationId is registered. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + */ +Result capscCheckApplicationIdRegistered(u64 application_id); + +/** + * @brief Generate an AlbumFileId based on parameters and current time. + * @param[in] application_id ApplicationId. + * @note Only available on [2.0.0+]. + * @param[in] contents \ref CapsAlbumFileContents + * @param[out] file_id \ref CapsAlbumFileId + */ +Result capscGenerateCurrentAlbumFileId(u64 application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id); + +/** + * @brief Generate an ApplicationAlbumEntry based on parameters. + * @note Output will be different between Shim Version 0 and 1. + * @note Only available on [2.0.0+]. + * @param[out] appEntry \ref CapsApplicationAlbumEntry + * @param[in] entry \ref CapsAlbumEntry + * @param[in] application_id ApplicationId. + */ +Result capscGenerateApplicationAlbumEntry(CapsApplicationAlbumEntry *appEntry, const CapsAlbumEntry *entry, u64 application_id); + +/** + * @brief Save a jpeg image. + * @note Only available on [2.0.0-3.0.2]. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] buffer JPEG image buffer. + * @param[in] buffer_size Size of the JPEG image. + */ +Result capscSaveAlbumScreenShotFile(const CapsAlbumFileId *file_id, const void* buffer, u64 buffer_size); + +/** + * @brief Save a jpeg image. + * @note Only available on [4.0.0+]. + * @note Version 3 as of [9.1.0]. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] version Revision number. + * @param[in] makernote_offset Offset to makernote in JPEG buffer. + * @param[in] makernote_size Size of the makernote in JPEG buffer. + * @param[in] buffer JPEG image buffer. + * @param[in] buffer_size Size of the JPEG image. + */ +Result capscSaveAlbumScreenShotFileEx(const CapsAlbumFileId *file_id, u64 version, u64 makernote_offset, u64 makernote_size, const void* buffer, u64 buffer_size); + +/** + * @brief Sets thumbnail data for the last taken screenshot. + * @note 96×54 Image will get saved. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] image RGBA8 image buffer. + * @param[in] image_size size of the RGBA8 image buffer. + */ +Result capscSetOverlayScreenShotThumbnailData(const CapsAlbumFileId *file_id, const void* image, u64 image_size); + +/** + * @brief Sets thumbnail data for the last recorded movie. + * @note Only availabe on [4.0.0+]. + * @note 96×54 Image will get saved. + * @param[in] file_id \ref CapsAlbumFileId + * @param[in] image RGBA8 image buffer. + * @param[in] image_size size of the RGBA8 image buffer. + */ +Result capscSetOverlayMovieThumbnailData(const CapsAlbumFileId *file_id, const void* image, u64 image_size); + +/** + * @brief Opens an AlbumMovieReadStream. + * @note This opens IAlbumControlSession if not previously opened, it's closed during \ref capscExit. + * @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsAlbumFileId. + * @note Only available on [4.0.0+]. + * @param[out] stream Stream handle. + * @param[in] entry \ref CapsAlbumFileId + */ +Result capscOpenAlbumMovieReadStream(u64 *stream, const CapsAlbumFileId *file_id); + +/** + * @brief Closes an AlbumMovieReadStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscCloseAlbumMovieStream(u64 stream); + +/** + * @brief Gets the data size of an AlbumMovieReadStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Size of the actual MP4, without the JPEG at the end. + */ +Result capscGetAlbumMovieStreamSize(u64 stream, u64 *size); + +/** + * @brief Reads data from an AlbumMovieReadStream. + * @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. + * @note When offset(+size) goes beyond the size from \ref capscGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capscReadMovieDataFromAlbumMovieReadStream(u64 stream, u64 offset, void* buffer, size_t size, u64 *actual_size); + +/** + * @brief Gets the BrokenReason for an AlbumMovieReadStream. + * @note Official sw doesn't use this. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscGetAlbumMovieReadStreamBrokenReason(u64 stream); + +/** + * @brief Gets the data size of an Image taken from an AlbumMovieReadStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Expected size of an Image. + */ +Result capscGetAlbumMovieReadStreamImageDataSize(u64 stream, u64 *size); + +/** + * @brief Reads data of an Image taken from an AlbumMovieReadStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] buffer Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capscReadImageDataFromAlbumMovieReadStream(u64 stream, u64 offset, void* buffer, size_t size, u64 *actual_size); + +/** + * @brief Gets the file attribute of an AlbumMovieReadStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] attr \ref CapsScreenShotAttribute + */ +Result capscReadFileAttributeFromAlbumMovieReadStream(u64 stream, CapsScreenShotAttribute *attribute); + +/** + * @brief Opens an AlbumMovieWriteStream. + * @note This opens IAlbumControlSession if not previously opened, it's closed during \ref capsaExit. + * @note Up to 2 streams can be open at the same time. + * @note Only available on [4.0.0+]. + * @param[out] stream Stream handle. + * @param[in] entry \ref CapsAlbumFileId + */ +Result capscOpenAlbumMovieWriteStream(u64 *stream, const CapsAlbumFileId *file_id); + +/** + * @brief Finish write to AlbumMovieWriteStream. + * @note Copies file from save to destination storage and deletes the temporary file. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscFinishAlbumMovieWriteStream(u64 stream); + +/** + * @brief Closes a finished AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscCommitAlbumMovieWriteStream(u64 stream); + +/** + * @brief Closes an AlbumMovieWriteStream in any state. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscDiscardAlbumMovieWriteStream(u64 stream); + +/** + * @brief Closes an AlbumMovieWriteStream in any state without deleting the temporary file. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscDiscardAlbumMovieWriteStreamNoDelete(u64 stream); + +/** + * @brief Closes a finished AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] entry \ref CapsAlbumEntry + */ +Result capscCommitAlbumMovieWriteStreamEx(u64 stream, CapsAlbumEntry *entry); + +/** + * @brief Start AlbumMovieWriteStream data section. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscStartAlbumMovieWriteStreamDataSection(u64 stream); + +/** + * @brief End AlbumMovieWriteStream data section. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscEndAlbumMovieWriteStreamDataSection(u64 stream); + +/** + * @brief Start AlbumMovieWriteStream meta section. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscStartAlbumMovieWriteStreamMetaSection(u64 stream); + +/** + * @brief End AlbumMovieWriteStream meta section. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscEndAlbumMovieWriteStreamMetaSection(u64 stream); + +/** + * @brief Reads data from an AlbumMovieWriteStream. + * @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. + * @note When offset(+size) goes beyond the size from \ref capscGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] buffer Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capscReadDataFromAlbumMovieWriteStream(u64 stream, u64 offset, void* buffer, u64 size, u64 *actual_size); + +/** + * @brief Write data to an AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[in] buffer Input data buffer. + * @param[in] size Data buffer size. + */ +Result capscWriteDataToAlbumMovieWriteStream(u64 stream, u64 offset, const void* buffer, u64 size); + +/** + * @brief Write meta data to an AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[in] buffer Input data buffer. + * @param[in] size Data buffer size. + */ +Result capscWriteMetaToAlbumMovieWriteStream(u64 stream, u64 offset, const void* buffer, u64 size); + +/** + * @brief Gets the BrokenReason for an AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + */ +Result capscGetAlbumMovieWriteStreamBrokenReason(u64 stream); + +/** + * @brief Gets the data size of an AlbumMovieWriteStream. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Size of the data section. + */ +Result capscGetAlbumMovieWriteStreamDataSize(u64 stream, u64 *size); + +/** + * @brief Sets the data size of an AlbumMovieWriteStream. + * @note Must not be bigger than 2GiB. + * @note Only available on [4.0.0+]. + * @param[in] stream Stream handle. + * @param[out] size Size of the data section. + */ +Result capscSetAlbumMovieWriteStreamDataSize(u64 stream, u64 size); diff --git a/src/libnx/wrapper/switch/services/capsc.nim b/src/libnx/wrapper/switch/services/capsc.nim new file mode 100644 index 0000000..e24e727 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsc.nim @@ -0,0 +1,385 @@ +## * +## @file capsc.h +## @brief Album Control (caps:c) service IPC wrapper. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/caps + +## / Initialize caps:c + +proc capscInitialize*(): Result {.cdecl, importc: "capscInitialize".} +## / Exit caps:c. + +proc capscExit*() {.cdecl, importc: "capscExit".} +## / Gets the Service for caps:c. + +proc capscGetServiceSession*(): ptr Service {.cdecl, + importc: "capscGetServiceSession".} +## * +## @brief Notify the service that a storage is now available. +## @note This will result in capsrv mounting the image directory on that storage medium. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capscNotifyAlbumStorageIsAvailable*(storage: CapsAlbumStorage): Result {.cdecl, + importc: "capscNotifyAlbumStorageIsAvailable".} +## * +## @brief Notify the service that a storage is now unavailable. +## @note This will result in capsrv unmounting the image directory on that storage medium. +## @param[in] storage \ref CapsAlbumStorage +## + +proc capscNotifyAlbumStorageIsUnAvailable*(storage: CapsAlbumStorage): Result {. + cdecl, importc: "capscNotifyAlbumStorageIsUnAvailable".} +## * +## @brief Register an applet for later usage. +## @note Called at application launch by the system. +## @note Will generate a random AES-256 key for this application for use on Shim-Version 0. +## @note Only available on [2.0.0+]. +## @param[in] appletResourceUserId AppletResourceUserId. +## @param[in] application_id ApplicationId. +## + +proc capscRegisterAppletResourceUserId*(appletResourceUserId: U64; + applicationId: U64): Result {.cdecl, + importc: "capscRegisterAppletResourceUserId".} +## * +## @brief Unregister an applet. +## @note Called at application exit by the system. +## @note Only available on [2.0.0+]. +## @param[in] appletResourceUserId AppletResourceUserId. +## @param[in] application_id ApplicationId. +## + +proc capscUnregisterAppletResourceUserId*(appletResourceUserId: U64; + applicationId: U64): Result {.cdecl, + importc: "capscUnregisterAppletResourceUserId".} +## * +## @brief Get an ApplicationId that corresponds to an AppletResourceUserId. +## @note Returns value set by \ref capscRegisterAppletResourceUserId. +## @note Only available on [2.0.0+]. +## @param[out] application_id ApplicationId. +## @param[in] appletResourceUserId AppletResourceUserId. +## + +proc capscGetApplicationIdFromAruid*(applicationId: ptr U64; aruid: U64): Result {. + cdecl, importc: "capscGetApplicationIdFromAruid".} +## * +## @brief Checks whether an ApplicationId is registered. +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## + +proc capscCheckApplicationIdRegistered*(applicationId: U64): Result {.cdecl, + importc: "capscCheckApplicationIdRegistered".} +## * +## @brief Generate an AlbumFileId based on parameters and current time. +## @param[in] application_id ApplicationId. +## @note Only available on [2.0.0+]. +## @param[in] contents \ref CapsAlbumFileContents +## @param[out] file_id \ref CapsAlbumFileId +## + +proc capscGenerateCurrentAlbumFileId*(applicationId: U64; + contents: CapsAlbumFileContents; + fileId: ptr CapsAlbumFileId): Result {.cdecl, + importc: "capscGenerateCurrentAlbumFileId".} +## * +## @brief Generate an ApplicationAlbumEntry based on parameters. +## @note Output will be different between Shim Version 0 and 1. +## @note Only available on [2.0.0+]. +## @param[out] appEntry \ref CapsApplicationAlbumEntry +## @param[in] entry \ref CapsAlbumEntry +## @param[in] application_id ApplicationId. +## + +proc capscGenerateApplicationAlbumEntry*(appEntry: ptr CapsApplicationAlbumEntry; + entry: ptr CapsAlbumEntry; + applicationId: U64): Result {.cdecl, + importc: "capscGenerateApplicationAlbumEntry".} +## * +## @brief Save a jpeg image. +## @note Only available on [2.0.0-3.0.2]. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] buffer JPEG image buffer. +## @param[in] buffer_size Size of the JPEG image. +## + +proc capscSaveAlbumScreenShotFile*(fileId: ptr CapsAlbumFileId; buffer: pointer; + bufferSize: U64): Result {.cdecl, + importc: "capscSaveAlbumScreenShotFile".} +## * +## @brief Save a jpeg image. +## @note Only available on [4.0.0+]. +## @note Version 3 as of [9.1.0]. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] version Revision number. +## @param[in] makernote_offset Offset to makernote in JPEG buffer. +## @param[in] makernote_size Size of the makernote in JPEG buffer. +## @param[in] buffer JPEG image buffer. +## @param[in] buffer_size Size of the JPEG image. +## + +proc capscSaveAlbumScreenShotFileEx*(fileId: ptr CapsAlbumFileId; version: U64; + makernoteOffset: U64; makernoteSize: U64; + buffer: pointer; bufferSize: U64): Result {. + cdecl, importc: "capscSaveAlbumScreenShotFileEx".} +## * +## @brief Sets thumbnail data for the last taken screenshot. +## @note 96×54 Image will get saved. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] image RGBA8 image buffer. +## @param[in] image_size size of the RGBA8 image buffer. +## + +proc capscSetOverlayScreenShotThumbnailData*(fileId: ptr CapsAlbumFileId; + image: pointer; imageSize: U64): Result {.cdecl, + importc: "capscSetOverlayScreenShotThumbnailData".} +## * +## @brief Sets thumbnail data for the last recorded movie. +## @note Only availabe on [4.0.0+]. +## @note 96×54 Image will get saved. +## @param[in] file_id \ref CapsAlbumFileId +## @param[in] image RGBA8 image buffer. +## @param[in] image_size size of the RGBA8 image buffer. +## + +proc capscSetOverlayMovieThumbnailData*(fileId: ptr CapsAlbumFileId; image: pointer; + imageSize: U64): Result {.cdecl, + importc: "capscSetOverlayMovieThumbnailData".} +## * +## @brief Opens an AlbumMovieReadStream. +## @note This opens IAlbumControlSession if not previously opened, it's closed during \ref capscExit. +## @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsAlbumFileId. +## @note Only available on [4.0.0+]. +## @param[out] stream Stream handle. +## @param[in] entry \ref CapsAlbumFileId +## + +proc capscOpenAlbumMovieReadStream*(stream: ptr U64; fileId: ptr CapsAlbumFileId): Result {. + cdecl, importc: "capscOpenAlbumMovieReadStream".} +## * +## @brief Closes an AlbumMovieReadStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscCloseAlbumMovieStream*(stream: U64): Result {.cdecl, + importc: "capscCloseAlbumMovieStream".} +## * +## @brief Gets the data size of an AlbumMovieReadStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Size of the actual MP4, without the JPEG at the end. +## + +proc capscGetAlbumMovieStreamSize*(stream: U64; size: ptr U64): Result {.cdecl, + importc: "capscGetAlbumMovieStreamSize".} +## * +## @brief Reads data from an AlbumMovieReadStream. +## @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. +## @note When offset(+size) goes beyond the size from \ref capscGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capscReadMovieDataFromAlbumMovieReadStream*(stream: U64; offset: U64; + buffer: pointer; size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "capscReadMovieDataFromAlbumMovieReadStream".} +## * +## @brief Gets the BrokenReason for an AlbumMovieReadStream. +## @note Official sw doesn't use this. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscGetAlbumMovieReadStreamBrokenReason*(stream: U64): Result {.cdecl, + importc: "capscGetAlbumMovieReadStreamBrokenReason".} +## * +## @brief Gets the data size of an Image taken from an AlbumMovieReadStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Expected size of an Image. +## + +proc capscGetAlbumMovieReadStreamImageDataSize*(stream: U64; size: ptr U64): Result {. + cdecl, importc: "capscGetAlbumMovieReadStreamImageDataSize".} +## * +## @brief Reads data of an Image taken from an AlbumMovieReadStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] buffer Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capscReadImageDataFromAlbumMovieReadStream*(stream: U64; offset: U64; + buffer: pointer; size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "capscReadImageDataFromAlbumMovieReadStream".} +## * +## @brief Gets the file attribute of an AlbumMovieReadStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] attr \ref CapsScreenShotAttribute +## + +proc capscReadFileAttributeFromAlbumMovieReadStream*(stream: U64; + attribute: ptr CapsScreenShotAttribute): Result {.cdecl, + importc: "capscReadFileAttributeFromAlbumMovieReadStream".} +## * +## @brief Opens an AlbumMovieWriteStream. +## @note This opens IAlbumControlSession if not previously opened, it's closed during \ref capsaExit. +## @note Up to 2 streams can be open at the same time. +## @note Only available on [4.0.0+]. +## @param[out] stream Stream handle. +## @param[in] entry \ref CapsAlbumFileId +## + +proc capscOpenAlbumMovieWriteStream*(stream: ptr U64; fileId: ptr CapsAlbumFileId): Result {. + cdecl, importc: "capscOpenAlbumMovieWriteStream".} +## * +## @brief Finish write to AlbumMovieWriteStream. +## @note Copies file from save to destination storage and deletes the temporary file. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscFinishAlbumMovieWriteStream*(stream: U64): Result {.cdecl, + importc: "capscFinishAlbumMovieWriteStream".} +## * +## @brief Closes a finished AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscCommitAlbumMovieWriteStream*(stream: U64): Result {.cdecl, + importc: "capscCommitAlbumMovieWriteStream".} +## * +## @brief Closes an AlbumMovieWriteStream in any state. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscDiscardAlbumMovieWriteStream*(stream: U64): Result {.cdecl, + importc: "capscDiscardAlbumMovieWriteStream".} +## * +## @brief Closes an AlbumMovieWriteStream in any state without deleting the temporary file. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscDiscardAlbumMovieWriteStreamNoDelete*(stream: U64): Result {.cdecl, + importc: "capscDiscardAlbumMovieWriteStreamNoDelete".} +## * +## @brief Closes a finished AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] entry \ref CapsAlbumEntry +## + +proc capscCommitAlbumMovieWriteStreamEx*(stream: U64; entry: ptr CapsAlbumEntry): Result {. + cdecl, importc: "capscCommitAlbumMovieWriteStreamEx".} +## * +## @brief Start AlbumMovieWriteStream data section. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscStartAlbumMovieWriteStreamDataSection*(stream: U64): Result {.cdecl, + importc: "capscStartAlbumMovieWriteStreamDataSection".} +## * +## @brief End AlbumMovieWriteStream data section. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscEndAlbumMovieWriteStreamDataSection*(stream: U64): Result {.cdecl, + importc: "capscEndAlbumMovieWriteStreamDataSection".} +## * +## @brief Start AlbumMovieWriteStream meta section. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscStartAlbumMovieWriteStreamMetaSection*(stream: U64): Result {.cdecl, + importc: "capscStartAlbumMovieWriteStreamMetaSection".} +## * +## @brief End AlbumMovieWriteStream meta section. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscEndAlbumMovieWriteStreamMetaSection*(stream: U64): Result {.cdecl, + importc: "capscEndAlbumMovieWriteStreamMetaSection".} +## * +## @brief Reads data from an AlbumMovieWriteStream. +## @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. +## @note When offset(+size) goes beyond the size from \ref capscGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] buffer Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capscReadDataFromAlbumMovieWriteStream*(stream: U64; offset: U64; + buffer: pointer; size: U64; actualSize: ptr U64): Result {.cdecl, + importc: "capscReadDataFromAlbumMovieWriteStream".} +## * +## @brief Write data to an AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[in] buffer Input data buffer. +## @param[in] size Data buffer size. +## + +proc capscWriteDataToAlbumMovieWriteStream*(stream: U64; offset: U64; + buffer: pointer; size: U64): Result {.cdecl, importc: "capscWriteDataToAlbumMovieWriteStream".} +## * +## @brief Write meta data to an AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[in] buffer Input data buffer. +## @param[in] size Data buffer size. +## + +proc capscWriteMetaToAlbumMovieWriteStream*(stream: U64; offset: U64; + buffer: pointer; size: U64): Result {.cdecl, importc: "capscWriteMetaToAlbumMovieWriteStream".} +## * +## @brief Gets the BrokenReason for an AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## + +proc capscGetAlbumMovieWriteStreamBrokenReason*(stream: U64): Result {.cdecl, + importc: "capscGetAlbumMovieWriteStreamBrokenReason".} +## * +## @brief Gets the data size of an AlbumMovieWriteStream. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Size of the data section. +## + +proc capscGetAlbumMovieWriteStreamDataSize*(stream: U64; size: ptr U64): Result {. + cdecl, importc: "capscGetAlbumMovieWriteStreamDataSize".} +## * +## @brief Sets the data size of an AlbumMovieWriteStream. +## @note Must not be bigger than 2GiB. +## @note Only available on [4.0.0+]. +## @param[in] stream Stream handle. +## @param[out] size Size of the data section. +## + +proc capscSetAlbumMovieWriteStreamDataSize*(stream: U64; size: U64): Result {.cdecl, + importc: "capscSetAlbumMovieWriteStreamDataSize".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capsdc.h b/src/libnx/wrapper/switch/services/capsdc.h new file mode 100644 index 0000000..3498e9c --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsdc.h @@ -0,0 +1,32 @@ +/** + * @file capsdc.h + * @brief Jpeg Decoder (caps:dc) service IPC wrapper. Only available on [4.0.0+]. + * @note Only holds one session that is occupied by capsrv. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" + +/// Initialize caps:dc +Result capsdcInitialize(void); + +/// Exit caps:dc. +void capsdcExit(void); + +/// Gets the Service for caps:dc. +Service* capsdcGetServiceSession(void); + +/** + * @brief Decodes a jpeg buffer into RGBX. + * @param[in] width Image width. + * @param[in] height Image height. + * @param[in] opts \ref CapsScreenShotDecodeOption. + * @param[in] jpeg Jpeg image input buffer. + * @param[in] jpeg_size Input image buffer size. + * @param[out] out_image RGBA8 image output buffer. + * @param[in] out_image_size Output image buffer size, should be at least large enough for RGBA8 width x height. + */ +Result capsdcDecodeJpeg(u32 width, u32 height, const CapsScreenShotDecodeOption *opts, const void* jpeg, size_t jpeg_size, void* out_image, size_t out_image_size); diff --git a/src/libnx/wrapper/switch/services/capsdc.nim b/src/libnx/wrapper/switch/services/capsdc.nim new file mode 100644 index 0000000..5c384d6 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsdc.nim @@ -0,0 +1,36 @@ +## * +## @file capsdc.h +## @brief Jpeg Decoder (caps:dc) service IPC wrapper. Only available on [4.0.0+]. +## @note Only holds one session that is occupied by capsrv. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/caps + +## / Initialize caps:dc + +proc capsdcInitialize*(): Result {.cdecl, importc: "capsdcInitialize".} +## / Exit caps:dc. + +proc capsdcExit*() {.cdecl, importc: "capsdcExit".} +## / Gets the Service for caps:dc. + +proc capsdcGetServiceSession*(): ptr Service {.cdecl, + importc: "capsdcGetServiceSession".} +## * +## @brief Decodes a jpeg buffer into RGBX. +## @param[in] width Image width. +## @param[in] height Image height. +## @param[in] opts \ref CapsScreenShotDecodeOption. +## @param[in] jpeg Jpeg image input buffer. +## @param[in] jpeg_size Input image buffer size. +## @param[out] out_image RGBA8 image output buffer. +## @param[in] out_image_size Output image buffer size, should be at least large enough for RGBA8 width x height. +## + +proc capsdcDecodeJpeg*(width: U32; height: U32; opts: ptr CapsScreenShotDecodeOption; + jpeg: pointer; jpegSize: csize_t; outImage: pointer; + outImageSize: csize_t): Result {.cdecl, + importc: "capsdcDecodeJpeg".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capssc.h b/src/libnx/wrapper/switch/services/capssc.h new file mode 100644 index 0000000..f02420c --- /dev/null +++ b/src/libnx/wrapper/switch/services/capssc.h @@ -0,0 +1,74 @@ +/** + * @file capssc.h + * @brief Screenshot control (caps:sc) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "vi.h" + +#define CAPSSC_JPEG_BUFFER_SIZE 0x80000 + +/// Initialize caps:sc. Only available on [2.0.0+]. +Result capsscInitialize(void); + +/// Exit caps:sc. +void capsscExit(void); + +/// Gets the Service for caps:sc. +Service* capsscGetServiceSession(void); + +/** + * @brief This takes a screenshot, with the screenshot being written into the output buffer. + * @note Not available with [5.0.0+] (stubbed). + * @note buffer_index and buffer_count correspond to buffers with size 0x384000(1280*720*4). These must not be negative. + * @param buf Output buffer containing the RGBA8 image. + * @param size Size of buf, should be 0x384000(1280*720*4) * buffer_count. + * @param layer_stack \ref ViLayerStack + * @param width Image width, must be 1280. + * @param height Image height, must be 720. + * @param buffer_count Total number of output image buffers. + * @param buffer_index Starting image buffer index. Must be < buffer_count. + * @param timeout Timeout in nanoseconds. A default value of 100000000 can be used. + */ +Result capsscCaptureRawImageWithTimeout(void* buf, size_t size, ViLayerStack layer_stack, u64 width, u64 height, s64 buffer_count, s64 buffer_index, s64 timeout); + +/** + * @brief This takes a raw screenshot, with the screenshot being held until \ref capsscCloseRawScreenShotReadStream is called. + * @note Only available on [3.0.0+]. Requires debug mode. + * @param out_size Pointer to write the size of the captured raw image to. Always 0x384000(1280*720*4). + * @param out_width Pointer to write the width of the captured raw image to. Always 1280. + * @param out_height Pointer to write the height of the captured raw image to. Always 720. + * @param layer_stack \ref ViLayerStack + * @param timeout Timeout in nanoseconds. + */ +Result capsscOpenRawScreenShotReadStream(u64 *out_size, u64 *out_width, u64 *out_height, ViLayerStack layer_stack, s64 timeout); + +/** + * @brief Discards a stream opened by \ref capsscOpenRawScreenShotReadStream. + * @note Only available on [3.0.0+]. Requires debug mode. + */ +Result capsscCloseRawScreenShotReadStream(void); + +/** + * @brief Reads from a stream opened by \ref capsscOpenRawScreenShotReadStream. + * @note Only available on [3.0.0+]. Requires debug mode. + * @param bytes_read Pointer to write the amounts of bytes written to buffer. + * @param buf Output buffer containing the RGBA8 image. + * @param size Size of buf. + * @param offset Offset in image where read should start. + */ +Result capsscReadRawScreenShotReadStream(u64 *bytes_read, void* buf, size_t size, u64 offset); + +/** + * @brief This takes a screenshot, with the screenshot being written as jpeg into the output buffer. + * @note Only available on [9.0.0+]. Requires debug mode before [10.0.0]. + * @param out_jpeg_size Pointer to write the size of the captured jpeg to. + * @param jpeg_buf Output buffer containing the JPEG image. + * @param jpeg_buf_size Size of jpeg_buf, official software uses 0x80000. + * @param layer_stack \ref ViLayerStack + * @param timeout Timeout in nanoseconds. + */ +Result capsscCaptureJpegScreenShot(u64* out_jpeg_size, void* jpeg_buf, size_t jpeg_buf_size, ViLayerStack layer_stack, s64 timeout); \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capssc.nim b/src/libnx/wrapper/switch/services/capssc.nim new file mode 100644 index 0000000..7ba1384 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capssc.nim @@ -0,0 +1,89 @@ +## * +## @file capssc.h +## @brief Screenshot control (caps:sc) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, vi + +const + CAPSSC_JPEG_BUFFER_SIZE* = 0x80000 + +## / Initialize caps:sc. Only available on [2.0.0+]. + +proc capsscInitialize*(): Result {.cdecl, importc: "capsscInitialize".} +## / Exit caps:sc. + +proc capsscExit*() {.cdecl, importc: "capsscExit".} +## / Gets the Service for caps:sc. + +proc capsscGetServiceSession*(): ptr Service {.cdecl, + importc: "capsscGetServiceSession".} +## * +## @brief This takes a screenshot, with the screenshot being written into the output buffer. +## @note Not available with [5.0.0+] (stubbed). +## @note buffer_index and buffer_count correspond to buffers with size 0x384000(1280*720*4). These must not be negative. +## @param buf Output buffer containing the RGBA8 image. +## @param size Size of buf, should be 0x384000(1280*720*4) * buffer_count. +## @param layer_stack \ref ViLayerStack +## @param width Image width, must be 1280. +## @param height Image height, must be 720. +## @param buffer_count Total number of output image buffers. +## @param buffer_index Starting image buffer index. Must be < buffer_count. +## @param timeout Timeout in nanoseconds. A default value of 100000000 can be used. +## + +proc capsscCaptureRawImageWithTimeout*(buf: pointer; size: csize_t; + layerStack: ViLayerStack; width: U64; + height: U64; bufferCount: S64; + bufferIndex: S64; timeout: S64): Result {. + cdecl, importc: "capsscCaptureRawImageWithTimeout".} +## * +## @brief This takes a raw screenshot, with the screenshot being held until \ref capsscCloseRawScreenShotReadStream is called. +## @note Only available on [3.0.0+]. Requires debug mode. +## @param out_size Pointer to write the size of the captured raw image to. Always 0x384000(1280*720*4). +## @param out_width Pointer to write the width of the captured raw image to. Always 1280. +## @param out_height Pointer to write the height of the captured raw image to. Always 720. +## @param layer_stack \ref ViLayerStack +## @param timeout Timeout in nanoseconds. +## + +proc capsscOpenRawScreenShotReadStream*(outSize: ptr U64; outWidth: ptr U64; + outHeight: ptr U64; + layerStack: ViLayerStack; timeout: S64): Result {. + cdecl, importc: "capsscOpenRawScreenShotReadStream".} +## * +## @brief Discards a stream opened by \ref capsscOpenRawScreenShotReadStream. +## @note Only available on [3.0.0+]. Requires debug mode. +## + +proc capsscCloseRawScreenShotReadStream*(): Result {.cdecl, + importc: "capsscCloseRawScreenShotReadStream".} +## * +## @brief Reads from a stream opened by \ref capsscOpenRawScreenShotReadStream. +## @note Only available on [3.0.0+]. Requires debug mode. +## @param bytes_read Pointer to write the amounts of bytes written to buffer. +## @param buf Output buffer containing the RGBA8 image. +## @param size Size of buf. +## @param offset Offset in image where read should start. +## + +proc capsscReadRawScreenShotReadStream*(bytesRead: ptr U64; buf: pointer; + size: csize_t; offset: U64): Result {.cdecl, + importc: "capsscReadRawScreenShotReadStream".} +## * +## @brief This takes a screenshot, with the screenshot being written as jpeg into the output buffer. +## @note Only available on [9.0.0+]. Requires debug mode before [10.0.0]. +## @param out_jpeg_size Pointer to write the size of the captured jpeg to. +## @param jpeg_buf Output buffer containing the JPEG image. +## @param jpeg_buf_size Size of jpeg_buf, official software uses 0x80000. +## @param layer_stack \ref ViLayerStack +## @param timeout Timeout in nanoseconds. +## + +proc capsscCaptureJpegScreenShot*(outJpegSize: ptr U64; jpegBuf: pointer; + jpegBufSize: csize_t; layerStack: ViLayerStack; + timeout: S64): Result {.cdecl, + importc: "capsscCaptureJpegScreenShot".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capssu.h b/src/libnx/wrapper/switch/services/capssu.h new file mode 100644 index 0000000..a6dce63 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capssu.h @@ -0,0 +1,94 @@ +/** + * @file capssu.h + * @brief Application screenshot saving (caps:su) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/acc.h" +#include "../services/caps.h" + +/// Initialize caps:su. Only available on [4.0.0+]. +Result capssuInitialize(void); + +/// Exit caps:su. +void capssuExit(void); + +/// Gets the Service for caps:su. +Service* capssuGetServiceSession(void); + +/** + * @brief This is a wrapper for \ref capssuSaveScreenShotEx0. + * @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. + * @param[in] buffer RGBA8 1280x720 image buffer. + * @param[in] size Size of the buffer. + * @param[in] reportoption \ref AlbumReportOption + * @param[in] orientation \ref AlbumImageOrientation + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShot(const void* buffer, size_t size, AlbumReportOption reportoption, AlbumImageOrientation orientation, CapsApplicationAlbumEntry *out); + +/** + * @brief Similar to \ref capssuSaveScreenShot, except this is a wrapper for \ref capssuSaveScreenShotEx1. + * @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. + * @note Only available on [8.0.0+]. + * @param[in] buffer RGBA8 1280x720 image data buffer. + * @param[in] size Size of the buffer. + * @param[in] reportoption \ref AlbumReportOption + * @param[in] orientation \ref AlbumImageOrientation + * @param[in] userdata Input UserData buffer. If NULL, the \ref CapsApplicationData will be empty. + * @param[in] userdata_size Input UserData size, must be within bounds for CapsApplicationData::userdata. If 0, the \ref CapsApplicationData will be empty. + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShotWithUserData(const void* buffer, size_t size, AlbumReportOption reportoption, AlbumImageOrientation orientation, const void* userdata, size_t userdata_size, CapsApplicationAlbumEntry *out); + +/** + * @brief Similar to \ref capssuSaveScreenShot, except this is a wrapper for \ref capssuSaveScreenShotEx2. + * @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. + * @note Only available on [6.0.0+]. + * @param[in] buffer RGBA8 1280x720 image data buffer. + * @param[in] size Size of the buffer. + * @param[in] reportoption \ref AlbumReportOption + * @param[in] orientation \ref AlbumImageOrientation + * @param[in] uids Input array of \ref AccountUid. If NULL, the \ref CapsUserIdList will be empty. + * @param[in] uid_count Size of the uids array in entries, must be within bounds for CapsUserIdList::uids. If 0, the \ref CapsUserIdList will be empty. + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShotWithUserIds(const void* buffer, size_t size, AlbumReportOption reportoption, AlbumImageOrientation orientation, const AccountUid* uids, size_t uid_count, CapsApplicationAlbumEntry *out); + +/** + * @brief Saves an Album screenshot using the specified gfx data in the buffer, with the specified \ref CapsScreenShotAttribute. + * @param[in] buffer RGBA8 1280x720 image data buffer. + * @param[in] size Size of the buffer, must be at least 0x384000. + * @param[in] attr \ref CapsScreenShotAttribute + * @param[in] reportoption \ref AlbumReportOption + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShotEx0(const void* buffer, size_t size, const CapsScreenShotAttribute *attr, AlbumReportOption reportoption, CapsApplicationAlbumEntry *out); + +/** + * @brief Same as \ref capssuSaveScreenShotEx0, except this allows specifying the \ref CapsApplicationData. + * @note Only available on [8.0.0+]. + * @param[in] buffer RGBA8 1280x720 image data buffer. + * @param[in] size Size of the buffer, must be at least 0x384000. + * @param[in] attr \ref CapsScreenShotAttribute + * @param[in] reportoption \ref AlbumReportOption + * @param[in] appdata \ref CapsApplicationData + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShotEx1(const void* buffer, size_t size, const CapsScreenShotAttribute *attr, AlbumReportOption reportoption, CapsApplicationData *appdata, CapsApplicationAlbumEntry *out); + +/** + * @brief Same as \ref capssuSaveScreenShotEx0, except this allows specifying the \ref CapsUserIdList. + * @note Only available on [6.0.0+]. + * @param[in] buffer RGBA8 1280x720 image data buffer. + * @param[in] size Size of the buffer, must be at least 0x384000. + * @param[in] attr \ref CapsScreenShotAttribute + * @param[in] reportoption \ref AlbumReportOption + * @param[in] list \ref CapsUserIdList + * @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. + */ +Result capssuSaveScreenShotEx2(const void* buffer, size_t size, const CapsScreenShotAttribute *attr, AlbumReportOption reportoption, CapsUserIdList *list, CapsApplicationAlbumEntry *out); + diff --git a/src/libnx/wrapper/switch/services/capssu.nim b/src/libnx/wrapper/switch/services/capssu.nim new file mode 100644 index 0000000..1388348 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capssu.nim @@ -0,0 +1,121 @@ +## * +## @file capssu.h +## @brief Application screenshot saving (caps:su) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/acc, ../services/caps + +## / Initialize caps:su. Only available on [4.0.0+]. + +proc capssuInitialize*(): Result {.cdecl, importc: "capssuInitialize".} +## / Exit caps:su. + +proc capssuExit*() {.cdecl, importc: "capssuExit".} +## / Gets the Service for caps:su. + +proc capssuGetServiceSession*(): ptr Service {.cdecl, + importc: "capssuGetServiceSession".} +## * +## @brief This is a wrapper for \ref capssuSaveScreenShotEx0. +## @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. +## @param[in] buffer RGBA8 1280x720 image buffer. +## @param[in] size Size of the buffer. +## @param[in] reportoption \ref AlbumReportOption +## @param[in] orientation \ref AlbumImageOrientation +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShot*(buffer: pointer; size: csize_t; + reportoption: AlbumReportOption; + orientation: AlbumImageOrientation; + `out`: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "capssuSaveScreenShot".} +## * +## @brief Similar to \ref capssuSaveScreenShot, except this is a wrapper for \ref capssuSaveScreenShotEx1. +## @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. +## @note Only available on [8.0.0+]. +## @param[in] buffer RGBA8 1280x720 image data buffer. +## @param[in] size Size of the buffer. +## @param[in] reportoption \ref AlbumReportOption +## @param[in] orientation \ref AlbumImageOrientation +## @param[in] userdata Input UserData buffer. If NULL, the \ref CapsApplicationData will be empty. +## @param[in] userdata_size Input UserData size, must be within bounds for CapsApplicationData::userdata. If 0, the \ref CapsApplicationData will be empty. +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShotWithUserData*(buffer: pointer; size: csize_t; + reportoption: AlbumReportOption; + orientation: AlbumImageOrientation; + userdata: pointer; userdataSize: csize_t; + `out`: ptr CapsApplicationAlbumEntry): Result {. + cdecl, importc: "capssuSaveScreenShotWithUserData".} +## * +## @brief Similar to \ref capssuSaveScreenShot, except this is a wrapper for \ref capssuSaveScreenShotEx2. +## @note This uses an all-zero \ref CapsScreenShotAttribute with orientation = input orientation, and unk_xc = 1. +## @note Only available on [6.0.0+]. +## @param[in] buffer RGBA8 1280x720 image data buffer. +## @param[in] size Size of the buffer. +## @param[in] reportoption \ref AlbumReportOption +## @param[in] orientation \ref AlbumImageOrientation +## @param[in] uids Input array of \ref AccountUid. If NULL, the \ref CapsUserIdList will be empty. +## @param[in] uid_count Size of the uids array in entries, must be within bounds for CapsUserIdList::uids. If 0, the \ref CapsUserIdList will be empty. +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShotWithUserIds*(buffer: pointer; size: csize_t; + reportoption: AlbumReportOption; + orientation: AlbumImageOrientation; + uids: ptr AccountUid; uidCount: csize_t; + `out`: ptr CapsApplicationAlbumEntry): Result {. + cdecl, importc: "capssuSaveScreenShotWithUserIds".} +## * +## @brief Saves an Album screenshot using the specified gfx data in the buffer, with the specified \ref CapsScreenShotAttribute. +## @param[in] buffer RGBA8 1280x720 image data buffer. +## @param[in] size Size of the buffer, must be at least 0x384000. +## @param[in] attr \ref CapsScreenShotAttribute +## @param[in] reportoption \ref AlbumReportOption +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShotEx0*(buffer: pointer; size: csize_t; + attr: ptr CapsScreenShotAttribute; + reportoption: AlbumReportOption; + `out`: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "capssuSaveScreenShotEx0".} +## * +## @brief Same as \ref capssuSaveScreenShotEx0, except this allows specifying the \ref CapsApplicationData. +## @note Only available on [8.0.0+]. +## @param[in] buffer RGBA8 1280x720 image data buffer. +## @param[in] size Size of the buffer, must be at least 0x384000. +## @param[in] attr \ref CapsScreenShotAttribute +## @param[in] reportoption \ref AlbumReportOption +## @param[in] appdata \ref CapsApplicationData +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShotEx1*(buffer: pointer; size: csize_t; + attr: ptr CapsScreenShotAttribute; + reportoption: AlbumReportOption; + appdata: ptr CapsApplicationData; + `out`: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "capssuSaveScreenShotEx1".} +## * +## @brief Same as \ref capssuSaveScreenShotEx0, except this allows specifying the \ref CapsUserIdList. +## @note Only available on [6.0.0+]. +## @param[in] buffer RGBA8 1280x720 image data buffer. +## @param[in] size Size of the buffer, must be at least 0x384000. +## @param[in] attr \ref CapsScreenShotAttribute +## @param[in] reportoption \ref AlbumReportOption +## @param[in] list \ref CapsUserIdList +## @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL. +## + +proc capssuSaveScreenShotEx2*(buffer: pointer; size: csize_t; + attr: ptr CapsScreenShotAttribute; + reportoption: AlbumReportOption; + list: ptr CapsUserIdList; + `out`: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "capssuSaveScreenShotEx2".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/capsu.h b/src/libnx/wrapper/switch/services/capsu.h new file mode 100644 index 0000000..06dfd09 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsu.h @@ -0,0 +1,173 @@ +/** + * @file capsu.h + * @brief Application Album (caps:u) service IPC wrapper. + * This is only usable with AlbumFiles associated with the current host Application. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" +#include "../services/acc.h" + +/// Initialize caps:u. Only available on [5.0.0+]. +Result capsuInitialize(void); + +/// Exit caps:u. +void capsuExit(void); + +/// Gets the Service for caps:u. +Service* capsuGetServiceSession(void); + +/// Gets the Service for IAlbumAccessorApplicationSession, only initialized after \ref capsuOpenAlbumMovieStream was used (unaffected by using \ref capsuCloseAlbumMovieStream). +Service* capsuGetServiceSession_Accessor(void); + +/** + * @brief Gets a listing of \ref CapsApplicationAlbumFileEntry. + * @note On [6.0.0+] this uses GetAlbumFileList1AafeAruidDeprecated, otherwise this uses GetAlbumFileList0AafeAruidDeprecated. + * @note This is an old version of \ref capsuGetAlbumFileList3. + * @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry. + * @param[in] count Max size of the output array in entries. + * @param[in] type \ref CapsContentType + * @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[out] total_entries Total output entries. + */ +Result capsuGetAlbumFileListDeprecated1(CapsApplicationAlbumFileEntry *entries, s32 count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, s32 *total_entries); + +/** + * @brief Gets a listing of \ref CapsApplicationAlbumFileEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds. + * @note Only available on [6.0.0+]. + * @note This is an old version of \ref capsuGetAlbumFileList4. + * @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry. + * @param[in] count Max size of the output array in entries. + * @param[in] type \ref CapsContentType + * @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] uid \ref AccountUid + * @param[out] total_entries Total output entries. + */ +Result capsuGetAlbumFileListDeprecated2(CapsApplicationAlbumFileEntry *entries, s32 count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, AccountUid uid, s32 *total_entries); + +/** + * @brief Gets a listing of \ref CapsApplicationAlbumEntry. + * @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated1 instead. + * @param[out] entries Output array of \ref CapsApplicationAlbumEntry. + * @param[in] count Max size of the output array in entries. + * @param[in] type \ref CapsContentType + * @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[out] total_entries Total output entries. + */ +Result capsuGetAlbumFileList3(CapsApplicationAlbumEntry *entries, s32 count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, s32 *total_entries); + +/** + * @brief Gets a listing of \ref CapsApplicationAlbumEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds. + * @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated2 instead. + * @param[out] entries Output array of \ref CapsApplicationAlbumEntry. + * @param[in] count Max size of the output array in entries. + * @param[in] type \ref CapsContentType + * @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. + * @param[in] uid \ref AccountUid + * @param[out] total_entries Total output entries. + */ +Result capsuGetAlbumFileList4(CapsApplicationAlbumEntry *entries, s32 count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, AccountUid uid, s32 *total_entries); + +/** + * @brief Deletes the specified AlbumFile. + * @param[in] type \ref CapsContentType, must match ::CapsContentType_ExtraMovie. + * @param[in] entry \ref CapsApplicationAlbumFileEntry + */ +Result capsuDeleteAlbumFile(CapsContentType type, const CapsApplicationAlbumFileEntry *entry); + +/** + * @brief Gets the filesize for the entire specified AlbumFile. + * @param[in] entry \ref CapsApplicationAlbumFileEntry + * @param[out] size Output filesize. + */ +Result capsuGetAlbumFileSize(const CapsApplicationAlbumFileEntry *entry, u64 *size); + +/** + * @brief Load the ScreenShotImage for the specified AlbumFile. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttributeForApplication + * @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy. + * @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0. + * @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed. + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + * @param[in] entry \ref CapsApplicationAlbumFileEntry + * @param[in] option \ref CapsScreenShotDecodeOption + */ +Result capsuLoadAlbumScreenShotImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option); + +/** + * @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. + * @param[out] width Output image width. Optional, can be NULL. + * @param[out] height Output image height. Optional, can be NULL. + * @param[out] attr \ref CapsScreenShotAttributeForApplication + * @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy. + * @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0. + * @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed. + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. + * @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. + * @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. + * @param[in] entry \ref CapsApplicationAlbumFileEntry + * @param[in] option \ref CapsScreenShotDecodeOption + */ +Result capsuLoadAlbumScreenShotThumbnailImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option); + +/** + * @brief PrecheckToCreateContents. Official sw only uses this with ::CapsContentType_ExtraMovie. + * @param[in] type \ref CapsContentType + * @param[in] unk Unknown. + */ +Result capsuPrecheckToCreateContents(CapsContentType type, u64 unk); + +/** + * @brief Opens an AlbumMovieStream. + * @note This opens IAlbumAccessorApplicationSession if not previously opened, it's closed during \ref capsuExit. + * @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsApplicationAlbumFileEntry. + * @param[out] stream Stream handle. + * @param[in] entry \ref CapsApplicationAlbumFileEntry + */ +Result capsuOpenAlbumMovieStream(u64 *stream, const CapsApplicationAlbumFileEntry *entry); + +/** + * @brief Closes an AlbumMovieStream. + * @param[in] stream Stream handle. + */ +Result capsuCloseAlbumMovieStream(u64 stream); + +/** + * @brief Gets the data size of an AlbumMovieStream. + * @param[in] stream Stream handle. + * @param[out] size Size of the actual MP4, without the JPEG at the end. + */ +Result capsuGetAlbumMovieStreamSize(u64 stream, u64 *size); + +/** + * @brief Reads data from an AlbumMovieStream. + * @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. + * @note When offset(+size) goes beyond the size from \ref capsuGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. + * @param[in] stream Stream handle. + * @param[in] offset Offset. + * @param[out] Output data buffer. + * @param[in] size Data buffer size. + * @param[out] actual_size Actual read size. + */ +Result capsuReadAlbumMovieStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size); + +/** + * @brief Gets the BrokenReason for an AlbumMovieStream. + * @note Official sw doesn't use this. + * @param[in] stream Stream handle. + */ +Result capsuGetAlbumMovieStreamBrokenReason(u64 stream); + diff --git a/src/libnx/wrapper/switch/services/capsu.nim b/src/libnx/wrapper/switch/services/capsu.nim new file mode 100644 index 0000000..0524cd7 --- /dev/null +++ b/src/libnx/wrapper/switch/services/capsu.nim @@ -0,0 +1,217 @@ +## * +## @file capsu.h +## @brief Application Album (caps:u) service IPC wrapper. +## This is only usable with AlbumFiles associated with the current host Application. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/caps, ../services/acc + +## / Initialize caps:u. Only available on [5.0.0+]. + +proc capsuInitialize*(): Result {.cdecl, importc: "capsuInitialize".} +## / Exit caps:u. + +proc capsuExit*() {.cdecl, importc: "capsuExit".} +## / Gets the Service for caps:u. + +proc capsuGetServiceSession*(): ptr Service {.cdecl, + importc: "capsuGetServiceSession".} +## / Gets the Service for IAlbumAccessorApplicationSession, only initialized after \ref capsuOpenAlbumMovieStream was used (unaffected by using \ref capsuCloseAlbumMovieStream). + +proc capsuGetServiceSessionAccessor*(): ptr Service {.cdecl, + importc: "capsuGetServiceSession_Accessor".} +## * +## @brief Gets a listing of \ref CapsApplicationAlbumFileEntry. +## @note On [6.0.0+] this uses GetAlbumFileList1AafeAruidDeprecated, otherwise this uses GetAlbumFileList0AafeAruidDeprecated. +## @note This is an old version of \ref capsuGetAlbumFileList3. +## @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry. +## @param[in] count Max size of the output array in entries. +## @param[in] type \ref CapsContentType +## @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[out] total_entries Total output entries. +## + +proc capsuGetAlbumFileListDeprecated1*(entries: ptr CapsApplicationAlbumFileEntry; + count: S32; `type`: CapsContentType; + startDatetime: ptr CapsAlbumFileDateTime; + endDatetime: ptr CapsAlbumFileDateTime; + totalEntries: ptr S32): Result {.cdecl, + importc: "capsuGetAlbumFileListDeprecated1".} +## * +## @brief Gets a listing of \ref CapsApplicationAlbumFileEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds. +## @note Only available on [6.0.0+]. +## @note This is an old version of \ref capsuGetAlbumFileList4. +## @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry. +## @param[in] count Max size of the output array in entries. +## @param[in] type \ref CapsContentType +## @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] uid \ref AccountUid +## @param[out] total_entries Total output entries. +## + +proc capsuGetAlbumFileListDeprecated2*(entries: ptr CapsApplicationAlbumFileEntry; + count: S32; `type`: CapsContentType; + startDatetime: ptr CapsAlbumFileDateTime; + endDatetime: ptr CapsAlbumFileDateTime; + uid: AccountUid; totalEntries: ptr S32): Result {. + cdecl, importc: "capsuGetAlbumFileListDeprecated2".} +## * +## @brief Gets a listing of \ref CapsApplicationAlbumEntry. +## @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated1 instead. +## @param[out] entries Output array of \ref CapsApplicationAlbumEntry. +## @param[in] count Max size of the output array in entries. +## @param[in] type \ref CapsContentType +## @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[out] total_entries Total output entries. +## + +proc capsuGetAlbumFileList3*(entries: ptr CapsApplicationAlbumEntry; count: S32; + `type`: CapsContentType; + startDatetime: ptr CapsAlbumFileDateTime; + endDatetime: ptr CapsAlbumFileDateTime; + totalEntries: ptr S32): Result {.cdecl, + importc: "capsuGetAlbumFileList3".} +## * +## @brief Gets a listing of \ref CapsApplicationAlbumEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds. +## @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated2 instead. +## @param[out] entries Output array of \ref CapsApplicationAlbumEntry. +## @param[in] count Max size of the output array in entries. +## @param[in] type \ref CapsContentType +## @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used. +## @param[in] uid \ref AccountUid +## @param[out] total_entries Total output entries. +## + +proc capsuGetAlbumFileList4*(entries: ptr CapsApplicationAlbumEntry; count: S32; + `type`: CapsContentType; + startDatetime: ptr CapsAlbumFileDateTime; + endDatetime: ptr CapsAlbumFileDateTime; + uid: AccountUid; totalEntries: ptr S32): Result {.cdecl, + importc: "capsuGetAlbumFileList4".} +## * +## @brief Deletes the specified AlbumFile. +## @param[in] type \ref CapsContentType, must match ::CapsContentType_ExtraMovie. +## @param[in] entry \ref CapsApplicationAlbumFileEntry +## + +proc capsuDeleteAlbumFile*(`type`: CapsContentType; + entry: ptr CapsApplicationAlbumFileEntry): Result {.cdecl, + importc: "capsuDeleteAlbumFile".} +## * +## @brief Gets the filesize for the entire specified AlbumFile. +## @param[in] entry \ref CapsApplicationAlbumFileEntry +## @param[out] size Output filesize. +## + +proc capsuGetAlbumFileSize*(entry: ptr CapsApplicationAlbumFileEntry; size: ptr U64): Result {. + cdecl, importc: "capsuGetAlbumFileSize".} +## * +## @brief Load the ScreenShotImage for the specified AlbumFile. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[out] attr \ref CapsScreenShotAttributeForApplication +## @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy. +## @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0. +## @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed. +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 1280x720. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## @param[in] entry \ref CapsApplicationAlbumFileEntry +## @param[in] option \ref CapsScreenShotDecodeOption +## + +proc capsuLoadAlbumScreenShotImage*(width: ptr S32; height: ptr S32; attr: ptr CapsScreenShotAttributeForApplication; + userdata: pointer; userdataMaxsize: csize_t; + userdataSize: ptr U32; image: pointer; + imageSize: csize_t; workbuf: pointer; + workbufSize: csize_t; + entry: ptr CapsApplicationAlbumFileEntry; + option: ptr CapsScreenShotDecodeOption): Result {. + cdecl, importc: "capsuLoadAlbumScreenShotImage".} +## * +## @brief Load the ScreenShotThumbnailImage for the specified AlbumFile. +## @param[out] width Output image width. Optional, can be NULL. +## @param[out] height Output image height. Optional, can be NULL. +## @param[out] attr \ref CapsScreenShotAttributeForApplication +## @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy. +## @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0. +## @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed. +## @param[out] image RGBA8 image output buffer. +## @param[in] image_size Image buffer size, should be at least large enough for RGBA8 320x180. +## @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns. +## @param[in] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile. +## @param[in] entry \ref CapsApplicationAlbumFileEntry +## @param[in] option \ref CapsScreenShotDecodeOption +## + +proc capsuLoadAlbumScreenShotThumbnailImage*(width: ptr S32; height: ptr S32; + attr: ptr CapsScreenShotAttributeForApplication; userdata: pointer; + userdataMaxsize: csize_t; userdataSize: ptr U32; image: pointer; + imageSize: csize_t; workbuf: pointer; workbufSize: csize_t; + entry: ptr CapsApplicationAlbumFileEntry; + option: ptr CapsScreenShotDecodeOption): Result {.cdecl, + importc: "capsuLoadAlbumScreenShotThumbnailImage".} +## * +## @brief PrecheckToCreateContents. Official sw only uses this with ::CapsContentType_ExtraMovie. +## @param[in] type \ref CapsContentType +## @param[in] unk Unknown. +## + +proc capsuPrecheckToCreateContents*(`type`: CapsContentType; unk: U64): Result {. + cdecl, importc: "capsuPrecheckToCreateContents".} +## * +## @brief Opens an AlbumMovieStream. +## @note This opens IAlbumAccessorApplicationSession if not previously opened, it's closed during \ref capsuExit. +## @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsApplicationAlbumFileEntry. +## @param[out] stream Stream handle. +## @param[in] entry \ref CapsApplicationAlbumFileEntry +## + +proc capsuOpenAlbumMovieStream*(stream: ptr U64; + entry: ptr CapsApplicationAlbumFileEntry): Result {. + cdecl, importc: "capsuOpenAlbumMovieStream".} +## * +## @brief Closes an AlbumMovieStream. +## @param[in] stream Stream handle. +## + +proc capsuCloseAlbumMovieStream*(stream: U64): Result {.cdecl, + importc: "capsuCloseAlbumMovieStream".} +## * +## @brief Gets the data size of an AlbumMovieStream. +## @param[in] stream Stream handle. +## @param[out] size Size of the actual MP4, without the JPEG at the end. +## + +proc capsuGetAlbumMovieStreamSize*(stream: U64; size: ptr U64): Result {.cdecl, + importc: "capsuGetAlbumMovieStreamSize".} +## * +## @brief Reads data from an AlbumMovieStream. +## @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes. +## @note When offset(+size) goes beyond the size from \ref capsuGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size. +## @param[in] stream Stream handle. +## @param[in] offset Offset. +## @param[out] Output data buffer. +## @param[in] size Data buffer size. +## @param[out] actual_size Actual read size. +## + +proc capsuReadAlbumMovieStream*(stream: U64; offset: S64; buffer: pointer; + size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "capsuReadAlbumMovieStream".} +## * +## @brief Gets the BrokenReason for an AlbumMovieStream. +## @note Official sw doesn't use this. +## @param[in] stream Stream handle. +## + +proc capsuGetAlbumMovieStreamBrokenReason*(stream: U64): Result {.cdecl, + importc: "capsuGetAlbumMovieStreamBrokenReason".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/clkrst.h b/src/libnx/wrapper/switch/services/clkrst.h new file mode 100644 index 0000000..305f20f --- /dev/null +++ b/src/libnx/wrapper/switch/services/clkrst.h @@ -0,0 +1,29 @@ +/** + * @file clkrst.h + * @brief Clkrst service IPC wrapper. + * @author p-sam + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/pcv.h" + +typedef struct { + Service s; +} ClkrstSession; + +/// Initialize clkrst. Only available on [8.0.0+]. +Result clkrstInitialize(void); + +/// Exit clkrst. +void clkrstExit(void); + +/// Gets the Service object for the actual clkrst service session. +Service* clkrstGetServiceSession(void); + +/// Opens a ClkrstSession for the requested PcvModuleId, unk is set to 3 in official sysmodules. +Result clkrstOpenSession(ClkrstSession* session_out, PcvModuleId module_id, u32 unk); +void clkrstCloseSession(ClkrstSession* session); +Result clkrstSetClockRate(ClkrstSession* session, u32 hz); +Result clkrstGetClockRate(ClkrstSession* session, u32 *out_hz); diff --git a/src/libnx/wrapper/switch/services/clkrst.nim b/src/libnx/wrapper/switch/services/clkrst.nim new file mode 100644 index 0000000..2312968 --- /dev/null +++ b/src/libnx/wrapper/switch/services/clkrst.nim @@ -0,0 +1,35 @@ +## * +## @file clkrst.h +## @brief Clkrst service IPC wrapper. +## @author p-sam +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/pcv + +type + ClkrstSession* {.bycopy.} = object + s*: Service + + +## / Initialize clkrst. Only available on [8.0.0+]. + +proc clkrstInitialize*(): Result {.cdecl, importc: "clkrstInitialize".} +## / Exit clkrst. + +proc clkrstExit*() {.cdecl, importc: "clkrstExit".} +## / Gets the Service object for the actual clkrst service session. + +proc clkrstGetServiceSession*(): ptr Service {.cdecl, + importc: "clkrstGetServiceSession".} +## / Opens a ClkrstSession for the requested PcvModuleId, unk is set to 3 in official sysmodules. + +proc clkrstOpenSession*(sessionOut: ptr ClkrstSession; moduleId: PcvModuleId; unk: U32): Result {. + cdecl, importc: "clkrstOpenSession".} +proc clkrstCloseSession*(session: ptr ClkrstSession) {.cdecl, + importc: "clkrstCloseSession".} +proc clkrstSetClockRate*(session: ptr ClkrstSession; hz: U32): Result {.cdecl, + importc: "clkrstSetClockRate".} +proc clkrstGetClockRate*(session: ptr ClkrstSession; outHz: ptr U32): Result {.cdecl, + importc: "clkrstGetClockRate".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/csrng.h b/src/libnx/wrapper/switch/services/csrng.h new file mode 100644 index 0000000..419710d --- /dev/null +++ b/src/libnx/wrapper/switch/services/csrng.h @@ -0,0 +1,20 @@ +/** + * @file csrng.h + * @brief Cryptographically-Secure Random Number Generation (csrng) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Initialize csrng. +Result csrngInitialize(void); + +/// Exit csrng. +void csrngExit(void); + +/// Gets the Service object for the actual csrng service session. +Service* csrngGetServiceSession(void); + +Result csrngGetRandomBytes(void *out, size_t out_size); diff --git a/src/libnx/wrapper/switch/services/csrng.nim b/src/libnx/wrapper/switch/services/csrng.nim new file mode 100644 index 0000000..0cb1d25 --- /dev/null +++ b/src/libnx/wrapper/switch/services/csrng.nim @@ -0,0 +1,22 @@ +## * +## @file csrng.h +## @brief Cryptographically-Secure Random Number Generation (csrng) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Initialize csrng. + +proc csrngInitialize*(): Result {.cdecl, importc: "csrngInitialize".} +## / Exit csrng. + +proc csrngExit*() {.cdecl, importc: "csrngExit".} +## / Gets the Service object for the actual csrng service session. + +proc csrngGetServiceSession*(): ptr Service {.cdecl, + importc: "csrngGetServiceSession".} +proc csrngGetRandomBytes*(`out`: pointer; outSize: csize_t): Result {.cdecl, + importc: "csrngGetRandomBytes".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/ectx.h b/src/libnx/wrapper/switch/services/ectx.h new file mode 100644 index 0000000..0a691e8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ectx.h @@ -0,0 +1,32 @@ +/** + * @file ectx.h + * @brief [11.0.0+] Error Context services IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +/// Initialize ectx:r. +Result ectxrInitialize(void); + +/// Exit ectx:r. +void ectxrExit(void); + +/// Gets the Service object for the actual ectx:r service session. +Service* ectxrGetServiceSession(void); + +/** + * @brief Retrieves the error context associated with an error descriptor and result. + * @param[out] out0 Output value. + * @param[out] out_total_size Total error context size. + * @param[out] out_size Error context size. + * @param[out] dst Buffer for output error context. + * @param[in] dst_size Buffer size for output error context. + * @param[in] descriptor Error descriptor. + * @param[in] result Error result. + * @return Result code. + */ +Result ectxrPullContext(s32 *out0, u32 *out_total_size, u32 *out_size, void *dst, size_t dst_size, u32 descriptor, Result result); diff --git a/src/libnx/wrapper/switch/services/ectx.nim b/src/libnx/wrapper/switch/services/ectx.nim new file mode 100644 index 0000000..47feaae --- /dev/null +++ b/src/libnx/wrapper/switch/services/ectx.nim @@ -0,0 +1,35 @@ +## * +## @file ectx.h +## @brief [11.0.0+] Error Context services IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +proc ectxrInitialize*(): Result {.cdecl, importc: "ectxrInitialize".} +## / Initialize ectx:r. + +proc ectxrExit*() {.cdecl, importc: "ectxrExit".} +## / Exit ectx:r. + +proc ectxrGetServiceSession*(): ptr Service {.cdecl, + importc: "ectxrGetServiceSession".} +## / Gets the Service object for the actual ectx:r service session. + +proc ectxrPullContext*(out0: ptr S32; outTotalSize: ptr U32; outSize: ptr U32; + dst: pointer; dstSize: csize_t; descriptor: U32; result: Result): Result {. + cdecl, importc: "ectxrPullContext".} +## * +## @brief Retrieves the error context associated with an error descriptor and result. +## @param[out] out0 Output value. +## @param[out] out_total_size Total error context size. +## @param[out] out_size Error context size. +## @param[out] dst Buffer for output error context. +## @param[in] dst_size Buffer size for output error context. +## @param[in] descriptor Error descriptor. +## @param[in] result Error result. +## @return Result code. +## + diff --git a/src/libnx/wrapper/switch/services/fan.h b/src/libnx/wrapper/switch/services/fan.h new file mode 100644 index 0000000..b77bf4b --- /dev/null +++ b/src/libnx/wrapper/switch/services/fan.h @@ -0,0 +1,32 @@ +/** + * @file fan.h + * @brief Fan service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef struct { + Service s; +} FanController; + +/// Initialize fan. +Result fanInitialize(void); + +/// Exit fan. +void fanExit(void); + +/// Gets the Service object for the actual fan service session. +Service* fanGetServiceSession(void); + +/// Opens IController session. +Result fanOpenController(FanController *out, u32 device_code); + +/// Close IController session. +void fanControllerClose(FanController *controller); + +/// @warning Disabling your fan can damage your system. +Result fanControllerSetRotationSpeedLevel(FanController *controller, float level); +Result fanControllerGetRotationSpeedLevel(FanController *controller, float *level); diff --git a/src/libnx/wrapper/switch/services/fan.nim b/src/libnx/wrapper/switch/services/fan.nim new file mode 100644 index 0000000..ed3241a --- /dev/null +++ b/src/libnx/wrapper/switch/services/fan.nim @@ -0,0 +1,40 @@ +## * +## @file fan.h +## @brief Fan service IPC wrapper. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + FanController* {.bycopy.} = object + s*: Service + + +## / Initialize fan. + +proc fanInitialize*(): Result {.cdecl, importc: "fanInitialize".} +## / Exit fan. + +proc fanExit*() {.cdecl, importc: "fanExit".} +## / Gets the Service object for the actual fan service session. + +proc fanGetServiceSession*(): ptr Service {.cdecl, importc: "fanGetServiceSession".} +## / Opens IController session. + +proc fanOpenController*(`out`: ptr FanController; deviceCode: U32): Result {.cdecl, + importc: "fanOpenController".} +## / Close IController session. + +proc fanControllerClose*(controller: ptr FanController) {.cdecl, + importc: "fanControllerClose".} +## / @warning Disabling your fan can damage your system. + +proc fanControllerSetRotationSpeedLevel*(controller: ptr FanController; + level: cfloat): Result {.cdecl, + importc: "fanControllerSetRotationSpeedLevel".} +proc fanControllerGetRotationSpeedLevel*(controller: ptr FanController; + level: ptr cfloat): Result {.cdecl, + importc: "fanControllerGetRotationSpeedLevel".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/fatal.h b/src/libnx/wrapper/switch/services/fatal.h new file mode 100644 index 0000000..80d1f6b --- /dev/null +++ b/src/libnx/wrapper/switch/services/fatal.h @@ -0,0 +1,99 @@ +/** + * @file fatal.h + * @brief Fatal error (fatal:u) service IPC wrapper. + * @author plutoo + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Type of thrown fatal error. +typedef enum { + FatalPolicy_ErrorReportAndErrorScreen = 0, + FatalPolicy_ErrorReport = 1, + FatalPolicy_ErrorScreen = 2 ///< Only available with [3.0.0+]. If specified, FatalPolicy_ErrorReportAndErrorScreen will be used instead on pre-3.0.0. +} FatalPolicy; + +/// Struct for fatal Cpu context, 64-bit. +typedef struct { + union { + u64 x[32]; + struct { + u64 _x[29]; + u64 fp; + u64 lr; + u64 sp; + u64 pc; + }; + }; + u64 pstate; + u64 afsr0; + u64 afsr1; + u64 esr; + u64 far; + + u64 stack_trace[32]; + u64 start_address; ///< Address of first NSO loaded (generally, process entrypoint). + u64 register_set_flags; ///< Bitmask, bit i indicates GPR i has a value. + u32 stack_trace_size; +} FatalAarch64Context; + +/// Struct for fatal Cpu context, 32-bit. +typedef struct { + union { + u32 r[16]; + struct { + u32 _r[11]; + u32 fp; + u32 ip; + u32 sp; + u32 lr; + u32 pc; + }; + }; + u32 pstate; + u32 afsr0; + u32 afsr1; + u32 esr; + u32 far; + + u32 stack_trace[32]; + u32 stack_trace_size; + u32 start_address; ///< Address of first NSO loaded (generally, process entrypoint). + u32 register_set_flags; ///< Bitmask, bit i indicates GPR i has a value. +} FatalAarch32Context; + +typedef struct { + union { + FatalAarch64Context aarch64_ctx; + FatalAarch32Context aarch32_ctx; + }; + + bool is_aarch32; + u32 type; +} FatalCpuContext; + +/** + * @brief Triggers a system fatal error. + * @param[in] err Result code to throw. + * @note This function does not return. + * @note This uses \ref fatalThrowWithPolicy with \ref FatalPolicy_ErrorScreen internally. + */ +void NORETURN fatalThrow(Result err); + +/** + * @brief Triggers a system fatal error with a custom \ref FatalPolicy. + * @param[in] err Result code to throw. + * @param[in] type Type of fatal error to throw. + * @note This function may not return, depending on \ref FatalPolicy. + */ +void fatalThrowWithPolicy(Result err, FatalPolicy type); + +/** + * @brief Triggers a system fatal error with a custom \ref FatalPolicy and \ref FatalCpuContext. + * @param[in] err Result code to throw. + * @param[in] type Type of fatal error to throw. + * @param[in] ctx Cpu context for fatal error to throw. + * @note This function may not return, depending on \ref FatalPolicy. + */ +void fatalThrowWithContext(Result err, FatalPolicy type, FatalCpuContext *ctx); diff --git a/src/libnx/wrapper/switch/services/fatal.nim b/src/libnx/wrapper/switch/services/fatal.nim new file mode 100644 index 0000000..9a49c71 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fatal.nim @@ -0,0 +1,109 @@ +## * +## @file fatal.h +## @brief Fatal error (fatal:u) service IPC wrapper. +## @author plutoo +## @copyright libnx Authors +## + +import + ../types + +## / Type of thrown fatal error. + +type + FatalPolicy* = enum + FatalPolicyErrorReportAndErrorScreen = 0, FatalPolicyErrorReport = 1, FatalPolicyErrorScreen = 2 ## /< Only available with [3.0.0+]. If specified, FatalPolicy_ErrorReportAndErrorScreen will be used instead on pre-3.0.0. + + +## / Struct for fatal Cpu context, 64-bit. + +type + INNER_C_STRUCT_fatal_5* {.bycopy.} = object + x*: array[29, U64] + fp*: U64 + lr*: U64 + sp*: U64 + pc*: U64 + + INNER_C_UNION_fatal_4* {.bycopy, union.} = object + x*: array[32, U64] + anoFatal6*: INNER_C_STRUCT_fatal_5 + + FatalAarch64Context* {.bycopy.} = object + anoFatal7*: INNER_C_UNION_fatal_4 + pstate*: U64 + afsr0*: U64 + afsr1*: U64 + esr*: U64 + far*: U64 + stackTrace*: array[32, U64] + startAddress*: U64 ## /< Address of first NSO loaded (generally, process entrypoint). + registerSetFlags*: U64 ## /< Bitmask, bit i indicates GPR i has a value. + stackTraceSize*: U32 + + +## / Struct for fatal Cpu context, 32-bit. + +type + INNER_C_STRUCT_fatal_13* {.bycopy.} = object + r*: array[11, U32] + fp*: U32 + ip*: U32 + sp*: U32 + lr*: U32 + pc*: U32 + + INNER_C_UNION_fatal_12* {.bycopy, union.} = object + r*: array[16, U32] + anoFatal14*: INNER_C_STRUCT_fatal_13 + + INNER_C_UNION_fatal_18* {.bycopy, union.} = object + aarch64Ctx*: FatalAarch64Context + aarch32Ctx*: FatalAarch32Context + + FatalAarch32Context* {.bycopy.} = object + anoFatal15*: INNER_C_UNION_fatal_12 + pstate*: U32 + afsr0*: U32 + afsr1*: U32 + esr*: U32 + far*: U32 + stackTrace*: array[32, U32] + stackTraceSize*: U32 + startAddress*: U32 ## /< Address of first NSO loaded (generally, process entrypoint). + registerSetFlags*: U32 ## /< Bitmask, bit i indicates GPR i has a value. + + FatalCpuContext* {.bycopy.} = object + anoFatal19*: INNER_C_UNION_fatal_18 + isAarch32*: bool + `type`*: U32 + + +## * +## @brief Triggers a system fatal error. +## @param[in] err Result code to throw. +## @note This function does not return. +## @note This uses \ref fatalThrowWithPolicy with \ref FatalPolicy_ErrorScreen internally. +## + +proc fatalThrow*(err: Result) {.cdecl, importc: "fatalThrow".} +## * +## @brief Triggers a system fatal error with a custom \ref FatalPolicy. +## @param[in] err Result code to throw. +## @param[in] type Type of fatal error to throw. +## @note This function may not return, depending on \ref FatalPolicy. +## + +proc fatalThrowWithPolicy*(err: Result; `type`: FatalPolicy) {.cdecl, + importc: "fatalThrowWithPolicy".} +## * +## @brief Triggers a system fatal error with a custom \ref FatalPolicy and \ref FatalCpuContext. +## @param[in] err Result code to throw. +## @param[in] type Type of fatal error to throw. +## @param[in] ctx Cpu context for fatal error to throw. +## @note This function may not return, depending on \ref FatalPolicy. +## + +proc fatalThrowWithContext*(err: Result; `type`: FatalPolicy; + ctx: ptr FatalCpuContext) {.cdecl, + importc: "fatalThrowWithContext".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/friends.h b/src/libnx/wrapper/switch/services/friends.h new file mode 100644 index 0000000..994b01d --- /dev/null +++ b/src/libnx/wrapper/switch/services/friends.h @@ -0,0 +1,91 @@ +/** + * @file friend.h + * @brief Friends (friend:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/applet.h" +#include "../services/acc.h" +#include "../sf/service.h" + +typedef enum { + FriendsServiceType_User = 0, ///< Initializes friend:u + FriendsServiceType_Viewer = 1, ///< Initializes friend:v + FriendsServiceType_Manager = 2, ///< Initializes friend:m + FriendsServiceType_System = 3, ///< Initializes friend:s + FriendsServiceType_Administrator = 4, ///< Initializes friend:a +} FriendsServiceType; + +/// InAppScreenName +typedef struct { + char name[0x40]; ///< UTF-8 string, NUL-terminated. + u64 languageCode; ///< LanguageCode, see set.h. +} FriendsInAppScreenName; + +/// FriendInvitationGameModeDescription +typedef struct { + u8 unk_x0[0xc00]; ///< Unknown. +} FriendsFriendInvitationGameModeDescription; + +/// FriendInvitationId +typedef struct { + u64 id; ///< Id. +} FriendsFriendInvitationId; + +/// FriendInvitationGroupId +typedef struct { + u64 id; ///< Id. +} FriendsFriendInvitationGroupId; + +/// FriendsUserSetting +typedef struct { + AccountUid uid; ///< User ID + u32 presence_permission; ///< Presence permission + u32 play_log_permission; ///< Play log permission + u64 friend_request_reception; ///< Unknown + char friend_code[0x20]; ///< Friend Code + u64 friend_code_next_issuable_time; ///< Unknown + u8 unk_x48[0x7C8]; ///< Unknown +} FriendsUserSetting; + +/// Initialize friends +Result friendsInitialize(FriendsServiceType service_type); + +/// Exit friends +void friendsExit(void); + +/// Gets the Service object for the friends service session. +Service* friendsGetServiceSession(void); + +/// Gets the Service object for the actual IFriendsService service session. +Service* friendsGetServiceSession_IFriendsService(void); + +/** + * @brief Gets the \ref FriendsUserSetting details + * @param[in] uid \ref User AccountUid. + * @param[out] user_setting \ref FriendsUserSetting + */ +Result friendsGetUserSetting(AccountUid uid, FriendsUserSetting *user_setting); + +/** + * @brief Gets an Event which is signaled when data is available with \ref friendsTryPopFriendInvitationNotificationInfo. + * @note This is a wrapper for \ref appletGetFriendInvitationStorageChannelEvent, see that for the usage requirements. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +NX_INLINE Result friendsGetFriendInvitationNotificationEvent(Event *out_event) { + return appletGetFriendInvitationStorageChannelEvent(out_event); +} + +/** + * @brief Uses \ref appletTryPopFromFriendInvitationStorageChannel then reads the data from there into the output params. + * @note This is a wrapper for \ref appletTryPopFromFriendInvitationStorageChannel, see that for the usage requirements. + * @param[out] uid \ref AccountUid. Optional, can be NULL. + * @param[out] buffer Output buffer. + * @param[out] size Output buffer size. + * @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL. + */ +Result friendsTryPopFriendInvitationNotificationInfo(AccountUid *uid, void* buffer, u64 size, u64 *out_size); diff --git a/src/libnx/wrapper/switch/services/friends.nim b/src/libnx/wrapper/switch/services/friends.nim new file mode 100644 index 0000000..e68232e --- /dev/null +++ b/src/libnx/wrapper/switch/services/friends.nim @@ -0,0 +1,107 @@ +## * +## @file friend.h +## @brief Friends (friend:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/applet, ../services/acc, ../sf/service + +type + FriendsServiceType* = enum + FriendsServiceTypeUser = 0, ## /< Initializes friend:u + FriendsServiceTypeViewer = 1, ## /< Initializes friend:v + FriendsServiceTypeManager = 2, ## /< Initializes friend:m + FriendsServiceTypeSystem = 3, ## /< Initializes friend:s + FriendsServiceTypeAdministrator = 4 ## /< Initializes friend:a + + +## / InAppScreenName + +type + FriendsInAppScreenName* {.bycopy.} = object + name*: array[0x40, char] ## /< UTF-8 string, NUL-terminated. + languageCode*: U64 ## /< LanguageCode, see set.h. + + +## / FriendInvitationGameModeDescription + +type + FriendsFriendInvitationGameModeDescription* {.bycopy.} = object + unkX0*: array[0xc00, U8] ## /< Unknown. + + +## / FriendInvitationId + +type + FriendsFriendInvitationId* {.bycopy.} = object + id*: U64 ## /< Id. + + +## / FriendInvitationGroupId + +type + FriendsFriendInvitationGroupId* {.bycopy.} = object + id*: U64 ## /< Id. + + +## / FriendsUserSetting + +type + FriendsUserSetting* {.bycopy.} = object + uid*: AccountUid ## /< User ID + presencePermission*: U32 ## /< Presence permission + playLogPermission*: U32 ## /< Play log permission + friendRequestReception*: U64 ## /< Unknown + friendCode*: array[0x20, char] ## /< Friend Code + friendCodeNextIssuableTime*: U64 ## /< Unknown + unkX48*: array[0x7C8, U8] ## /< Unknown + + +## / Initialize friends + +proc friendsInitialize*(serviceType: FriendsServiceType): Result {.cdecl, + importc: "friendsInitialize".} +## / Exit friends + +proc friendsExit*() {.cdecl, importc: "friendsExit".} +## / Gets the Service object for the friends service session. + +proc friendsGetServiceSession*(): ptr Service {.cdecl, + importc: "friendsGetServiceSession".} +## / Gets the Service object for the actual IFriendsService service session. + +proc friendsGetServiceSessionIFriendsService*(): ptr Service {.cdecl, + importc: "friendsGetServiceSession_IFriendsService".} +## * +## @brief Gets the \ref FriendsUserSetting details +## @param[in] uid \ref User AccountUid. +## @param[out] user_setting \ref FriendsUserSetting +## + +proc friendsGetUserSetting*(uid: AccountUid; userSetting: ptr FriendsUserSetting): Result {. + cdecl, importc: "friendsGetUserSetting".} +## * +## @brief Gets an Event which is signaled when data is available with \ref friendsTryPopFriendInvitationNotificationInfo. +## @note This is a wrapper for \ref appletGetFriendInvitationStorageChannelEvent, see that for the usage requirements. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc friendsGetFriendInvitationNotificationEvent*(outEvent: ptr Event): Result {. + inline, cdecl.} = + return appletGetFriendInvitationStorageChannelEvent(outEvent) + +## * +## @brief Uses \ref appletTryPopFromFriendInvitationStorageChannel then reads the data from there into the output params. +## @note This is a wrapper for \ref appletTryPopFromFriendInvitationStorageChannel, see that for the usage requirements. +## @param[out] uid \ref AccountUid. Optional, can be NULL. +## @param[out] buffer Output buffer. +## @param[out] size Output buffer size. +## @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL. +## + +proc friendsTryPopFriendInvitationNotificationInfo*(uid: ptr AccountUid; + buffer: pointer; size: U64; outSize: ptr U64): Result {.cdecl, + importc: "friendsTryPopFriendInvitationNotificationInfo".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/fs.h b/src/libnx/wrapper/switch/services/fs.h new file mode 100644 index 0000000..fd11c90 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fs.h @@ -0,0 +1,519 @@ +/** + * @file fs.h + * @brief Filesystem (fsp-srv) service IPC wrapper. + * Normally applications should just use standard stdio not FS-serv directly. However this can be used if obtaining a FsFileSystem, FsFile, or FsStorage, for mounting with fs_dev/romfs_dev, etc. + * @author plutoo + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/ncm_types.h" +#include "../services/acc.h" +#include "../sf/service.h" + +// We use wrapped handles for type safety. + +#define FS_MAX_PATH 0x301 + +/// For use with \ref FsSaveDataAttribute. +#define FS_SAVEDATA_CURRENT_APPLICATIONID 0 + +typedef struct { + u8 c[0x10]; +} FsRightsId; + +typedef struct { + Service s; +} FsFileSystem; + +typedef struct { + Service s; +} FsFile; + +typedef struct { + Service s; +} FsDir; + +typedef struct { + Service s; +} FsStorage; + +typedef struct { + Service s; +} FsSaveDataInfoReader; + +typedef struct { + Service s; +} FsEventNotifier; + +typedef struct { + Service s; +} FsDeviceOperator; + +/// Directory entry. +typedef struct { + char name[FS_MAX_PATH]; ///< Entry name. + u8 pad[3]; + s8 type; ///< See FsDirEntryType. + u8 pad2[3]; ///< ? + s64 file_size; ///< File size. +} FsDirectoryEntry; + +/// SaveDataAttribute +typedef struct { + u64 application_id; ///< ApplicationId of the savedata to access when accessing other programs' savedata via SaveData, otherwise FS_SAVEDATA_CURRENT_APPLICATIONID. + AccountUid uid; ///< \ref AccountUid for the user-specific savedata to access, otherwise 0 for common savedata. + u64 system_save_data_id; ///< SystemSaveDataId, 0 for ::FsSaveDataType_Account. + u8 save_data_type; ///< \ref FsSaveDataType + u8 save_data_rank; ///< \ref FsSaveDataRank + u16 save_data_index; ///< SaveDataIndex + u32 pad_x24; ///< Padding. + u64 unk_x28; ///< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. + u64 unk_x30; ///< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. + u64 unk_x38; ///< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. +} FsSaveDataAttribute; + +/// SaveDataExtraData +typedef struct { + FsSaveDataAttribute attr; ///< \ref FsSaveDataAttribute + u64 owner_id; ///< ProgramId of the owner of this save data. 0 for ::FsSaveDataType_System. + u64 timestamp; ///< POSIX timestamp. + u32 flags; ///< \ref FsSaveDataFlags + u32 unk_x54; ///< Normally 0. Possibly unused? + s64 data_size; ///< Usable save data size. + s64 journal_size; ///< Journal size of the save data. + u64 commit_id; ///< Id of the latest commit. + u8 unused[0x190]; ///< Uninitialized. +} FsSaveDataExtraData; + +/// SaveDataMetaInfo +typedef struct { + u32 size; + u8 type; ///< \ref FsSaveDataMetaType + u8 reserved[0x0B]; +} FsSaveDataMetaInfo; + +/// SaveDataCreationInfo +typedef struct { + s64 save_data_size; ///< Size of the save data. + s64 journal_size; ///< Journal size of the save data. + u64 available_size; ///< AvailableSize + u64 owner_id; ///< ProgramId of the owner of this save data. 0 for ::FsSaveDataType_System. + u32 flags; ///< \ref FsSaveDataFlags + u8 save_data_space_id; ///< \ref FsSaveDataSpaceId + u8 unk; ///< 0 for ::FsSaveDataType_System. + u8 padding[0x1a]; ///< Uninitialized for ::FsSaveDataType_System. +} FsSaveDataCreationInfo; + +/// SaveDataInfo +typedef struct { + u64 save_data_id; ///< SaveDataId + u8 save_data_space_id; ///< \ref FsSaveDataSpaceId + u8 save_data_type; ///< \ref FsSaveDataType + u8 pad[6]; ///< Padding. + AccountUid uid; ///< FsSave::userID + u64 system_save_data_id; ///< FsSaveDataAttribute::system_save_data_id + u64 application_id; ///< ApplicationId for ::FsSaveDataType_Account. + u64 size; ///< Raw saveimage size. + u16 save_data_index; ///< SaveDataIndex + u8 save_data_rank; ///< \ref FsSaveDataRank + u8 unk_x3b[0x25]; ///< Unknown. Usually zeros? +} FsSaveDataInfo; + +/// SaveDataFilter +typedef struct { + bool filter_by_application_id; ///< Filter by \ref FsSaveDataAttribute::application_id + bool filter_by_save_data_type; ///< Filter by \ref FsSaveDataAttribute::save_data_type + bool filter_by_user_id; ///< Filter by \ref FsSaveDataAttribute::uid + bool filter_by_system_save_data_id; ///< Filter by \ref FsSaveDataAttribute::system_save_data_id + bool filter_by_index; ///< Filter by \ref FsSaveDataAttribute::save_data_index + u8 save_data_rank; ///< \ref FsSaveDataRank + u8 padding[0x2]; ///< Padding + FsSaveDataAttribute attr; ///< \ref FsSaveDataAttribute +} FsSaveDataFilter; + +typedef struct { + u64 created; ///< POSIX timestamp. + u64 modified; ///< POSIX timestamp. + u64 accessed; ///< POSIX timestamp. + u8 is_valid; ///< 0x1 when the timestamps are set. + u8 padding[7]; +} FsTimeStampRaw; + +/// This is nn::fssystem::ArchiveMacKey. Used by \ref setsysGetThemeKey and \ref setsysSetThemeKey. Does not appear to be in use elsewhere. +typedef struct { + u8 key[0x10]; +} FsArchiveMacKey; + +/// Returned by fsFsGetEntryType. +typedef enum { + FsDirEntryType_Dir = 0, ///< Entry is a directory. + FsDirEntryType_File = 1, ///< Entry is a file. +} FsDirEntryType; + +/// For use with fsFsOpenFile. +typedef enum { + FsOpenMode_Read = BIT(0), ///< Open for reading. + FsOpenMode_Write = BIT(1), ///< Open for writing. + FsOpenMode_Append = BIT(2), ///< Append file. +} FsOpenMode; + +/// For use with fsFsCreateFile. +typedef enum { + FsCreateOption_BigFile = BIT(0), ///< Creates a ConcatenationFile (dir with archive bit) instead of file. +} FsCreateOption; + +/// For use with fsFsOpenDirectory. +typedef enum { + FsDirOpenMode_ReadDirs = BIT(0), ///< Enable reading directory entries. + FsDirOpenMode_ReadFiles = BIT(1), ///< Enable reading file entries. + FsDirOpenMode_NoFileSize = BIT(31), ///< Causes result entries to not contain filesize information (always 0). +} FsDirOpenMode; + +/// For use with fsFileRead. +typedef enum { + FsReadOption_None = 0, ///< No option. +} FsReadOption; + +/// For use with fsFileWrite. +typedef enum { + FsWriteOption_None = 0, ///< No option. + FsWriteOption_Flush = BIT(0), ///< Forces a flush after write. +} FsWriteOption; + +typedef enum { + FsContentStorageId_System = 0, + FsContentStorageId_User = 1, + FsContentStorageId_SdCard = 2, +} FsContentStorageId; + +typedef enum { + FsCustomStorageId_System = 0, + FsCustomStorageId_SdCard = 1, +} FsCustomStorageId; + +/// ImageDirectoryId +typedef enum { + FsImageDirectoryId_Nand = 0, + FsImageDirectoryId_Sd = 1, +} FsImageDirectoryId; + +/// SaveDataSpaceId +typedef enum { + FsSaveDataSpaceId_System = 0, ///< System + FsSaveDataSpaceId_User = 1, ///< User + FsSaveDataSpaceId_SdSystem = 2, ///< SdSystem + FsSaveDataSpaceId_Temporary = 3, ///< [3.0.0+] Temporary + FsSaveDataSpaceId_SdUser = 4, ///< [4.0.0+] SdUser + FsSaveDataSpaceId_ProperSystem = 100, ///< [3.0.0+] ProperSystem + FsSaveDataSpaceId_SafeMode = 101, ///< [3.0.0+] SafeMode + + FsSaveDataSpaceId_All = -1, ///< Pseudo value for fsOpenSaveDataInfoReader(). +} FsSaveDataSpaceId; + +/// SaveDataType +typedef enum { + FsSaveDataType_System = 0, ///< System + FsSaveDataType_Account = 1, ///< Account + FsSaveDataType_Bcat = 2, ///< Bcat + FsSaveDataType_Device = 3, ///< Device + FsSaveDataType_Temporary = 4, ///< [3.0.0+] Temporary + FsSaveDataType_Cache = 5, ///< [3.0.0+] Cache + FsSaveDataType_SystemBcat = 6, ///< [4.0.0+] SystemBcat +} FsSaveDataType; + +/// SaveDataRank +typedef enum { + FsSaveDataRank_Primary = 0, ///< Primary + FsSaveDataRank_Secondary = 1, ///< Secondary +} FsSaveDataRank; + +/// SaveDataFlags +typedef enum { + FsSaveDataFlags_KeepAfterResettingSystemSaveData = BIT(0), + FsSaveDataFlags_KeepAfterRefurbishment = BIT(1), + FsSaveDataFlags_KeepAfterResettingSystemSaveDataWithoutUserSaveData = BIT(2), + FsSaveDataFlags_NeedsSecureDelete = BIT(3), +} FsSaveDataFlags; + +/// SaveDataMetaType +typedef enum { + FsSaveDataMetaType_None = 0, + FsSaveDataMetaType_Thumbnail = 1, + FsSaveDataMetaType_ExtensionContext = 2, +} FsSaveDataMetaType; + +typedef enum { + FsGameCardAttribute_AutoBootFlag = BIT(0), ///< Causes the cartridge to automatically start on bootup + FsGameCardAttribute_HistoryEraseFlag = BIT(1), ///< Causes NS to throw an error on attempt to load the cartridge + FsGameCardAttribute_RepairToolFlag = BIT(2), ///< [4.0.0+] Indicates that this gamecard is a repair tool. + FsGameCardAttribute_DifferentRegionCupToTerraDeviceFlag = BIT(3), ///< [9.0.0+] DifferentRegionCupToTerraDeviceFlag + FsGameCardAttribute_DifferentRegionCupToGlobalDeviceFlag = BIT(4), ///< [9.0.0+] DifferentRegionCupToGlobalDeviceFlag +} FsGameCardAttribute; + +typedef enum { + FsGameCardPartition_Update = 0, + FsGameCardPartition_Normal = 1, + FsGameCardPartition_Secure = 2, + FsGameCardPartition_Logo = 3, ///< [4.0.0+] +} FsGameCardPartition; + +typedef struct { + u32 value; +} FsGameCardHandle; + +typedef struct { + u32 aes_ctr_key_type; ///< Contains bitflags describing how data is AES encrypted. + u32 speed_emulation_type; ///< Contains bitflags describing how data is emulated. + u32 reserved[0x38/sizeof(u32)]; +} FsRangeInfo; + +typedef enum { + FsOperationId_Clear, ///< Fill range with zero for supported file/storage. + FsOperationId_ClearSignature, ///< Clears signature for supported file/storage. + FsOperationId_InvalidateCache, ///< Invalidates cache for supported file/storage. + FsOperationId_QueryRange, ///< Retrieves information on data for supported file/storage. +} FsOperationId; + +/// BisPartitionId +typedef enum { + FsBisPartitionId_BootPartition1Root = 0, + + FsBisPartitionId_BootPartition2Root = 10, + + FsBisPartitionId_UserDataRoot = 20, + FsBisPartitionId_BootConfigAndPackage2Part1 = 21, + FsBisPartitionId_BootConfigAndPackage2Part2 = 22, + FsBisPartitionId_BootConfigAndPackage2Part3 = 23, + FsBisPartitionId_BootConfigAndPackage2Part4 = 24, + FsBisPartitionId_BootConfigAndPackage2Part5 = 25, + FsBisPartitionId_BootConfigAndPackage2Part6 = 26, + FsBisPartitionId_CalibrationBinary = 27, + FsBisPartitionId_CalibrationFile = 28, + FsBisPartitionId_SafeMode = 29, + FsBisPartitionId_User = 30, + FsBisPartitionId_System = 31, + FsBisPartitionId_SystemProperEncryption = 32, + FsBisPartitionId_SystemProperPartition = 33, + FsBisPartitionId_SignedSystemPartitionOnSafeMode = 34, +} FsBisPartitionId; + +/// FileSystemType +typedef enum { + FsFileSystemType_Logo = 2, ///< Logo + FsFileSystemType_ContentControl = 3, ///< ContentControl + FsFileSystemType_ContentManual = 4, ///< ContentManual + FsFileSystemType_ContentMeta = 5, ///< ContentMeta + FsFileSystemType_ContentData = 6, ///< ContentData + FsFileSystemType_ApplicationPackage = 7, ///< ApplicationPackage + FsFileSystemType_RegisteredUpdate = 8, ///< [4.0.0+] RegisteredUpdate +} FsFileSystemType; + +/// FileSystemQueryId +typedef enum { + FsFileSystemQueryId_SetConcatenationFileAttribute = 0, ///< [4.0.0+] + FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard = 2, ///< [8.0.0+] +} FsFileSystemQueryId; + +/// FsPriority +typedef enum { + FsPriority_Normal = 0, + FsPriority_Realtime = 1, + FsPriority_Low = 2, + FsPriority_Background = 3, +} FsPriority; + +/// For use with fsOpenHostFileSystemWithOption +typedef enum { + FsMountHostOptionFlag_None = 0, ///< Host filesystem will be case insensitive. + FsMountHostOptionFlag_PseudoCaseSensitive = BIT(0), ///< Host filesystem will be pseudo case sensitive. +} FsMountHostOption; + +/// Initialize fsp-srv. Used automatically during app startup. +Result fsInitialize(void); + +/// Exit fsp-srv. Used automatically during app exit. +void fsExit(void); + +/// Gets the Service object for the actual fsp-srv service session. +Service* fsGetServiceSession(void); + +/// [5.0.0+] Configures the \ref FsPriority of all filesystem commands issued within the current thread. +void fsSetPriority(FsPriority prio); + +/// Mount requested filesystem type from content file +Result fsOpenFileSystem(FsFileSystem* out, FsFileSystemType fsType, const char* contentPath); ///< same as calling fsOpenFileSystemWithId with 0 as id +Result fsOpenDataFileSystemByCurrentProcess(FsFileSystem *out); +Result fsOpenFileSystemWithPatch(FsFileSystem* out, u64 id, FsFileSystemType fsType); ///< [2.0.0+], like OpenFileSystemWithId but without content path. +Result fsOpenFileSystemWithId(FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath); ///< works on all firmwares, id is ignored on [1.0.0] +Result fsOpenDataFileSystemByProgramId(FsFileSystem *out, u64 program_id); ///< [3.0.0+] +Result fsOpenBisFileSystem(FsFileSystem* out, FsBisPartitionId partitionId, const char* string); +Result fsOpenBisStorage(FsStorage* out, FsBisPartitionId partitionId); + +/// Do not call this directly, see fs_dev.h. +Result fsOpenSdCardFileSystem(FsFileSystem* out); + +Result fsOpenHostFileSystem(FsFileSystem* out, const char *path); +Result fsOpenHostFileSystemWithOption(FsFileSystem* out, const char *path, u32 flags); ///< [9.0.0+] + +Result fsDeleteSaveDataFileSystem(u64 application_id); +Result fsCreateSaveDataFileSystem(const FsSaveDataAttribute* attr, const FsSaveDataCreationInfo* creation_info, const FsSaveDataMetaInfo* meta); +Result fsCreateSaveDataFileSystemBySystemSaveDataId(const FsSaveDataAttribute* attr, const FsSaveDataCreationInfo* creation_info); +Result fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId save_data_space_id, u64 saveID); ///< [2.0.0+] +Result fsDeleteSaveDataFileSystemBySaveDataAttribute(FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute* attr); ///< [4.0.0+] + +Result fsIsExFatSupported(bool* out); + +Result fsOpenGameCardFileSystem(FsFileSystem* out, const FsGameCardHandle* handle, FsGameCardPartition partition); + +Result fsExtendSaveDataFileSystem(FsSaveDataSpaceId save_data_space_id, u64 saveID, s64 dataSize, s64 journalSize); ///< [3.0.0+] + +Result fsOpenSaveDataFileSystem(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr); +Result fsOpenSaveDataFileSystemBySystemSaveDataId(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr); +Result fsOpenReadOnlySaveDataFileSystem(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr); ///< [2.0.0+]. + +Result fsReadSaveDataFileSystemExtraDataBySaveDataSpaceId(void* buf, size_t len, FsSaveDataSpaceId save_data_space_id, u64 saveID); +Result fsReadSaveDataFileSystemExtraData(void* buf, size_t len, u64 saveID); +Result fsWriteSaveDataFileSystemExtraData(const void* buf, size_t len, FsSaveDataSpaceId save_data_space_id, u64 saveID); + +Result fsOpenSaveDataInfoReader(FsSaveDataInfoReader* out, FsSaveDataSpaceId save_data_space_id); + +Result fsOpenSaveDataInfoReaderWithFilter(FsSaveDataInfoReader* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataFilter *save_data_filter); ///< [6.0.0+] + +Result fsOpenImageDirectoryFileSystem(FsFileSystem* out, FsImageDirectoryId image_directory_id); +Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id); +Result fsOpenCustomStorageFileSystem(FsFileSystem* out, FsCustomStorageId custom_storage_id); ///< [7.0.0+] + +Result fsOpenDataStorageByCurrentProcess(FsStorage* out); +Result fsOpenDataStorageByProgramId(FsStorage *out, u64 program_id); /// <[3.0.0+] +Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, NcmStorageId storageId); +Result fsOpenPatchDataStorageByCurrentProcess(FsStorage* out); + +Result fsOpenDeviceOperator(FsDeviceOperator* out); +Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out); + +Result fsIsSignedSystemPartitionOnSdCardValid(bool *out); + +/// Retrieves the rights id corresponding to the content path. Only available on [2.0.0+]. +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+]. +Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id); + +Result fsDisableAutoSaveDataCreation(void); + +Result fsSetGlobalAccessLogMode(u32 mode); +Result fsGetGlobalAccessLogMode(u32* out_mode); +Result fsOutputAccessLogToSdCard(const char *log, size_t size); + +/// Only available on [7.0.0+]. +Result fsGetProgramIndexForAccessLog(u32 *out_program_index, u32 *out_program_count); + +// Wrapper(s) for fsCreateSaveDataFileSystem. +Result fsCreate_TemporaryStorage(u64 application_id, u64 owner_id, s64 size, u32 flags); + +// Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId. +Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid, u64 owner_id, s64 size, s64 journal_size, u32 flags); +Result fsCreate_SystemSaveData(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, s64 size, s64 journal_size, u32 flags); + +/// Wrapper for fsOpenSaveDataFileSystem. +/// See \ref FsSaveDataAttribute for application_id and uid. +Result fsOpen_SaveData(FsFileSystem* out, u64 application_id, AccountUid uid); + +/// Wrapper for fsOpenReadOnlySaveDataFileSystem. +/// Only available on [2.0.0+]. +/// See \ref FsSaveDataAttribute for application_id and uid. +Result fsOpen_SaveDataReadOnly(FsFileSystem* out, u64 application_id, AccountUid uid); + +/// Wrapper for fsOpenSaveDataFileSystem, for opening BcatSaveData. +Result fsOpen_BcatSaveData(FsFileSystem* out, u64 application_id); + +/// Wrapper for fsOpenSaveDataFileSystem, for opening DeviceSaveData. +/// See \ref FsSaveDataAttribute for application_id. +Result fsOpen_DeviceSaveData(FsFileSystem* out, u64 application_id); + +/// Wrapper for fsOpenSaveDataFileSystem, for opening TemporaryStorage. +/// Only available on [3.0.0+]. +Result fsOpen_TemporaryStorage(FsFileSystem* out); + +/// Wrapper for fsOpenSaveDataFileSystem, for opening CacheStorage. +/// Only available on [3.0.0+]. +/// See \ref FsSaveDataAttribute for application_id. +Result fsOpen_CacheStorage(FsFileSystem* out, u64 application_id, u16 save_data_index); + +/// Wrapper for fsOpenSaveDataFileSystemBySystemSaveDataId, for opening SystemSaveData. +/// WARNING: You can brick when writing to SystemSaveData, if the data is corrupted etc. +Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid); + +/// Wrapper for fsOpenSaveDataFileSystemBySystemSaveDataId, for opening SystemBcatSaveData. +/// Only available on [4.0.0+]. +Result fsOpen_SystemBcatSaveData(FsFileSystem* out, u64 system_save_data_id); + +// IFileSystem +Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option); +Result fsFsDeleteFile(FsFileSystem* fs, const char* path); +Result fsFsCreateDirectory(FsFileSystem* fs, const char* path); +Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path); +Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path); +Result fsFsRenameFile(FsFileSystem* fs, const char* cur_path, const char* new_path); +Result fsFsRenameDirectory(FsFileSystem* fs, const char* cur_path, const char* new_path); +Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out); +Result fsFsOpenFile(FsFileSystem* fs, const char* path, u32 mode, FsFile* out); +Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, u32 mode, FsDir* out); +Result fsFsCommit(FsFileSystem* fs); +Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out); +Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out); +Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out); ///< [3.0.0+] +Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path); ///< [3.0.0+] +Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id); ///< [4.0.0+] +void fsFsClose(FsFileSystem* fs); + +/// Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path. +/// This will cause HOS to treat the directory as if it were a file containing the directory's concatenated contents. +Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path); + +/// Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard. +/// Only available on [8.0.0+]. +Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out); + +// IFile +Result fsFileRead(FsFile* f, s64 off, void* buf, u64 read_size, u32 option, u64* bytes_read); +Result fsFileWrite(FsFile* f, s64 off, const void* buf, u64 write_size, u32 option); +Result fsFileFlush(FsFile* f); +Result fsFileSetSize(FsFile* f, s64 sz); +Result fsFileGetSize(FsFile* f, s64* out); +Result fsFileOperateRange(FsFile* f, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out); ///< [4.0.0+] +void fsFileClose(FsFile* f); + +// IDirectory +Result fsDirRead(FsDir* d, s64* total_entries, size_t max_entries, FsDirectoryEntry *buf); +Result fsDirGetEntryCount(FsDir* d, s64* count); +void fsDirClose(FsDir* d); + +// IStorage +Result fsStorageRead(FsStorage* s, s64 off, void* buf, u64 read_size); +Result fsStorageWrite(FsStorage* s, s64 off, const void* buf, u64 write_size); +Result fsStorageFlush(FsStorage* s); +Result fsStorageSetSize(FsStorage* s, s64 sz); +Result fsStorageGetSize(FsStorage* s, s64* out); +Result fsStorageOperateRange(FsStorage* s, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out); ///< [4.0.0+] +void fsStorageClose(FsStorage* s); + +// ISaveDataInfoReader + +/// Read FsSaveDataInfo data into the buf array. +Result fsSaveDataInfoReaderRead(FsSaveDataInfoReader *s, FsSaveDataInfo* buf, size_t max_entries, s64* total_entries); +void fsSaveDataInfoReaderClose(FsSaveDataInfoReader *s); + +// IEventNotifier +Result fsEventNotifierGetEventHandle(FsEventNotifier* e, Event* out, bool autoclear); +void fsEventNotifierClose(FsEventNotifier* e); + +// IDeviceOperator +Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out); +Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out); +Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out); +Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out); +void fsDeviceOperatorClose(FsDeviceOperator* d); diff --git a/src/libnx/wrapper/switch/services/fs.nim b/src/libnx/wrapper/switch/services/fs.nim new file mode 100644 index 0000000..369cd13 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fs.nim @@ -0,0 +1,698 @@ +## * +## @file fs.h +## @brief Filesystem (fsp-srv) service IPC wrapper. +## Normally applications should just use standard stdio not FS-serv directly. However this can be used if obtaining a FsFileSystem, FsFile, or FsStorage, for mounting with fs_dev/romfs_dev, etc. +## @author plutoo +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/ncm_types, ../services/acc, ../sf/service + +## We use wrapped handles for type safety. + +const + FS_MAX_PATH* = 0x301 + +## / For use with \ref FsSaveDataAttribute. + +const + FS_SAVEDATA_CURRENT_APPLICATIONID* = 0 + +type + FsRightsId* {.bycopy.} = object + c*: array[0x10, U8] + + FsFileSystem* {.bycopy.} = object + s*: Service + + FsFile* {.bycopy.} = object + s*: Service + + FsDir* {.bycopy.} = object + s*: Service + + FsStorage* {.bycopy.} = object + s*: Service + + FsSaveDataInfoReader* {.bycopy.} = object + s*: Service + + FsEventNotifier* {.bycopy.} = object + s*: Service + + FsDeviceOperator* {.bycopy.} = object + s*: Service + + +## / Directory entry. + +type + FsDirectoryEntry* {.bycopy.} = object + name*: array[Fs_Max_Path, char] ## /< Entry name. + pad*: array[3, U8] + `type`*: S8 ## /< See FsDirEntryType. + pad2*: array[3, U8] ## /< ? + fileSize*: S64 ## /< File size. + + +## / SaveDataAttribute + +type + FsSaveDataAttribute* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId of the savedata to access when accessing other programs' savedata via SaveData, otherwise FS_SAVEDATA_CURRENT_APPLICATIONID. + uid*: AccountUid ## /< \ref AccountUid for the user-specific savedata to access, otherwise 0 for common savedata. + systemSaveDataId*: U64 ## /< SystemSaveDataId, 0 for ::FsSaveDataType_Account. + saveDataType*: U8 ## /< \ref FsSaveDataType + saveDataRank*: U8 ## /< \ref FsSaveDataRank + saveDataIndex*: U16 ## /< SaveDataIndex + padX24*: U32 ## /< Padding. + unkX28*: U64 ## /< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. + unkX30*: U64 ## /< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. + unkX38*: U64 ## /< 0 for ::FsSaveDataType_System/::FsSaveDataType_Account. + + +## / SaveDataExtraData + +type + FsSaveDataExtraData* {.bycopy.} = object + attr*: FsSaveDataAttribute ## /< \ref FsSaveDataAttribute + ownerId*: U64 ## /< ProgramId of the owner of this save data. 0 for ::FsSaveDataType_System. + timestamp*: U64 ## /< POSIX timestamp. + flags*: U32 ## /< \ref FsSaveDataFlags + unkX54*: U32 ## /< Normally 0. Possibly unused? + dataSize*: S64 ## /< Usable save data size. + journalSize*: S64 ## /< Journal size of the save data. + commitId*: U64 ## /< Id of the latest commit. + unused*: array[0x190, U8] ## /< Uninitialized. + + +## / SaveDataMetaInfo + +type + FsSaveDataMetaInfo* {.bycopy.} = object + size*: U32 + `type`*: U8 ## /< \ref FsSaveDataMetaType + reserved*: array[0x0B, U8] + + +## / SaveDataCreationInfo + +type + FsSaveDataCreationInfo* {.bycopy.} = object + saveDataSize*: S64 ## /< Size of the save data. + journalSize*: S64 ## /< Journal size of the save data. + availableSize*: U64 ## /< AvailableSize + ownerId*: U64 ## /< ProgramId of the owner of this save data. 0 for ::FsSaveDataType_System. + flags*: U32 ## /< \ref FsSaveDataFlags + saveDataSpaceId*: U8 ## /< \ref FsSaveDataSpaceId + unk*: U8 ## /< 0 for ::FsSaveDataType_System. + padding*: array[0x1a, U8] ## /< Uninitialized for ::FsSaveDataType_System. + + +## / SaveDataInfo + +type + FsSaveDataInfo* {.bycopy.} = object + saveDataId*: U64 ## /< SaveDataId + saveDataSpaceId*: U8 ## /< \ref FsSaveDataSpaceId + saveDataType*: U8 ## /< \ref FsSaveDataType + pad*: array[6, U8] ## /< Padding. + uid*: AccountUid ## /< FsSave::userID + systemSaveDataId*: U64 ## /< FsSaveDataAttribute::system_save_data_id + applicationId*: U64 ## /< ApplicationId for ::FsSaveDataType_Account. + size*: U64 ## /< Raw saveimage size. + saveDataIndex*: U16 ## /< SaveDataIndex + saveDataRank*: U8 ## /< \ref FsSaveDataRank + unkX3b*: array[0x25, U8] ## /< Unknown. Usually zeros? + + +## / SaveDataFilter + +type + FsSaveDataFilter* {.bycopy.} = object + filterByApplicationId*: bool ## /< Filter by \ref FsSaveDataAttribute::application_id + filterBySaveDataType*: bool ## /< Filter by \ref FsSaveDataAttribute::save_data_type + filterByUserId*: bool ## /< Filter by \ref FsSaveDataAttribute::uid + filterBySystemSaveDataId*: bool ## /< Filter by \ref FsSaveDataAttribute::system_save_data_id + filterByIndex*: bool ## /< Filter by \ref FsSaveDataAttribute::save_data_index + saveDataRank*: U8 ## /< \ref FsSaveDataRank + padding*: array[0x2, U8] ## /< Padding + attr*: FsSaveDataAttribute ## /< \ref FsSaveDataAttribute + + FsTimeStampRaw* {.bycopy.} = object + created*: U64 ## /< POSIX timestamp. + modified*: U64 ## /< POSIX timestamp. + accessed*: U64 ## /< POSIX timestamp. + isValid*: U8 ## /< 0x1 when the timestamps are set. + padding*: array[7, U8] + + +## / This is nn::fssystem::ArchiveMacKey. Used by \ref setsysGetThemeKey and \ref setsysSetThemeKey. Does not appear to be in use elsewhere. + +type + FsArchiveMacKey* {.bycopy.} = object + key*: array[0x10, U8] + + +## / Returned by fsFsGetEntryType. + +type + FsDirEntryType* = enum + FsDirEntryTypeDir = 0, ## /< Entry is a directory. + FsDirEntryTypeFile = 1 ## /< Entry is a file. + + +## / For use with fsFsOpenFile. + +type + FsOpenMode* = enum + FsOpenModeRead = bit(0), ## /< Open for reading. + FsOpenModeWrite = bit(1), ## /< Open for writing. + FsOpenModeAppend = bit(2) ## /< Append file. + + +## / For use with fsFsCreateFile. + +type + FsCreateOption* = enum + FsCreateOptionBigFile = bit(0) ## /< Creates a ConcatenationFile (dir with archive bit) instead of file. + + +## / For use with fsFsOpenDirectory. + +type + FsDirOpenMode* = enum + FsDirOpenModeReadDirs = bit(0), ## /< Enable reading directory entries. + FsDirOpenModeReadFiles = bit(1), ## /< Enable reading file entries. + FsDirOpenModeNoFileSize = bit(31) ## /< Causes result entries to not contain filesize information (always 0). + + +## / For use with fsFileRead. + +type + FsReadOption* = enum + FsReadOptionNone = 0 ## /< No option. + + +## / For use with fsFileWrite. + +type + FsWriteOption* = enum + FsWriteOptionNone = 0, ## /< No option. + FsWriteOptionFlush = bit(0) ## /< Forces a flush after write. + FsContentStorageId* = enum + FsContentStorageIdSystem = 0, FsContentStorageIdUser = 1, + FsContentStorageIdSdCard = 2 + FsCustomStorageId* = enum + FsCustomStorageIdSystem = 0, FsCustomStorageIdSdCard = 1 + + + + +## / ImageDirectoryId + +type + FsImageDirectoryId* = enum + FsImageDirectoryIdNand = 0, FsImageDirectoryIdSd = 1 + + +## / SaveDataSpaceId + +type + FsSaveDataSpaceId* = enum + FsSaveDataSpaceIdAll = -1, ## /< Pseudo value for fsOpenSaveDataInfoReader(). + FsSaveDataSpaceIdSystem = 0, ## /< System + FsSaveDataSpaceIdUser = 1, ## /< User + FsSaveDataSpaceIdSdSystem = 2, ## /< SdSystem + FsSaveDataSpaceIdTemporary = 3, ## /< [3.0.0+] Temporary + FsSaveDataSpaceIdSdUser = 4, ## /< [4.0.0+] SdUser + FsSaveDataSpaceIdProperSystem = 100, ## /< [3.0.0+] ProperSystem + FsSaveDataSpaceIdSafeMode = 101 ## /< [3.0.0+] SafeMode + + +## / SaveDataType + +type + FsSaveDataType* = enum + FsSaveDataTypeSystem = 0, ## /< System + FsSaveDataTypeAccount = 1, ## /< Account + FsSaveDataTypeBcat = 2, ## /< Bcat + FsSaveDataTypeDevice = 3, ## /< Device + FsSaveDataTypeTemporary = 4, ## /< [3.0.0+] Temporary + FsSaveDataTypeCache = 5, ## /< [3.0.0+] Cache + FsSaveDataTypeSystemBcat = 6 ## /< [4.0.0+] SystemBcat + + +## / SaveDataRank + +type + FsSaveDataRank* = enum + FsSaveDataRankPrimary = 0, ## /< Primary + FsSaveDataRankSecondary = 1 ## /< Secondary + + +## / SaveDataFlags + +type + FsSaveDataFlags* = enum + FsSaveDataFlagsKeepAfterResettingSystemSaveData = bit(0), + FsSaveDataFlagsKeepAfterRefurbishment = bit(1), FsSaveDataFlagsKeepAfterResettingSystemSaveDataWithoutUserSaveData = bit( + 2), FsSaveDataFlagsNeedsSecureDelete = bit(3) + + +## / SaveDataMetaType + +type + FsSaveDataMetaType* = enum + FsSaveDataMetaTypeNone = 0, FsSaveDataMetaTypeThumbnail = 1, + FsSaveDataMetaTypeExtensionContext = 2 + FsGameCardAttribute* = enum + FsGameCardAttributeAutoBootFlag = bit(0), ## /< Causes the cartridge to automatically start on bootup + FsGameCardAttributeHistoryEraseFlag = bit(1), ## /< Causes NS to throw an error on attempt to load the cartridge + FsGameCardAttributeRepairToolFlag = bit(2), ## /< [4.0.0+] Indicates that this gamecard is a repair tool. + FsGameCardAttributeDifferentRegionCupToTerraDeviceFlag = bit(3), ## /< [9.0.0+] DifferentRegionCupToTerraDeviceFlag + FsGameCardAttributeDifferentRegionCupToGlobalDeviceFlag = bit(4) ## /< [9.0.0+] DifferentRegionCupToGlobalDeviceFlag + FsGameCardPartition* = enum + FsGameCardPartitionUpdate = 0, FsGameCardPartitionNormal = 1, + FsGameCardPartitionSecure = 2, FsGameCardPartitionLogo = 3 ## /< [4.0.0+] + FsGameCardHandle* {.bycopy.} = object + value*: U32 + + FsRangeInfo* {.bycopy.} = object + aesCtrKeyType*: U32 ## /< Contains bitflags describing how data is AES encrypted. + speedEmulationType*: U32 ## /< Contains bitflags describing how data is emulated. + reserved*: array[0x38 div sizeof((U32)), U32] + + FsOperationId* = enum + FsOperationIdClear, ## /< Fill range with zero for supported file/storage. + FsOperationIdClearSignature, ## /< Clears signature for supported file/storage. + FsOperationIdInvalidateCache, ## /< Invalidates cache for supported file/storage. + FsOperationIdQueryRange ## /< Retrieves information on data for supported file/storage. + + + + + +## / BisPartitionId + +type + FsBisPartitionId* = enum + FsBisPartitionIdBootPartition1Root = 0, + FsBisPartitionIdBootPartition2Root = 10, FsBisPartitionIdUserDataRoot = 20, + FsBisPartitionIdBootConfigAndPackage2Part1 = 21, + FsBisPartitionIdBootConfigAndPackage2Part2 = 22, + FsBisPartitionIdBootConfigAndPackage2Part3 = 23, + FsBisPartitionIdBootConfigAndPackage2Part4 = 24, + FsBisPartitionIdBootConfigAndPackage2Part5 = 25, + FsBisPartitionIdBootConfigAndPackage2Part6 = 26, + FsBisPartitionIdCalibrationBinary = 27, FsBisPartitionIdCalibrationFile = 28, + FsBisPartitionIdSafeMode = 29, FsBisPartitionIdUser = 30, + FsBisPartitionIdSystem = 31, FsBisPartitionIdSystemProperEncryption = 32, + FsBisPartitionIdSystemProperPartition = 33, + FsBisPartitionIdSignedSystemPartitionOnSafeMode = 34 + + +## / FileSystemType + +type + FsFileSystemType* = enum + FsFileSystemTypeLogo = 2, ## /< Logo + FsFileSystemTypeContentControl = 3, ## /< ContentControl + FsFileSystemTypeContentManual = 4, ## /< ContentManual + FsFileSystemTypeContentMeta = 5, ## /< ContentMeta + FsFileSystemTypeContentData = 6, ## /< ContentData + FsFileSystemTypeApplicationPackage = 7, ## /< ApplicationPackage + FsFileSystemTypeRegisteredUpdate = 8 ## /< [4.0.0+] RegisteredUpdate + + +## / FileSystemQueryId + +type + FsFileSystemQueryId* = enum + FsFileSystemQueryIdSetConcatenationFileAttribute = 0, ## /< [4.0.0+] + FsFileSystemQueryIdIsValidSignedSystemPartitionOnSdCard = 2 ## /< [8.0.0+] + + +## / FsPriority + +type + FsPriority* = enum + FsPriorityNormal = 0, FsPriorityRealtime = 1, FsPriorityLow = 2, + FsPriorityBackground = 3 + + +## / For use with fsOpenHostFileSystemWithOption + +type + FsMountHostOption* = enum + FsMountHostOptionFlagNone = 0, ## /< Host filesystem will be case insensitive. + FsMountHostOptionFlagPseudoCaseSensitive = bit(0) ## /< Host filesystem will be pseudo case sensitive. + +proc fsInitialize*(): Result {.cdecl, importc: "fsInitialize".} +## / Initialize fsp-srv. Used automatically during app startup. +proc fsExit*() {.cdecl, importc: "fsExit".} +## / Exit fsp-srv. Used automatically during app exit. +proc fsGetServiceSession*(): ptr Service {.cdecl, importc: "fsGetServiceSession".} +## / Gets the Service object for the actual fsp-srv service session. +proc fsSetPriority*(prio: FsPriority) {.cdecl, importc: "fsSetPriority".} +## / [5.0.0+] Configures the \ref FsPriority of all filesystem commands issued within the current thread. +proc fsOpenFileSystem*(`out`: ptr FsFileSystem; fsType: FsFileSystemType; + contentPath: cstring): Result {.cdecl, + importc: "fsOpenFileSystem".} +## / Mount requested filesystem type from content file +proc fsOpenDataFileSystemByCurrentProcess*(`out`: ptr FsFileSystem): Result {.cdecl, + importc: "fsOpenDataFileSystemByCurrentProcess".} + +proc fsOpenFileSystemWithPatch*(`out`: ptr FsFileSystem; id: U64; + fsType: FsFileSystemType): Result {.cdecl, + importc: "fsOpenFileSystemWithPatch".} +## /< same as calling fsOpenFileSystemWithId with 0 as id + +proc fsOpenFileSystemWithId*(`out`: ptr FsFileSystem; id: U64; + fsType: FsFileSystemType; contentPath: cstring): Result {. + cdecl, importc: "fsOpenFileSystemWithId".} +## /< [2.0.0+], like OpenFileSystemWithId but without content path. + +proc fsOpenDataFileSystemByProgramId*(`out`: ptr FsFileSystem; programId: U64): Result {. + cdecl, importc: "fsOpenDataFileSystemByProgramId".} +## /< works on all firmwares, id is ignored on [1.0.0] + +proc fsOpenBisFileSystem*(`out`: ptr FsFileSystem; partitionId: FsBisPartitionId; + string: cstring): Result {.cdecl, + importc: "fsOpenBisFileSystem".} +## /< [3.0.0+] +proc fsOpenBisStorage*(`out`: ptr FsStorage; partitionId: FsBisPartitionId): Result {. + cdecl, importc: "fsOpenBisStorage".} + +proc fsOpenSdCardFileSystem*(`out`: ptr FsFileSystem): Result {.cdecl, + importc: "fsOpenSdCardFileSystem".} +## / Do not call this directly, see fs_dev.h. +proc fsOpenHostFileSystem*(`out`: ptr FsFileSystem; path: cstring): Result {.cdecl, + importc: "fsOpenHostFileSystem".} +proc fsOpenHostFileSystemWithOption*(`out`: ptr FsFileSystem; path: cstring; + flags: U32): Result {.cdecl, + importc: "fsOpenHostFileSystemWithOption".} + +proc fsDeleteSaveDataFileSystem*(applicationId: U64): Result {.cdecl, + importc: "fsDeleteSaveDataFileSystem".} +## /< [9.0.0+] +proc fsCreateSaveDataFileSystem*(attr: ptr FsSaveDataAttribute; + creationInfo: ptr FsSaveDataCreationInfo; + meta: ptr FsSaveDataMetaInfo): Result {.cdecl, + importc: "fsCreateSaveDataFileSystem".} +proc fsCreateSaveDataFileSystemBySystemSaveDataId*(attr: ptr FsSaveDataAttribute; + creationInfo: ptr FsSaveDataCreationInfo): Result {.cdecl, + importc: "fsCreateSaveDataFileSystemBySystemSaveDataId".} +proc fsDeleteSaveDataFileSystemBySaveDataSpaceId*( + saveDataSpaceId: FsSaveDataSpaceId; saveID: U64): Result {.cdecl, + importc: "fsDeleteSaveDataFileSystemBySaveDataSpaceId".} + +proc fsDeleteSaveDataFileSystemBySaveDataAttribute*( + saveDataSpaceId: FsSaveDataSpaceId; attr: ptr FsSaveDataAttribute): Result {. + cdecl, importc: "fsDeleteSaveDataFileSystemBySaveDataAttribute".} +## /< [2.0.0+] + +proc fsIsExFatSupported*(`out`: ptr bool): Result {.cdecl, + importc: "fsIsExFatSupported".} +## /< [4.0.0+] +proc fsOpenGameCardFileSystem*(`out`: ptr FsFileSystem; + handle: ptr FsGameCardHandle; + partition: FsGameCardPartition): Result {.cdecl, + importc: "fsOpenGameCardFileSystem".} +proc fsExtendSaveDataFileSystem*(saveDataSpaceId: FsSaveDataSpaceId; saveID: U64; + dataSize: S64; journalSize: S64): Result {.cdecl, + importc: "fsExtendSaveDataFileSystem".} + +proc fsOpenSaveDataFileSystem*(`out`: ptr FsFileSystem; + saveDataSpaceId: FsSaveDataSpaceId; + attr: ptr FsSaveDataAttribute): Result {.cdecl, + importc: "fsOpenSaveDataFileSystem".} +## /< [3.0.0+] +proc fsOpenSaveDataFileSystemBySystemSaveDataId*(`out`: ptr FsFileSystem; + saveDataSpaceId: FsSaveDataSpaceId; attr: ptr FsSaveDataAttribute): Result {. + cdecl, importc: "fsOpenSaveDataFileSystemBySystemSaveDataId".} +proc fsOpenReadOnlySaveDataFileSystem*(`out`: ptr FsFileSystem; + saveDataSpaceId: FsSaveDataSpaceId; + attr: ptr FsSaveDataAttribute): Result {. + cdecl, importc: "fsOpenReadOnlySaveDataFileSystem".} + +proc fsReadSaveDataFileSystemExtraDataBySaveDataSpaceId*(buf: pointer; + len: csize_t; saveDataSpaceId: FsSaveDataSpaceId; saveID: U64): Result {.cdecl, + importc: "fsReadSaveDataFileSystemExtraDataBySaveDataSpaceId".} +## /< [2.0.0+]. +proc fsReadSaveDataFileSystemExtraData*(buf: pointer; len: csize_t; saveID: U64): Result {. + cdecl, importc: "fsReadSaveDataFileSystemExtraData".} +proc fsWriteSaveDataFileSystemExtraData*(buf: pointer; len: csize_t; + saveDataSpaceId: FsSaveDataSpaceId; + saveID: U64): Result {.cdecl, + importc: "fsWriteSaveDataFileSystemExtraData".} +proc fsOpenSaveDataInfoReader*(`out`: ptr FsSaveDataInfoReader; + saveDataSpaceId: FsSaveDataSpaceId): Result {.cdecl, + importc: "fsOpenSaveDataInfoReader".} +proc fsOpenSaveDataInfoReaderWithFilter*(`out`: ptr FsSaveDataInfoReader; + saveDataSpaceId: FsSaveDataSpaceId; + saveDataFilter: ptr FsSaveDataFilter): Result {. + cdecl, importc: "fsOpenSaveDataInfoReaderWithFilter".} + +proc fsOpenImageDirectoryFileSystem*(`out`: ptr FsFileSystem; + imageDirectoryId: FsImageDirectoryId): Result {. + cdecl, importc: "fsOpenImageDirectoryFileSystem".} +## /< [6.0.0+] +proc fsOpenContentStorageFileSystem*(`out`: ptr FsFileSystem; + contentStorageId: FsContentStorageId): Result {. + cdecl, importc: "fsOpenContentStorageFileSystem".} +proc fsOpenCustomStorageFileSystem*(`out`: ptr FsFileSystem; + customStorageId: FsCustomStorageId): Result {. + cdecl, importc: "fsOpenCustomStorageFileSystem".} + +proc fsOpenDataStorageByCurrentProcess*(`out`: ptr FsStorage): Result {.cdecl, + importc: "fsOpenDataStorageByCurrentProcess".} +## /< [7.0.0+] +proc fsOpenDataStorageByProgramId*(`out`: ptr FsStorage; programId: U64): Result {. + cdecl, importc: "fsOpenDataStorageByProgramId".} + +proc fsOpenDataStorageByDataId*(`out`: ptr FsStorage; dataId: U64; + storageId: NcmStorageId): Result {.cdecl, + importc: "fsOpenDataStorageByDataId".} +## / <[3.0.0+] +proc fsOpenPatchDataStorageByCurrentProcess*(`out`: ptr FsStorage): Result {.cdecl, + importc: "fsOpenPatchDataStorageByCurrentProcess".} +proc fsOpenDeviceOperator*(`out`: ptr FsDeviceOperator): Result {.cdecl, + importc: "fsOpenDeviceOperator".} +proc fsOpenSdCardDetectionEventNotifier*(`out`: ptr FsEventNotifier): Result {.cdecl, + importc: "fsOpenSdCardDetectionEventNotifier".} +proc fsIsSignedSystemPartitionOnSdCardValid*(`out`: ptr bool): Result {.cdecl, + importc: "fsIsSignedSystemPartitionOnSdCardValid".} + +proc fsGetRightsIdByPath*(path: cstring; outRightsId: ptr FsRightsId): Result {.cdecl, + importc: "fsGetRightsIdByPath".} +## / Retrieves the rights id corresponding to the content path. Only available on [2.0.0+]. + +proc fsGetRightsIdAndKeyGenerationByPath*(path: cstring; outKeyGeneration: ptr U8; + outRightsId: ptr FsRightsId): Result {.cdecl, importc: "fsGetRightsIdAndKeyGenerationByPath".} +## / Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+]. +proc fsDisableAutoSaveDataCreation*(): Result {.cdecl, + importc: "fsDisableAutoSaveDataCreation".} +proc fsSetGlobalAccessLogMode*(mode: U32): Result {.cdecl, + importc: "fsSetGlobalAccessLogMode".} +proc fsGetGlobalAccessLogMode*(outMode: ptr U32): Result {.cdecl, + importc: "fsGetGlobalAccessLogMode".} +proc fsOutputAccessLogToSdCard*(log: cstring; size: csize_t): Result {.cdecl, + importc: "fsOutputAccessLogToSdCard".} + +proc fsGetProgramIndexForAccessLog*(outProgramIndex: ptr U32; + outProgramCount: ptr U32): Result {.cdecl, + importc: "fsGetProgramIndexForAccessLog".} +## / Only available on [7.0.0+]. + +proc fsCreateTemporaryStorage*(applicationId: U64; ownerId: U64; size: S64; flags: U32): Result {. + cdecl, importc: "fsCreate_TemporaryStorage".} +## Wrapper(s) for fsCreateSaveDataFileSystem. + +proc fsCreateSystemSaveDataWithOwner*(saveDataSpaceId: FsSaveDataSpaceId; + systemSaveDataId: U64; uid: AccountUid; + ownerId: U64; size: S64; journalSize: S64; + flags: U32): Result {.cdecl, + importc: "fsCreate_SystemSaveDataWithOwner".} +## Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId. +proc fsCreateSystemSaveData*(saveDataSpaceId: FsSaveDataSpaceId; + systemSaveDataId: U64; size: S64; journalSize: S64; + flags: U32): Result {.cdecl, + importc: "fsCreate_SystemSaveData".} + +proc fsOpenSaveData*(`out`: ptr FsFileSystem; applicationId: U64; uid: AccountUid): Result {. + cdecl, importc: "fsOpen_SaveData".} +## / Wrapper for fsOpenSaveDataFileSystem. +## / See \ref FsSaveDataAttribute for application_id and uid. + +proc fsOpenSaveDataReadOnly*(`out`: ptr FsFileSystem; applicationId: U64; + uid: AccountUid): Result {.cdecl, + importc: "fsOpen_SaveDataReadOnly".} +## / Wrapper for fsOpenReadOnlySaveDataFileSystem. +## / Only available on [2.0.0+]. +## / See \ref FsSaveDataAttribute for application_id and uid. + +proc fsOpenBcatSaveData*(`out`: ptr FsFileSystem; applicationId: U64): Result {.cdecl, + importc: "fsOpen_BcatSaveData".} +## / Wrapper for fsOpenSaveDataFileSystem, for opening BcatSaveData. + +proc fsOpenDeviceSaveData*(`out`: ptr FsFileSystem; applicationId: U64): Result {. + cdecl, importc: "fsOpen_DeviceSaveData".} +## / Wrapper for fsOpenSaveDataFileSystem, for opening DeviceSaveData. +## / See \ref FsSaveDataAttribute for application_id. + +proc fsOpenTemporaryStorage*(`out`: ptr FsFileSystem): Result {.cdecl, + importc: "fsOpen_TemporaryStorage".} +## / Wrapper for fsOpenSaveDataFileSystem, for opening TemporaryStorage. +## / Only available on [3.0.0+]. + +proc fsOpenCacheStorage*(`out`: ptr FsFileSystem; applicationId: U64; + saveDataIndex: U16): Result {.cdecl, + importc: "fsOpen_CacheStorage".} +## / Wrapper for fsOpenSaveDataFileSystem, for opening CacheStorage. +## / Only available on [3.0.0+]. +## / See \ref FsSaveDataAttribute for application_id. + +proc fsOpenSystemSaveData*(`out`: ptr FsFileSystem; + saveDataSpaceId: FsSaveDataSpaceId; + systemSaveDataId: U64; uid: AccountUid): Result {.cdecl, + importc: "fsOpen_SystemSaveData".} +## / Wrapper for fsOpenSaveDataFileSystemBySystemSaveDataId, for opening SystemSaveData. +## / WARNING: You can brick when writing to SystemSaveData, if the data is corrupted etc. + +proc fsOpenSystemBcatSaveData*(`out`: ptr FsFileSystem; systemSaveDataId: U64): Result {. + cdecl, importc: "fsOpen_SystemBcatSaveData".} +## / Wrapper for fsOpenSaveDataFileSystemBySystemSaveDataId, for opening SystemBcatSaveData. +## / Only available on [4.0.0+]. + +## IFileSystem + +proc fsFsCreateFile*(fs: ptr FsFileSystem; path: cstring; size: S64; option: U32): Result {. + cdecl, importc: "fsFsCreateFile".} +proc fsFsDeleteFile*(fs: ptr FsFileSystem; path: cstring): Result {.cdecl, + importc: "fsFsDeleteFile".} +proc fsFsCreateDirectory*(fs: ptr FsFileSystem; path: cstring): Result {.cdecl, + importc: "fsFsCreateDirectory".} +proc fsFsDeleteDirectory*(fs: ptr FsFileSystem; path: cstring): Result {.cdecl, + importc: "fsFsDeleteDirectory".} +proc fsFsDeleteDirectoryRecursively*(fs: ptr FsFileSystem; path: cstring): Result {. + cdecl, importc: "fsFsDeleteDirectoryRecursively".} +proc fsFsRenameFile*(fs: ptr FsFileSystem; curPath: cstring; newPath: cstring): Result {. + cdecl, importc: "fsFsRenameFile".} +proc fsFsRenameDirectory*(fs: ptr FsFileSystem; curPath: cstring; newPath: cstring): Result {. + cdecl, importc: "fsFsRenameDirectory".} +proc fsFsGetEntryType*(fs: ptr FsFileSystem; path: cstring; `out`: ptr FsDirEntryType): Result {. + cdecl, importc: "fsFsGetEntryType".} +proc fsFsOpenFile*(fs: ptr FsFileSystem; path: cstring; mode: U32; `out`: ptr FsFile): Result {. + cdecl, importc: "fsFsOpenFile".} +proc fsFsOpenDirectory*(fs: ptr FsFileSystem; path: cstring; mode: U32; `out`: ptr FsDir): Result {. + cdecl, importc: "fsFsOpenDirectory".} +proc fsFsCommit*(fs: ptr FsFileSystem): Result {.cdecl, importc: "fsFsCommit".} +proc fsFsGetFreeSpace*(fs: ptr FsFileSystem; path: cstring; `out`: ptr S64): Result {. + cdecl, importc: "fsFsGetFreeSpace".} +proc fsFsGetTotalSpace*(fs: ptr FsFileSystem; path: cstring; `out`: ptr S64): Result {. + cdecl, importc: "fsFsGetTotalSpace".} +proc fsFsGetFileTimeStampRaw*(fs: ptr FsFileSystem; path: cstring; + `out`: ptr FsTimeStampRaw): Result {.cdecl, + importc: "fsFsGetFileTimeStampRaw".} +## /< [3.0.0+] + +proc fsFsCleanDirectoryRecursively*(fs: ptr FsFileSystem; path: cstring): Result {. + cdecl, importc: "fsFsCleanDirectoryRecursively".} +## /< [3.0.0+] + +proc fsFsQueryEntry*(fs: ptr FsFileSystem; `out`: pointer; outSize: csize_t; + `in`: pointer; inSize: csize_t; path: cstring; + queryId: FsFileSystemQueryId): Result {.cdecl, + importc: "fsFsQueryEntry".} +## /< [4.0.0+] + +proc fsFsClose*(fs: ptr FsFileSystem) {.cdecl, importc: "fsFsClose".} + +proc fsFsSetConcatenationFileAttribute*(fs: ptr FsFileSystem; path: cstring): Result {. + cdecl, importc: "fsFsSetConcatenationFileAttribute".} +## / Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path. +## / This will cause HOS to treat the directory as if it were a file containing the directory's concatenated contents. + +proc fsFsIsValidSignedSystemPartitionOnSdCard*(fs: ptr FsFileSystem; `out`: ptr bool): Result {. + cdecl, importc: "fsFsIsValidSignedSystemPartitionOnSdCard".} +## / Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard. +## / Only available on [8.0.0+]. + +## IFile + +proc fsFileRead*(f: ptr FsFile; off: S64; buf: pointer; readSize: U64; option: U32; + bytesRead: ptr U64): Result {.cdecl, importc: "fsFileRead".} +proc fsFileWrite*(f: ptr FsFile; off: S64; buf: pointer; writeSize: U64; option: U32): Result {. + cdecl, importc: "fsFileWrite".} +proc fsFileFlush*(f: ptr FsFile): Result {.cdecl, importc: "fsFileFlush".} +proc fsFileSetSize*(f: ptr FsFile; sz: S64): Result {.cdecl, importc: "fsFileSetSize".} +proc fsFileGetSize*(f: ptr FsFile; `out`: ptr S64): Result {.cdecl, + importc: "fsFileGetSize".} +proc fsFileOperateRange*(f: ptr FsFile; opId: FsOperationId; off: S64; len: S64; + `out`: ptr FsRangeInfo): Result {.cdecl, + importc: "fsFileOperateRange".} + +proc fsFileClose*(f: ptr FsFile) {.cdecl, importc: "fsFileClose".} +## /< [4.0.0+] + +## IDirectory + +proc fsDirRead*(d: ptr FsDir; totalEntries: ptr S64; maxEntries: csize_t; + buf: ptr FsDirectoryEntry): Result {.cdecl, importc: "fsDirRead".} +proc fsDirGetEntryCount*(d: ptr FsDir; count: ptr S64): Result {.cdecl, + importc: "fsDirGetEntryCount".} +proc fsDirClose*(d: ptr FsDir) {.cdecl, importc: "fsDirClose".} + +## IStorage + +proc fsStorageRead*(s: ptr FsStorage; off: S64; buf: pointer; readSize: U64): Result {. + cdecl, importc: "fsStorageRead".} +proc fsStorageWrite*(s: ptr FsStorage; off: S64; buf: pointer; writeSize: U64): Result {. + cdecl, importc: "fsStorageWrite".} +proc fsStorageFlush*(s: ptr FsStorage): Result {.cdecl, importc: "fsStorageFlush".} +proc fsStorageSetSize*(s: ptr FsStorage; sz: S64): Result {.cdecl, + importc: "fsStorageSetSize".} +proc fsStorageGetSize*(s: ptr FsStorage; `out`: ptr S64): Result {.cdecl, + importc: "fsStorageGetSize".} +proc fsStorageOperateRange*(s: ptr FsStorage; opId: FsOperationId; off: S64; len: S64; + `out`: ptr FsRangeInfo): Result {.cdecl, + importc: "fsStorageOperateRange".} + +proc fsStorageClose*(s: ptr FsStorage) {.cdecl, importc: "fsStorageClose".} +## /< [4.0.0+] + +## ISaveDataInfoReader + +proc fsSaveDataInfoReaderRead*(s: ptr FsSaveDataInfoReader; buf: ptr FsSaveDataInfo; + maxEntries: csize_t; totalEntries: ptr S64): Result {. + cdecl, importc: "fsSaveDataInfoReaderRead".} +## / Read FsSaveDataInfo data into the buf array. + +proc fsSaveDataInfoReaderClose*(s: ptr FsSaveDataInfoReader) {.cdecl, + importc: "fsSaveDataInfoReaderClose".} + +## IEventNotifier + +proc fsEventNotifierGetEventHandle*(e: ptr FsEventNotifier; `out`: ptr Event; + autoclear: bool): Result {.cdecl, + importc: "fsEventNotifierGetEventHandle".} +proc fsEventNotifierClose*(e: ptr FsEventNotifier) {.cdecl, + importc: "fsEventNotifierClose".} + +## IDeviceOperator + +proc fsDeviceOperatorIsSdCardInserted*(d: ptr FsDeviceOperator; `out`: ptr bool): Result {. + cdecl, importc: "fsDeviceOperatorIsSdCardInserted".} +proc fsDeviceOperatorIsGameCardInserted*(d: ptr FsDeviceOperator; `out`: ptr bool): Result {. + cdecl, importc: "fsDeviceOperatorIsGameCardInserted".} +proc fsDeviceOperatorGetGameCardHandle*(d: ptr FsDeviceOperator; + `out`: ptr FsGameCardHandle): Result {.cdecl, + importc: "fsDeviceOperatorGetGameCardHandle".} +proc fsDeviceOperatorGetGameCardAttribute*(d: ptr FsDeviceOperator; + handle: ptr FsGameCardHandle; `out`: ptr U8): Result {.cdecl, + importc: "fsDeviceOperatorGetGameCardAttribute".} +proc fsDeviceOperatorClose*(d: ptr FsDeviceOperator) {.cdecl, + importc: "fsDeviceOperatorClose".} diff --git a/src/libnx/wrapper/switch/services/fsldr.h b/src/libnx/wrapper/switch/services/fsldr.h new file mode 100644 index 0000000..e7f761d --- /dev/null +++ b/src/libnx/wrapper/switch/services/fsldr.h @@ -0,0 +1,30 @@ +/** + * @file fsldr.h + * @brief FilesystemProxy-ForLoader (fsp-ldr) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/fs.h" +#include "../crypto/sha256.h" + +typedef struct { + u8 signature[0x100]; + u8 hash[SHA256_HASH_SIZE]; + bool is_signed; + u8 reserved[3]; +} FsCodeInfo; + +/// Initialize fsp-ldr. +Result fsldrInitialize(void); + +/// Exit fsp-ldr. +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, FsFileSystem* out); +Result fsldrIsArchivedProgram(u64 pid, bool *out); diff --git a/src/libnx/wrapper/switch/services/fsldr.nim b/src/libnx/wrapper/switch/services/fsldr.nim new file mode 100644 index 0000000..595e104 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fsldr.nim @@ -0,0 +1,34 @@ +## * +## @file fsldr.h +## @brief FilesystemProxy-ForLoader (fsp-ldr) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/fs, ../crypto/sha256 + +type + FsCodeInfo* {.bycopy.} = object + signature*: array[0x100, U8] + hash*: array[Sha256Hash_Size, U8] + isSigned*: bool + reserved*: array[3, U8] + + + +proc fsldrInitialize*(): Result {.cdecl, importc: "fsldrInitialize".} +## / Initialize fsp-ldr. + +proc fsldrExit*() {.cdecl, importc: "fsldrExit".} +## / Exit fsp-ldr. + +proc fsldrGetServiceSession*(): ptr Service {.cdecl, + importc: "fsldrGetServiceSession".} +## / Gets the Service object for the actual fsp-ldr service session. + +proc fsldrOpenCodeFileSystem*(outCodeInfo: ptr FsCodeInfo; tid: U64; path: cstring; + `out`: ptr FsFileSystem): Result {.cdecl, + importc: "fsldrOpenCodeFileSystem".} +proc fsldrIsArchivedProgram*(pid: U64; `out`: ptr bool): Result {.cdecl, + importc: "fsldrIsArchivedProgram".} diff --git a/src/libnx/wrapper/switch/services/fspr.h b/src/libnx/wrapper/switch/services/fspr.h new file mode 100644 index 0000000..33eaed7 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fspr.h @@ -0,0 +1,24 @@ +/** + * @file fspr.h + * @brief FilesystemProxy-ProgramRegistry (fsp-pr) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/ncm_types.h" + +/// Initialize fsp-pr. +Result fsprInitialize(void); + +/// Exit fsp-pr. +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 fsprUnregisterProgram(u64 pid); +Result fsprSetCurrentProcess(void); +Result fsprSetEnabledProgramVerification(bool enabled); diff --git a/src/libnx/wrapper/switch/services/fspr.nim b/src/libnx/wrapper/switch/services/fspr.nim new file mode 100644 index 0000000..f163f31 --- /dev/null +++ b/src/libnx/wrapper/switch/services/fspr.nim @@ -0,0 +1,28 @@ +## * +## @file fspr.h +## @brief FilesystemProxy-ProgramRegistry (fsp-pr) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/ncm_types + + +proc fsprInitialize*(): Result {.cdecl, importc: "fsprInitialize".} +## / Initialize fsp-pr. + +proc fsprExit*() {.cdecl, importc: "fsprExit".} +## / Exit fsp-pr. + +proc fsprGetServiceSession*(): ptr Service {.cdecl, importc: "fsprGetServiceSession".} +## / Gets the Service object for the actual fsp-pr service session. +proc fsprRegisterProgram*(pid: U64; tid: U64; sid: NcmStorageId; + fsAccessHeader: pointer; fahSize: csize_t; + fsAccessControl: pointer; facSize: csize_t): Result {.cdecl, + importc: "fsprRegisterProgram".} +proc fsprUnregisterProgram*(pid: U64): Result {.cdecl, + importc: "fsprUnregisterProgram".} +proc fsprSetCurrentProcess*(): Result {.cdecl, importc: "fsprSetCurrentProcess".} +proc fsprSetEnabledProgramVerification*(enabled: bool): Result {.cdecl, + importc: "fsprSetEnabledProgramVerification".} diff --git a/src/libnx/wrapper/switch/services/gpio.h b/src/libnx/wrapper/switch/services/gpio.h new file mode 100644 index 0000000..f0a80dd --- /dev/null +++ b/src/libnx/wrapper/switch/services/gpio.h @@ -0,0 +1,77 @@ +/** + * @file gpio.h + * @brief GPIO service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +typedef enum { + GpioPadName_AudioCodec = 1, + GpioPadName_ButtonVolUp = 25, + GpioPadName_ButtonVolDown = 26, + GpioPadName_SdCd = 56, +} GpioPadName; + +typedef struct { + Service s; +} GpioPadSession; + +typedef enum { + GpioDirection_Input = 0, + GpioDirection_Output = 1, +} GpioDirection; + +typedef enum { + GpioValue_Low = 0, + GpioValue_High = 1, +} GpioValue; + +typedef enum { + GpioInterruptMode_LowLevel = 0, + GpioInterruptMode_HighLevel = 1, + GpioInterruptMode_RisingEdge = 2, + GpioInterruptMode_FallingEdge = 3, + GpioInterruptMode_AnyEdge = 4, +} GpioInterruptMode; + +typedef enum { + GpioInterruptStatus_Inactive = 0, + GpioInterruptStatus_Active = 1, +} GpioInterruptStatus; + +/// Initialize gpio. +Result gpioInitialize(void); + +/// Exit gpio. +void gpioExit(void); + +/// Gets the Service object for the actual gpio service session. +Service* gpioGetServiceSession(void); + +Result gpioOpenSession(GpioPadSession *out, GpioPadName name); +Result gpioOpenSession2(GpioPadSession *out, u32 device_code, u32 access_mode); + +Result gpioIsWakeEventActive(bool *out, GpioPadName name); +Result gpioIsWakeEventActive2(bool *out, u32 device_code); + +Result gpioPadSetDirection(GpioPadSession *p, GpioDirection dir); +Result gpioPadGetDirection(GpioPadSession *p, GpioDirection *out); +Result gpioPadSetInterruptMode(GpioPadSession *p, GpioInterruptMode mode); +Result gpioPadGetInterruptMode(GpioPadSession *p, GpioInterruptMode *out); +Result gpioPadSetInterruptEnable(GpioPadSession *p, bool en); +Result gpioPadGetInterruptEnable(GpioPadSession *p, bool *out); +Result gpioPadGetInterruptStatus(GpioPadSession *p, GpioInterruptStatus *out); +Result gpioPadClearInterruptStatus(GpioPadSession *p); +Result gpioPadSetValue(GpioPadSession *p, GpioValue val); +Result gpioPadGetValue(GpioPadSession *p, GpioValue *out); +Result gpioPadBindInterrupt(GpioPadSession *p, Event *out); +Result gpioPadUnbindInterrupt(GpioPadSession *p); +Result gpioPadSetDebounceEnabled(GpioPadSession *p, bool en); +Result gpioPadGetDebounceEnabled(GpioPadSession *p, bool *out); +Result gpioPadSetDebounceTime(GpioPadSession *p, s32 ms); +Result gpioPadGetDebounceTime(GpioPadSession *p, s32 *out); +void gpioPadClose(GpioPadSession *p); diff --git a/src/libnx/wrapper/switch/services/gpio.nim b/src/libnx/wrapper/switch/services/gpio.nim new file mode 100644 index 0000000..2b1e532 --- /dev/null +++ b/src/libnx/wrapper/switch/services/gpio.nim @@ -0,0 +1,84 @@ +## * +## @file gpio.h +## @brief GPIO service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +type + GpioPadName* = enum + GpioPadNameAudioCodec = 1, GpioPadNameButtonVolUp = 25, + GpioPadNameButtonVolDown = 26, GpioPadNameSdCd = 56 + GpioPadSession* {.bycopy.} = object + s*: Service + + GpioDirection* = enum + GpioDirectionInput = 0, GpioDirectionOutput = 1 + GpioValue* = enum + GpioValueLow = 0, GpioValueHigh = 1 + GpioInterruptMode* = enum + GpioInterruptModeLowLevel = 0, GpioInterruptModeHighLevel = 1, + GpioInterruptModeRisingEdge = 2, GpioInterruptModeFallingEdge = 3, + GpioInterruptModeAnyEdge = 4 + GpioInterruptStatus* = enum + GpioInterruptStatusInactive = 0, GpioInterruptStatusActive = 1 + + + + + + +## / Initialize gpio. + +proc gpioInitialize*(): Result {.cdecl, importc: "gpioInitialize".} +## / Exit gpio. + +proc gpioExit*() {.cdecl, importc: "gpioExit".} +## / Gets the Service object for the actual gpio service session. + +proc gpioGetServiceSession*(): ptr Service {.cdecl, importc: "gpioGetServiceSession".} +proc gpioOpenSession*(`out`: ptr GpioPadSession; name: GpioPadName): Result {.cdecl, + importc: "gpioOpenSession".} +proc gpioOpenSession2*(`out`: ptr GpioPadSession; deviceCode: U32; accessMode: U32): Result {. + cdecl, importc: "gpioOpenSession2".} +proc gpioIsWakeEventActive*(`out`: ptr bool; name: GpioPadName): Result {.cdecl, + importc: "gpioIsWakeEventActive".} +proc gpioIsWakeEventActive2*(`out`: ptr bool; deviceCode: U32): Result {.cdecl, + importc: "gpioIsWakeEventActive2".} +proc gpioPadSetDirection*(p: ptr GpioPadSession; dir: GpioDirection): Result {.cdecl, + importc: "gpioPadSetDirection".} +proc gpioPadGetDirection*(p: ptr GpioPadSession; `out`: ptr GpioDirection): Result {. + cdecl, importc: "gpioPadGetDirection".} +proc gpioPadSetInterruptMode*(p: ptr GpioPadSession; mode: GpioInterruptMode): Result {. + cdecl, importc: "gpioPadSetInterruptMode".} +proc gpioPadGetInterruptMode*(p: ptr GpioPadSession; `out`: ptr GpioInterruptMode): Result {. + cdecl, importc: "gpioPadGetInterruptMode".} +proc gpioPadSetInterruptEnable*(p: ptr GpioPadSession; en: bool): Result {.cdecl, + importc: "gpioPadSetInterruptEnable".} +proc gpioPadGetInterruptEnable*(p: ptr GpioPadSession; `out`: ptr bool): Result {.cdecl, + importc: "gpioPadGetInterruptEnable".} +proc gpioPadGetInterruptStatus*(p: ptr GpioPadSession; + `out`: ptr GpioInterruptStatus): Result {.cdecl, + importc: "gpioPadGetInterruptStatus".} +proc gpioPadClearInterruptStatus*(p: ptr GpioPadSession): Result {.cdecl, + importc: "gpioPadClearInterruptStatus".} +proc gpioPadSetValue*(p: ptr GpioPadSession; val: GpioValue): Result {.cdecl, + importc: "gpioPadSetValue".} +proc gpioPadGetValue*(p: ptr GpioPadSession; `out`: ptr GpioValue): Result {.cdecl, + importc: "gpioPadGetValue".} +proc gpioPadBindInterrupt*(p: ptr GpioPadSession; `out`: ptr Event): Result {.cdecl, + importc: "gpioPadBindInterrupt".} +proc gpioPadUnbindInterrupt*(p: ptr GpioPadSession): Result {.cdecl, + importc: "gpioPadUnbindInterrupt".} +proc gpioPadSetDebounceEnabled*(p: ptr GpioPadSession; en: bool): Result {.cdecl, + importc: "gpioPadSetDebounceEnabled".} +proc gpioPadGetDebounceEnabled*(p: ptr GpioPadSession; `out`: ptr bool): Result {.cdecl, + importc: "gpioPadGetDebounceEnabled".} +proc gpioPadSetDebounceTime*(p: ptr GpioPadSession; ms: S32): Result {.cdecl, + importc: "gpioPadSetDebounceTime".} +proc gpioPadGetDebounceTime*(p: ptr GpioPadSession; `out`: ptr S32): Result {.cdecl, + importc: "gpioPadGetDebounceTime".} +proc gpioPadClose*(p: ptr GpioPadSession) {.cdecl, importc: "gpioPadClose".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/grc.h b/src/libnx/wrapper/switch/services/grc.h new file mode 100644 index 0000000..58aa9f0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/grc.h @@ -0,0 +1,197 @@ +/** + * @file grc.h + * @brief GRC Game Recording (grc:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/caps.h" +#include "../kernel/event.h" +#include "../kernel/tmem.h" +#include "../display/native_window.h" + +/// Stream type values for \ref grcdTransfer. +typedef enum { + GrcStream_Video = 0, ///< Video stream with H.264 NAL units. Official sw uses buffer size 0x32000. + GrcStream_Audio = 1, ///< Audio stream with PcmFormat_Int16, 2 channels, and samplerate = 48000Hz. Official sw uses buffer size 0x1000. +} GrcStream; + +/// GameMovieTrimmer +typedef struct { + Service s; ///< IGameMovieTrimmer + TransferMemory tmem; ///< TransferMemory +} GrcGameMovieTrimmer; + +/// IMovieMaker +typedef struct { + Service a; ///< applet IMovieMaker + Service s; ///< grc IMovieMaker + Service video_proxy; ///< IHOSBinderDriver VideoProxy + Event recording_event; ///< Output Event from GetOffscreenLayerRecordingFinishReadyEvent with autoclear=false. + Event audio_event; ///< Output Event from GetOffscreenLayerAudioEncodeReadyEvent with autoclear=false. + TransferMemory tmem; ///< TransferMemory + NWindow win; ///< \ref NWindow + u64 layer_handle; ///< LayerHandle + bool layer_open; ///< Whether OpenOffscreenLayer was used successfully, indicating that CloseOffscreenLayer should be used during \ref grcMovieMakerClose. + bool started_flag; ///< Whether \ref grcMovieMakerStart was used successfully. This is also used by \ref grcMovieMakerAbort. +} GrcMovieMaker; + +/// GameMovieId +typedef struct { + CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId + u8 reserved[0x28]; ///< Unused, always zero. +} GrcGameMovieId; + +/// OffscreenRecordingParameter +typedef struct { + u8 unk_x0[0x10]; ///< Unknown. Default value is 0. + u32 unk_x10; ///< Unknown. Must match value 0x103, which is the default value. + + s32 video_bitrate; ///< VideoBitRate, 0 is invalid. Default value is 8000000. + s32 video_width; ///< VideoWidth, must match 1280 or 1920. Default value is 1280. + s32 video_height; ///< VideoHeight, must match 720 or 1080. Default value is 720. + s32 video_framerate; ///< VideoFrameRate, must match 30 or 60. Default value is 30. + s32 video_keyFrameInterval; ///< VideoKeyFrameInterval, 0 is invalid. Default value is 30. + + s32 audio_bitrate; ///< AudioBitRate. Default value is 128000 ([5.0.0-5.1.0] 1536000). + s32 audio_samplerate; ///< AudioSampleRate, 0 is invalid. Default value is 48000. + s32 audio_channel_count; ///< AudioChannelCount. Must match 2, which is the default value. + s32 audio_sample_format; ///< \ref PcmFormat AudioSampleFormat. Must match PcmFormat_Int16, which is the default value. + + s32 video_imageOrientation; ///< \ref AlbumImageOrientation VideoImageOrientation. Default value is ::AlbumImageOrientation_Unknown0. + + u8 unk_x3c[0x44]; ///< Unknown. Default value is 0. +} GrcOffscreenRecordingParameter; + +/// Default size for \ref grcCreateMovieMaker, this is the size used by official sw. +#define GRC_MOVIEMAKER_WORKMEMORY_SIZE_DEFAULT 0x6000000 + +///@name Trimming +///@{ + +/** + * @brief Creates a \ref GrcGameMovieTrimmer using \ref appletCreateGameMovieTrimmer, uses the cmds from it to trim the specified video, then closes it. + * @note See \ref appletCreateGameMovieTrimmer for the requirements for using this. + * @note This will block until video trimming finishes. + * @param[out] dst_movieid \ref GrcGameMovieId for the output video. + * @param[in] src_movieid \ref GrcGameMovieId for the input video. + * @param[in] tmem_size TransferMemory size. Official sw uses size 0x2000000. + * @param[in] thumbnail Optional, can be NULL. RGBA8 1280x720 thumbnail image data. + * @param[in] start Start timestamp in 0.5s units. + * @param[in] end End timestamp in 0.5s units. + */ +Result grcTrimGameMovie(GrcGameMovieId *dst_movieid, const GrcGameMovieId *src_movieid, size_t tmem_size, const void* thumbnail, s32 start, s32 end); + +///@} + +///@name IMovieMaker +///@{ + +/** + * @brief Creates a \ref GrcOffscreenRecordingParameter with the default values, see \ref GrcOffscreenRecordingParameter for the default values. + * @param[out] param \ref GrcOffscreenRecordingParameter + */ +void grcCreateOffscreenRecordingParameter(GrcOffscreenRecordingParameter *param); + +/** + * @brief Creates a \ref GrcMovieMaker using \ref appletCreateMovieMaker, and does the required initialization. + * @note See \ref appletCreateMovieMaker for the requirements for using this. + * @param[out] m \ref GrcMovieMaker + * @param[in] size TransferMemory WorkMemory size. See \ref GRC_MOVIEMAKER_WORKMEMORY_SIZE_DEFAULT. + */ +Result grcCreateMovieMaker(GrcMovieMaker *m, size_t size); + +/** + * @brief Closes a \ref GrcMovieMaker. + * @note This also uses \ref grcMovieMakerAbort. + * @param m \ref GrcMovieMaker + */ +void grcMovieMakerClose(GrcMovieMaker *m); + +/** + * @brief Gets the \ref NWindow for the specified MovieMaker. + * @param m \ref GrcMovieMaker + */ +static inline NWindow* grcMovieMakerGetNWindow(GrcMovieMaker *m) { + return &m->win; +} + +/** + * @brief Aborts recording with the specified MovieMaker. + * @note This is used automatically by \ref grcMovieMakerClose. + * @note This will throw an error if \ref grcMovieMakerStart was not used previously, with the flag used for this being cleared afterwards on success. + * @param m \ref GrcMovieMaker + */ +Result grcMovieMakerAbort(GrcMovieMaker *m); + +/** + * @brief Starts recording with the specified MovieMaker and \ref GrcOffscreenRecordingParameter. + * @param m \ref GrcMovieMaker + * @param[in] param \ref GrcOffscreenRecordingParameter + */ +Result grcMovieMakerStart(GrcMovieMaker *m, const GrcOffscreenRecordingParameter *param); + +/** + * @brief Finishes recording with the specified MovieMaker. + * @note This automatically uses \ref grcMovieMakerAbort on error. + * @note The recorded video will not be accessible via the Album-applet since it's stored separately from other Album data. + * @param m \ref GrcMovieMaker + * @param width Width for the thumbnail, must be 1280. + * @param height Height for the thumbnail, must be 720. + * @param[in] userdata UserData input buffer for the JPEG thumbnail. Optional, can be NULL. + * @param[in] userdata_size Size of the UserData input buffer. Optional, can be 0. Must be <=0x400. + * @param[in] thumbnail RGBA8 image buffer containing the thumbnail. Optional, can be NULL. + * @param[in] thumbnail_size Size of the thumbnail buffer. Optional, can be 0. + * @param[out] entry Output \ref CapsApplicationAlbumEntry for the recorded video. Optional, can be NULL. Only available on [7.0.0+], if this is not NULL on pre-7.0.0 an error is thrown. + */ +Result grcMovieMakerFinish(GrcMovieMaker *m, s32 width, s32 height, const void* userdata, size_t userdata_size, const void* thumbnail, size_t thumbnail_size, CapsApplicationAlbumEntry *entry); + +/** + * @brief Gets the recording error with the specified MovieMaker. + * @param m \ref GrcMovieMaker + */ +Result grcMovieMakerGetError(GrcMovieMaker *m); + +/** + * @brief Encodes audio sample data with the specified MovieMaker. + * @note This waits on the event and uses the cmd repeatedly until the entire input buffer is handled. + * @note If you don't use this the recorded video will be missing audio. + * @param m \ref GrcMovieMaker + * @param[in] buffer Audio buffer. + * @param[in] size Size of the buffer. + */ +Result grcMovieMakerEncodeAudioSample(GrcMovieMaker *m, const void* buffer, size_t size); + +///@} + +///@name grc:d +///@{ + +/// Initialize grc:d. +Result grcdInitialize(void); + +/// Exit grc:d. +void grcdExit(void); + +/// Gets the Service for grc:d. +Service* grcdGetServiceSession(void); + +/// Begins streaming. This must not be called more than once, even from a different service session: otherwise the sysmodule will assert. +Result grcdBegin(void); + +/** + * @brief Retrieves stream data from the continuous recorder in use (from the video recording of the currently running application). + * @note This will block until data is available. This will hang if there is no application running which has video capture enabled. + * @param[in] stream \ref GrcStream + * @param[out] buffer Output buffer. + * @param[in] size Max size of the output buffer. + * @param[out] num_frames num_frames + * @param[out] data_size Actual output data size. + * @param[out] start_timestamp Start timestamp. + */ +Result grcdTransfer(GrcStream stream, void* buffer, size_t size, u32 *num_frames, u32 *data_size, u64 *start_timestamp); + +///@} + diff --git a/src/libnx/wrapper/switch/services/grc.nim b/src/libnx/wrapper/switch/services/grc.nim new file mode 100644 index 0000000..b557c72 --- /dev/null +++ b/src/libnx/wrapper/switch/services/grc.nim @@ -0,0 +1,212 @@ +## * +## @file grc.h +## @brief GRC Game Recording (grc:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/caps, ../kernel/event, ../kernel/tmem, + ../display/native_window + +## / Stream type values for \ref grcdTransfer. + +type + GrcStream* = enum + GrcStreamVideo = 0, ## /< Video stream with H.264 NAL units. Official sw uses buffer size 0x32000. + GrcStreamAudio = 1 ## /< Audio stream with PcmFormat_Int16, 2 channels, and samplerate = 48000Hz. Official sw uses buffer size 0x1000. + + +## / GameMovieTrimmer + +type + GrcGameMovieTrimmer* {.bycopy.} = object + s*: Service ## /< IGameMovieTrimmer + tmem*: TransferMemory ## /< TransferMemory + + +## / IMovieMaker + +type + GrcMovieMaker* {.bycopy.} = object + a*: Service ## /< applet IMovieMaker + s*: Service ## /< grc IMovieMaker + videoProxy*: Service ## /< IHOSBinderDriver VideoProxy + recordingEvent*: Event ## /< Output Event from GetOffscreenLayerRecordingFinishReadyEvent with autoclear=false. + audioEvent*: Event ## /< Output Event from GetOffscreenLayerAudioEncodeReadyEvent with autoclear=false. + tmem*: TransferMemory ## /< TransferMemory + win*: NWindow ## /< \ref NWindow + layerHandle*: U64 ## /< LayerHandle + layerOpen*: bool ## /< Whether OpenOffscreenLayer was used successfully, indicating that CloseOffscreenLayer should be used during \ref grcMovieMakerClose. + startedFlag*: bool ## /< Whether \ref grcMovieMakerStart was used successfully. This is also used by \ref grcMovieMakerAbort. + + +## / GameMovieId + +type + GrcGameMovieId* {.bycopy.} = object + fileId*: CapsAlbumFileId ## /< \ref CapsAlbumFileId + reserved*: array[0x28, U8] ## /< Unused, always zero. + + +## / OffscreenRecordingParameter + +type + GrcOffscreenRecordingParameter* {.bycopy.} = object + unkX0*: array[0x10, U8] ## /< Unknown. Default value is 0. + unkX10*: U32 ## /< Unknown. Must match value 0x103, which is the default value. + videoBitrate*: S32 ## /< VideoBitRate, 0 is invalid. Default value is 8000000. + videoWidth*: S32 ## /< VideoWidth, must match 1280 or 1920. Default value is 1280. + videoHeight*: S32 ## /< VideoHeight, must match 720 or 1080. Default value is 720. + videoFramerate*: S32 ## /< VideoFrameRate, must match 30 or 60. Default value is 30. + videoKeyFrameInterval*: S32 ## /< VideoKeyFrameInterval, 0 is invalid. Default value is 30. + audioBitrate*: S32 ## /< AudioBitRate. Default value is 128000 ([5.0.0-5.1.0] 1536000). + audioSamplerate*: S32 ## /< AudioSampleRate, 0 is invalid. Default value is 48000. + audioChannelCount*: S32 ## /< AudioChannelCount. Must match 2, which is the default value. + audioSampleFormat*: S32 ## /< \ref PcmFormat AudioSampleFormat. Must match PcmFormat_Int16, which is the default value. + videoImageOrientation*: S32 ## /< \ref AlbumImageOrientation VideoImageOrientation. Default value is ::AlbumImageOrientation_Unknown0. + unkX3c*: array[0x44, U8] ## /< Unknown. Default value is 0. + + +## / Default size for \ref grcCreateMovieMaker, this is the size used by official sw. + +const + GRC_MOVIEMAKER_WORKMEMORY_SIZE_DEFAULT* = 0x6000000 +proc grcTrimGameMovie*(dstMovieid: ptr GrcGameMovieId; + srcMovieid: ptr GrcGameMovieId; tmemSize: csize_t; + thumbnail: pointer; start: S32; `end`: S32): Result {.cdecl, + importc: "grcTrimGameMovie".} +## /@name Trimming +## /@{ +## * +## @brief Creates a \ref GrcGameMovieTrimmer using \ref appletCreateGameMovieTrimmer, uses the cmds from it to trim the specified video, then closes it. +## @note See \ref appletCreateGameMovieTrimmer for the requirements for using this. +## @note This will block until video trimming finishes. +## @param[out] dst_movieid \ref GrcGameMovieId for the output video. +## @param[in] src_movieid \ref GrcGameMovieId for the input video. +## @param[in] tmem_size TransferMemory size. Official sw uses size 0x2000000. +## @param[in] thumbnail Optional, can be NULL. RGBA8 1280x720 thumbnail image data. +## @param[in] start Start timestamp in 0.5s units. +## @param[in] end End timestamp in 0.5s units. +## + +proc grcCreateOffscreenRecordingParameter*( + param: ptr GrcOffscreenRecordingParameter) {.cdecl, + importc: "grcCreateOffscreenRecordingParameter".} +## /@} +## /@name IMovieMaker +## /@{ +## * +## @brief Creates a \ref GrcOffscreenRecordingParameter with the default values, see \ref GrcOffscreenRecordingParameter for the default values. +## @param[out] param \ref GrcOffscreenRecordingParameter +## + +proc grcCreateMovieMaker*(m: ptr GrcMovieMaker; size: csize_t): Result {.cdecl, + importc: "grcCreateMovieMaker".} +## * +## @brief Creates a \ref GrcMovieMaker using \ref appletCreateMovieMaker, and does the required initialization. +## @note See \ref appletCreateMovieMaker for the requirements for using this. +## @param[out] m \ref GrcMovieMaker +## @param[in] size TransferMemory WorkMemory size. See \ref GRC_MOVIEMAKER_WORKMEMORY_SIZE_DEFAULT. +## + +proc grcMovieMakerClose*(m: ptr GrcMovieMaker) {.cdecl, importc: "grcMovieMakerClose".} +## * +## @brief Closes a \ref GrcMovieMaker. +## @note This also uses \ref grcMovieMakerAbort. +## @param m \ref GrcMovieMaker +## + +proc grcMovieMakerGetNWindow*(m: ptr GrcMovieMaker): ptr NWindow {.inline, cdecl.} = + ## * + ## @brief Gets the \ref NWindow for the specified MovieMaker. + ## @param m \ref GrcMovieMaker + ## + return addr(m.win) + +proc grcMovieMakerAbort*(m: ptr GrcMovieMaker): Result {.cdecl, + importc: "grcMovieMakerAbort".} +## * +## @brief Aborts recording with the specified MovieMaker. +## @note This is used automatically by \ref grcMovieMakerClose. +## @note This will throw an error if \ref grcMovieMakerStart was not used previously, with the flag used for this being cleared afterwards on success. +## @param m \ref GrcMovieMaker +## + +proc grcMovieMakerStart*(m: ptr GrcMovieMaker; + param: ptr GrcOffscreenRecordingParameter): Result {.cdecl, + importc: "grcMovieMakerStart".} +## * +## @brief Starts recording with the specified MovieMaker and \ref GrcOffscreenRecordingParameter. +## @param m \ref GrcMovieMaker +## @param[in] param \ref GrcOffscreenRecordingParameter +## + +proc grcMovieMakerFinish*(m: ptr GrcMovieMaker; width: S32; height: S32; + userdata: pointer; userdataSize: csize_t; + thumbnail: pointer; thumbnailSize: csize_t; + entry: ptr CapsApplicationAlbumEntry): Result {.cdecl, + importc: "grcMovieMakerFinish".} +## * +## @brief Finishes recording with the specified MovieMaker. +## @note This automatically uses \ref grcMovieMakerAbort on error. +## @note The recorded video will not be accessible via the Album-applet since it's stored separately from other Album data. +## @param m \ref GrcMovieMaker +## @param width Width for the thumbnail, must be 1280. +## @param height Height for the thumbnail, must be 720. +## @param[in] userdata UserData input buffer for the JPEG thumbnail. Optional, can be NULL. +## @param[in] userdata_size Size of the UserData input buffer. Optional, can be 0. Must be <=0x400. +## @param[in] thumbnail RGBA8 image buffer containing the thumbnail. Optional, can be NULL. +## @param[in] thumbnail_size Size of the thumbnail buffer. Optional, can be 0. +## @param[out] entry Output \ref CapsApplicationAlbumEntry for the recorded video. Optional, can be NULL. Only available on [7.0.0+], if this is not NULL on pre-7.0.0 an error is thrown. +## + +proc grcMovieMakerGetError*(m: ptr GrcMovieMaker): Result {.cdecl, + importc: "grcMovieMakerGetError".} +## * +## @brief Gets the recording error with the specified MovieMaker. +## @param m \ref GrcMovieMaker +## + +proc grcMovieMakerEncodeAudioSample*(m: ptr GrcMovieMaker; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "grcMovieMakerEncodeAudioSample".} +## * +## @brief Encodes audio sample data with the specified MovieMaker. +## @note This waits on the event and uses the cmd repeatedly until the entire input buffer is handled. +## @note If you don't use this the recorded video will be missing audio. +## @param m \ref GrcMovieMaker +## @param[in] buffer Audio buffer. +## @param[in] size Size of the buffer. +## + +proc grcdInitialize*(): Result {.cdecl, importc: "grcdInitialize".} +## /@} +## /@name grc:d +## /@{ +## / Initialize grc:d. + +proc grcdExit*() {.cdecl, importc: "grcdExit".} +## / Exit grc:d. + +proc grcdGetServiceSession*(): ptr Service {.cdecl, importc: "grcdGetServiceSession".} +## / Gets the Service for grc:d. + +proc grcdBegin*(): Result {.cdecl, importc: "grcdBegin".} +## / Begins streaming. This must not be called more than once, even from a different service session: otherwise the sysmodule will assert. + +proc grcdTransfer*(stream: GrcStream; buffer: pointer; size: csize_t; + numFrames: ptr U32; dataSize: ptr U32; startTimestamp: ptr U64): Result {. + cdecl, importc: "grcdTransfer".} +## * +## @brief Retrieves stream data from the continuous recorder in use (from the video recording of the currently running application). +## @note This will block until data is available. This will hang if there is no application running which has video capture enabled. +## @param[in] stream \ref GrcStream +## @param[out] buffer Output buffer. +## @param[in] size Max size of the output buffer. +## @param[out] num_frames num_frames +## @param[out] data_size Actual output data size. +## @param[out] start_timestamp Start timestamp. +## + +## /@} diff --git a/src/libnx/wrapper/switch/services/hid.h b/src/libnx/wrapper/switch/services/hid.h new file mode 100644 index 0000000..bc4a713 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hid.h @@ -0,0 +1,2207 @@ +/** + * @file hid.h + * @brief Human input device (hid) service IPC wrapper. + * @author shinyquagsire23 + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/btdrv_types.h" +#include "../sf/service.h" + +// Begin enums and output structs + +/// HidDebugPadButton +typedef enum { + HidDebugPadButton_A = BIT(0), ///< A button + HidDebugPadButton_B = BIT(1), ///< B button + HidDebugPadButton_X = BIT(2), ///< X button + HidDebugPadButton_Y = BIT(3), ///< Y button + HidDebugPadButton_L = BIT(4), ///< L button + HidDebugPadButton_R = BIT(5), ///< R button + HidDebugPadButton_ZL = BIT(6), ///< ZL button + HidDebugPadButton_ZR = BIT(7), ///< ZR button + HidDebugPadButton_Start = BIT(8), ///< Start button + HidDebugPadButton_Select = BIT(9), ///< Select button + HidDebugPadButton_Left = BIT(10), ///< D-Pad Left button + HidDebugPadButton_Up = BIT(11), ///< D-Pad Up button + HidDebugPadButton_Right = BIT(12), ///< D-Pad Right button + HidDebugPadButton_Down = BIT(13), ///< D-Pad Down button +} HidDebugPadButton; + +/// HidTouchScreenModeForNx +typedef enum { + HidTouchScreenModeForNx_UseSystemSetting = 0, ///< UseSystemSetting + HidTouchScreenModeForNx_Finger = 1, ///< Finger + HidTouchScreenModeForNx_Heat2 = 2, ///< Heat2 +} HidTouchScreenModeForNx; + +/// HidMouseButton +typedef enum { + HidMouseButton_Left = BIT(0), + HidMouseButton_Right = BIT(1), + HidMouseButton_Middle = BIT(2), + HidMouseButton_Forward = BIT(3), + HidMouseButton_Back = BIT(4), +} HidMouseButton; + +/// HidKeyboardKey +typedef enum { + HidKeyboardKey_A = 4, + HidKeyboardKey_B = 5, + HidKeyboardKey_C = 6, + HidKeyboardKey_D = 7, + HidKeyboardKey_E = 8, + HidKeyboardKey_F = 9, + HidKeyboardKey_G = 10, + HidKeyboardKey_H = 11, + HidKeyboardKey_I = 12, + HidKeyboardKey_J = 13, + HidKeyboardKey_K = 14, + HidKeyboardKey_L = 15, + HidKeyboardKey_M = 16, + HidKeyboardKey_N = 17, + HidKeyboardKey_O = 18, + HidKeyboardKey_P = 19, + HidKeyboardKey_Q = 20, + HidKeyboardKey_R = 21, + HidKeyboardKey_S = 22, + HidKeyboardKey_T = 23, + HidKeyboardKey_U = 24, + HidKeyboardKey_V = 25, + HidKeyboardKey_W = 26, + HidKeyboardKey_X = 27, + HidKeyboardKey_Y = 28, + HidKeyboardKey_Z = 29, + HidKeyboardKey_D1 = 30, + HidKeyboardKey_D2 = 31, + HidKeyboardKey_D3 = 32, + HidKeyboardKey_D4 = 33, + HidKeyboardKey_D5 = 34, + HidKeyboardKey_D6 = 35, + HidKeyboardKey_D7 = 36, + HidKeyboardKey_D8 = 37, + HidKeyboardKey_D9 = 38, + HidKeyboardKey_D0 = 39, + HidKeyboardKey_Return = 40, + HidKeyboardKey_Escape = 41, + HidKeyboardKey_Backspace = 42, + HidKeyboardKey_Tab = 43, + HidKeyboardKey_Space = 44, + HidKeyboardKey_Minus = 45, + HidKeyboardKey_Plus = 46, + HidKeyboardKey_OpenBracket = 47, + HidKeyboardKey_CloseBracket = 48, + HidKeyboardKey_Pipe = 49, + HidKeyboardKey_Tilde = 50, + HidKeyboardKey_Semicolon = 51, + HidKeyboardKey_Quote = 52, + HidKeyboardKey_Backquote = 53, + HidKeyboardKey_Comma = 54, + HidKeyboardKey_Period = 55, + HidKeyboardKey_Slash = 56, + HidKeyboardKey_CapsLock = 57, + HidKeyboardKey_F1 = 58, + HidKeyboardKey_F2 = 59, + HidKeyboardKey_F3 = 60, + HidKeyboardKey_F4 = 61, + HidKeyboardKey_F5 = 62, + HidKeyboardKey_F6 = 63, + HidKeyboardKey_F7 = 64, + HidKeyboardKey_F8 = 65, + HidKeyboardKey_F9 = 66, + HidKeyboardKey_F10 = 67, + HidKeyboardKey_F11 = 68, + HidKeyboardKey_F12 = 69, + HidKeyboardKey_PrintScreen = 70, + HidKeyboardKey_ScrollLock = 71, + HidKeyboardKey_Pause = 72, + HidKeyboardKey_Insert = 73, + HidKeyboardKey_Home = 74, + HidKeyboardKey_PageUp = 75, + HidKeyboardKey_Delete = 76, + HidKeyboardKey_End = 77, + HidKeyboardKey_PageDown = 78, + HidKeyboardKey_RightArrow = 79, + HidKeyboardKey_LeftArrow = 80, + HidKeyboardKey_DownArrow = 81, + HidKeyboardKey_UpArrow = 82, + HidKeyboardKey_NumLock = 83, + HidKeyboardKey_NumPadDivide = 84, + HidKeyboardKey_NumPadMultiply = 85, + HidKeyboardKey_NumPadSubtract = 86, + HidKeyboardKey_NumPadAdd = 87, + HidKeyboardKey_NumPadEnter = 88, + HidKeyboardKey_NumPad1 = 89, + HidKeyboardKey_NumPad2 = 90, + HidKeyboardKey_NumPad3 = 91, + HidKeyboardKey_NumPad4 = 92, + HidKeyboardKey_NumPad5 = 93, + HidKeyboardKey_NumPad6 = 94, + HidKeyboardKey_NumPad7 = 95, + HidKeyboardKey_NumPad8 = 96, + HidKeyboardKey_NumPad9 = 97, + HidKeyboardKey_NumPad0 = 98, + HidKeyboardKey_NumPadDot = 99, + HidKeyboardKey_Backslash = 100, + HidKeyboardKey_Application = 101, + HidKeyboardKey_Power = 102, + HidKeyboardKey_NumPadEquals = 103, + HidKeyboardKey_F13 = 104, + HidKeyboardKey_F14 = 105, + HidKeyboardKey_F15 = 106, + HidKeyboardKey_F16 = 107, + HidKeyboardKey_F17 = 108, + HidKeyboardKey_F18 = 109, + HidKeyboardKey_F19 = 110, + HidKeyboardKey_F20 = 111, + HidKeyboardKey_F21 = 112, + HidKeyboardKey_F22 = 113, + HidKeyboardKey_F23 = 114, + HidKeyboardKey_F24 = 115, + HidKeyboardKey_NumPadComma = 133, + HidKeyboardKey_Ro = 135, + HidKeyboardKey_KatakanaHiragana = 136, + HidKeyboardKey_Yen = 137, + HidKeyboardKey_Henkan = 138, + HidKeyboardKey_Muhenkan = 139, + HidKeyboardKey_NumPadCommaPc98 = 140, + HidKeyboardKey_HangulEnglish = 144, + HidKeyboardKey_Hanja = 145, + HidKeyboardKey_Katakana = 146, + HidKeyboardKey_Hiragana = 147, + HidKeyboardKey_ZenkakuHankaku = 148, + HidKeyboardKey_LeftControl = 224, + HidKeyboardKey_LeftShift = 225, + HidKeyboardKey_LeftAlt = 226, + HidKeyboardKey_LeftGui = 227, + HidKeyboardKey_RightControl = 228, + HidKeyboardKey_RightShift = 229, + HidKeyboardKey_RightAlt = 230, + HidKeyboardKey_RightGui = 231, +} HidKeyboardKey; + +/// HidKeyboardModifier +typedef enum { + HidKeyboardModifier_Control = BIT(0), + HidKeyboardModifier_Shift = BIT(1), + HidKeyboardModifier_LeftAlt = BIT(2), + HidKeyboardModifier_RightAlt = BIT(3), + HidKeyboardModifier_Gui = BIT(4), + HidKeyboardModifier_CapsLock = BIT(8), + HidKeyboardModifier_ScrollLock = BIT(9), + HidKeyboardModifier_NumLock = BIT(10), + HidKeyboardModifier_Katakana = BIT(11), + HidKeyboardModifier_Hiragana = BIT(12), +} HidKeyboardModifier; + +/// KeyboardLockKeyEvent +typedef enum { + HidKeyboardLockKeyEvent_NumLockOn = BIT(0), ///< NumLockOn + HidKeyboardLockKeyEvent_NumLockOff = BIT(1), ///< NumLockOff + HidKeyboardLockKeyEvent_NumLockToggle = BIT(2), ///< NumLockToggle + HidKeyboardLockKeyEvent_CapsLockOn = BIT(3), ///< CapsLockOn + HidKeyboardLockKeyEvent_CapsLockOff = BIT(4), ///< CapsLockOff + HidKeyboardLockKeyEvent_CapsLockToggle = BIT(5), ///< CapsLockToggle + HidKeyboardLockKeyEvent_ScrollLockOn = BIT(6), ///< ScrollLockOn + HidKeyboardLockKeyEvent_ScrollLockOff = BIT(7), ///< ScrollLockOff + HidKeyboardLockKeyEvent_ScrollLockToggle = BIT(8), ///< ScrollLockToggle +} HidKeyboardLockKeyEvent; + +/// HID controller IDs +typedef enum { + HidNpadIdType_No1 = 0, ///< Player 1 controller + HidNpadIdType_No2 = 1, ///< Player 2 controller + HidNpadIdType_No3 = 2, ///< Player 3 controller + HidNpadIdType_No4 = 3, ///< Player 4 controller + HidNpadIdType_No5 = 4, ///< Player 5 controller + HidNpadIdType_No6 = 5, ///< Player 6 controller + HidNpadIdType_No7 = 6, ///< Player 7 controller + HidNpadIdType_No8 = 7, ///< Player 8 controller + HidNpadIdType_Other = 0x10, ///< Other controller + HidNpadIdType_Handheld = 0x20, ///< Handheld mode controls +} HidNpadIdType; + +/// HID controller styles +typedef enum { + HidNpadStyleTag_NpadFullKey = BIT(0), ///< Pro Controller + HidNpadStyleTag_NpadHandheld = BIT(1), ///< Joy-Con controller in handheld mode + HidNpadStyleTag_NpadJoyDual = BIT(2), ///< Joy-Con controller in dual mode + HidNpadStyleTag_NpadJoyLeft = BIT(3), ///< Joy-Con left controller in single mode + HidNpadStyleTag_NpadJoyRight = BIT(4), ///< Joy-Con right controller in single mode + HidNpadStyleTag_NpadGc = BIT(5), ///< GameCube controller + HidNpadStyleTag_NpadPalma = BIT(6), ///< Poké Ball Plus controller + HidNpadStyleTag_NpadLark = BIT(7), ///< NES/Famicom controller + HidNpadStyleTag_NpadHandheldLark = BIT(8), ///< NES/Famicom controller in handheld mode + HidNpadStyleTag_NpadLucia = BIT(9), ///< SNES controller + HidNpadStyleTag_NpadLagon = BIT(10), ///< N64 controller + HidNpadStyleTag_NpadLager = BIT(11), ///< Sega Genesis controller + HidNpadStyleTag_NpadSystemExt = BIT(29), ///< Generic external controller + HidNpadStyleTag_NpadSystem = BIT(30), ///< Generic controller + + HidNpadStyleSet_NpadFullCtrl = HidNpadStyleTag_NpadFullKey | HidNpadStyleTag_NpadHandheld | HidNpadStyleTag_NpadJoyDual, ///< Style set comprising Npad styles containing the full set of controls {FullKey, Handheld, JoyDual} + HidNpadStyleSet_NpadStandard = HidNpadStyleSet_NpadFullCtrl | HidNpadStyleTag_NpadJoyLeft | HidNpadStyleTag_NpadJoyRight, ///< Style set comprising all standard Npad styles {FullKey, Handheld, JoyDual, JoyLeft, JoyRight} +} HidNpadStyleTag; + +/// HidColorAttribute +typedef enum { + HidColorAttribute_Ok = 0, ///< Ok + HidColorAttribute_ReadError = 1, ///< ReadError + HidColorAttribute_NoController = 2, ///< NoController +} HidColorAttribute; + +/// HidNpadButton +typedef enum { + HidNpadButton_A = BITL(0), ///< A button / Right face button + HidNpadButton_B = BITL(1), ///< B button / Down face button + HidNpadButton_X = BITL(2), ///< X button / Up face button + HidNpadButton_Y = BITL(3), ///< Y button / Left face button + HidNpadButton_StickL = BITL(4), ///< Left Stick button + HidNpadButton_StickR = BITL(5), ///< Right Stick button + HidNpadButton_L = BITL(6), ///< L button + HidNpadButton_R = BITL(7), ///< R button + HidNpadButton_ZL = BITL(8), ///< ZL button + HidNpadButton_ZR = BITL(9), ///< ZR button + HidNpadButton_Plus = BITL(10), ///< Plus button + HidNpadButton_Minus = BITL(11), ///< Minus button + HidNpadButton_Left = BITL(12), ///< D-Pad Left button + HidNpadButton_Up = BITL(13), ///< D-Pad Up button + HidNpadButton_Right = BITL(14), ///< D-Pad Right button + HidNpadButton_Down = BITL(15), ///< D-Pad Down button + HidNpadButton_StickLLeft = BITL(16), ///< Left Stick pseudo-button when moved Left + HidNpadButton_StickLUp = BITL(17), ///< Left Stick pseudo-button when moved Up + HidNpadButton_StickLRight = BITL(18), ///< Left Stick pseudo-button when moved Right + HidNpadButton_StickLDown = BITL(19), ///< Left Stick pseudo-button when moved Down + HidNpadButton_StickRLeft = BITL(20), ///< Right Stick pseudo-button when moved Left + HidNpadButton_StickRUp = BITL(21), ///< Right Stick pseudo-button when moved Up + HidNpadButton_StickRRight = BITL(22), ///< Right Stick pseudo-button when moved Right + HidNpadButton_StickRDown = BITL(23), ///< Right Stick pseudo-button when moved Left + HidNpadButton_LeftSL = BITL(24), ///< SL button on Left Joy-Con + HidNpadButton_LeftSR = BITL(25), ///< SR button on Left Joy-Con + HidNpadButton_RightSL = BITL(26), ///< SL button on Right Joy-Con + HidNpadButton_RightSR = BITL(27), ///< SR button on Right Joy-Con + HidNpadButton_Palma = BITL(28), ///< Top button on Poké Ball Plus (Palma) controller + HidNpadButton_Verification = BITL(29), ///< Verification + HidNpadButton_HandheldLeftB = BITL(30), ///< B button on Left NES/HVC controller in Handheld mode + HidNpadButton_LagonCLeft = BITL(31), ///< Left C button in N64 controller + HidNpadButton_LagonCUp = BITL(32), ///< Up C button in N64 controller + HidNpadButton_LagonCRight = BITL(33), ///< Right C button in N64 controller + HidNpadButton_LagonCDown = BITL(34), ///< Down C button in N64 controller + + HidNpadButton_AnyLeft = HidNpadButton_Left | HidNpadButton_StickLLeft | HidNpadButton_StickRLeft, ///< Bitmask containing all buttons that are considered Left (D-Pad, Sticks) + HidNpadButton_AnyUp = HidNpadButton_Up | HidNpadButton_StickLUp | HidNpadButton_StickRUp, ///< Bitmask containing all buttons that are considered Up (D-Pad, Sticks) + HidNpadButton_AnyRight = HidNpadButton_Right | HidNpadButton_StickLRight | HidNpadButton_StickRRight, ///< Bitmask containing all buttons that are considered Right (D-Pad, Sticks) + HidNpadButton_AnyDown = HidNpadButton_Down | HidNpadButton_StickLDown | HidNpadButton_StickRDown, ///< Bitmask containing all buttons that are considered Down (D-Pad, Sticks) + HidNpadButton_AnySL = HidNpadButton_LeftSL | HidNpadButton_RightSL, ///< Bitmask containing SL buttons on both Joy-Cons (Left/Right) + HidNpadButton_AnySR = HidNpadButton_LeftSR | HidNpadButton_RightSR, ///< Bitmask containing SR buttons on both Joy-Cons (Left/Right) +} HidNpadButton; + +/// HidDebugPadAttribute +typedef enum { + HidDebugPadAttribute_IsConnected = BIT(0), ///< IsConnected +} HidDebugPadAttribute; + +/// HidTouchAttribute +typedef enum { + HidTouchAttribute_Start = BIT(0), ///< Start + HidTouchAttribute_End = BIT(1), ///< End +} HidTouchAttribute; + +/// HidMouseAttribute +typedef enum { + HidMouseAttribute_Transferable = BIT(0), ///< Transferable + HidMouseAttribute_IsConnected = BIT(1), ///< IsConnected +} HidMouseAttribute; + +/// HidNpadAttribute +typedef enum { + HidNpadAttribute_IsConnected = BIT(0), ///< IsConnected + HidNpadAttribute_IsWired = BIT(1), ///< IsWired + HidNpadAttribute_IsLeftConnected = BIT(2), ///< IsLeftConnected + HidNpadAttribute_IsLeftWired = BIT(3), ///< IsLeftWired + HidNpadAttribute_IsRightConnected = BIT(4), ///< IsRightConnected + HidNpadAttribute_IsRightWired = BIT(5), ///< IsRightWired +} HidNpadAttribute; + +/// HidSixAxisSensorAttribute +typedef enum { + HidSixAxisSensorAttribute_IsConnected = BIT(0), ///< IsConnected + HidSixAxisSensorAttribute_IsInterpolated = BIT(1), ///< IsInterpolated +} HidSixAxisSensorAttribute; + +/// HidGestureAttribute +typedef enum { + HidGestureAttribute_IsNewTouch = BIT(4), ///< IsNewTouch + HidGestureAttribute_IsDoubleTap = BIT(8), ///< IsDoubleTap +} HidGestureAttribute; + +/// HidGestureDirection +typedef enum { + HidGestureDirection_None = 0, ///< None + HidGestureDirection_Left = 1, ///< Left + HidGestureDirection_Up = 2, ///< Up + HidGestureDirection_Right = 3, ///< Right + HidGestureDirection_Down = 4, ///< Down +} HidGestureDirection; + +/// HidGestureType +typedef enum { + HidGestureType_Idle = 0, ///< Idle + HidGestureType_Complete = 1, ///< Complete + HidGestureType_Cancel = 2, ///< Cancel + HidGestureType_Touch = 3, ///< Touch + HidGestureType_Press = 4, ///< Press + HidGestureType_Tap = 5, ///< Tap + HidGestureType_Pan = 6, ///< Pan + HidGestureType_Swipe = 7, ///< Swipe + HidGestureType_Pinch = 8, ///< Pinch + HidGestureType_Rotate = 9, ///< Rotate +} HidGestureType; + +/// GyroscopeZeroDriftMode +typedef enum { + HidGyroscopeZeroDriftMode_Loose = 0, ///< Loose + HidGyroscopeZeroDriftMode_Standard = 1, ///< Standard + HidGyroscopeZeroDriftMode_Tight = 2, ///< Tight +} HidGyroscopeZeroDriftMode; + +/// NpadJoyHoldType +typedef enum { + HidNpadJoyHoldType_Vertical = 0, ///< Default / Joy-Con held vertically. + HidNpadJoyHoldType_Horizontal = 1, ///< Joy-Con held horizontally. +} HidNpadJoyHoldType; + +/// NpadJoyDeviceType +typedef enum { + HidNpadJoyDeviceType_Left = 0, ///< Left + HidNpadJoyDeviceType_Right = 1, ///< Right +} HidNpadJoyDeviceType; + +/// This controls how many Joy-Cons must be attached for handheld-mode to be activated. +typedef enum { + HidNpadHandheldActivationMode_Dual = 0, ///< Dual (2 Joy-Cons) + HidNpadHandheldActivationMode_Single = 1, ///< Single (1 Joy-Con) + HidNpadHandheldActivationMode_None = 2, ///< None (0 Joy-Cons) +} HidNpadHandheldActivationMode; + +/// NpadJoyAssignmentMode +typedef enum { + HidNpadJoyAssignmentMode_Dual = 0, ///< Dual (Set by \ref hidSetNpadJoyAssignmentModeDual) + HidNpadJoyAssignmentMode_Single = 1, ///< Single (Set by hidSetNpadJoyAssignmentModeSingle*()) +} HidNpadJoyAssignmentMode; + +/// NpadCommunicationMode +typedef enum { + HidNpadCommunicationMode_5ms = 0, ///< 5ms + HidNpadCommunicationMode_10ms = 1, ///< 10ms + HidNpadCommunicationMode_15ms = 2, ///< 15ms + HidNpadCommunicationMode_Default = 3, ///< Default +} HidNpadCommunicationMode; + +/// DeviceType (system) +typedef enum { + HidDeviceTypeBits_FullKey = BIT(0), ///< Pro Controller and Gc controller. + HidDeviceTypeBits_DebugPad = BIT(1), ///< DebugPad + HidDeviceTypeBits_HandheldLeft = BIT(2), ///< Joy-Con/Famicom/NES left controller in handheld mode. + HidDeviceTypeBits_HandheldRight = BIT(3), ///< Joy-Con/Famicom/NES right controller in handheld mode. + HidDeviceTypeBits_JoyLeft = BIT(4), ///< Joy-Con left controller. + HidDeviceTypeBits_JoyRight = BIT(5), ///< Joy-Con right controller. + HidDeviceTypeBits_Palma = BIT(6), ///< Poké Ball Plus controller. + HidDeviceTypeBits_LarkHvcLeft = BIT(7), ///< Famicom left controller. + HidDeviceTypeBits_LarkHvcRight = BIT(8), ///< Famicom right controller (with microphone). + HidDeviceTypeBits_LarkNesLeft = BIT(9), ///< NES left controller. + HidDeviceTypeBits_LarkNesRight = BIT(10), ///< NES right controller. + HidDeviceTypeBits_HandheldLarkHvcLeft = BIT(11), ///< Famicom left controller in handheld mode. + HidDeviceTypeBits_HandheldLarkHvcRight = BIT(12), ///< Famicom right controller (with microphone) in handheld mode. + HidDeviceTypeBits_HandheldLarkNesLeft = BIT(13), ///< NES left controller in handheld mode. + HidDeviceTypeBits_HandheldLarkNesRight = BIT(14), ///< NES right controller in handheld mode. + HidDeviceTypeBits_Lucia = BIT(15), ///< SNES controller + HidDeviceTypeBits_Lagon = BIT(16), ///< N64 controller + HidDeviceTypeBits_Lager = BIT(17), ///< Sega Genesis controller + HidDeviceTypeBits_System = BIT(31), ///< Generic controller. +} HidDeviceTypeBits; + +/// Internal DeviceType for [9.0.0+]. Converted to/from the pre-9.0.0 version of this by the hiddbg funcs. +typedef enum { + HidDeviceType_JoyRight1 = 1, ///< ::HidDeviceTypeBits_JoyRight + HidDeviceType_JoyLeft2 = 2, ///< ::HidDeviceTypeBits_JoyLeft + HidDeviceType_FullKey3 = 3, ///< ::HidDeviceTypeBits_FullKey + HidDeviceType_JoyLeft4 = 4, ///< ::HidDeviceTypeBits_JoyLeft + HidDeviceType_JoyRight5 = 5, ///< ::HidDeviceTypeBits_JoyRight + HidDeviceType_FullKey6 = 6, ///< ::HidDeviceTypeBits_FullKey + HidDeviceType_LarkHvcLeft = 7, ///< ::HidDeviceTypeBits_LarkHvcLeft, ::HidDeviceTypeBits_HandheldLarkHvcLeft + HidDeviceType_LarkHvcRight = 8, ///< ::HidDeviceTypeBits_LarkHvcRight, ::HidDeviceTypeBits_HandheldLarkHvcRight + HidDeviceType_LarkNesLeft = 9, ///< ::HidDeviceTypeBits_LarkNesLeft, ::HidDeviceTypeBits_HandheldLarkNesLeft + HidDeviceType_LarkNesRight = 10, ///< ::HidDeviceTypeBits_LarkNesRight, ::HidDeviceTypeBits_HandheldLarkNesRight + HidDeviceType_Lucia = 11, ///< ::HidDeviceTypeBits_Lucia + HidDeviceType_Palma = 12, ///< [9.0.0+] ::HidDeviceTypeBits_Palma + HidDeviceType_FullKey13 = 13, ///< ::HidDeviceTypeBits_FullKey + HidDeviceType_FullKey15 = 15, ///< ::HidDeviceTypeBits_FullKey + HidDeviceType_DebugPad = 17, ///< ::HidDeviceTypeBits_DebugPad + HidDeviceType_System19 = 19, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadFullKey. + HidDeviceType_System20 = 20, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. + HidDeviceType_System21 = 21, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. + HidDeviceType_Lagon = 22, ///< ::HidDeviceTypeBits_Lagon + HidDeviceType_Lager = 28, ///< ::HidDeviceTypeBits_Lager +} HidDeviceType; + +/// AppletFooterUiType (system) +typedef enum { + HidAppletFooterUiType_None = 0, ///< None + HidAppletFooterUiType_HandheldNone = 1, ///< HandheldNone + HidAppletFooterUiType_HandheldJoyConLeftOnly = 2, ///< HandheldJoyConLeftOnly + HidAppletFooterUiType_HandheldJoyConRightOnly = 3, ///< HandheldJoyConRightOnly + HidAppletFooterUiType_HandheldJoyConLeftJoyConRight = 4, ///< HandheldJoyConLeftJoyConRight + HidAppletFooterUiType_JoyDual = 5, ///< JoyDual + HidAppletFooterUiType_JoyDualLeftOnly = 6, ///< JoyDualLeftOnly + HidAppletFooterUiType_JoyDualRightOnly = 7, ///< JoyDualRightOnly + HidAppletFooterUiType_JoyLeftHorizontal = 8, ///< JoyLeftHorizontal + HidAppletFooterUiType_JoyLeftVertical = 9, ///< JoyLeftVertical + HidAppletFooterUiType_JoyRightHorizontal = 10, ///< JoyRightHorizontal + HidAppletFooterUiType_JoyRightVertical = 11, ///< JoyRightVertical + HidAppletFooterUiType_SwitchProController = 12, ///< SwitchProController + HidAppletFooterUiType_CompatibleProController = 13, ///< CompatibleProController + HidAppletFooterUiType_CompatibleJoyCon = 14, ///< CompatibleJoyCon + HidAppletFooterUiType_LarkHvc1 = 15, ///< LarkHvc1 + HidAppletFooterUiType_LarkHvc2 = 16, ///< LarkHvc2 + HidAppletFooterUiType_LarkNesLeft = 17, ///< LarkNesLeft + HidAppletFooterUiType_LarkNesRight = 18, ///< LarkNesRight + HidAppletFooterUiType_Lucia = 19, ///< Lucia + HidAppletFooterUiType_Verification = 20, ///< Verification + HidAppletFooterUiType_Lagon = 21, ///< [13.0.0+] Lagon +} HidAppletFooterUiType; + +/// NpadInterfaceType (system) +typedef enum { + HidNpadInterfaceType_Bluetooth = 1, ///< Bluetooth. + HidNpadInterfaceType_Rail = 2, ///< Rail. + HidNpadInterfaceType_USB = 3, ///< USB. + HidNpadInterfaceType_Unknown4 = 4, ///< Unknown. +} HidNpadInterfaceType; + +/// XcdInterfaceType +typedef enum { + XcdInterfaceType_Bluetooth = BIT(0), + XcdInterfaceType_Uart = BIT(1), + XcdInterfaceType_Usb = BIT(2), + XcdInterfaceType_FieldSet = BIT(7), +} XcdInterfaceType; + +/// NpadLarkType +typedef enum { + HidNpadLarkType_Invalid = 0, ///< Invalid + HidNpadLarkType_H1 = 1, ///< H1 + HidNpadLarkType_H2 = 2, ///< H2 + HidNpadLarkType_NL = 3, ///< NL + HidNpadLarkType_NR = 4, ///< NR +} HidNpadLarkType; + +/// NpadLuciaType +typedef enum { + HidNpadLuciaType_Invalid = 0, ///< Invalid + HidNpadLuciaType_J = 1, ///< J + HidNpadLuciaType_E = 2, ///< E + HidNpadLuciaType_U = 3, ///< U +} HidNpadLuciaType; + +/// NpadLagerType +typedef enum { + HidNpadLagerType_Invalid = 0, ///< Invalid + HidNpadLagerType_J = 1, ///< J + HidNpadLagerType_E = 2, ///< E + HidNpadLagerType_U = 3, ///< U +} HidNpadLagerType; + +/// Type values for HidVibrationDeviceInfo::type. +typedef enum { + HidVibrationDeviceType_Unknown = 0, ///< Unknown + HidVibrationDeviceType_LinearResonantActuator = 1, ///< LinearResonantActuator + HidVibrationDeviceType_GcErm = 2, ///< GcErm (::HidNpadStyleTag_NpadGc) +} HidVibrationDeviceType; + +/// VibrationDevicePosition +typedef enum { + HidVibrationDevicePosition_None = 0, ///< None + HidVibrationDevicePosition_Left = 1, ///< Left + HidVibrationDevicePosition_Right = 2, ///< Right +} HidVibrationDevicePosition; + +/// VibrationGcErmCommand +typedef enum { + HidVibrationGcErmCommand_Stop = 0, ///< Stops the vibration with a decay phase. + HidVibrationGcErmCommand_Start = 1, ///< Starts the vibration. + HidVibrationGcErmCommand_StopHard = 2, ///< Stops the vibration immediately, with no decay phase. +} HidVibrationGcErmCommand; + +/// PalmaOperationType +typedef enum { + HidPalmaOperationType_PlayActivity = 0, ///< PlayActivity + HidPalmaOperationType_SetFrModeType = 1, ///< SetFrModeType + HidPalmaOperationType_ReadStep = 2, ///< ReadStep + HidPalmaOperationType_EnableStep = 3, ///< EnableStep + HidPalmaOperationType_ResetStep = 4, ///< ResetStep + HidPalmaOperationType_ReadApplicationSection = 5, ///< ReadApplicationSection + HidPalmaOperationType_WriteApplicationSection = 6, ///< WriteApplicationSection + HidPalmaOperationType_ReadUniqueCode = 7, ///< ReadUniqueCode + HidPalmaOperationType_SetUniqueCodeInvalid = 8, ///< SetUniqueCodeInvalid + HidPalmaOperationType_WriteActivityEntry = 9, ///< WriteActivityEntry + HidPalmaOperationType_WriteRgbLedPatternEntry = 10, ///< WriteRgbLedPatternEntry + HidPalmaOperationType_WriteWaveEntry = 11, ///< WriteWaveEntry + HidPalmaOperationType_ReadDataBaseIdentificationVersion = 12, ///< ReadDataBaseIdentificationVersion + HidPalmaOperationType_WriteDataBaseIdentificationVersion = 13, ///< WriteDataBaseIdentificationVersion + HidPalmaOperationType_SuspendFeature = 14, ///< SuspendFeature + HidPalmaOperationType_ReadPlayLog = 15, ///< [5.1.0+] ReadPlayLog + HidPalmaOperationType_ResetPlayLog = 16, ///< [5.1.0+] ResetPlayLog +} HidPalmaOperationType; + +/// PalmaFrModeType +typedef enum { + HidPalmaFrModeType_Off = 0, ///< Off + HidPalmaFrModeType_B01 = 1, ///< B01 + HidPalmaFrModeType_B02 = 2, ///< B02 + HidPalmaFrModeType_B03 = 3, ///< B03 + HidPalmaFrModeType_Downloaded = 4, ///< Downloaded +} HidPalmaFrModeType; + +/// PalmaWaveSet +typedef enum { + HidPalmaWaveSet_Small = 0, ///< Small + HidPalmaWaveSet_Medium = 1, ///< Medium + HidPalmaWaveSet_Large = 2, ///< Large +} HidPalmaWaveSet; + +/// PalmaFeature +typedef enum { + HidPalmaFeature_FrMode = BIT(0), ///< FrMode + HidPalmaFeature_RumbleFeedback = BIT(1), ///< RumbleFeedback + HidPalmaFeature_Step = BIT(2), ///< Step + HidPalmaFeature_MuteSwitch = BIT(3), ///< MuteSwitch +} HidPalmaFeature; + +/// HidAnalogStickState +typedef struct HidAnalogStickState { + s32 x; ///< X + s32 y; ///< Y +} HidAnalogStickState; + +/// HidVector +typedef struct HidVector { + float x; + float y; + float z; +} HidVector; + +/// HidDirectionState +typedef struct HidDirectionState { + float direction[3][3]; ///< 3x3 matrix +} HidDirectionState; + +#define JOYSTICK_MAX (0x7FFF) +#define JOYSTICK_MIN (-0x7FFF) + +// End enums and output structs + +/// HidCommonLifoHeader +typedef struct HidCommonLifoHeader { + u64 unused; ///< Unused + u64 buffer_count; ///< BufferCount + u64 tail; ///< Tail + u64 count; ///< Count +} HidCommonLifoHeader; + +// Begin HidDebugPad + +/// HidDebugPadState +typedef struct HidDebugPadState { + u64 sampling_number; ///< SamplingNumber + u32 attributes; ///< Bitfield of \ref HidDebugPadAttribute. + u32 buttons; ///< Bitfield of \ref HidDebugPadButton. + HidAnalogStickState analog_stick_r; ///< AnalogStickR + HidAnalogStickState analog_stick_l; ///< AnalogStickL +} HidDebugPadState; + +/// HidDebugPadStateAtomicStorage +typedef struct HidDebugPadStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidDebugPadState state; ///< \ref HidDebugPadState +} HidDebugPadStateAtomicStorage; + +/// HidDebugPadLifo +typedef struct HidDebugPadLifo { + HidCommonLifoHeader header; ///< \ref HidCommonLifoHeader + HidDebugPadStateAtomicStorage storage[17]; ///< \ref HidDebugPadStateAtomicStorage +} HidDebugPadLifo; + +/// HidDebugPadSharedMemoryFormat +typedef struct HidDebugPadSharedMemoryFormat { + HidDebugPadLifo lifo; + u8 padding[0x138]; +} HidDebugPadSharedMemoryFormat; + +// End HidDebugPad + +// Begin HidTouchScreen + +/// HidTouchState +typedef struct HidTouchState { + u64 delta_time; ///< DeltaTime + u32 attributes; ///< Bitfield of \ref HidTouchAttribute. + u32 finger_id; ///< FingerId + u32 x; ///< X + u32 y; ///< Y + u32 diameter_x; ///< DiameterX + u32 diameter_y; ///< DiameterY + u32 rotation_angle; ///< RotationAngle + u32 reserved; ///< Reserved +} HidTouchState; + +/// HidTouchScreenState +typedef struct HidTouchScreenState { + u64 sampling_number; ///< SamplingNumber + s32 count; ///< Number of entries in the touches array. + u32 reserved; ///< Reserved + HidTouchState touches[16]; ///< Array of \ref HidTouchState, with the above count. +} HidTouchScreenState; + +/// HidTouchScreenStateAtomicStorage +typedef struct HidTouchScreenStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidTouchScreenState state; ///< \ref HidTouchScreenState +} HidTouchScreenStateAtomicStorage; + +/// HidTouchScreenLifo +typedef struct HidTouchScreenLifo { + HidCommonLifoHeader header; ///< \ref HidCommonLifoHeader + HidTouchScreenStateAtomicStorage storage[17]; ///< \ref HidTouchScreenStateAtomicStorage +} HidTouchScreenLifo; + +/// HidTouchScreenSharedMemoryFormat +typedef struct HidTouchScreenSharedMemoryFormat { + HidTouchScreenLifo lifo; + u8 padding[0x3c8]; +} HidTouchScreenSharedMemoryFormat; + +/// HidTouchScreenConfigurationForNx +typedef struct { + u8 mode; ///< \ref HidTouchScreenModeForNx + u8 reserved[0xF]; ///< Reserved +} HidTouchScreenConfigurationForNx; + +// End HidTouchScreen + +// Begin HidMouse + +/// HidMouseState +typedef struct HidMouseState { + u64 sampling_number; ///< SamplingNumber + s32 x; ///< X + s32 y; ///< Y + s32 delta_x; ///< DeltaX + s32 delta_y; ///< DeltaY + s32 wheel_delta_x; ///< WheelDeltaX + s32 wheel_delta_y; ///< WheelDeltaY + u32 buttons; ///< Bitfield of \ref HidMouseButton. + u32 attributes; ///< Bitfield of \ref HidMouseAttribute. +} HidMouseState; + +/// HidMouseStateAtomicStorage +typedef struct HidMouseStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidMouseState state; +} HidMouseStateAtomicStorage; + +/// HidMouseLifo +typedef struct HidMouseLifo { + HidCommonLifoHeader header; + HidMouseStateAtomicStorage storage[17]; +} HidMouseLifo; + +/// HidMouseSharedMemoryFormat +typedef struct HidMouseSharedMemoryFormat { + HidMouseLifo lifo; + u8 padding[0xB0]; +} HidMouseSharedMemoryFormat; + +// End HidMouse + +// Begin HidKeyboard + +/// HidKeyboardState +typedef struct HidKeyboardState { + u64 sampling_number; ///< SamplingNumber + u64 modifiers; ///< Bitfield of \ref HidKeyboardModifier. + u64 keys[4]; +} HidKeyboardState; + +/// HidKeyboardStateAtomicStorage +typedef struct HidKeyboardStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidKeyboardState state; +} HidKeyboardStateAtomicStorage; + +/// HidKeyboardLifo +typedef struct HidKeyboardLifo { + HidCommonLifoHeader header; + HidKeyboardStateAtomicStorage storage[17]; +} HidKeyboardLifo; + +/// HidKeyboardSharedMemoryFormat +typedef struct HidKeyboardSharedMemoryFormat { + HidKeyboardLifo lifo; + u8 padding[0x28]; +} HidKeyboardSharedMemoryFormat; + +// End HidKeyboard + +// Begin HidNpad + +/// Npad colors. +/// Color fields are zero when not set. +typedef struct HidNpadControllerColor { + u32 main; ///< RGBA Body Color + u32 sub; ///< RGBA Buttons Color +} HidNpadControllerColor; + +/// HidNpadFullKeyColorState +typedef struct HidNpadFullKeyColorState { + u32 attribute; ///< \ref HidColorAttribute + HidNpadControllerColor full_key; ///< \ref HidNpadControllerColor FullKey +} HidNpadFullKeyColorState; + +/// HidNpadJoyColorState +typedef struct HidNpadJoyColorState { + u32 attribute; ///< \ref HidColorAttribute + HidNpadControllerColor left; ///< \ref HidNpadControllerColor Left + HidNpadControllerColor right; ///< \ref HidNpadControllerColor Right +} HidNpadJoyColorState; + +/// HidNpadCommonState +typedef struct HidNpadCommonState { + u64 sampling_number; ///< SamplingNumber + u64 buttons; ///< Bitfield of \ref HidNpadButton. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + u32 attributes; ///< Bitfield of \ref HidNpadAttribute. + u32 reserved; ///< Reserved +} HidNpadCommonState; + +typedef HidNpadCommonState HidNpadFullKeyState; ///< State for ::HidNpadStyleTag_NpadFullKey. +typedef HidNpadCommonState HidNpadHandheldState; ///< State for ::HidNpadStyleTag_NpadHandheld. +typedef HidNpadCommonState HidNpadJoyDualState; ///< State for ::HidNpadStyleTag_NpadJoyDual. +typedef HidNpadCommonState HidNpadJoyLeftState; ///< State for ::HidNpadStyleTag_NpadJoyLeft. +typedef HidNpadCommonState HidNpadJoyRightState; ///< State for ::HidNpadStyleTag_NpadJoyRight. + +/// State for ::HidNpadStyleTag_NpadGc. Loaded from the same lifo as \ref HidNpadFullKeyState, with the additional trigger_l/trigger_r loaded from elsewhere. +typedef struct HidNpadGcState { + u64 sampling_number; ///< SamplingNumber + u64 buttons; ///< Bitfield of \ref HidNpadButton. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + u32 attributes; ///< Bitfield of \ref HidNpadAttribute. + u32 trigger_l; ///< L analog trigger. Valid range: 0x0-0x7FFF. + u32 trigger_r; ///< R analog trigger. Valid range: 0x0-0x7FFF. + u32 pad; +} HidNpadGcState; + +typedef HidNpadCommonState HidNpadPalmaState; ///< State for ::HidNpadStyleTag_NpadPalma. + +/// State for ::HidNpadStyleTag_NpadLark. The base state is loaded from the same lifo as \ref HidNpadFullKeyState. +typedef struct HidNpadLarkState { + u64 sampling_number; ///< SamplingNumber + u64 buttons; ///< Bitfield of \ref HidNpadButton. + HidAnalogStickState analog_stick_l; ///< This is always zero. + HidAnalogStickState analog_stick_r; ///< This is always zero. + u32 attributes; ///< Bitfield of \ref HidNpadAttribute. + HidNpadLarkType lark_type_l_and_main; ///< \ref HidNpadLarkType LarkTypeLAndMain +} HidNpadLarkState; + +/// State for ::HidNpadStyleTag_NpadHandheldLark. The base state is loaded from the same lifo as \ref HidNpadHandheldState. +typedef struct HidNpadHandheldLarkState { + u64 sampling_number; ///< SamplingNumber + u64 buttons; ///< Bitfield of \ref HidNpadButton. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + u32 attributes; ///< Bitfield of \ref HidNpadAttribute. + HidNpadLarkType lark_type_l_and_main; ///< \ref HidNpadLarkType LarkTypeLAndMain + HidNpadLarkType lark_type_r; ///< \ref HidNpadLarkType LarkTypeR + u32 pad; +} HidNpadHandheldLarkState; + +/// State for ::HidNpadStyleTag_NpadLucia. The base state is loaded from the same lifo as \ref HidNpadFullKeyState. +typedef struct HidNpadLuciaState { + u64 sampling_number; ///< SamplingNumber + u64 buttons; ///< Bitfield of \ref HidNpadButton. + HidAnalogStickState analog_stick_l; ///< This is always zero. + HidAnalogStickState analog_stick_r; ///< This is always zero. + u32 attributes; ///< Bitfield of \ref HidNpadAttribute. + HidNpadLuciaType lucia_type; ///< \ref HidNpadLuciaType +} HidNpadLuciaState; + +typedef HidNpadCommonState HidNpadLagerState; ///< State for ::HidNpadStyleTag_NpadLager. Analog-sticks state are always zero. + +typedef HidNpadCommonState HidNpadSystemExtState; ///< State for ::HidNpadStyleTag_NpadSystemExt. +typedef HidNpadCommonState HidNpadSystemState; ///< State for ::HidNpadStyleTag_NpadSystem. Analog-sticks state are always zero. Only the following button bits are available: HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y, HidNpadButton_Left, HidNpadButton_Up, HidNpadButton_Right, HidNpadButton_Down, HidNpadButton_L, HidNpadButton_R. + +/// HidNpadCommonStateAtomicStorage +typedef struct HidNpadCommonStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidNpadCommonState state; +} HidNpadCommonStateAtomicStorage; + +/// HidNpadCommonLifo +typedef struct HidNpadCommonLifo { + HidCommonLifoHeader header; + HidNpadCommonStateAtomicStorage storage[17]; +} HidNpadCommonLifo; + +/// HidNpadGcTriggerState +typedef struct HidNpadGcTriggerState { + u64 sampling_number; ///< SamplingNumber + u32 trigger_l; + u32 trigger_r; +} HidNpadGcTriggerState; + +/// HidNpadGcTriggerStateAtomicStorage +typedef struct HidNpadGcTriggerStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidNpadGcTriggerState state; +} HidNpadGcTriggerStateAtomicStorage; + +/// HidNpadGcTriggerLifo +typedef struct HidNpadGcTriggerLifo { + HidCommonLifoHeader header; + HidNpadGcTriggerStateAtomicStorage storage[17]; +} HidNpadGcTriggerLifo; + +/// HidSixAxisSensorState +typedef struct HidSixAxisSensorState { + u64 delta_time; ///< DeltaTime + u64 sampling_number; ///< SamplingNumber + HidVector acceleration; ///< Acceleration + HidVector angular_velocity; ///< AngularVelocity + HidVector angle; ///< Angle + HidDirectionState direction; ///< Direction + u32 attributes; ///< Bitfield of \ref HidSixAxisSensorAttribute. + u32 reserved; ///< Reserved +} HidSixAxisSensorState; + +/// HidSixAxisSensorStateAtomicStorage +typedef struct HidSixAxisSensorStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidSixAxisSensorState state; +} HidSixAxisSensorStateAtomicStorage; + +/// HidNpadSixAxisSensorLifo +typedef struct HidNpadSixAxisSensorLifo { + HidCommonLifoHeader header; + HidSixAxisSensorStateAtomicStorage storage[17]; +} HidNpadSixAxisSensorLifo; + +/// NpadSystemProperties +typedef struct { + u64 is_charging : 3; ///< Use \ref hidGetNpadPowerInfoSingle / \ref hidGetNpadPowerInfoSplit instead of accessing this directly. + u64 is_powered : 3; ///< Use \ref hidGetNpadPowerInfoSingle / \ref hidGetNpadPowerInfoSplit instead of accessing this directly. + + u64 bit6 : 1; ///< Unused + u64 bit7 : 1; ///< Unused + u64 bit8 : 1; ///< Unused + u64 is_unsupported_button_pressed_on_npad_system : 1; ///< IsUnsupportedButtonPressedOnNpadSystem + u64 is_unsupported_button_pressed_on_npad_system_ext : 1; ///< IsUnsupportedButtonPressedOnNpadSystemExt + + u64 is_abxy_button_oriented : 1; ///< IsAbxyButtonOriented + u64 is_sl_sr_button_oriented : 1; ///< IsSlSrButtonOriented + u64 is_plus_available : 1; ///< [4.0.0+] IsPlusAvailable + u64 is_minus_available : 1; ///< [4.0.0+] IsMinusAvailable + u64 is_directional_buttons_available : 1; ///< [8.0.0+] IsDirectionalButtonsAvailable + + u64 unused : 48; ///< Unused +} HidNpadSystemProperties; + +/// NpadSystemButtonProperties +typedef struct { + u32 is_unintended_home_button_input_protection_enabled : 1; ///< IsUnintendedHomeButtonInputProtectionEnabled +} HidNpadSystemButtonProperties; + +/// HidPowerInfo (system) +typedef struct { + bool is_powered; ///< IsPowered + bool is_charging; ///< IsCharging + u8 reserved[6]; ///< Reserved + u32 battery_level; ///< BatteryLevel, always 0-4. +} HidPowerInfo; + +/// XcdDeviceHandle +typedef struct XcdDeviceHandle { + u64 handle; +} XcdDeviceHandle; + +/// HidNfcXcdDeviceHandleStateImpl +typedef struct HidNfcXcdDeviceHandleStateImpl { + XcdDeviceHandle handle; + u8 is_available; + u8 is_activated; + u8 reserved[6]; + u64 sampling_number; ///< SamplingNumber +} HidNfcXcdDeviceHandleStateImpl; + +/// HidNfcXcdDeviceHandleStateImplAtomicStorage +typedef struct HidNfcXcdDeviceHandleStateImplAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidNfcXcdDeviceHandleStateImpl state; ///< \ref HidNfcXcdDeviceHandleStateImpl +} HidNfcXcdDeviceHandleStateImplAtomicStorage; + +/// HidNfcXcdDeviceHandleState +typedef struct HidNfcXcdDeviceHandleState { + HidCommonLifoHeader header; + HidNfcXcdDeviceHandleStateImplAtomicStorage storage[2]; +} HidNfcXcdDeviceHandleState; + +/// HidNpadInternalState +typedef struct HidNpadInternalState { + u32 style_set; ///< Bitfield of \ref HidNpadStyleTag. + u32 joy_assignment_mode; ///< \ref HidNpadJoyAssignmentMode + HidNpadFullKeyColorState full_key_color; ///< \ref HidNpadFullKeyColorState + HidNpadJoyColorState joy_color; ///< \ref HidNpadJoyColorState + + HidNpadCommonLifo full_key_lifo; ///< FullKeyLifo + HidNpadCommonLifo handheld_lifo; ///< HandheldLifo + HidNpadCommonLifo joy_dual_lifo; ///< JoyDualLifo + HidNpadCommonLifo joy_left_lifo; ///< JoyLeftLifo + HidNpadCommonLifo joy_right_lifo; ///< JoyRightLifo + HidNpadCommonLifo palma_lifo; ///< PalmaLifo + HidNpadCommonLifo system_ext_lifo; ///< SystemExtLifo + + HidNpadSixAxisSensorLifo full_key_six_axis_sensor_lifo; ///< FullKeySixAxisSensorLifo + HidNpadSixAxisSensorLifo handheld_six_axis_sensor_lifo; ///< HandheldSixAxisSensorLifo + HidNpadSixAxisSensorLifo joy_dual_left_six_axis_sensor_lifo; ///< JoyDualLeftSixAxisSensorLifo + HidNpadSixAxisSensorLifo joy_dual_right_six_axis_sensor_lifo; ///< JoyDualRightSixAxisSensorLifo + HidNpadSixAxisSensorLifo joy_left_six_axis_sensor_lifo; ///< JoyLeftSixAxisSensorLifo + HidNpadSixAxisSensorLifo joy_right_six_axis_sensor_lifo; ///< JoyRightSixAxisSensorLifo + + u32 device_type; ///< Bitfield of \ref HidDeviceTypeBits. + u32 reserved; ///< Reserved + HidNpadSystemProperties system_properties; + HidNpadSystemButtonProperties system_button_properties; + u32 battery_level[3]; + union { + struct { // [1.0.0-3.0.2] + HidNfcXcdDeviceHandleState nfc_xcd_device_handle; + }; + + struct { + u32 applet_footer_ui_attribute; ///< Bitfield of AppletFooterUiAttribute. + u8 applet_footer_ui_type; ///< \ref HidAppletFooterUiType + u8 reserved_x41AD[0x5B]; + }; + }; + u8 reserved_x4208[0x20]; ///< Mutex on pre-10.0.0. + HidNpadGcTriggerLifo gc_trigger_lifo; + u32 lark_type_l_and_main; ///< \ref HidNpadLarkType + u32 lark_type_r; ///< \ref HidNpadLarkType + u32 lucia_type; ///< \ref HidNpadLuciaType + u32 lager_type; ///< \ref HidNpadLagerType +} HidNpadInternalState; + +/// HidNpadSharedMemoryEntry +typedef struct HidNpadSharedMemoryEntry { + HidNpadInternalState internal_state; + u8 pad[0xC10]; +} HidNpadSharedMemoryEntry; + +/// HidNpadSharedMemoryFormat +typedef struct HidNpadSharedMemoryFormat { + HidNpadSharedMemoryEntry entries[10]; +} HidNpadSharedMemoryFormat; + +// End HidNpad + +// Begin HidGesture + +/// HidGesturePoint +typedef struct HidGesturePoint { + u32 x; ///< X + u32 y; ///< Y +} HidGesturePoint; + +/// HidGestureState +typedef struct HidGestureState { + u64 sampling_number; ///< SamplingNumber + u64 context_number; ///< ContextNumber + u32 type; ///< \ref HidGestureType + u32 direction; ///< \ref HidGestureDirection + u32 x; ///< X + u32 y; ///< Y + s32 delta_x; ///< DeltaX + s32 delta_y; ///< DeltaY + float velocity_x; ///< VelocityX + float velocity_y; ///< VelocityY + u32 attributes; ///< Bitfield of \ref HidGestureAttribute. + float scale; ///< Scale + float rotation_angle; ///< RotationAngle + s32 point_count; ///< Number of entries in the points array. + HidGesturePoint points[4]; ///< Array of \ref HidGesturePoint with the above count. +} HidGestureState; + +/// HidGestureDummyStateAtomicStorage +typedef struct HidGestureDummyStateAtomicStorage { + u64 sampling_number; ///< SamplingNumber + HidGestureState state; +} HidGestureDummyStateAtomicStorage; + +/// HidGestureLifo +typedef struct HidGestureLifo { + HidCommonLifoHeader header; + HidGestureDummyStateAtomicStorage storage[17]; +} HidGestureLifo; + +/// HidGestureSharedMemoryFormat +typedef struct HidGestureSharedMemoryFormat { + HidGestureLifo lifo; + u8 pad[0xF8]; +} HidGestureSharedMemoryFormat; + +// End HidGesture + +/// HidConsoleSixAxisSensor +typedef struct { + u64 sampling_number; ///< SamplingNumber + u8 is_seven_six_axis_sensor_at_rest; ///< IsSevenSixAxisSensorAtRest + u8 pad[0x3]; ///< Padding + float verticalization_error; ///< VerticalizationError + UtilFloat3 gyro_bias; ///< GyroBias + u8 pad2[0x4]; ///< Padding +} HidConsoleSixAxisSensor; + +/// HidSharedMemory +typedef struct HidSharedMemory { + HidDebugPadSharedMemoryFormat debug_pad; + 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 + HidNpadSharedMemoryFormat npad; + HidGestureSharedMemoryFormat gesture; + HidConsoleSixAxisSensor console_six_axis_sensor; ///< [5.0.0+] ConsoleSixAxisSensor + u8 unk_x3C220[0x3DE0]; +} HidSharedMemory; + +/// HidSevenSixAxisSensorState +typedef struct { + u64 timestamp0; + u64 sampling_number; + + u64 unk_x10; + float unk_x18[10]; +} HidSevenSixAxisSensorState; + +/// HidSevenSixAxisSensorStateEntry +typedef struct { + u64 sampling_number; + u64 unused; + HidSevenSixAxisSensorState state; +} HidSevenSixAxisSensorStateEntry; + +/// HidSevenSixAxisSensorStates +typedef struct { + HidCommonLifoHeader header; + HidSevenSixAxisSensorStateEntry storage[0x21]; +} HidSevenSixAxisSensorStates; + +/// HidSixAxisSensorHandle +typedef union HidSixAxisSensorHandle { + u32 type_value; ///< TypeValue + struct { + u32 npad_style_index : 8; ///< NpadStyleIndex + u32 player_number : 8; ///< PlayerNumber + u32 device_idx : 8; ///< DeviceIdx + u32 pad : 8; ///< Padding + }; +} HidSixAxisSensorHandle; + +/// HidVibrationDeviceHandle +typedef union HidVibrationDeviceHandle { + u32 type_value; ///< TypeValue + struct { + u32 npad_style_index : 8; ///< NpadStyleIndex + u32 player_number : 8; ///< PlayerNumber + u32 device_idx : 8; ///< DeviceIdx + u32 pad : 8; ///< Padding + }; +} HidVibrationDeviceHandle; + +/// HidVibrationDeviceInfo +typedef struct HidVibrationDeviceInfo { + u32 type; ///< \ref HidVibrationDeviceType + u32 position; ///< \ref HidVibrationDevicePosition +} HidVibrationDeviceInfo; + +/// HidVibrationValue +typedef struct HidVibrationValue { + float amp_low; ///< Low Band amplitude. 1.0f: Max amplitude. + float freq_low; ///< Low Band frequency in Hz. + float amp_high; ///< High Band amplitude. 1.0f: Max amplitude. + float freq_high; ///< High Band frequency in Hz. +} HidVibrationValue; + +/// PalmaConnectionHandle +typedef struct HidPalmaConnectionHandle { + u64 handle; ///< Handle +} HidPalmaConnectionHandle; + +/// PalmaOperationInfo +typedef struct HidPalmaOperationInfo { + u32 type; ///< \ref HidPalmaOperationType + Result res; ///< Result + u8 data[0x140]; ///< Data +} HidPalmaOperationInfo; + +/// PalmaApplicationSectionAccessBuffer +typedef struct HidPalmaApplicationSectionAccessBuffer { + u8 data[0x100]; ///< Application data. +} HidPalmaApplicationSectionAccessBuffer; + +/// PalmaActivityEntry +typedef struct HidPalmaActivityEntry { + u16 rgb_led_pattern_index; ///< RgbLedPatternIndex + u16 pad; ///< Padding + u32 wave_set; ///< \ref HidPalmaWaveSet + u16 wave_index; ///< WaveIndex +} HidPalmaActivityEntry; + +/// Initialize hid. Called automatically during app startup. +Result hidInitialize(void); + +/// Exit hid. Called automatically during app exit. +void hidExit(void); + +/// Gets the Service object for the actual hid service session. +Service* hidGetServiceSession(void); + +/// Gets the address of the SharedMemory. +void* hidGetSharedmemAddr(void); + +///@name TouchScreen +///@{ + +/// Initialize TouchScreen. Must be called when TouchScreen is being used. Used automatically by \ref hidScanInput when required. +void hidInitializeTouchScreen(void); + +/** + * @brief Gets \ref HidTouchScreenState. + * @param[out] states Output array of \ref HidTouchScreenState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetTouchScreenStates(HidTouchScreenState *states, size_t count); + +///@} + +///@name Mouse +///@{ + +/// Initialize Mouse. Must be called when Mouse is being used. Used automatically by \ref hidScanInput when required. +void hidInitializeMouse(void); + +/** + * @brief Gets \ref HidMouseState. + * @param[out] states Output array of \ref HidMouseState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetMouseStates(HidMouseState *states, size_t count); + +///@} + +///@name Keyboard +///@{ + +/// Initialize Keyboard. Must be called when Keyboard is being used. Used automatically by \ref hidScanInput when required. +void hidInitializeKeyboard(void); + +/** + * @brief Gets \ref HidKeyboardState. + * @param[out] states Output array of \ref HidKeyboardState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetKeyboardStates(HidKeyboardState *states, size_t count); + +/** + * @brief Gets the state of a key in a \ref HidKeyboardState. + * @param[in] state \ref HidKeyboardState. + * @param[in] key \ref HidKeyboardKey. + * @return true if the key is pressed, false if not. + */ +NX_CONSTEXPR bool hidKeyboardStateGetKey(const HidKeyboardState *state, HidKeyboardKey key) { + return (state->keys[key / 64] & (1UL << (key & 63))) != 0; +} + +///@} + +///@name Npad +///@{ + +/// Initialize Npad. Must be called when Npad is being used. Used automatically by \ref hidScanInput when required. +void hidInitializeNpad(void); + +/** + * @brief Gets the StyleSet for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @return Bitfield of \ref HidNpadStyleTag. + */ +u32 hidGetNpadStyleSet(HidNpadIdType id); + +/** + * @brief Gets the \ref HidNpadJoyAssignmentMode for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @return \ref HidNpadJoyAssignmentMode + */ +HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(HidNpadIdType id); + +/** + * @brief Gets the main \ref HidNpadControllerColor for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @param[out] color \ref HidNpadControllerColor + */ +Result hidGetNpadControllerColorSingle(HidNpadIdType id, HidNpadControllerColor *color); + +/** + * @brief Gets the left/right \ref HidNpadControllerColor for the specified Npad (Joy-Con pair in dual mode). + * @param[in] id \ref HidNpadIdType + * @param[out] color_left \ref HidNpadControllerColor + * @param[out] color_right \ref HidNpadControllerColor + */ +Result hidGetNpadControllerColorSplit(HidNpadIdType id, HidNpadControllerColor *color_left, HidNpadControllerColor *color_right); + +/** + * @brief Gets the DeviceType for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @return Bitfield of \ref HidDeviceTypeBits. + */ +u32 hidGetNpadDeviceType(HidNpadIdType id); + +/** + * @brief Gets the \ref HidNpadSystemProperties for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @param[out] out \ref HidNpadSystemProperties + */ +void hidGetNpadSystemProperties(HidNpadIdType id, HidNpadSystemProperties *out); + +/** + * @brief Gets the \ref HidNpadSystemButtonProperties for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @param[out] out \ref HidNpadSystemButtonProperties + */ +void hidGetNpadSystemButtonProperties(HidNpadIdType id, HidNpadSystemButtonProperties *out); + +/** + * @brief Gets the main \ref HidPowerInfo for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @param[out] info \ref HidPowerInfo + */ +void hidGetNpadPowerInfoSingle(HidNpadIdType id, HidPowerInfo *info); + +/** + * @brief Gets the left/right \ref HidPowerInfo for the specified Npad (Joy-Con pair in dual mode). + * @param[in] id \ref HidNpadIdType + * @param[out] info_left \ref HidPowerInfo + * @param[out] info_right \ref HidPowerInfo + */ +void hidGetNpadPowerInfoSplit(HidNpadIdType id, HidPowerInfo *info_left, HidPowerInfo *info_right); + +/** + * @brief Gets the AppletFooterUiAttributesSet for the specified Npad. + * @note Only available on [9.0.0+]. + * @param[in] id \ref HidNpadIdType + * @return Bitfield of AppletFooterUiAttribute (system). + */ +u32 hidGetAppletFooterUiAttributesSet(HidNpadIdType id); + +/** + * @brief Gets \ref HidAppletFooterUiType for the specified Npad. + * @note Only available on [9.0.0+]. + * @param[in] id \ref HidNpadIdType + * @return \ref HidAppletFooterUiType + */ +HidAppletFooterUiType hidGetAppletFooterUiTypes(HidNpadIdType id); + +/** + * @brief Gets \ref HidNpadLagerType for the specified Npad. + * @param[in] id \ref HidNpadIdType + * @return \ref HidNpadLagerType + */ +HidNpadLagerType hidGetNpadLagerType(HidNpadIdType id); + +/** + * @brief Gets \ref HidNpadFullKeyState. + * @param[out] states Output array of \ref HidNpadFullKeyState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesFullKey(HidNpadIdType id, HidNpadFullKeyState *states, size_t count); + +/** + * @brief Gets \ref HidNpadHandheldState. + * @param[out] states Output array of \ref HidNpadHandheldState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesHandheld(HidNpadIdType id, HidNpadHandheldState *states, size_t count); + +/** + * @brief Gets \ref HidNpadJoyDualState. + * @param[out] states Output array of \ref HidNpadJoyDualState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesJoyDual(HidNpadIdType id, HidNpadJoyDualState *states, size_t count); + +/** + * @brief Gets \ref HidNpadJoyLeftState. + * @param[out] states Output array of \ref HidNpadJoyLeftState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesJoyLeft(HidNpadIdType id, HidNpadJoyLeftState *states, size_t count); + +/** + * @brief Gets \ref HidNpadJoyRightState. + * @param[out] states Output array of \ref HidNpadJoyRightState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesJoyRight(HidNpadIdType id, HidNpadJoyRightState *states, size_t count); + +/** + * @brief Gets \ref HidNpadGcState. + * @param[out] states Output array of \ref HidNpadGcState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesGc(HidNpadIdType id, HidNpadGcState *states, size_t count); + +/** + * @brief Gets \ref HidNpadPalmaState. + * @param[out] states Output array of \ref HidNpadPalmaState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesPalma(HidNpadIdType id, HidNpadPalmaState *states, size_t count); + +/** + * @brief Gets \ref HidNpadLarkState. + * @param[out] states Output array of \ref HidNpadLarkState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesLark(HidNpadIdType id, HidNpadLarkState *states, size_t count); + +/** + * @brief Gets \ref HidNpadHandheldLarkState. + * @param[out] states Output array of \ref HidNpadHandheldLarkState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesHandheldLark(HidNpadIdType id, HidNpadHandheldLarkState *states, size_t count); + +/** + * @brief Gets \ref HidNpadLuciaState. + * @param[out] states Output array of \ref HidNpadLuciaState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesLucia(HidNpadIdType id, HidNpadLuciaState *states, size_t count); + +/** + * @brief Gets \ref HidNpadLagerState. + * @param[out] states Output array of \ref HidNpadLagerState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesLager(HidNpadIdType id, HidNpadLagerState *states, size_t count); + +/** + * @brief Gets \ref HidNpadSystemExtState. + * @param[out] states Output array of \ref HidNpadSystemExtState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesSystemExt(HidNpadIdType id, HidNpadSystemExtState *states, size_t count); + +/** + * @brief Gets \ref HidNpadSystemState. + * @param[out] states Output array of \ref HidNpadSystemState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetNpadStatesSystem(HidNpadIdType id, HidNpadSystemState *states, size_t count); + +/** + * @brief Gets \ref HidSixAxisSensorState for the specified handle. + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] states Output array of \ref HidSixAxisSensorState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetSixAxisSensorStates(HidSixAxisSensorHandle handle, HidSixAxisSensorState *states, size_t count); + +///@} + +///@name Gesture +///@{ + +/// Initialize Gesture. Must be called when Gesture is being used. +void hidInitializeGesture(void); + +/** + * @brief Gets \ref HidGestureState. + * @param[out] states Output array of \ref HidGestureState. + * @param[in] count Size of the states array in entries. + * @return Total output entries. + */ +size_t hidGetGestureStates(HidGestureState *states, size_t count); + +///@} + +/** + * @brief SendKeyboardLockKeyEvent + * @note Same as \ref hidsysSendKeyboardLockKeyEvent. + * @note Only available on [6.0.0+]. + * @param[in] events Bitfield of \ref HidKeyboardLockKeyEvent. + */ +Result hidSendKeyboardLockKeyEvent(u32 events); + +/** + * @brief Gets SixAxisSensorHandles. + * @note Only ::HidNpadStyleTag_NpadJoyDual supports total_handles==2. + * @param[out] handles Output array of \ref HidSixAxisSensorHandle. + * @param[in] total_handles Total handles for the handles array. Must be 1 or 2, if 2 handles aren't supported by the specified style an error is thrown. + * @param[in] id \ref HidNpadIdType + * @param[in] style \ref HidNpadStyleTag + */ +Result hidGetSixAxisSensorHandles(HidSixAxisSensorHandle *handles, s32 total_handles, HidNpadIdType id, HidNpadStyleTag style); + +/** + * @brief Starts the SixAxisSensor for the specified handle. + * @param[in] handle \ref HidSixAxisSensorHandle + */ +Result hidStartSixAxisSensor(HidSixAxisSensorHandle handle); + +/** + * @brief Stops the SixAxisSensor for the specified handle. + * @param[in] handle \ref HidSixAxisSensorHandle + */ +Result hidStopSixAxisSensor(HidSixAxisSensorHandle handle); + +/** + * @brief IsSixAxisSensorFusionEnabled + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] out Output flag. + */ +Result hidIsSixAxisSensorFusionEnabled(HidSixAxisSensorHandle handle, bool *out); + +/** + * @brief EnableSixAxisSensorFusion + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[in] flag Flag + */ +Result hidEnableSixAxisSensorFusion(HidSixAxisSensorHandle handle, bool flag); + +/** + * @brief SetSixAxisSensorFusionParameters + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[in] unk0 Must be 0.0f-1.0f. + * @param[in] unk1 Unknown + */ +Result hidSetSixAxisSensorFusionParameters(HidSixAxisSensorHandle handle, float unk0, float unk1); + +/** + * @brief GetSixAxisSensorFusionParameters + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] unk0 Unknown + * @param[out] unk1 Unknown + */ +Result hidGetSixAxisSensorFusionParameters(HidSixAxisSensorHandle handle, float *unk0, float *unk1); + +/** + * @brief ResetSixAxisSensorFusionParameters + * @param[in] handle \ref HidSixAxisSensorHandle + */ +Result hidResetSixAxisSensorFusionParameters(HidSixAxisSensorHandle handle); + +/** + * @brief Sets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle. + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[in] mode \ref HidGyroscopeZeroDriftMode + */ +Result hidSetGyroscopeZeroDriftMode(HidSixAxisSensorHandle handle, HidGyroscopeZeroDriftMode mode); + +/** + * @brief Gets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle. + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] mode \ref HidGyroscopeZeroDriftMode + */ +Result hidGetGyroscopeZeroDriftMode(HidSixAxisSensorHandle handle, HidGyroscopeZeroDriftMode *mode); + +/** + * @brief Resets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle to ::HidGyroscopeZeroDriftMode_Standard. + * @param[in] handle \ref HidSixAxisSensorHandle + */ +Result hidResetGyroscopeZeroDriftMode(HidSixAxisSensorHandle handle); + +/** + * @brief IsSixAxisSensorAtRest + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] out Output flag. + */ +Result hidIsSixAxisSensorAtRest(HidSixAxisSensorHandle handle, bool *out); + +/** + * @brief IsFirmwareUpdateAvailableForSixAxisSensor + * @note Only available on [6.0.0+]. + * @param[in] handle \ref HidSixAxisSensorHandle + * @param[out] out Output flag. + */ +Result hidIsFirmwareUpdateAvailableForSixAxisSensor(HidSixAxisSensorHandle handle, bool *out); + +/** + * @brief Sets which controller styles are supported. + * @note This is automatically called with the needed styles in \ref hidScanInput when required. + * @param[in] style_set Bitfield of \ref HidNpadStyleTag. + */ +Result hidSetSupportedNpadStyleSet(u32 style_set); + +/** + * @brief Gets which controller styles are supported. + * @param[out] style_set Bitfield of \ref HidNpadStyleTag. + */ +Result hidGetSupportedNpadStyleSet(u32 *style_set); + +/** + * @brief Sets which \ref HidNpadIdType are supported. + * @note This is automatically called with HidNpadIdType_No{1-8} and HidNpadIdType_Handheld when required in \ref hidScanInput. + * @param[in] ids Input array of \ref HidNpadIdType. + * @param[in] count Total entries in the ids array. Must be <=10. + */ +Result hidSetSupportedNpadIdType(const HidNpadIdType *ids, size_t count); + +/** + * @brief Gets an Event which is signaled when the \ref hidGetNpadStyleSet output is updated for the specified controller. + * @note The Event must be closed by the user once finished with it. + * @param[in] id \ref HidNpadIdType + * @param[out] out_event Output Event. + * @param[in] autoclear The autoclear for the Event. +**/ +Result hidAcquireNpadStyleSetUpdateEventHandle(HidNpadIdType id, Event* out_event, bool autoclear); + +/** + * @brief DisconnectNpad + * @param[in] id \ref HidNpadIdType + */ +Result hidDisconnectNpad(HidNpadIdType id); + +/** + * @brief GetPlayerLedPattern + * @param[in] id \ref HidNpadIdType + * @param[out] out Output value. + */ +Result hidGetPlayerLedPattern(HidNpadIdType id, u8 *out); + +/** + * @brief Sets the \ref HidNpadJoyHoldType. + * @note Used automatically by \ref hidScanInput when required. + * @param[in] type \ref HidNpadJoyHoldType + */ +Result hidSetNpadJoyHoldType(HidNpadJoyHoldType type); + +/** + * @brief Gets the \ref HidNpadJoyHoldType. + * @param[out] type \ref HidNpadJoyHoldType + */ +Result hidGetNpadJoyHoldType(HidNpadJoyHoldType *type); + +/** + * @brief This is the same as \ref hidSetNpadJoyAssignmentModeSingle, except ::HidNpadJoyDeviceType_Left is used for the type. + * @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. + */ +Result hidSetNpadJoyAssignmentModeSingleByDefault(HidNpadIdType id); + +/** + * @brief This is the same as \ref hidSetNpadJoyAssignmentModeSingleWithDestination, except without the output params. + * @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. + * @param[in] type \ref HidNpadJoyDeviceType + */ +Result hidSetNpadJoyAssignmentModeSingle(HidNpadIdType id, HidNpadJoyDeviceType type); + +/** + * @brief Use this if you want to use a pair of joy-cons as a single HidNpadIdType_No*. When used, both joy-cons in a pair should be used with this (HidNpadIdType_No1 and HidNpadIdType_No2 for example). + * @note Used automatically by \ref hidScanInput when required. + * @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. + */ +Result hidSetNpadJoyAssignmentModeDual(HidNpadIdType id); + +/** + * @brief Merge two single joy-cons into a dual-mode controller. Use this after \ref hidSetNpadJoyAssignmentModeDual, when \ref hidSetNpadJoyAssignmentModeSingleByDefault was previously used (this includes using this manually at application exit). + * @brief To be successful, id0/id1 must correspond to controllers supporting styles HidNpadStyleTag_NpadJoyLeft/Right, or HidNpadStyleTag_NpadJoyRight/Left. + * @brief If successful, the id of the resulting dual controller is set to id0. + * @param[in] id0 \ref HidNpadIdType + * @param[in] id1 \ref HidNpadIdType + */ +Result hidMergeSingleJoyAsDualJoy(HidNpadIdType id0, HidNpadIdType id1); + +/** + * @brief StartLrAssignmentMode + */ +Result hidStartLrAssignmentMode(void); + +/** + * @brief StopLrAssignmentMode + */ +Result hidStopLrAssignmentMode(void); + +/** + * @brief Sets the \ref HidNpadHandheldActivationMode. + * @param[in] mode \ref HidNpadHandheldActivationMode + */ +Result hidSetNpadHandheldActivationMode(HidNpadHandheldActivationMode mode); + +/** + * @brief Gets the \ref HidNpadHandheldActivationMode. + * @param[out] out \ref HidNpadHandheldActivationMode + */ +Result hidGetNpadHandheldActivationMode(HidNpadHandheldActivationMode *out); + +/** + * @brief SwapNpadAssignment + * @param[in] id0 \ref HidNpadIdType + * @param[in] id1 \ref HidNpadIdType + */ +Result hidSwapNpadAssignment(HidNpadIdType id0, HidNpadIdType id1); + +/** + * @brief EnableUnintendedHomeButtonInputProtection + * @note To get the state of this, use \ref hidGetNpadSystemButtonProperties to access HidNpadSystemButtonProperties::is_unintended_home_button_input_protection_enabled. + * @param[in] id \ref HidNpadIdType + * @param[in] flag Whether UnintendedHomeButtonInputProtection is enabled. + */ +Result hidEnableUnintendedHomeButtonInputProtection(HidNpadIdType id, bool flag); + +/** + * @brief Use this if you want to use a single joy-con as a dedicated HidNpadIdType_No*. When used, both joy-cons in a pair should be used with this (HidNpadIdType_No1 and HidNpadIdType_No2 for example). + * @note Only available on [5.0.0+]. + * @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. + * @param[in] type \ref HidNpadJoyDeviceType + * @param[out] flag Whether the dest output is set. + * @param[out] dest \ref HidNpadIdType + */ +Result hidSetNpadJoyAssignmentModeSingleWithDestination(HidNpadIdType id, HidNpadJoyDeviceType type, bool *flag, HidNpadIdType *dest); + +/** + * @brief SetNpadAnalogStickUseCenterClamp + * @note Only available on [6.1.0+]. + * @param[in] flag Flag + */ +Result hidSetNpadAnalogStickUseCenterClamp(bool flag); + +/** + * @brief Assigns the button(s) which trigger the CaptureButton. + * @note Only available on [8.0.0+]. + * @param[in] style \ref HidNpadStyleTag, exactly 1 bit must be set. + * @param[in] buttons Bitfield of \ref HidNpadButton, multiple bits can be set. + */ +Result hidSetNpadCaptureButtonAssignment(HidNpadStyleTag style, u64 buttons); + +/** + * @brief ClearNpadCaptureButtonAssignment + * @note Only available on [8.0.0+]. + */ +Result hidClearNpadCaptureButtonAssignment(void); + +/** + * @brief Gets and initializes vibration handles. + * @note Only the following styles support total_handles 2: ::HidNpadStyleTag_NpadFullKey, ::HidNpadStyleTag_NpadHandheld, ::HidNpadStyleTag_NpadJoyDual, ::HidNpadStyleTag_NpadHandheldLark, ::HidNpadStyleTag_NpadSystem, ::HidNpadStyleTag_NpadSystemExt. + * @param[out] handles Output array of \ref HidVibrationDeviceHandle. + * @param[in] total_handles Total handles for the handles array. Must be 1 or 2, if 2 handles aren't supported by the specified style an error is thrown. + * @param[in] id \ref HidNpadIdType + * @param[in] style \ref HidNpadStyleTag + */ +Result hidInitializeVibrationDevices(HidVibrationDeviceHandle *handles, s32 total_handles, HidNpadIdType id, HidNpadStyleTag style); + +/** + * @brief Gets \ref HidVibrationDeviceInfo for the specified device. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[out] out \ref HidVibrationDeviceInfo + */ +Result hidGetVibrationDeviceInfo(HidVibrationDeviceHandle handle, HidVibrationDeviceInfo *out); + +/** + * @brief Sends the \ref HidVibrationDeviceHandle to the specified device. + * @note With ::HidVibrationDeviceType_GcErm, use \ref hidSendVibrationGcErmCommand instead. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[in] value \ref HidVibrationValue + */ +Result hidSendVibrationValue(HidVibrationDeviceHandle handle, const HidVibrationValue *value); + +/** + * @brief Gets the current \ref HidVibrationValue for the specified device. + * @note With ::HidVibrationDeviceType_GcErm, use \ref hidGetActualVibrationGcErmCommand instead. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[out] out \ref HidVibrationValue + */ +Result hidGetActualVibrationValue(HidVibrationDeviceHandle handle, HidVibrationValue *out); + +/** + * @brief Sets whether vibration is allowed, this also affects the config displayed by System Settings. + * @param[in] flag Flag + */ +Result hidPermitVibration(bool flag); + +/** + * @brief Gets whether vibration is allowed. + * @param[out] flag Flag + */ +Result hidIsVibrationPermitted(bool *flag); + +/** + * @brief Send vibration values[index] to handles[index]. + * @note With ::HidVibrationDeviceType_GcErm, use \ref hidSendVibrationGcErmCommand instead. + * @param[in] handles Input array of \ref HidVibrationDeviceHandle. + * @param[in] values Input array of \ref HidVibrationValue. + * @param[in] count Total entries in the handles/values arrays. + */ +Result hidSendVibrationValues(const HidVibrationDeviceHandle *handles, const HidVibrationValue *values, s32 count); + +/** + * @brief Send \ref HidVibrationGcErmCommand to the specified device, for ::HidVibrationDeviceType_GcErm. + * @note Only available on [4.0.0+]. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[in] cmd \ref HidVibrationGcErmCommand + */ +Result hidSendVibrationGcErmCommand(HidVibrationDeviceHandle handle, HidVibrationGcErmCommand cmd); + +/** + * @brief Get \ref HidVibrationGcErmCommand for the specified device, for ::HidVibrationDeviceType_GcErm. + * @note Only available on [4.0.0+]. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[out] out \ref HidVibrationGcErmCommand + */ +Result hidGetActualVibrationGcErmCommand(HidVibrationDeviceHandle handle, HidVibrationGcErmCommand *out); + +/** + * @brief Begins a forced-permitted vibration session. + * @note Only available on [4.0.0+]. + */ +Result hidBeginPermitVibrationSession(void); + +/** + * @brief Ends the session started by \ref hidBeginPermitVibrationSession. + * @note Only available on [4.0.0+]. + */ +Result hidEndPermitVibrationSession(void); + +/** + * @brief Gets whether vibration is available with the specified device. + * @note Only available on [7.0.0+]. + * @param[in] handle \ref HidVibrationDeviceHandle + * @param[out] flag Flag + */ +Result hidIsVibrationDeviceMounted(HidVibrationDeviceHandle handle, bool *flag); + +/** + * @brief Starts the SevenSixAxisSensor. + * @note Only available on [5.0.0+]. + */ +Result hidStartSevenSixAxisSensor(void); + +/** + * @brief Stops the SevenSixAxisSensor. + * @note Only available on [5.0.0+]. + */ +Result hidStopSevenSixAxisSensor(void); + +/** + * @brief Initializes the SevenSixAxisSensor. + * @note Only available on [5.0.0+]. + */ +Result hidInitializeSevenSixAxisSensor(void); + +/** + * @brief Finalizes the SevenSixAxisSensor. + * @note This must be called before \ref hidExit. + * @note Only available on [5.0.0+]. + */ +Result hidFinalizeSevenSixAxisSensor(void); + +/** + * @brief Sets the SevenSixAxisSensor FusionStrength. + * @note Only available on [5.0.0+]. + * @param[in] strength Strength + */ +Result hidSetSevenSixAxisSensorFusionStrength(float strength); + +/** + * @brief Gets the SevenSixAxisSensor FusionStrength. + * @note Only available on [5.0.0+]. + * @param[out] strength Strength + */ +Result hidGetSevenSixAxisSensorFusionStrength(float *strength); + +/** + * @brief Resets the timestamp for the SevenSixAxisSensor. + * @note Only available on [6.0.0+]. + */ +Result hidResetSevenSixAxisSensorTimestamp(void); + +/** + * @brief GetSevenSixAxisSensorStates + * @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. + * @param[out] states Output array of \ref HidSevenSixAxisSensorState. + * @param[in] count Size of the states array in entries. + * @param[out] total_out Total output entries. + */ +Result hidGetSevenSixAxisSensorStates(HidSevenSixAxisSensorState *states, size_t count, size_t *total_out); + +/** + * @brief IsSevenSixAxisSensorAtRest + * @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. + * @param[out] out Output flag. + */ +Result hidIsSevenSixAxisSensorAtRest(bool *out); + +/** + * @brief GetSensorFusionError + * @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. + * @param[out] out Output data. + */ +Result hidGetSensorFusionError(float *out); + +/** + * @brief GetGyroBias + * @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. + * @param[out] out \ref UtilFloat3 + */ +Result hidGetGyroBias(UtilFloat3 *out); + +/** + * @brief IsUsbFullKeyControllerEnabled + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result hidIsUsbFullKeyControllerEnabled(bool *out); + +/** + * @brief EnableUsbFullKeyController + * @note Only available on [3.0.0+]. + * @param[in] flag Flag + */ +Result hidEnableUsbFullKeyController(bool flag); + +/** + * @brief IsUsbFullKeyControllerConnected + * @note Only available on [3.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out Output flag. + */ +Result hidIsUsbFullKeyControllerConnected(HidNpadIdType id, bool *out); + +/** + * @brief Gets the \ref HidNpadInterfaceType for the specified controller. + * @note When available, \ref hidsysGetNpadInterfaceType should be used instead. + * @note Only available on [4.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out \ref HidNpadInterfaceType + */ +Result hidGetNpadInterfaceType(HidNpadIdType id, u8 *out); + +/** + * @brief GetNpadOfHighestBatteryLevel + * @note Only available on [10.0.0+]. + * @param[in] ids Input array of \ref HidNpadIdType, ::HidNpadIdType_Handheld is ignored. + * @param[in] count Total entries in the ids array. + * @param[out] out \ref HidNpadIdType + */ +Result hidGetNpadOfHighestBatteryLevel(const HidNpadIdType *ids, size_t count, HidNpadIdType *out); + +///@name Palma, see ::HidNpadStyleTag_NpadPalma. +///@{ + +/** + * @brief GetPalmaConnectionHandle + * @note Only available on [5.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out \ref HidPalmaConnectionHandle + */ +Result hidGetPalmaConnectionHandle(HidNpadIdType id, HidPalmaConnectionHandle *out); + +/** + * @brief InitializePalma + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidInitializePalma(HidPalmaConnectionHandle handle); + +/** + * @brief Gets an Event which is signaled when data is available with \ref hidGetPalmaOperationInfo. + * @note The Event must be closed by the user once finished with it. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[out] out_event Output Event. + * @param[in] autoclear The autoclear for the Event. +**/ +Result hidAcquirePalmaOperationCompleteEvent(HidPalmaConnectionHandle handle, Event* out_event, bool autoclear); + +/** + * @brief Gets \ref HidPalmaOperationInfo for a completed operation. + * @note This must be used at some point following using any of the other Palma cmds which trigger an Operation, once the Event from \ref hidAcquirePalmaOperationCompleteEvent is signaled. Up to 4 Operations can be queued at once, the other cmds will throw an error once there's too many operations. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[out] out \ref HidPalmaOperationInfo + */ +Result hidGetPalmaOperationInfo(HidPalmaConnectionHandle handle, HidPalmaOperationInfo *out); + +/** + * @brief PlayPalmaActivity + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] val Input value. + */ +Result hidPlayPalmaActivity(HidPalmaConnectionHandle handle, u16 val); + +/** + * @brief SetPalmaFrModeType + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] type \ref HidPalmaFrModeType + */ +Result hidSetPalmaFrModeType(HidPalmaConnectionHandle handle, HidPalmaFrModeType type); + +/** + * @brief ReadPalmaStep + * @note See \ref hidGetPalmaOperationInfo. + * @note \ref hidEnablePalmaStep should be used before this. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidReadPalmaStep(HidPalmaConnectionHandle handle); + +/** + * @brief EnablePalmaStep + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] flag Flag + */ +Result hidEnablePalmaStep(HidPalmaConnectionHandle handle, bool flag); + +/** + * @brief ResetPalmaStep + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidResetPalmaStep(HidPalmaConnectionHandle handle); + +/** + * @brief ReadPalmaApplicationSection + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] inval0 First input value. + * @param[in] size This must be within the size of \ref HidPalmaApplicationSectionAccessBuffer. + */ +Result hidReadPalmaApplicationSection(HidPalmaConnectionHandle handle, s32 inval0, u64 size); + +/** + * @brief WritePalmaApplicationSection + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] inval0 First input value. + * @param[in] size Size of the data in \ref HidPalmaApplicationSectionAccessBuffer. + * @param[in] buf \ref HidPalmaApplicationSectionAccessBuffer + */ +Result hidWritePalmaApplicationSection(HidPalmaConnectionHandle handle, s32 inval0, u64 size, const HidPalmaApplicationSectionAccessBuffer *buf); + +/** + * @brief ReadPalmaUniqueCode + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidReadPalmaUniqueCode(HidPalmaConnectionHandle handle); + +/** + * @brief SetPalmaUniqueCodeInvalid + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidSetPalmaUniqueCodeInvalid(HidPalmaConnectionHandle handle); + +/** + * @brief WritePalmaActivityEntry + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] unk Unknown + * @param[in] entry \ref HidPalmaActivityEntry + */ +Result hidWritePalmaActivityEntry(HidPalmaConnectionHandle handle, u16 unk, const HidPalmaActivityEntry *entry); + +/** + * @brief WritePalmaRgbLedPatternEntry + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] unk Unknown + * @param[in] buffer Input buffer. + * @param[in] size Input buffer size. + */ +Result hidWritePalmaRgbLedPatternEntry(HidPalmaConnectionHandle handle, u16 unk, const void* buffer, size_t size); + +/** + * @brief WritePalmaWaveEntry + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] wave_set \ref HidPalmaWaveSet + * @param[in] unk Unknown + * @param[in] buffer TransferMemory buffer, must be 0x1000-byte aligned. + * @param[in] tmem_size TransferMemory buffer size, must be 0x1000-byte aligned. + * @param[in] size Actual size of the data in the buffer. + */ +Result hidWritePalmaWaveEntry(HidPalmaConnectionHandle handle, HidPalmaWaveSet wave_set, u16 unk, const void* buffer, size_t tmem_size, size_t size); + +/** + * @brief SetPalmaDataBaseIdentificationVersion + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] version Version + */ +Result hidSetPalmaDataBaseIdentificationVersion(HidPalmaConnectionHandle handle, s32 version); + +/** + * @brief GetPalmaDataBaseIdentificationVersion + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidGetPalmaDataBaseIdentificationVersion(HidPalmaConnectionHandle handle); + +/** + * @brief SuspendPalmaFeature + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] features Bitfield of \ref HidPalmaFeature. + */ +Result hidSuspendPalmaFeature(HidPalmaConnectionHandle handle, u32 features); + +/** + * @brief ReadPalmaPlayLog + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.1.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] unk Unknown + */ +Result hidReadPalmaPlayLog(HidPalmaConnectionHandle handle, u16 unk); + +/** + * @brief ResetPalmaPlayLog + * @note See \ref hidGetPalmaOperationInfo. + * @note Only available on [5.1.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[in] unk Unknown + */ +Result hidResetPalmaPlayLog(HidPalmaConnectionHandle handle, u16 unk); + +/** + * @brief Sets whether any Palma can connect. + * @note Only available on [5.1.0+]. + * @param[in] flag Flag + */ +Result hidSetIsPalmaAllConnectable(bool flag); + +/** + * @brief Sets whether paired Palma can connect. + * @note Only available on [5.1.0+]. + * @param[in] flag Flag + */ +Result hidSetIsPalmaPairedConnectable(bool flag); + +/** + * @brief PairPalma + * @note Only available on [5.1.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidPairPalma(HidPalmaConnectionHandle handle); + +/** + * @brief CancelWritePalmaWaveEntry + * @note Only available on [7.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + */ +Result hidCancelWritePalmaWaveEntry(HidPalmaConnectionHandle handle); + +/** + * @brief EnablePalmaBoostMode + * @note Only available on [5.1.0+]. Uses cmd EnablePalmaBoostMode on [8.0.0+], otherwise cmd SetPalmaBoostMode is used. + * @param[in] flag Flag + */ +Result hidEnablePalmaBoostMode(bool flag); + +/** + * @brief GetPalmaBluetoothAddress + * @note Only available on [8.0.0+]. + * @param[in] handle \ref HidPalmaConnectionHandle + * @param[out] out \ref BtdrvAddress + */ +Result hidGetPalmaBluetoothAddress(HidPalmaConnectionHandle handle, BtdrvAddress *out); + +/** + * @brief SetDisallowedPalmaConnection + * @note Only available on [8.0.0+]. + * @param[in] addrs Input array of \ref BtdrvAddress. + * @param[in] count Total entries in the addrs array. + */ +Result hidSetDisallowedPalmaConnection(const BtdrvAddress *addrs, s32 count); + +///@} + +/** + * @brief SetNpadCommunicationMode + * @note [2.0.0+] Stubbed, just returns 0. + * @param[in] mode \ref HidNpadCommunicationMode + */ +Result hidSetNpadCommunicationMode(HidNpadCommunicationMode mode); + +/** + * @brief GetNpadCommunicationMode + * @note [2.0.0+] Stubbed, always returns output mode ::HidNpadCommunicationMode_Default. + * @param[out] out \ref HidNpadCommunicationMode + */ +Result hidGetNpadCommunicationMode(HidNpadCommunicationMode *out); + +/** + * @brief SetTouchScreenConfiguration + * @note Only available on [9.0.0+]. + * @param[in] config \ref HidTouchScreenConfigurationForNx + */ +Result hidSetTouchScreenConfiguration(const HidTouchScreenConfigurationForNx *config); + +/** + * @brief IsFirmwareUpdateNeededForNotification + * @note Only available on [9.0.0+]. + * @param[out] out Output flag. + */ +Result hidIsFirmwareUpdateNeededForNotification(bool *out); diff --git a/src/libnx/wrapper/switch/services/hid.nim b/src/libnx/wrapper/switch/services/hid.nim new file mode 100644 index 0000000..8c71449 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hid.nim @@ -0,0 +1,2498 @@ +## * +## @file hid.h +## @brief Human input device (hid) service IPC wrapper. +## @author shinyquagsire23 +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/btdrv_types, ../sf/service + +## Begin enums and output structs +## / HidDebugPadButton + +type + HidDebugPadButton* = enum + HidDebugPadButtonA = bit(0), ## /< A button + HidDebugPadButtonB = bit(1), ## /< B button + HidDebugPadButtonX = bit(2), ## /< X button + HidDebugPadButtonY = bit(3), ## /< Y button + HidDebugPadButtonL = bit(4), ## /< L button + HidDebugPadButtonR = bit(5), ## /< R button + HidDebugPadButtonZL = bit(6), ## /< ZL button + HidDebugPadButtonZR = bit(7), ## /< ZR button + HidDebugPadButtonStart = bit(8), ## /< Start button + HidDebugPadButtonSelect = bit(9), ## /< Select button + HidDebugPadButtonLeft = bit(10), ## /< D-Pad Left button + HidDebugPadButtonUp = bit(11), ## /< D-Pad Up button + HidDebugPadButtonRight = bit(12), ## /< D-Pad Right button + HidDebugPadButtonDown = bit(13) ## /< D-Pad Down button + + +## / HidTouchScreenModeForNx + +type + HidTouchScreenModeForNx* = enum + HidTouchScreenModeForNxUseSystemSetting = 0, ## /< UseSystemSetting + HidTouchScreenModeForNxFinger = 1, ## /< Finger + HidTouchScreenModeForNxHeat2 = 2 ## /< Heat2 + + +## / HidMouseButton + +type + HidMouseButton* = enum + HidMouseButtonLeft = bit(0), HidMouseButtonRight = bit(1), + HidMouseButtonMiddle = bit(2), HidMouseButtonForward = bit(3), + HidMouseButtonBack = bit(4) + + +## / HidKeyboardKey + +type + HidKeyboardKey* = enum + HidKeyboardKeyA = 4, HidKeyboardKeyB = 5, HidKeyboardKeyC = 6, HidKeyboardKeyD = 7, + HidKeyboardKeyE = 8, HidKeyboardKeyF = 9, HidKeyboardKeyG = 10, HidKeyboardKeyH = 11, + HidKeyboardKeyI = 12, HidKeyboardKeyJ = 13, HidKeyboardKeyK = 14, + HidKeyboardKeyL = 15, HidKeyboardKeyM = 16, HidKeyboardKeyN = 17, + HidKeyboardKeyO = 18, HidKeyboardKeyP = 19, HidKeyboardKeyQ = 20, + HidKeyboardKeyR = 21, HidKeyboardKeyS = 22, HidKeyboardKeyT = 23, + HidKeyboardKeyU = 24, HidKeyboardKeyV = 25, HidKeyboardKeyW = 26, + HidKeyboardKeyX = 27, HidKeyboardKeyY = 28, HidKeyboardKeyZ = 29, + HidKeyboardKeyD1 = 30, HidKeyboardKeyD2 = 31, HidKeyboardKeyD3 = 32, + HidKeyboardKeyD4 = 33, HidKeyboardKeyD5 = 34, HidKeyboardKeyD6 = 35, + HidKeyboardKeyD7 = 36, HidKeyboardKeyD8 = 37, HidKeyboardKeyD9 = 38, + HidKeyboardKeyD0 = 39, HidKeyboardKeyReturn = 40, HidKeyboardKeyEscape = 41, + HidKeyboardKeyBackspace = 42, HidKeyboardKeyTab = 43, HidKeyboardKeySpace = 44, + HidKeyboardKeyMinus = 45, HidKeyboardKeyPlus = 46, HidKeyboardKeyOpenBracket = 47, + HidKeyboardKeyCloseBracket = 48, HidKeyboardKeyPipe = 49, + HidKeyboardKeyTilde = 50, HidKeyboardKeySemicolon = 51, HidKeyboardKeyQuote = 52, + HidKeyboardKeyBackquote = 53, HidKeyboardKeyComma = 54, HidKeyboardKeyPeriod = 55, + HidKeyboardKeySlash = 56, HidKeyboardKeyCapsLock = 57, HidKeyboardKeyF1 = 58, + HidKeyboardKeyF2 = 59, HidKeyboardKeyF3 = 60, HidKeyboardKeyF4 = 61, + HidKeyboardKeyF5 = 62, HidKeyboardKeyF6 = 63, HidKeyboardKeyF7 = 64, + HidKeyboardKeyF8 = 65, HidKeyboardKeyF9 = 66, HidKeyboardKeyF10 = 67, + HidKeyboardKeyF11 = 68, HidKeyboardKeyF12 = 69, HidKeyboardKeyPrintScreen = 70, + HidKeyboardKeyScrollLock = 71, HidKeyboardKeyPause = 72, + HidKeyboardKeyInsert = 73, HidKeyboardKeyHome = 74, HidKeyboardKeyPageUp = 75, + HidKeyboardKeyDelete = 76, HidKeyboardKeyEnd = 77, HidKeyboardKeyPageDown = 78, + HidKeyboardKeyRightArrow = 79, HidKeyboardKeyLeftArrow = 80, + HidKeyboardKeyDownArrow = 81, HidKeyboardKeyUpArrow = 82, + HidKeyboardKeyNumLock = 83, HidKeyboardKeyNumPadDivide = 84, + HidKeyboardKeyNumPadMultiply = 85, HidKeyboardKeyNumPadSubtract = 86, + HidKeyboardKeyNumPadAdd = 87, HidKeyboardKeyNumPadEnter = 88, + HidKeyboardKeyNumPad1 = 89, HidKeyboardKeyNumPad2 = 90, + HidKeyboardKeyNumPad3 = 91, HidKeyboardKeyNumPad4 = 92, + HidKeyboardKeyNumPad5 = 93, HidKeyboardKeyNumPad6 = 94, + HidKeyboardKeyNumPad7 = 95, HidKeyboardKeyNumPad8 = 96, + HidKeyboardKeyNumPad9 = 97, HidKeyboardKeyNumPad0 = 98, + HidKeyboardKeyNumPadDot = 99, HidKeyboardKeyBackslash = 100, + HidKeyboardKeyApplication = 101, HidKeyboardKeyPower = 102, + HidKeyboardKeyNumPadEquals = 103, HidKeyboardKeyF13 = 104, + HidKeyboardKeyF14 = 105, HidKeyboardKeyF15 = 106, HidKeyboardKeyF16 = 107, + HidKeyboardKeyF17 = 108, HidKeyboardKeyF18 = 109, HidKeyboardKeyF19 = 110, + HidKeyboardKeyF20 = 111, HidKeyboardKeyF21 = 112, HidKeyboardKeyF22 = 113, + HidKeyboardKeyF23 = 114, HidKeyboardKeyF24 = 115, HidKeyboardKeyNumPadComma = 133, + HidKeyboardKeyRo = 135, HidKeyboardKeyKatakanaHiragana = 136, + HidKeyboardKeyYen = 137, HidKeyboardKeyHenkan = 138, HidKeyboardKeyMuhenkan = 139, + HidKeyboardKeyNumPadCommaPc98 = 140, HidKeyboardKeyHangulEnglish = 144, + HidKeyboardKeyHanja = 145, HidKeyboardKeyKatakana = 146, + HidKeyboardKeyHiragana = 147, HidKeyboardKeyZenkakuHankaku = 148, + HidKeyboardKeyLeftControl = 224, HidKeyboardKeyLeftShift = 225, + HidKeyboardKeyLeftAlt = 226, HidKeyboardKeyLeftGui = 227, + HidKeyboardKeyRightControl = 228, HidKeyboardKeyRightShift = 229, + HidKeyboardKeyRightAlt = 230, HidKeyboardKeyRightGui = 231 + + +## / HidKeyboardModifier + +type + HidKeyboardModifier* = enum + HidKeyboardModifierControl = bit(0), HidKeyboardModifierShift = bit(1), + HidKeyboardModifierLeftAlt = bit(2), HidKeyboardModifierRightAlt = bit(3), + HidKeyboardModifierGui = bit(4), HidKeyboardModifierCapsLock = bit(8), + HidKeyboardModifierScrollLock = bit(9), HidKeyboardModifierNumLock = bit(10), + HidKeyboardModifierKatakana = bit(11), HidKeyboardModifierHiragana = bit(12) + + +## / KeyboardLockKeyEvent + +type + HidKeyboardLockKeyEvent* = enum + HidKeyboardLockKeyEventNumLockOn = bit(0), ## /< NumLockOn + HidKeyboardLockKeyEventNumLockOff = bit(1), ## /< NumLockOff + HidKeyboardLockKeyEventNumLockToggle = bit(2), ## /< NumLockToggle + HidKeyboardLockKeyEventCapsLockOn = bit(3), ## /< CapsLockOn + HidKeyboardLockKeyEventCapsLockOff = bit(4), ## /< CapsLockOff + HidKeyboardLockKeyEventCapsLockToggle = bit(5), ## /< CapsLockToggle + HidKeyboardLockKeyEventScrollLockOn = bit(6), ## /< ScrollLockOn + HidKeyboardLockKeyEventScrollLockOff = bit(7), ## /< ScrollLockOff + HidKeyboardLockKeyEventScrollLockToggle = bit(8) ## /< ScrollLockToggle + + +## / HID controller IDs + +type + HidNpadIdType* = enum + HidNpadIdTypeNo1 = 0, ## /< Player 1 controller + HidNpadIdTypeNo2 = 1, ## /< Player 2 controller + HidNpadIdTypeNo3 = 2, ## /< Player 3 controller + HidNpadIdTypeNo4 = 3, ## /< Player 4 controller + HidNpadIdTypeNo5 = 4, ## /< Player 5 controller + HidNpadIdTypeNo6 = 5, ## /< Player 6 controller + HidNpadIdTypeNo7 = 6, ## /< Player 7 controller + HidNpadIdTypeNo8 = 7, ## /< Player 8 controller + HidNpadIdTypeOther = 0x10, ## /< Other controller + HidNpadIdTypeHandheld = 0x20 ## /< Handheld mode controls + + +## / HID controller styles + +type + HidNpadStyleTag* = enum + HidNpadStyleTagNpadFullKey = bit(0), ## /< Pro Controller + HidNpadStyleTagNpadHandheld = bit(1), ## /< Joy-Con controller in handheld mode + HidNpadStyleTagNpadJoyDual = bit(2), ## /< Joy-Con controller in dual mode + HidNpadStyleSetNpadFullCtrl = HidNpadStyleTagNpadFullKey.int or + HidNpadStyleTagNpadHandheld.int or HidNpadStyleTagNpadJoyDual.int, ## /< Style set comprising Npad styles containing the full set of controls {FullKey, Handheld, JoyDual} + HidNpadStyleTagNpadJoyLeft = bit(3), ## /< Joy-Con left controller in single mode + HidNpadStyleTagNpadJoyRight = bit(4), ## /< Joy-Con right controller in single mode + HidNpadStyleSetNpadStandard = HidNpadStyleSetNpadFullCtrl.int or + HidNpadStyleTagNpadJoyLeft.int or HidNpadStyleTagNpadJoyRight.int ## /< Style set comprising all standard Npad styles {FullKey, Handheld, JoyDual, JoyLeft, JoyRight} + HidNpadStyleTagNpadGc = bit(5), ## /< GameCube controller + HidNpadStyleTagNpadPalma = bit(6), ## /< Poké Ball Plus controller + HidNpadStyleTagNpadLark = bit(7), ## /< NES/Famicom controller + HidNpadStyleTagNpadHandheldLark = bit(8), ## /< NES/Famicom controller in handheld mode + HidNpadStyleTagNpadLucia = bit(9), ## /< SNES controller + HidNpadStyleTagNpadLagon = bit(10), ## /< N64 controller + HidNpadStyleTagNpadLager = bit(11), ## /< Sega Genesis controller + HidNpadStyleTagNpadSystemExt = bit(29), ## /< Generic external controller + HidNpadStyleTagNpadSystem = bit(30), ## /< Generic controller + + +## / HidColorAttribute + +type + HidColorAttribute* = enum + HidColorAttributeOk = 0, ## /< Ok + HidColorAttributeReadError = 1, ## /< ReadError + HidColorAttributeNoController = 2 ## /< NoController + + +## / HidNpadButton + +type + HidNpadButton*{.size: sizeof(uint64).} = enum + HidNpadButtonA = bitl(0), ## /< A button / Right face button + HidNpadButtonB = bitl(1), ## /< B button / Down face button + HidNpadButtonX = bitl(2), ## /< X button / Up face button + HidNpadButtonY = bitl(3), ## /< Y button / Left face button + HidNpadButtonStickL = bitl(4), ## /< Left Stick button + HidNpadButtonStickR = bitl(5), ## /< Right Stick button + HidNpadButtonL = bitl(6), ## /< L button + HidNpadButtonR = bitl(7), ## /< R button + HidNpadButtonZL = bitl(8), ## /< ZL button + HidNpadButtonZR = bitl(9), ## /< ZR button + HidNpadButtonPlus = bitl(10), ## /< Plus button + HidNpadButtonMinus = bitl(11), ## /< Minus button + HidNpadButtonLeft = bitl(12), ## /< D-Pad Left button + HidNpadButtonUp = bitl(13), ## /< D-Pad Up button + HidNpadButtonRight = bitl(14), ## /< D-Pad Right button + HidNpadButtonDown = bitl(15), ## /< D-Pad Down button + HidNpadButtonStickLLeft = bitl(16), ## /< Left Stick pseudo-button when moved Left + HidNpadButtonStickLUp = bitl(17), ## /< Left Stick pseudo-button when moved Up + HidNpadButtonStickLRight = bitl(18), ## /< Left Stick pseudo-button when moved Right + HidNpadButtonStickLDown = bitl(19), ## /< Left Stick pseudo-button when moved Down + HidNpadButtonStickRLeft = bitl(20), ## /< Right Stick pseudo-button when moved Left + HidNpadButtonAnyLeft = HidNpadButtonLeft.cint or HidNpadButtonStickLLeft.cint or + HidNpadButtonStickRLeft.cint, ## /< Bitmask containing all buttons that are considered Left (D-Pad, Sticks) + HidNpadButtonStickRUp = bitl(21), ## /< Right Stick pseudo-button when moved Up + HidNpadButtonAnyUp = HidNpadButtonUp.cint or HidNpadButtonStickLUp.cint or + HidNpadButtonStickRUp.cint, ## /< Bitmask containing all buttons that are considered Up (D-Pad, Sticks) + HidNpadButtonStickRRight = bitl(22), ## /< Right Stick pseudo-button when moved Right + HidNpadButtonAnyRight = HidNpadButtonRight.cint or HidNpadButtonStickLRight.cint or + HidNpadButtonStickRRight.cint, ## /< Bitmask containing all buttons that are considered Right (D-Pad, Sticks) + HidNpadButtonStickRDown = bitl(23), ## /< Right Stick pseudo-button when moved Left + HidNpadButtonAnyDown = HidNpadButtonDown.cint or HidNpadButtonStickLDown.cint or + HidNpadButtonStickRDown.cint, ## /< Bitmask containing all buttons that are considered Down (D-Pad, Sticks) + HidNpadButtonLeftSL = bitl(24), ## /< SL button on Left Joy-Con + HidNpadButtonLeftSR = bitl(25), ## /< SR button on Left Joy-Con + HidNpadButtonRightSL = bitl(26), ## /< SL button on Right Joy-Con + HidNpadButtonAnySL = HidNpadButtonLeftSL.cint or HidNpadButtonRightSL.cint, ## /< Bitmask containing SL buttons on both Joy-Cons (Left/Right) + HidNpadButtonRightSR = bitl(27), ## /< SR button on Right Joy-Con + HidNpadButtonAnySR = HidNpadButtonLeftSR.cint or HidNpadButtonRightSR.cint ## /< Bitmask containing SR buttons on both Joy-Cons (Left/Right) + HidNpadButtonPalma = bitl(28), ## /< Top button on Poké Ball Plus (Palma) controller + HidNpadButtonVerification = bitl(29), ## /< Verification + HidNpadButtonHandheldLeftB = bitl(30), ## /< B button on Left NES/HVC controller in Handheld mode + HidNpadButtonLagonCLeft = bitl(31), ## /< Left C button in N64 controller + HidNpadButtonLagonCUp = bitl(32), ## /< Up C button in N64 controller + HidNpadButtonLagonCRight = bitl(33), ## /< Right C button in N64 controller + HidNpadButtonLagonCDown = bitl(34), ## /< Down C button in N64 controller + + +## / HidDebugPadAttribute + +type + HidDebugPadAttribute* = enum + HidDebugPadAttributeIsConnected = bit(0) ## /< IsConnected + + +## / HidTouchAttribute + +type + HidTouchAttribute* = enum + HidTouchAttributeStart = bit(0), ## /< Start + HidTouchAttributeEnd = bit(1) ## /< End + + +## / HidMouseAttribute + +type + HidMouseAttribute* = enum + HidMouseAttributeTransferable = bit(0), ## /< Transferable + HidMouseAttributeIsConnected = bit(1) ## /< IsConnected + + +## / HidNpadAttribute + +type + HidNpadAttribute* = enum + HidNpadAttributeIsConnected = bit(0), ## /< IsConnected + HidNpadAttributeIsWired = bit(1), ## /< IsWired + HidNpadAttributeIsLeftConnected = bit(2), ## /< IsLeftConnected + HidNpadAttributeIsLeftWired = bit(3), ## /< IsLeftWired + HidNpadAttributeIsRightConnected = bit(4), ## /< IsRightConnected + HidNpadAttributeIsRightWired = bit(5) ## /< IsRightWired + + +## / HidSixAxisSensorAttribute + +type + HidSixAxisSensorAttribute* = enum + HidSixAxisSensorAttributeIsConnected = bit(0), ## /< IsConnected + HidSixAxisSensorAttributeIsInterpolated = bit(1) ## /< IsInterpolated + + +## / HidGestureAttribute + +type + HidGestureAttribute* = enum + HidGestureAttributeIsNewTouch = bit(4), ## /< IsNewTouch + HidGestureAttributeIsDoubleTap = bit(8) ## /< IsDoubleTap + + +## / HidGestureDirection + +type + HidGestureDirection* = enum + HidGestureDirectionNone = 0, ## /< None + HidGestureDirectionLeft = 1, ## /< Left + HidGestureDirectionUp = 2, ## /< Up + HidGestureDirectionRight = 3, ## /< Right + HidGestureDirectionDown = 4 ## /< Down + + +## / HidGestureType + +type + HidGestureType* = enum + HidGestureTypeIdle = 0, ## /< Idle + HidGestureTypeComplete = 1, ## /< Complete + HidGestureTypeCancel = 2, ## /< Cancel + HidGestureTypeTouch = 3, ## /< Touch + HidGestureTypePress = 4, ## /< Press + HidGestureTypeTap = 5, ## /< Tap + HidGestureTypePan = 6, ## /< Pan + HidGestureTypeSwipe = 7, ## /< Swipe + HidGestureTypePinch = 8, ## /< Pinch + HidGestureTypeRotate = 9 ## /< Rotate + + +## / GyroscopeZeroDriftMode + +type + HidGyroscopeZeroDriftMode* = enum + HidGyroscopeZeroDriftModeLoose = 0, ## /< Loose + HidGyroscopeZeroDriftModeStandard = 1, ## /< Standard + HidGyroscopeZeroDriftModeTight = 2 ## /< Tight + + +## / NpadJoyHoldType + +type + HidNpadJoyHoldType* = enum + HidNpadJoyHoldTypeVertical = 0, ## /< Default / Joy-Con held vertically. + HidNpadJoyHoldTypeHorizontal = 1 ## /< Joy-Con held horizontally. + + +## / NpadJoyDeviceType + +type + HidNpadJoyDeviceType* = enum + HidNpadJoyDeviceTypeLeft = 0, ## /< Left + HidNpadJoyDeviceTypeRight = 1 ## /< Right + + +## / This controls how many Joy-Cons must be attached for handheld-mode to be activated. + +type + HidNpadHandheldActivationMode* = enum + HidNpadHandheldActivationModeDual = 0, ## /< Dual (2 Joy-Cons) + HidNpadHandheldActivationModeSingle = 1, ## /< Single (1 Joy-Con) + HidNpadHandheldActivationModeNone = 2 ## /< None (0 Joy-Cons) + + +## / NpadJoyAssignmentMode + +type + HidNpadJoyAssignmentMode* = enum + HidNpadJoyAssignmentModeDual = 0, ## /< Dual (Set by \ref hidSetNpadJoyAssignmentModeDual) + HidNpadJoyAssignmentModeSingle = 1 ## /< Single (Set by hidSetNpadJoyAssignmentModeSingle*()) + + +## / NpadCommunicationMode + +type + HidNpadCommunicationMode* = enum + HidNpadCommunicationMode5ms = 0, ## /< 5ms + HidNpadCommunicationMode10ms = 1, ## /< 10ms + HidNpadCommunicationMode15ms = 2, ## /< 15ms + HidNpadCommunicationModeDefault = 3 ## /< Default + + +## / DeviceType (system) + +type + HidDeviceTypeBits* = enum + HidDeviceTypeBitsFullKey = bit(0), ## /< Pro Controller and Gc controller. + HidDeviceTypeBitsDebugPad = bit(1), ## /< DebugPad + HidDeviceTypeBitsHandheldLeft = bit(2), ## /< Joy-Con/Famicom/NES left controller in handheld mode. + HidDeviceTypeBitsHandheldRight = bit(3), ## /< Joy-Con/Famicom/NES right controller in handheld mode. + HidDeviceTypeBitsJoyLeft = bit(4), ## /< Joy-Con left controller. + HidDeviceTypeBitsJoyRight = bit(5), ## /< Joy-Con right controller. + HidDeviceTypeBitsPalma = bit(6), ## /< Poké Ball Plus controller. + HidDeviceTypeBitsLarkHvcLeft = bit(7), ## /< Famicom left controller. + HidDeviceTypeBitsLarkHvcRight = bit(8), ## /< Famicom right controller (with microphone). + HidDeviceTypeBitsLarkNesLeft = bit(9), ## /< NES left controller. + HidDeviceTypeBitsLarkNesRight = bit(10), ## /< NES right controller. + HidDeviceTypeBitsHandheldLarkHvcLeft = bit(11), ## /< Famicom left controller in handheld mode. + HidDeviceTypeBitsHandheldLarkHvcRight = bit(12), ## /< Famicom right controller (with microphone) in handheld mode. + HidDeviceTypeBitsHandheldLarkNesLeft = bit(13), ## /< NES left controller in handheld mode. + HidDeviceTypeBitsHandheldLarkNesRight = bit(14), ## /< NES right controller in handheld mode. + HidDeviceTypeBitsLucia = bit(15), ## /< SNES controller + HidDeviceTypeBitsLagon = bit(16), ## /< N64 controller + HidDeviceTypeBitsLager = bit(17), ## /< Sega Genesis controller + HidDeviceTypeBitsSystem = bit(31) ## /< Generic controller. + + +## / Internal DeviceType for [9.0.0+]. Converted to/from the pre-9.0.0 version of this by the hiddbg funcs. + +type + HidDeviceType* = enum + HidDeviceTypeJoyRight1 = 1, ## /< ::HidDeviceTypeBits_JoyRight + HidDeviceTypeJoyLeft2 = 2, ## /< ::HidDeviceTypeBits_JoyLeft + HidDeviceTypeFullKey3 = 3, ## /< ::HidDeviceTypeBits_FullKey + HidDeviceTypeJoyLeft4 = 4, ## /< ::HidDeviceTypeBits_JoyLeft + HidDeviceTypeJoyRight5 = 5, ## /< ::HidDeviceTypeBits_JoyRight + HidDeviceTypeFullKey6 = 6, ## /< ::HidDeviceTypeBits_FullKey + HidDeviceTypeLarkHvcLeft = 7, ## /< ::HidDeviceTypeBits_LarkHvcLeft, ::HidDeviceTypeBits_HandheldLarkHvcLeft + HidDeviceTypeLarkHvcRight = 8, ## /< ::HidDeviceTypeBits_LarkHvcRight, ::HidDeviceTypeBits_HandheldLarkHvcRight + HidDeviceTypeLarkNesLeft = 9, ## /< ::HidDeviceTypeBits_LarkNesLeft, ::HidDeviceTypeBits_HandheldLarkNesLeft + HidDeviceTypeLarkNesRight = 10, ## /< ::HidDeviceTypeBits_LarkNesRight, ::HidDeviceTypeBits_HandheldLarkNesRight + HidDeviceTypeLucia = 11, ## /< ::HidDeviceTypeBits_Lucia + HidDeviceTypePalma = 12, ## /< [9.0.0+] ::HidDeviceTypeBits_Palma + HidDeviceTypeFullKey13 = 13, ## /< ::HidDeviceTypeBits_FullKey + HidDeviceTypeFullKey15 = 15, ## /< ::HidDeviceTypeBits_FullKey + HidDeviceTypeDebugPad = 17, ## /< ::HidDeviceTypeBits_DebugPad + HidDeviceTypeSystem19 = 19, ## /< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadFullKey. + HidDeviceTypeSystem20 = 20, ## /< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. + HidDeviceTypeSystem21 = 21, ## /< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. + HidDeviceTypeLagon = 22, ## /< ::HidDeviceTypeBits_Lagon + HidDeviceTypeLager = 28 ## /< ::HidDeviceTypeBits_Lager + + +## / AppletFooterUiType (system) + +type + HidAppletFooterUiType* = enum + HidAppletFooterUiTypeNone = 0, ## /< None + HidAppletFooterUiTypeHandheldNone = 1, ## /< HandheldNone + HidAppletFooterUiTypeHandheldJoyConLeftOnly = 2, ## /< HandheldJoyConLeftOnly + HidAppletFooterUiTypeHandheldJoyConRightOnly = 3, ## /< HandheldJoyConRightOnly + HidAppletFooterUiTypeHandheldJoyConLeftJoyConRight = 4, ## /< HandheldJoyConLeftJoyConRight + HidAppletFooterUiTypeJoyDual = 5, ## /< JoyDual + HidAppletFooterUiTypeJoyDualLeftOnly = 6, ## /< JoyDualLeftOnly + HidAppletFooterUiTypeJoyDualRightOnly = 7, ## /< JoyDualRightOnly + HidAppletFooterUiTypeJoyLeftHorizontal = 8, ## /< JoyLeftHorizontal + HidAppletFooterUiTypeJoyLeftVertical = 9, ## /< JoyLeftVertical + HidAppletFooterUiTypeJoyRightHorizontal = 10, ## /< JoyRightHorizontal + HidAppletFooterUiTypeJoyRightVertical = 11, ## /< JoyRightVertical + HidAppletFooterUiTypeSwitchProController = 12, ## /< SwitchProController + HidAppletFooterUiTypeCompatibleProController = 13, ## /< CompatibleProController + HidAppletFooterUiTypeCompatibleJoyCon = 14, ## /< CompatibleJoyCon + HidAppletFooterUiTypeLarkHvc1 = 15, ## /< LarkHvc1 + HidAppletFooterUiTypeLarkHvc2 = 16, ## /< LarkHvc2 + HidAppletFooterUiTypeLarkNesLeft = 17, ## /< LarkNesLeft + HidAppletFooterUiTypeLarkNesRight = 18, ## /< LarkNesRight + HidAppletFooterUiTypeLucia = 19, ## /< Lucia + HidAppletFooterUiTypeVerification = 20, ## /< Verification + HidAppletFooterUiTypeLagon = 21 ## /< [13.0.0+] Lagon + + +## / NpadInterfaceType (system) + +type + HidNpadInterfaceType* = enum + HidNpadInterfaceTypeBluetooth = 1, ## /< Bluetooth. + HidNpadInterfaceTypeRail = 2, ## /< Rail. + HidNpadInterfaceTypeUSB = 3, ## /< USB. + HidNpadInterfaceTypeUnknown4 = 4 ## /< Unknown. + + +## / XcdInterfaceType + +type + XcdInterfaceType* = enum + XcdInterfaceTypeBluetooth = bit(0), XcdInterfaceTypeUart = bit(1), + XcdInterfaceTypeUsb = bit(2), XcdInterfaceTypeFieldSet = bit(7) + + +## / NpadLarkType + +type + HidNpadLarkType* = enum + HidNpadLarkTypeInvalid = 0, ## /< Invalid + HidNpadLarkTypeH1 = 1, ## /< H1 + HidNpadLarkTypeH2 = 2, ## /< H2 + HidNpadLarkTypeNL = 3, ## /< NL + HidNpadLarkTypeNR = 4 ## /< NR + + +## / NpadLuciaType + +type + HidNpadLuciaType* = enum + HidNpadLuciaTypeInvalid = 0, ## /< Invalid + HidNpadLuciaTypeJ = 1, ## /< J + HidNpadLuciaTypeE = 2, ## /< E + HidNpadLuciaTypeU = 3 ## /< U + + +## / NpadLagerType + +type + HidNpadLagerType* = enum + HidNpadLagerTypeInvalid = 0, ## /< Invalid + HidNpadLagerTypeJ = 1, ## /< J + HidNpadLagerTypeE = 2, ## /< E + HidNpadLagerTypeU = 3 ## /< U + + +## / Type values for HidVibrationDeviceInfo::type. + +type + HidVibrationDeviceType* = enum + HidVibrationDeviceTypeUnknown = 0, ## /< Unknown + HidVibrationDeviceTypeLinearResonantActuator = 1, ## /< LinearResonantActuator + HidVibrationDeviceTypeGcErm = 2 ## /< GcErm (::HidNpadStyleTag_NpadGc) + + +## / VibrationDevicePosition + +type + HidVibrationDevicePosition* = enum + HidVibrationDevicePositionNone = 0, ## /< None + HidVibrationDevicePositionLeft = 1, ## /< Left + HidVibrationDevicePositionRight = 2 ## /< Right + + +## / VibrationGcErmCommand + +type + HidVibrationGcErmCommand* = enum + HidVibrationGcErmCommandStop = 0, ## /< Stops the vibration with a decay phase. + HidVibrationGcErmCommandStart = 1, ## /< Starts the vibration. + HidVibrationGcErmCommandStopHard = 2 ## /< Stops the vibration immediately, with no decay phase. + + +## / PalmaOperationType + +type + HidPalmaOperationType* = enum + HidPalmaOperationTypePlayActivity = 0, ## /< PlayActivity + HidPalmaOperationTypeSetFrModeType = 1, ## /< SetFrModeType + HidPalmaOperationTypeReadStep = 2, ## /< ReadStep + HidPalmaOperationTypeEnableStep = 3, ## /< EnableStep + HidPalmaOperationTypeResetStep = 4, ## /< ResetStep + HidPalmaOperationTypeReadApplicationSection = 5, ## /< ReadApplicationSection + HidPalmaOperationTypeWriteApplicationSection = 6, ## /< WriteApplicationSection + HidPalmaOperationTypeReadUniqueCode = 7, ## /< ReadUniqueCode + HidPalmaOperationTypeSetUniqueCodeInvalid = 8, ## /< SetUniqueCodeInvalid + HidPalmaOperationTypeWriteActivityEntry = 9, ## /< WriteActivityEntry + HidPalmaOperationTypeWriteRgbLedPatternEntry = 10, ## /< WriteRgbLedPatternEntry + HidPalmaOperationTypeWriteWaveEntry = 11, ## /< WriteWaveEntry + HidPalmaOperationTypeReadDataBaseIdentificationVersion = 12, ## /< ReadDataBaseIdentificationVersion + HidPalmaOperationTypeWriteDataBaseIdentificationVersion = 13, ## /< WriteDataBaseIdentificationVersion + HidPalmaOperationTypeSuspendFeature = 14, ## /< SuspendFeature + HidPalmaOperationTypeReadPlayLog = 15, ## /< [5.1.0+] ReadPlayLog + HidPalmaOperationTypeResetPlayLog = 16 ## /< [5.1.0+] ResetPlayLog + + +## / PalmaFrModeType + +type + HidPalmaFrModeType* = enum + HidPalmaFrModeTypeOff = 0, ## /< Off + HidPalmaFrModeTypeB01 = 1, ## /< B01 + HidPalmaFrModeTypeB02 = 2, ## /< B02 + HidPalmaFrModeTypeB03 = 3, ## /< B03 + HidPalmaFrModeTypeDownloaded = 4 ## /< Downloaded + + +## / PalmaWaveSet + +type + HidPalmaWaveSet* = enum + HidPalmaWaveSetSmall = 0, ## /< Small + HidPalmaWaveSetMedium = 1, ## /< Medium + HidPalmaWaveSetLarge = 2 ## /< Large + + +## / PalmaFeature + +type + HidPalmaFeature* = enum + HidPalmaFeatureFrMode = bit(0), ## /< FrMode + HidPalmaFeatureRumbleFeedback = bit(1), ## /< RumbleFeedback + HidPalmaFeatureStep = bit(2), ## /< Step + HidPalmaFeatureMuteSwitch = bit(3) ## /< MuteSwitch + + +## / HidAnalogStickState + +type + HidAnalogStickState* {.bycopy.} = object + x*: S32 ## /< X + y*: S32 ## /< Y + + +## / HidVector + +type + HidVector* {.bycopy.} = object + x*: cfloat + y*: cfloat + z*: cfloat + + +## / HidDirectionState + +type + HidDirectionState* {.bycopy.} = object + direction*: array[3, array[3, cfloat]] ## /< 3x3 matrix + + +const + JOYSTICK_MAX* = (0x7FFF) + JOYSTICK_MIN* = (-0x7FFF) + +## End enums and output structs +## / HidCommonLifoHeader + +type + HidCommonLifoHeader* {.bycopy.} = object + unused*: U64 ## /< Unused + bufferCount*: U64 ## /< BufferCount + tail*: U64 ## /< Tail + count*: U64 ## /< Count + + +## Begin HidDebugPad +## / HidDebugPadState + +type + HidDebugPadState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + attributes*: U32 ## /< Bitfield of \ref HidDebugPadAttribute. + buttons*: U32 ## /< Bitfield of \ref HidDebugPadButton. + analogStickR*: HidAnalogStickState ## /< AnalogStickR + analogStickL*: HidAnalogStickState ## /< AnalogStickL + + +## / HidDebugPadStateAtomicStorage + +type + HidDebugPadStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidDebugPadState ## /< \ref HidDebugPadState + + +## / HidDebugPadLifo + +type + HidDebugPadLifo* {.bycopy.} = object + header*: HidCommonLifoHeader ## /< \ref HidCommonLifoHeader + storage*: array[17, HidDebugPadStateAtomicStorage] ## /< \ref HidDebugPadStateAtomicStorage + + +## / HidDebugPadSharedMemoryFormat + +type + HidDebugPadSharedMemoryFormat* {.bycopy.} = object + lifo*: HidDebugPadLifo + padding*: array[0x138, U8] + + +## End HidDebugPad +## Begin HidTouchScreen +## / HidTouchState + +type + HidTouchState* {.bycopy.} = object + deltaTime*: U64 ## /< DeltaTime + attributes*: U32 ## /< Bitfield of \ref HidTouchAttribute. + fingerId*: U32 ## /< FingerId + x*: U32 ## /< X + y*: U32 ## /< Y + diameterX*: U32 ## /< DiameterX + diameterY*: U32 ## /< DiameterY + rotationAngle*: U32 ## /< RotationAngle + reserved*: U32 ## /< Reserved + + +## / HidTouchScreenState + +type + HidTouchScreenState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + count*: S32 ## /< Number of entries in the touches array. + reserved*: U32 ## /< Reserved + touches*: array[16, HidTouchState] ## /< Array of \ref HidTouchState, with the above count. + + +## / HidTouchScreenStateAtomicStorage + +type + HidTouchScreenStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidTouchScreenState ## /< \ref HidTouchScreenState + + +## / HidTouchScreenLifo + +type + HidTouchScreenLifo* {.bycopy.} = object + header*: HidCommonLifoHeader ## /< \ref HidCommonLifoHeader + storage*: array[17, HidTouchScreenStateAtomicStorage] ## /< \ref HidTouchScreenStateAtomicStorage + + +## / HidTouchScreenSharedMemoryFormat + +type + HidTouchScreenSharedMemoryFormat* {.bycopy.} = object + lifo*: HidTouchScreenLifo + padding*: array[0x3c8, U8] + + +## / HidTouchScreenConfigurationForNx + +type + HidTouchScreenConfigurationForNx* {.bycopy.} = object + mode*: U8 ## /< \ref HidTouchScreenModeForNx + reserved*: array[0xF, U8] ## /< Reserved + + +## End HidTouchScreen +## Begin HidMouse +## / HidMouseState + +type + HidMouseState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + x*: S32 ## /< X + y*: S32 ## /< Y + deltaX*: S32 ## /< DeltaX + deltaY*: S32 ## /< DeltaY + wheelDeltaX*: S32 ## /< WheelDeltaX + wheelDeltaY*: S32 ## /< WheelDeltaY + buttons*: U32 ## /< Bitfield of \ref HidMouseButton. + attributes*: U32 ## /< Bitfield of \ref HidMouseAttribute. + + +## / HidMouseStateAtomicStorage + +type + HidMouseStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidMouseState + + +## / HidMouseLifo + +type + HidMouseLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidMouseStateAtomicStorage] + + +## / HidMouseSharedMemoryFormat + +type + HidMouseSharedMemoryFormat* {.bycopy.} = object + lifo*: HidMouseLifo + padding*: array[0xB0, U8] + + +## End HidMouse +## Begin HidKeyboard +## / HidKeyboardState + +type + HidKeyboardState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + modifiers*: U64 ## /< Bitfield of \ref HidKeyboardModifier. + keys*: array[4, U64] + + +## / HidKeyboardStateAtomicStorage + +type + HidKeyboardStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidKeyboardState + + +## / HidKeyboardLifo + +type + HidKeyboardLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidKeyboardStateAtomicStorage] + + +## / HidKeyboardSharedMemoryFormat + +type + HidKeyboardSharedMemoryFormat* {.bycopy.} = object + lifo*: HidKeyboardLifo + padding*: array[0x28, U8] + + +## End HidKeyboard +## Begin HidNpad +## / Npad colors. +## / Color fields are zero when not set. + +type + HidNpadControllerColor* {.bycopy.} = object + main*: U32 ## /< RGBA Body Color + sub*: U32 ## /< RGBA Buttons Color + + +## / HidNpadFullKeyColorState + +type + HidNpadFullKeyColorState* {.bycopy.} = object + attribute*: U32 ## /< \ref HidColorAttribute + fullKey*: HidNpadControllerColor ## /< \ref HidNpadControllerColor FullKey + + +## / HidNpadJoyColorState + +type + HidNpadJoyColorState* {.bycopy.} = object + attribute*: U32 ## /< \ref HidColorAttribute + left*: HidNpadControllerColor ## /< \ref HidNpadControllerColor Left + right*: HidNpadControllerColor ## /< \ref HidNpadControllerColor Right + + +## / HidNpadCommonState + +type + HidNpadCommonState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + buttons*: U64 ## /< Bitfield of \ref HidNpadButton. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + attributes*: U32 ## /< Bitfield of \ref HidNpadAttribute. + reserved*: U32 ## /< Reserved + + HidNpadFullKeyState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadFullKey. + +type + HidNpadHandheldState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadHandheld. + +type + HidNpadJoyDualState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadJoyDual. + +type + HidNpadJoyLeftState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadJoyLeft. + +type + HidNpadJoyRightState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadJoyRight. +## / State for ::HidNpadStyleTag_NpadGc. Loaded from the same lifo as \ref HidNpadFullKeyState, with the additional trigger_l/trigger_r loaded from elsewhere. + +type + HidNpadGcState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + buttons*: U64 ## /< Bitfield of \ref HidNpadButton. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + attributes*: U32 ## /< Bitfield of \ref HidNpadAttribute. + triggerL*: U32 ## /< L analog trigger. Valid range: 0x0-0x7FFF. + triggerR*: U32 ## /< R analog trigger. Valid range: 0x0-0x7FFF. + pad*: U32 + + HidNpadPalmaState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadPalma. +## / State for ::HidNpadStyleTag_NpadLark. The base state is loaded from the same lifo as \ref HidNpadFullKeyState. + +type + HidNpadLarkState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + buttons*: U64 ## /< Bitfield of \ref HidNpadButton. + analogStickL*: HidAnalogStickState ## /< This is always zero. + analogStickR*: HidAnalogStickState ## /< This is always zero. + attributes*: U32 ## /< Bitfield of \ref HidNpadAttribute. + larkTypeLAndMain*: HidNpadLarkType ## /< \ref HidNpadLarkType LarkTypeLAndMain + + +## / State for ::HidNpadStyleTag_NpadHandheldLark. The base state is loaded from the same lifo as \ref HidNpadHandheldState. + +type + HidNpadHandheldLarkState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + buttons*: U64 ## /< Bitfield of \ref HidNpadButton. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + attributes*: U32 ## /< Bitfield of \ref HidNpadAttribute. + larkTypeLAndMain*: HidNpadLarkType ## /< \ref HidNpadLarkType LarkTypeLAndMain + larkTypeR*: HidNpadLarkType ## /< \ref HidNpadLarkType LarkTypeR + pad*: U32 + + +## / State for ::HidNpadStyleTag_NpadLucia. The base state is loaded from the same lifo as \ref HidNpadFullKeyState. + +type + HidNpadLuciaState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + buttons*: U64 ## /< Bitfield of \ref HidNpadButton. + analogStickL*: HidAnalogStickState ## /< This is always zero. + analogStickR*: HidAnalogStickState ## /< This is always zero. + attributes*: U32 ## /< Bitfield of \ref HidNpadAttribute. + luciaType*: HidNpadLuciaType ## /< \ref HidNpadLuciaType + + HidNpadLagerState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadLager. Analog-sticks state are always zero. + +type + HidNpadSystemExtState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadSystemExt. + +type + HidNpadSystemState* = HidNpadCommonState + +## /< State for ::HidNpadStyleTag_NpadSystem. Analog-sticks state are always zero. Only the following button bits are available: HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y, HidNpadButton_Left, HidNpadButton_Up, HidNpadButton_Right, HidNpadButton_Down, HidNpadButton_L, HidNpadButton_R. +## / HidNpadCommonStateAtomicStorage + +type + HidNpadCommonStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidNpadCommonState + + +## / HidNpadCommonLifo + +type + HidNpadCommonLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidNpadCommonStateAtomicStorage] + + +## / HidNpadGcTriggerState + +type + HidNpadGcTriggerState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + triggerL*: U32 + triggerR*: U32 + + +## / HidNpadGcTriggerStateAtomicStorage + +type + HidNpadGcTriggerStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidNpadGcTriggerState + + +## / HidNpadGcTriggerLifo + +type + HidNpadGcTriggerLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidNpadGcTriggerStateAtomicStorage] + + +## / HidSixAxisSensorState + +type + HidSixAxisSensorState* {.bycopy.} = object + deltaTime*: U64 ## /< DeltaTime + samplingNumber*: U64 ## /< SamplingNumber + acceleration*: HidVector ## /< Acceleration + angularVelocity*: HidVector ## /< AngularVelocity + angle*: HidVector ## /< Angle + direction*: HidDirectionState ## /< Direction + attributes*: U32 ## /< Bitfield of \ref HidSixAxisSensorAttribute. + reserved*: U32 ## /< Reserved + + +## / HidSixAxisSensorStateAtomicStorage + +type + HidSixAxisSensorStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidSixAxisSensorState + + +## / HidNpadSixAxisSensorLifo + +type + HidNpadSixAxisSensorLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidSixAxisSensorStateAtomicStorage] + + +## / NpadSystemProperties + +type + HidNpadSystemProperties* {.bycopy.} = object + isCharging* {.bitsize: 3.}: U64 ## /< Use \ref hidGetNpadPowerInfoSingle / \ref hidGetNpadPowerInfoSplit instead of accessing this directly. + isPowered* {.bitsize: 3.}: U64 ## /< Use \ref hidGetNpadPowerInfoSingle / \ref hidGetNpadPowerInfoSplit instead of accessing this directly. + bit6* {.bitsize: 1.}: U64 ## /< Unused + bit7* {.bitsize: 1.}: U64 ## /< Unused + bit8* {.bitsize: 1.}: U64 ## /< Unused + isUnsupportedButtonPressedOnNpadSystem* {.bitsize: 1.}: U64 ## /< IsUnsupportedButtonPressedOnNpadSystem + isUnsupportedButtonPressedOnNpadSystemExt* {.bitsize: 1.}: U64 ## /< IsUnsupportedButtonPressedOnNpadSystemExt + isAbxyButtonOriented* {.bitsize: 1.}: U64 ## /< IsAbxyButtonOriented + isSlSrButtonOriented* {.bitsize: 1.}: U64 ## /< IsSlSrButtonOriented + isPlusAvailable* {.bitsize: 1.}: U64 ## /< [4.0.0+] IsPlusAvailable + isMinusAvailable* {.bitsize: 1.}: U64 ## /< [4.0.0+] IsMinusAvailable + isDirectionalButtonsAvailable* {.bitsize: 1.}: U64 ## /< [8.0.0+] IsDirectionalButtonsAvailable + unused* {.bitsize: 48.}: U64 ## /< Unused + + +## / NpadSystemButtonProperties + +type + HidNpadSystemButtonProperties* {.bycopy.} = object + isUnintendedHomeButtonInputProtectionEnabled* {.bitsize: 1.}: U32 ## /< IsUnintendedHomeButtonInputProtectionEnabled + + +## / HidPowerInfo (system) + +type + HidPowerInfo* {.bycopy.} = object + isPowered*: bool ## /< IsPowered + isCharging*: bool ## /< IsCharging + reserved*: array[6, U8] ## /< Reserved + batteryLevel*: U32 ## /< BatteryLevel, always 0-4. + + +## / XcdDeviceHandle + +type + XcdDeviceHandle* {.bycopy.} = object + handle*: U64 + + +## / HidNfcXcdDeviceHandleStateImpl + +type + HidNfcXcdDeviceHandleStateImpl* {.bycopy.} = object + handle*: XcdDeviceHandle + isAvailable*: U8 + isActivated*: U8 + reserved*: array[6, U8] + samplingNumber*: U64 ## /< SamplingNumber + + +## / HidNfcXcdDeviceHandleStateImplAtomicStorage + +type + HidNfcXcdDeviceHandleStateImplAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidNfcXcdDeviceHandleStateImpl ## /< \ref HidNfcXcdDeviceHandleStateImpl + + +## / HidNfcXcdDeviceHandleState + +type + HidNfcXcdDeviceHandleState* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[2, HidNfcXcdDeviceHandleStateImplAtomicStorage] + + +## / HidNpadInternalState + +type + INNER_C_STRUCT_hid_7* {.bycopy.} = object + nfcXcdDeviceHandle*: HidNfcXcdDeviceHandleState ## [1.0.0-3.0.2] + + INNER_C_STRUCT_hid_9* {.bycopy.} = object + appletFooterUiAttribute*: U32 ## /< Bitfield of AppletFooterUiAttribute. + appletFooterUiType*: U8 ## /< \ref HidAppletFooterUiType + reservedX41AD*: array[0x5B, U8] + + INNER_C_UNION_hid_6* {.bycopy, union.} = object + anoHid8*: INNER_C_STRUCT_hid_7 + anoHid10*: INNER_C_STRUCT_hid_9 + + HidNpadInternalState* {.bycopy.} = object + styleSet*: U32 ## /< Bitfield of \ref HidNpadStyleTag. + joyAssignmentMode*: U32 ## /< \ref HidNpadJoyAssignmentMode + fullKeyColor*: HidNpadFullKeyColorState ## /< \ref HidNpadFullKeyColorState + joyColor*: HidNpadJoyColorState ## /< \ref HidNpadJoyColorState + fullKeyLifo*: HidNpadCommonLifo ## /< FullKeyLifo + handheldLifo*: HidNpadCommonLifo ## /< HandheldLifo + joyDualLifo*: HidNpadCommonLifo ## /< JoyDualLifo + joyLeftLifo*: HidNpadCommonLifo ## /< JoyLeftLifo + joyRightLifo*: HidNpadCommonLifo ## /< JoyRightLifo + palmaLifo*: HidNpadCommonLifo ## /< PalmaLifo + systemExtLifo*: HidNpadCommonLifo ## /< SystemExtLifo + fullKeySixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< FullKeySixAxisSensorLifo + handheldSixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< HandheldSixAxisSensorLifo + joyDualLeftSixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< JoyDualLeftSixAxisSensorLifo + joyDualRightSixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< JoyDualRightSixAxisSensorLifo + joyLeftSixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< JoyLeftSixAxisSensorLifo + joyRightSixAxisSensorLifo*: HidNpadSixAxisSensorLifo ## /< JoyRightSixAxisSensorLifo + deviceType*: U32 ## /< Bitfield of \ref HidDeviceTypeBits. + reserved*: U32 ## /< Reserved + systemProperties*: HidNpadSystemProperties + systemButtonProperties*: HidNpadSystemButtonProperties + batteryLevel*: array[3, U32] + anoHid11*: INNER_C_UNION_hid_6 + reservedX4208*: array[0x20, U8] ## /< Mutex on pre-10.0.0. + gcTriggerLifo*: HidNpadGcTriggerLifo + larkTypeLAndMain*: U32 ## /< \ref HidNpadLarkType + larkTypeR*: U32 ## /< \ref HidNpadLarkType + luciaType*: U32 ## /< \ref HidNpadLuciaType + lagerType*: U32 ## /< \ref HidNpadLagerType + + +## / HidNpadSharedMemoryEntry + +type + HidNpadSharedMemoryEntry* {.bycopy.} = object + internalState*: HidNpadInternalState + pad*: array[0xC10, U8] + + +## / HidNpadSharedMemoryFormat + +type + HidNpadSharedMemoryFormat* {.bycopy.} = object + entries*: array[10, HidNpadSharedMemoryEntry] + + +## End HidNpad +## Begin HidGesture +## / HidGesturePoint + +type + HidGesturePoint* {.bycopy.} = object + x*: U32 ## /< X + y*: U32 ## /< Y + + +## / HidGestureState + +type + HidGestureState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + contextNumber*: U64 ## /< ContextNumber + `type`*: U32 ## /< \ref HidGestureType + direction*: U32 ## /< \ref HidGestureDirection + x*: U32 ## /< X + y*: U32 ## /< Y + deltaX*: S32 ## /< DeltaX + deltaY*: S32 ## /< DeltaY + velocityX*: cfloat ## /< VelocityX + velocityY*: cfloat ## /< VelocityY + attributes*: U32 ## /< Bitfield of \ref HidGestureAttribute. + scale*: cfloat ## /< Scale + rotationAngle*: cfloat ## /< RotationAngle + pointCount*: S32 ## /< Number of entries in the points array. + points*: array[4, HidGesturePoint] ## /< Array of \ref HidGesturePoint with the above count. + + +## / HidGestureDummyStateAtomicStorage + +type + HidGestureDummyStateAtomicStorage* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + state*: HidGestureState + + +## / HidGestureLifo + +type + HidGestureLifo* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[17, HidGestureDummyStateAtomicStorage] + + +## / HidGestureSharedMemoryFormat + +type + HidGestureSharedMemoryFormat* {.bycopy.} = object + lifo*: HidGestureLifo + pad*: array[0xF8, U8] + + +## End HidGesture +## / HidConsoleSixAxisSensor + +type + HidConsoleSixAxisSensor* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + isSevenSixAxisSensorAtRest*: U8 ## /< IsSevenSixAxisSensorAtRest + pad*: array[0x3, U8] ## /< Padding + verticalizationError*: cfloat ## /< VerticalizationError + gyroBias*: UtilFloat3 ## /< GyroBias + pad2*: array[0x4, U8] ## /< Padding + + +## / HidSharedMemory + +type + HidSharedMemory* {.bycopy.} = object + debugPad*: HidDebugPadSharedMemoryFormat + touchscreen*: HidTouchScreenSharedMemoryFormat + mouse*: HidMouseSharedMemoryFormat + keyboard*: HidKeyboardSharedMemoryFormat + digitizer*: array[0x1000, U8] ## /< [10.0.0+] Digitizer [1.0.0-9.2.0] BasicXpad + homeButton*: array[0x200, U8] + sleepButton*: array[0x200, U8] + captureButton*: array[0x200, U8] + inputDetector*: array[0x800, U8] + uniquePad*: array[0x4000, U8] ## /< [1.0.0-4.1.0] UniquePad + npad*: HidNpadSharedMemoryFormat + gesture*: HidGestureSharedMemoryFormat + consoleSixAxisSensor*: HidConsoleSixAxisSensor ## /< [5.0.0+] ConsoleSixAxisSensor + unkX3C220*: array[0x3DE0, U8] + + +## / HidSevenSixAxisSensorState + +type + HidSevenSixAxisSensorState* {.bycopy.} = object + timestamp0*: U64 + samplingNumber*: U64 + unkX10*: U64 + unkX18*: array[10, cfloat] + + +## / HidSevenSixAxisSensorStateEntry + +type + HidSevenSixAxisSensorStateEntry* {.bycopy.} = object + samplingNumber*: U64 + unused*: U64 + state*: HidSevenSixAxisSensorState + + +## / HidSevenSixAxisSensorStates + +type + HidSevenSixAxisSensorStates* {.bycopy.} = object + header*: HidCommonLifoHeader + storage*: array[0x21, HidSevenSixAxisSensorStateEntry] + + +## / HidSixAxisSensorHandle + +type + INNER_C_STRUCT_hid_14* {.bycopy.} = object + npadStyleIndex* {.bitsize: 8.}: U32 ## /< NpadStyleIndex + playerNumber* {.bitsize: 8.}: U32 ## /< PlayerNumber + deviceIdx* {.bitsize: 8.}: U32 ## /< DeviceIdx + pad* {.bitsize: 8.}: U32 ## /< Padding + + HidSixAxisSensorHandle* {.bycopy, union.} = object + typeValue*: U32 ## /< TypeValue + anoHid15*: INNER_C_STRUCT_hid_14 + + +## / HidVibrationDeviceHandle + +type + INNER_C_STRUCT_hid_18* {.bycopy.} = object + npadStyleIndex* {.bitsize: 8.}: U32 ## /< NpadStyleIndex + playerNumber* {.bitsize: 8.}: U32 ## /< PlayerNumber + deviceIdx* {.bitsize: 8.}: U32 ## /< DeviceIdx + pad* {.bitsize: 8.}: U32 ## /< Padding + + HidVibrationDeviceHandle* {.bycopy, union.} = object + typeValue*: U32 ## /< TypeValue + anoHid19*: INNER_C_STRUCT_hid_18 + + +## / HidVibrationDeviceInfo + +type + HidVibrationDeviceInfo* {.bycopy.} = object + `type`*: U32 ## /< \ref HidVibrationDeviceType + position*: U32 ## /< \ref HidVibrationDevicePosition + + +## / HidVibrationValue + +type + HidVibrationValue* {.bycopy.} = object + ampLow*: cfloat ## /< Low Band amplitude. 1.0f: Max amplitude. + freqLow*: cfloat ## /< Low Band frequency in Hz. + ampHigh*: cfloat ## /< High Band amplitude. 1.0f: Max amplitude. + freqHigh*: cfloat ## /< High Band frequency in Hz. + + +## / PalmaConnectionHandle + +type + HidPalmaConnectionHandle* {.bycopy.} = object + handle*: U64 ## /< Handle + + +## / PalmaOperationInfo + +type + HidPalmaOperationInfo* {.bycopy.} = object + `type`*: U32 ## /< \ref HidPalmaOperationType + res*: Result ## /< Result + data*: array[0x140, U8] ## /< Data + + +## / PalmaApplicationSectionAccessBuffer + +type + HidPalmaApplicationSectionAccessBuffer* {.bycopy.} = object + data*: array[0x100, U8] ## /< Application data. + + +## / PalmaActivityEntry + +type + HidPalmaActivityEntry* {.bycopy.} = object + rgbLedPatternIndex*: U16 ## /< RgbLedPatternIndex + pad*: U16 ## /< Padding + waveSet*: U32 ## /< \ref HidPalmaWaveSet + waveIndex*: U16 ## /< WaveIndex + +proc hidInitialize*(): Result {.cdecl, importc: "hidInitialize".} +## / Initialize hid. Called automatically during app startup. + +proc hidExit*() {.cdecl, importc: "hidExit".} +## / Exit hid. Called automatically during app exit. + +proc hidGetServiceSession*(): ptr Service {.cdecl, importc: "hidGetServiceSession".} +## / Gets the Service object for the actual hid service session. + +proc hidGetSharedmemAddr*(): pointer {.cdecl, importc: "hidGetSharedmemAddr".} +## / Gets the address of the SharedMemory. + +proc hidInitializeTouchScreen*() {.cdecl, importc: "hidInitializeTouchScreen".} +## /@name TouchScreen +## /@{ +## / Initialize TouchScreen. Must be called when TouchScreen is being used. Used automatically by \ref hidScanInput when required. + +proc hidGetTouchScreenStates*(states: ptr HidTouchScreenState; count: csize_t): csize_t {. + cdecl, importc: "hidGetTouchScreenStates".} +## * +## @brief Gets \ref HidTouchScreenState. +## @param[out] states Output array of \ref HidTouchScreenState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidInitializeMouse*() {.cdecl, importc: "hidInitializeMouse".} +## /@} +## /@name Mouse +## /@{ +## / Initialize Mouse. Must be called when Mouse is being used. Used automatically by \ref hidScanInput when required. + +proc hidGetMouseStates*(states: ptr HidMouseState; count: csize_t): csize_t {.cdecl, + importc: "hidGetMouseStates".} +## * +## @brief Gets \ref HidMouseState. +## @param[out] states Output array of \ref HidMouseState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidInitializeKeyboard*() {.cdecl, importc: "hidInitializeKeyboard".} +## /@} +## /@name Keyboard +## /@{ +## / Initialize Keyboard. Must be called when Keyboard is being used. Used automatically by \ref hidScanInput when required. + +proc hidGetKeyboardStates*(states: ptr HidKeyboardState; count: csize_t): csize_t {. + cdecl, importc: "hidGetKeyboardStates".} +## * +## @brief Gets \ref HidKeyboardState. +## @param[out] states Output array of \ref HidKeyboardState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidKeyboardStateGetKey*(state: ptr HidKeyboardState; key: HidKeyboardKey): bool {. + inline, cdecl.} = + ## * + ## @brief Gets the state of a key in a \ref HidKeyboardState. + ## @param[in] state \ref HidKeyboardState. + ## @param[in] key \ref HidKeyboardKey. + ## @return true if the key is pressed, false if not. + ## + return (state.keys[key.uint64 div 64] and (1'u32 shl (key.uint64 and 63))) != 0 + +proc hidInitializeNpad*() {.cdecl, importc: "hidInitializeNpad".} +## /@} +## /@name Npad +## /@{ +## / Initialize Npad. Must be called when Npad is being used. Used automatically by \ref hidScanInput when required. + +proc hidGetNpadStyleSet*(id: HidNpadIdType): U32 {.cdecl, + importc: "hidGetNpadStyleSet".} +## * +## @brief Gets the StyleSet for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @return Bitfield of \ref HidNpadStyleTag. +## + +proc hidGetNpadJoyAssignment*(id: HidNpadIdType): HidNpadJoyAssignmentMode {.cdecl, + importc: "hidGetNpadJoyAssignment".} +## * +## @brief Gets the \ref HidNpadJoyAssignmentMode for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @return \ref HidNpadJoyAssignmentMode +## + +proc hidGetNpadControllerColorSingle*(id: HidNpadIdType; + color: ptr HidNpadControllerColor): Result {. + cdecl, importc: "hidGetNpadControllerColorSingle".} +## * +## @brief Gets the main \ref HidNpadControllerColor for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @param[out] color \ref HidNpadControllerColor +## + +proc hidGetNpadControllerColorSplit*(id: HidNpadIdType; + colorLeft: ptr HidNpadControllerColor; + colorRight: ptr HidNpadControllerColor): Result {. + cdecl, importc: "hidGetNpadControllerColorSplit".} +## * +## @brief Gets the left/right \ref HidNpadControllerColor for the specified Npad (Joy-Con pair in dual mode). +## @param[in] id \ref HidNpadIdType +## @param[out] color_left \ref HidNpadControllerColor +## @param[out] color_right \ref HidNpadControllerColor +## + +proc hidGetNpadDeviceType*(id: HidNpadIdType): U32 {.cdecl, + importc: "hidGetNpadDeviceType".} +## * +## @brief Gets the DeviceType for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @return Bitfield of \ref HidDeviceTypeBits. +## + +proc hidGetNpadSystemProperties*(id: HidNpadIdType; + `out`: ptr HidNpadSystemProperties) {.cdecl, + importc: "hidGetNpadSystemProperties".} +## * +## @brief Gets the \ref HidNpadSystemProperties for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @param[out] out \ref HidNpadSystemProperties +## + +proc hidGetNpadSystemButtonProperties*(id: HidNpadIdType; + `out`: ptr HidNpadSystemButtonProperties) {. + cdecl, importc: "hidGetNpadSystemButtonProperties".} +## * +## @brief Gets the \ref HidNpadSystemButtonProperties for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @param[out] out \ref HidNpadSystemButtonProperties +## + +proc hidGetNpadPowerInfoSingle*(id: HidNpadIdType; info: ptr HidPowerInfo) {.cdecl, + importc: "hidGetNpadPowerInfoSingle".} +## * +## @brief Gets the main \ref HidPowerInfo for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @param[out] info \ref HidPowerInfo +## + +proc hidGetNpadPowerInfoSplit*(id: HidNpadIdType; infoLeft: ptr HidPowerInfo; + infoRight: ptr HidPowerInfo) {.cdecl, + importc: "hidGetNpadPowerInfoSplit".} +## * +## @brief Gets the left/right \ref HidPowerInfo for the specified Npad (Joy-Con pair in dual mode). +## @param[in] id \ref HidNpadIdType +## @param[out] info_left \ref HidPowerInfo +## @param[out] info_right \ref HidPowerInfo +## + +proc hidGetAppletFooterUiAttributesSet*(id: HidNpadIdType): U32 {.cdecl, + importc: "hidGetAppletFooterUiAttributesSet".} +## * +## @brief Gets the AppletFooterUiAttributesSet for the specified Npad. +## @note Only available on [9.0.0+]. +## @param[in] id \ref HidNpadIdType +## @return Bitfield of AppletFooterUiAttribute (system). +## + +proc hidGetAppletFooterUiTypes*(id: HidNpadIdType): HidAppletFooterUiType {.cdecl, + importc: "hidGetAppletFooterUiTypes".} +## * +## @brief Gets \ref HidAppletFooterUiType for the specified Npad. +## @note Only available on [9.0.0+]. +## @param[in] id \ref HidNpadIdType +## @return \ref HidAppletFooterUiType +## + +proc hidGetNpadLagerType*(id: HidNpadIdType): HidNpadLagerType {.cdecl, + importc: "hidGetNpadLagerType".} +## * +## @brief Gets \ref HidNpadLagerType for the specified Npad. +## @param[in] id \ref HidNpadIdType +## @return \ref HidNpadLagerType +## + +proc hidGetNpadStatesFullKey*(id: HidNpadIdType; states: ptr HidNpadFullKeyState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesFullKey".} +## * +## @brief Gets \ref HidNpadFullKeyState. +## @param[out] states Output array of \ref HidNpadFullKeyState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesHandheld*(id: HidNpadIdType; states: ptr HidNpadHandheldState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesHandheld".} +## * +## @brief Gets \ref HidNpadHandheldState. +## @param[out] states Output array of \ref HidNpadHandheldState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesJoyDual*(id: HidNpadIdType; states: ptr HidNpadJoyDualState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesJoyDual".} +## * +## @brief Gets \ref HidNpadJoyDualState. +## @param[out] states Output array of \ref HidNpadJoyDualState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesJoyLeft*(id: HidNpadIdType; states: ptr HidNpadJoyLeftState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesJoyLeft".} +## * +## @brief Gets \ref HidNpadJoyLeftState. +## @param[out] states Output array of \ref HidNpadJoyLeftState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesJoyRight*(id: HidNpadIdType; states: ptr HidNpadJoyRightState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesJoyRight".} +## * +## @brief Gets \ref HidNpadJoyRightState. +## @param[out] states Output array of \ref HidNpadJoyRightState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesGc*(id: HidNpadIdType; states: ptr HidNpadGcState; count: csize_t): csize_t {. + cdecl, importc: "hidGetNpadStatesGc".} +## * +## @brief Gets \ref HidNpadGcState. +## @param[out] states Output array of \ref HidNpadGcState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesPalma*(id: HidNpadIdType; states: ptr HidNpadPalmaState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesPalma".} +## * +## @brief Gets \ref HidNpadPalmaState. +## @param[out] states Output array of \ref HidNpadPalmaState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesLark*(id: HidNpadIdType; states: ptr HidNpadLarkState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesLark".} +## * +## @brief Gets \ref HidNpadLarkState. +## @param[out] states Output array of \ref HidNpadLarkState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesHandheldLark*(id: HidNpadIdType; + states: ptr HidNpadHandheldLarkState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesHandheldLark".} +## * +## @brief Gets \ref HidNpadHandheldLarkState. +## @param[out] states Output array of \ref HidNpadHandheldLarkState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesLucia*(id: HidNpadIdType; states: ptr HidNpadLuciaState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesLucia".} +## * +## @brief Gets \ref HidNpadLuciaState. +## @param[out] states Output array of \ref HidNpadLuciaState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesLager*(id: HidNpadIdType; states: ptr HidNpadLagerState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesLager".} +## * +## @brief Gets \ref HidNpadLagerState. +## @param[out] states Output array of \ref HidNpadLagerState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesSystemExt*(id: HidNpadIdType; + states: ptr HidNpadSystemExtState; count: csize_t): csize_t {. + cdecl, importc: "hidGetNpadStatesSystemExt".} +## * +## @brief Gets \ref HidNpadSystemExtState. +## @param[out] states Output array of \ref HidNpadSystemExtState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetNpadStatesSystem*(id: HidNpadIdType; states: ptr HidNpadSystemState; + count: csize_t): csize_t {.cdecl, + importc: "hidGetNpadStatesSystem".} +## * +## @brief Gets \ref HidNpadSystemState. +## @param[out] states Output array of \ref HidNpadSystemState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidGetSixAxisSensorStates*(handle: HidSixAxisSensorHandle; + states: ptr HidSixAxisSensorState; count: csize_t): csize_t {. + cdecl, importc: "hidGetSixAxisSensorStates".} +## * +## @brief Gets \ref HidSixAxisSensorState for the specified handle. +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] states Output array of \ref HidSixAxisSensorState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidInitializeGesture*() {.cdecl, importc: "hidInitializeGesture".} +## /@} +## /@name Gesture +## /@{ +## / Initialize Gesture. Must be called when Gesture is being used. +proc hidGetGestureStates*(states: ptr HidGestureState; count: csize_t): csize_t {. + cdecl, importc: "hidGetGestureStates".} +## * +## @brief Gets \ref HidGestureState. +## @param[out] states Output array of \ref HidGestureState. +## @param[in] count Size of the states array in entries. +## @return Total output entries. +## + +proc hidSendKeyboardLockKeyEvent*(events: U32): Result {.cdecl, + importc: "hidSendKeyboardLockKeyEvent".} +## /@} +## * +## @brief SendKeyboardLockKeyEvent +## @note Same as \ref hidsysSendKeyboardLockKeyEvent. +## @note Only available on [6.0.0+]. +## @param[in] events Bitfield of \ref HidKeyboardLockKeyEvent. +## + +proc hidGetSixAxisSensorHandles*(handles: ptr HidSixAxisSensorHandle; + totalHandles: S32; id: HidNpadIdType; + style: HidNpadStyleTag): Result {.cdecl, + importc: "hidGetSixAxisSensorHandles".} +## * +## @brief Gets SixAxisSensorHandles. +## @note Only ::HidNpadStyleTag_NpadJoyDual supports total_handles==2. +## @param[out] handles Output array of \ref HidSixAxisSensorHandle. +## @param[in] total_handles Total handles for the handles array. Must be 1 or 2, if 2 handles aren't supported by the specified style an error is thrown. +## @param[in] id \ref HidNpadIdType +## @param[in] style \ref HidNpadStyleTag +## + +proc hidStartSixAxisSensor*(handle: HidSixAxisSensorHandle): Result {.cdecl, + importc: "hidStartSixAxisSensor".} +## * +## @brief Starts the SixAxisSensor for the specified handle. +## @param[in] handle \ref HidSixAxisSensorHandle +## + +proc hidStopSixAxisSensor*(handle: HidSixAxisSensorHandle): Result {.cdecl, + importc: "hidStopSixAxisSensor".} +## * +## @brief Stops the SixAxisSensor for the specified handle. +## @param[in] handle \ref HidSixAxisSensorHandle +## + +proc hidIsSixAxisSensorFusionEnabled*(handle: HidSixAxisSensorHandle; + `out`: ptr bool): Result {.cdecl, + importc: "hidIsSixAxisSensorFusionEnabled".} +## * +## @brief IsSixAxisSensorFusionEnabled +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] out Output flag. +## + +proc hidEnableSixAxisSensorFusion*(handle: HidSixAxisSensorHandle; flag: bool): Result {. + cdecl, importc: "hidEnableSixAxisSensorFusion".} +## * +## @brief EnableSixAxisSensorFusion +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[in] flag Flag +## + +proc hidSetSixAxisSensorFusionParameters*(handle: HidSixAxisSensorHandle; + unk0: cfloat; unk1: cfloat): Result {.cdecl, importc: "hidSetSixAxisSensorFusionParameters".} +## * +## @brief SetSixAxisSensorFusionParameters +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[in] unk0 Must be 0.0f-1.0f. +## @param[in] unk1 Unknown +## + +proc hidGetSixAxisSensorFusionParameters*(handle: HidSixAxisSensorHandle; + unk0: ptr cfloat; unk1: ptr cfloat): Result {.cdecl, + importc: "hidGetSixAxisSensorFusionParameters".} +## * +## @brief GetSixAxisSensorFusionParameters +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] unk0 Unknown +## @param[out] unk1 Unknown +## + +proc hidResetSixAxisSensorFusionParameters*(handle: HidSixAxisSensorHandle): Result {. + cdecl, importc: "hidResetSixAxisSensorFusionParameters".} +## * +## @brief ResetSixAxisSensorFusionParameters +## @param[in] handle \ref HidSixAxisSensorHandle +## + +proc hidSetGyroscopeZeroDriftMode*(handle: HidSixAxisSensorHandle; + mode: HidGyroscopeZeroDriftMode): Result {.cdecl, + importc: "hidSetGyroscopeZeroDriftMode".} +## * +## @brief Sets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle. +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[in] mode \ref HidGyroscopeZeroDriftMode +## + +proc hidGetGyroscopeZeroDriftMode*(handle: HidSixAxisSensorHandle; + mode: ptr HidGyroscopeZeroDriftMode): Result {. + cdecl, importc: "hidGetGyroscopeZeroDriftMode".} +## * +## @brief Gets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle. +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] mode \ref HidGyroscopeZeroDriftMode +## + +proc hidResetGyroscopeZeroDriftMode*(handle: HidSixAxisSensorHandle): Result {. + cdecl, importc: "hidResetGyroscopeZeroDriftMode".} +## * +## @brief Resets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle to ::HidGyroscopeZeroDriftMode_Standard. +## @param[in] handle \ref HidSixAxisSensorHandle +## + +proc hidIsSixAxisSensorAtRest*(handle: HidSixAxisSensorHandle; `out`: ptr bool): Result {. + cdecl, importc: "hidIsSixAxisSensorAtRest".} +## * +## @brief IsSixAxisSensorAtRest +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] out Output flag. +## + +proc hidIsFirmwareUpdateAvailableForSixAxisSensor*( + handle: HidSixAxisSensorHandle; `out`: ptr bool): Result {.cdecl, + importc: "hidIsFirmwareUpdateAvailableForSixAxisSensor".} +## * +## @brief IsFirmwareUpdateAvailableForSixAxisSensor +## @note Only available on [6.0.0+]. +## @param[in] handle \ref HidSixAxisSensorHandle +## @param[out] out Output flag. +## + +proc hidSetSupportedNpadStyleSet*(styleSet: U32): Result {.cdecl, + importc: "hidSetSupportedNpadStyleSet".} +## * +## @brief Sets which controller styles are supported. +## @note This is automatically called with the needed styles in \ref hidScanInput when required. +## @param[in] style_set Bitfield of \ref HidNpadStyleTag. +## + +proc hidGetSupportedNpadStyleSet*(styleSet: ptr U32): Result {.cdecl, + importc: "hidGetSupportedNpadStyleSet".} +## * +## @brief Gets which controller styles are supported. +## @param[out] style_set Bitfield of \ref HidNpadStyleTag. +## + +proc hidSetSupportedNpadIdType*(ids: ptr HidNpadIdType; count: csize_t): Result {. + cdecl, importc: "hidSetSupportedNpadIdType".} +## * +## @brief Sets which \ref HidNpadIdType are supported. +## @note This is automatically called with HidNpadIdType_No{1-8} and HidNpadIdType_Handheld when required in \ref hidScanInput. +## @param[in] ids Input array of \ref HidNpadIdType. +## @param[in] count Total entries in the ids array. Must be <=10. +## + +proc hidAcquireNpadStyleSetUpdateEventHandle*(id: HidNpadIdType; + outEvent: ptr Event; autoclear: bool): Result {.cdecl, + importc: "hidAcquireNpadStyleSetUpdateEventHandle".} +## * +## @brief Gets an Event which is signaled when the \ref hidGetNpadStyleSet output is updated for the specified controller. +## @note The Event must be closed by the user once finished with it. +## @param[in] id \ref HidNpadIdType +## @param[out] out_event Output Event. +## @param[in] autoclear The autoclear for the Event. +## + +proc hidDisconnectNpad*(id: HidNpadIdType): Result {.cdecl, + importc: "hidDisconnectNpad".} +## * +## @brief DisconnectNpad +## @param[in] id \ref HidNpadIdType +## + +proc hidGetPlayerLedPattern*(id: HidNpadIdType; `out`: ptr U8): Result {.cdecl, + importc: "hidGetPlayerLedPattern".} +## * +## @brief GetPlayerLedPattern +## @param[in] id \ref HidNpadIdType +## @param[out] out Output value. +## + +proc hidSetNpadJoyHoldType*(`type`: HidNpadJoyHoldType): Result {.cdecl, + importc: "hidSetNpadJoyHoldType".} +## * +## @brief Sets the \ref HidNpadJoyHoldType. +## @note Used automatically by \ref hidScanInput when required. +## @param[in] type \ref HidNpadJoyHoldType +## + +proc hidGetNpadJoyHoldType*(`type`: ptr HidNpadJoyHoldType): Result {.cdecl, + importc: "hidGetNpadJoyHoldType".} +## * +## @brief Gets the \ref HidNpadJoyHoldType. +## @param[out] type \ref HidNpadJoyHoldType +## + +proc hidSetNpadJoyAssignmentModeSingleByDefault*(id: HidNpadIdType): Result {.cdecl, + importc: "hidSetNpadJoyAssignmentModeSingleByDefault".} +## * +## @brief This is the same as \ref hidSetNpadJoyAssignmentModeSingle, except ::HidNpadJoyDeviceType_Left is used for the type. +## @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. +## + +proc hidSetNpadJoyAssignmentModeSingle*(id: HidNpadIdType; + `type`: HidNpadJoyDeviceType): Result {. + cdecl, importc: "hidSetNpadJoyAssignmentModeSingle".} +## * +## @brief This is the same as \ref hidSetNpadJoyAssignmentModeSingleWithDestination, except without the output params. +## @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. +## @param[in] type \ref HidNpadJoyDeviceType +## + +proc hidSetNpadJoyAssignmentModeDual*(id: HidNpadIdType): Result {.cdecl, + importc: "hidSetNpadJoyAssignmentModeDual".} +## * +## @brief Use this if you want to use a pair of joy-cons as a single HidNpadIdType_No*. When used, both joy-cons in a pair should be used with this (HidNpadIdType_No1 and HidNpadIdType_No2 for example). +## @note Used automatically by \ref hidScanInput when required. +## @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. +## + +proc hidMergeSingleJoyAsDualJoy*(id0: HidNpadIdType; id1: HidNpadIdType): Result {. + cdecl, importc: "hidMergeSingleJoyAsDualJoy".} +## * +## @brief Merge two single joy-cons into a dual-mode controller. Use this after \ref hidSetNpadJoyAssignmentModeDual, when \ref hidSetNpadJoyAssignmentModeSingleByDefault was previously used (this includes using this manually at application exit). +## @brief To be successful, id0/id1 must correspond to controllers supporting styles HidNpadStyleTag_NpadJoyLeft/Right, or HidNpadStyleTag_NpadJoyRight/Left. +## @brief If successful, the id of the resulting dual controller is set to id0. +## @param[in] id0 \ref HidNpadIdType +## @param[in] id1 \ref HidNpadIdType +## + +proc hidStartLrAssignmentMode*(): Result {.cdecl, + importc: "hidStartLrAssignmentMode".} +## * +## @brief StartLrAssignmentMode +## + +proc hidStopLrAssignmentMode*(): Result {.cdecl, importc: "hidStopLrAssignmentMode".} +## * +## @brief StopLrAssignmentMode +## + +proc hidSetNpadHandheldActivationMode*(mode: HidNpadHandheldActivationMode): Result {. + cdecl, importc: "hidSetNpadHandheldActivationMode".} +## * +## @brief Sets the \ref HidNpadHandheldActivationMode. +## @param[in] mode \ref HidNpadHandheldActivationMode +## + +proc hidGetNpadHandheldActivationMode*(`out`: ptr HidNpadHandheldActivationMode): Result {. + cdecl, importc: "hidGetNpadHandheldActivationMode".} +## * +## @brief Gets the \ref HidNpadHandheldActivationMode. +## @param[out] out \ref HidNpadHandheldActivationMode +## + +proc hidSwapNpadAssignment*(id0: HidNpadIdType; id1: HidNpadIdType): Result {.cdecl, + importc: "hidSwapNpadAssignment".} +## * +## @brief SwapNpadAssignment +## @param[in] id0 \ref HidNpadIdType +## @param[in] id1 \ref HidNpadIdType +## + +proc hidEnableUnintendedHomeButtonInputProtection*(id: HidNpadIdType; flag: bool): Result {. + cdecl, importc: "hidEnableUnintendedHomeButtonInputProtection".} +## * +## @brief EnableUnintendedHomeButtonInputProtection +## @note To get the state of this, use \ref hidGetNpadSystemButtonProperties to access HidNpadSystemButtonProperties::is_unintended_home_button_input_protection_enabled. +## @param[in] id \ref HidNpadIdType +## @param[in] flag Whether UnintendedHomeButtonInputProtection is enabled. +## + +proc hidSetNpadJoyAssignmentModeSingleWithDestination*(id: HidNpadIdType; + `type`: HidNpadJoyDeviceType; flag: ptr bool; dest: ptr HidNpadIdType): Result {. + cdecl, importc: "hidSetNpadJoyAssignmentModeSingleWithDestination".} +## * +## @brief Use this if you want to use a single joy-con as a dedicated HidNpadIdType_No*. When used, both joy-cons in a pair should be used with this (HidNpadIdType_No1 and HidNpadIdType_No2 for example). +## @note Only available on [5.0.0+]. +## @param[in] id \ref HidNpadIdType, must be HidNpadIdType_No*. +## @param[in] type \ref HidNpadJoyDeviceType +## @param[out] flag Whether the dest output is set. +## @param[out] dest \ref HidNpadIdType +## + +proc hidSetNpadAnalogStickUseCenterClamp*(flag: bool): Result {.cdecl, + importc: "hidSetNpadAnalogStickUseCenterClamp".} +## * +## @brief SetNpadAnalogStickUseCenterClamp +## @note Only available on [6.1.0+]. +## @param[in] flag Flag +## + +proc hidSetNpadCaptureButtonAssignment*(style: HidNpadStyleTag; buttons: U64): Result {. + cdecl, importc: "hidSetNpadCaptureButtonAssignment".} +## * +## @brief Assigns the button(s) which trigger the CaptureButton. +## @note Only available on [8.0.0+]. +## @param[in] style \ref HidNpadStyleTag, exactly 1 bit must be set. +## @param[in] buttons Bitfield of \ref HidNpadButton, multiple bits can be set. +## + +proc hidClearNpadCaptureButtonAssignment*(): Result {.cdecl, + importc: "hidClearNpadCaptureButtonAssignment".} +## * +## @brief ClearNpadCaptureButtonAssignment +## @note Only available on [8.0.0+]. +## + +proc hidInitializeVibrationDevices*(handles: ptr HidVibrationDeviceHandle; + totalHandles: S32; id: HidNpadIdType; + style: HidNpadStyleTag): Result {.cdecl, + importc: "hidInitializeVibrationDevices".} +## * +## @brief Gets and initializes vibration handles. +## @note Only the following styles support total_handles 2: ::HidNpadStyleTag_NpadFullKey, ::HidNpadStyleTag_NpadHandheld, ::HidNpadStyleTag_NpadJoyDual, ::HidNpadStyleTag_NpadHandheldLark, ::HidNpadStyleTag_NpadSystem, ::HidNpadStyleTag_NpadSystemExt. +## @param[out] handles Output array of \ref HidVibrationDeviceHandle. +## @param[in] total_handles Total handles for the handles array. Must be 1 or 2, if 2 handles aren't supported by the specified style an error is thrown. +## @param[in] id \ref HidNpadIdType +## @param[in] style \ref HidNpadStyleTag +## + +proc hidGetVibrationDeviceInfo*(handle: HidVibrationDeviceHandle; + `out`: ptr HidVibrationDeviceInfo): Result {.cdecl, + importc: "hidGetVibrationDeviceInfo".} +## * +## @brief Gets \ref HidVibrationDeviceInfo for the specified device. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[out] out \ref HidVibrationDeviceInfo +## + +proc hidSendVibrationValue*(handle: HidVibrationDeviceHandle; + value: ptr HidVibrationValue): Result {.cdecl, + importc: "hidSendVibrationValue".} +## * +## @brief Sends the \ref HidVibrationDeviceHandle to the specified device. +## @note With ::HidVibrationDeviceType_GcErm, use \ref hidSendVibrationGcErmCommand instead. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[in] value \ref HidVibrationValue +## + +proc hidGetActualVibrationValue*(handle: HidVibrationDeviceHandle; + `out`: ptr HidVibrationValue): Result {.cdecl, + importc: "hidGetActualVibrationValue".} +## * +## @brief Gets the current \ref HidVibrationValue for the specified device. +## @note With ::HidVibrationDeviceType_GcErm, use \ref hidGetActualVibrationGcErmCommand instead. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[out] out \ref HidVibrationValue +## + +proc hidPermitVibration*(flag: bool): Result {.cdecl, importc: "hidPermitVibration".} +## * +## @brief Sets whether vibration is allowed, this also affects the config displayed by System Settings. +## @param[in] flag Flag +## + +proc hidIsVibrationPermitted*(flag: ptr bool): Result {.cdecl, + importc: "hidIsVibrationPermitted".} +## * +## @brief Gets whether vibration is allowed. +## @param[out] flag Flag +## + +proc hidSendVibrationValues*(handles: ptr HidVibrationDeviceHandle; + values: ptr HidVibrationValue; count: S32): Result {. + cdecl, importc: "hidSendVibrationValues".} +## * +## @brief Send vibration values[index] to handles[index]. +## @note With ::HidVibrationDeviceType_GcErm, use \ref hidSendVibrationGcErmCommand instead. +## @param[in] handles Input array of \ref HidVibrationDeviceHandle. +## @param[in] values Input array of \ref HidVibrationValue. +## @param[in] count Total entries in the handles/values arrays. +## + +proc hidSendVibrationGcErmCommand*(handle: HidVibrationDeviceHandle; + cmd: HidVibrationGcErmCommand): Result {.cdecl, + importc: "hidSendVibrationGcErmCommand".} +## * +## @brief Send \ref HidVibrationGcErmCommand to the specified device, for ::HidVibrationDeviceType_GcErm. +## @note Only available on [4.0.0+]. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[in] cmd \ref HidVibrationGcErmCommand +## + +proc hidGetActualVibrationGcErmCommand*(handle: HidVibrationDeviceHandle; + `out`: ptr HidVibrationGcErmCommand): Result {. + cdecl, importc: "hidGetActualVibrationGcErmCommand".} +## * +## @brief Get \ref HidVibrationGcErmCommand for the specified device, for ::HidVibrationDeviceType_GcErm. +## @note Only available on [4.0.0+]. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[out] out \ref HidVibrationGcErmCommand +## + +proc hidBeginPermitVibrationSession*(): Result {.cdecl, + importc: "hidBeginPermitVibrationSession".} +## * +## @brief Begins a forced-permitted vibration session. +## @note Only available on [4.0.0+]. +## + +proc hidEndPermitVibrationSession*(): Result {.cdecl, + importc: "hidEndPermitVibrationSession".} +## * +## @brief Ends the session started by \ref hidBeginPermitVibrationSession. +## @note Only available on [4.0.0+]. +## + +proc hidIsVibrationDeviceMounted*(handle: HidVibrationDeviceHandle; flag: ptr bool): Result {. + cdecl, importc: "hidIsVibrationDeviceMounted".} +## * +## @brief Gets whether vibration is available with the specified device. +## @note Only available on [7.0.0+]. +## @param[in] handle \ref HidVibrationDeviceHandle +## @param[out] flag Flag +## + +proc hidStartSevenSixAxisSensor*(): Result {.cdecl, + importc: "hidStartSevenSixAxisSensor".} +## * +## @brief Starts the SevenSixAxisSensor. +## @note Only available on [5.0.0+]. +## + +proc hidStopSevenSixAxisSensor*(): Result {.cdecl, + importc: "hidStopSevenSixAxisSensor".} +## * +## @brief Stops the SevenSixAxisSensor. +## @note Only available on [5.0.0+]. +## + +proc hidInitializeSevenSixAxisSensor*(): Result {.cdecl, + importc: "hidInitializeSevenSixAxisSensor".} +## * +## @brief Initializes the SevenSixAxisSensor. +## @note Only available on [5.0.0+]. +## + +proc hidFinalizeSevenSixAxisSensor*(): Result {.cdecl, + importc: "hidFinalizeSevenSixAxisSensor".} +## * +## @brief Finalizes the SevenSixAxisSensor. +## @note This must be called before \ref hidExit. +## @note Only available on [5.0.0+]. +## + +proc hidSetSevenSixAxisSensorFusionStrength*(strength: cfloat): Result {.cdecl, + importc: "hidSetSevenSixAxisSensorFusionStrength".} +## * +## @brief Sets the SevenSixAxisSensor FusionStrength. +## @note Only available on [5.0.0+]. +## @param[in] strength Strength +## + +proc hidGetSevenSixAxisSensorFusionStrength*(strength: ptr cfloat): Result {.cdecl, + importc: "hidGetSevenSixAxisSensorFusionStrength".} +## * +## @brief Gets the SevenSixAxisSensor FusionStrength. +## @note Only available on [5.0.0+]. +## @param[out] strength Strength +## + +proc hidResetSevenSixAxisSensorTimestamp*(): Result {.cdecl, + importc: "hidResetSevenSixAxisSensorTimestamp".} +## * +## @brief Resets the timestamp for the SevenSixAxisSensor. +## @note Only available on [6.0.0+]. +## + +proc hidGetSevenSixAxisSensorStates*(states: ptr HidSevenSixAxisSensorState; + count: csize_t; totalOut: ptr csize_t): Result {. + cdecl, importc: "hidGetSevenSixAxisSensorStates".} +## * +## @brief GetSevenSixAxisSensorStates +## @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. +## @param[out] states Output array of \ref HidSevenSixAxisSensorState. +## @param[in] count Size of the states array in entries. +## @param[out] total_out Total output entries. +## + +proc hidIsSevenSixAxisSensorAtRest*(`out`: ptr bool): Result {.cdecl, + importc: "hidIsSevenSixAxisSensorAtRest".} +## * +## @brief IsSevenSixAxisSensorAtRest +## @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. +## @param[out] out Output flag. +## + +proc hidGetSensorFusionError*(`out`: ptr cfloat): Result {.cdecl, + importc: "hidGetSensorFusionError".} +## * +## @brief GetSensorFusionError +## @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. +## @param[out] out Output data. +## + +proc hidGetGyroBias*(`out`: ptr UtilFloat3): Result {.cdecl, importc: "hidGetGyroBias".} +## * +## @brief GetGyroBias +## @note Only available when \ref hidInitializeSevenSixAxisSensor was previously used. +## @param[out] out \ref UtilFloat3 +## + +proc hidIsUsbFullKeyControllerEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "hidIsUsbFullKeyControllerEnabled".} +## * +## @brief IsUsbFullKeyControllerEnabled +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc hidEnableUsbFullKeyController*(flag: bool): Result {.cdecl, + importc: "hidEnableUsbFullKeyController".} +## * +## @brief EnableUsbFullKeyController +## @note Only available on [3.0.0+]. +## @param[in] flag Flag +## + +proc hidIsUsbFullKeyControllerConnected*(id: HidNpadIdType; `out`: ptr bool): Result {. + cdecl, importc: "hidIsUsbFullKeyControllerConnected".} +## * +## @brief IsUsbFullKeyControllerConnected +## @note Only available on [3.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out Output flag. +## + +proc hidGetNpadInterfaceType*(id: HidNpadIdType; `out`: ptr U8): Result {.cdecl, + importc: "hidGetNpadInterfaceType".} +## * +## @brief Gets the \ref HidNpadInterfaceType for the specified controller. +## @note When available, \ref hidsysGetNpadInterfaceType should be used instead. +## @note Only available on [4.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out \ref HidNpadInterfaceType +## + +proc hidGetNpadOfHighestBatteryLevel*(ids: ptr HidNpadIdType; count: csize_t; + `out`: ptr HidNpadIdType): Result {.cdecl, + importc: "hidGetNpadOfHighestBatteryLevel".} +## * +## @brief GetNpadOfHighestBatteryLevel +## @note Only available on [10.0.0+]. +## @param[in] ids Input array of \ref HidNpadIdType, ::HidNpadIdType_Handheld is ignored. +## @param[in] count Total entries in the ids array. +## @param[out] out \ref HidNpadIdType +## + +proc hidGetPalmaConnectionHandle*(id: HidNpadIdType; + `out`: ptr HidPalmaConnectionHandle): Result {. + cdecl, importc: "hidGetPalmaConnectionHandle".} +## /@name Palma, see ::HidNpadStyleTag_NpadPalma. +## /@{ +## * +## @brief GetPalmaConnectionHandle +## @note Only available on [5.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out \ref HidPalmaConnectionHandle +## + +proc hidInitializePalma*(handle: HidPalmaConnectionHandle): Result {.cdecl, + importc: "hidInitializePalma".} +## * +## @brief InitializePalma +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidAcquirePalmaOperationCompleteEvent*(handle: HidPalmaConnectionHandle; + outEvent: ptr Event; autoclear: bool): Result {.cdecl, + importc: "hidAcquirePalmaOperationCompleteEvent".} +## * +## @brief Gets an Event which is signaled when data is available with \ref hidGetPalmaOperationInfo. +## @note The Event must be closed by the user once finished with it. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[out] out_event Output Event. +## @param[in] autoclear The autoclear for the Event. +## + +proc hidGetPalmaOperationInfo*(handle: HidPalmaConnectionHandle; + `out`: ptr HidPalmaOperationInfo): Result {.cdecl, + importc: "hidGetPalmaOperationInfo".} +## * +## @brief Gets \ref HidPalmaOperationInfo for a completed operation. +## @note This must be used at some point following using any of the other Palma cmds which trigger an Operation, once the Event from \ref hidAcquirePalmaOperationCompleteEvent is signaled. Up to 4 Operations can be queued at once, the other cmds will throw an error once there's too many operations. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[out] out \ref HidPalmaOperationInfo +## + +proc hidPlayPalmaActivity*(handle: HidPalmaConnectionHandle; val: U16): Result {. + cdecl, importc: "hidPlayPalmaActivity".} +## * +## @brief PlayPalmaActivity +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] val Input value. +## + +proc hidSetPalmaFrModeType*(handle: HidPalmaConnectionHandle; + `type`: HidPalmaFrModeType): Result {.cdecl, + importc: "hidSetPalmaFrModeType".} +## * +## @brief SetPalmaFrModeType +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] type \ref HidPalmaFrModeType +## + +proc hidReadPalmaStep*(handle: HidPalmaConnectionHandle): Result {.cdecl, + importc: "hidReadPalmaStep".} +## * +## @brief ReadPalmaStep +## @note See \ref hidGetPalmaOperationInfo. +## @note \ref hidEnablePalmaStep should be used before this. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidEnablePalmaStep*(handle: HidPalmaConnectionHandle; flag: bool): Result {. + cdecl, importc: "hidEnablePalmaStep".} +## * +## @brief EnablePalmaStep +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] flag Flag +## + +proc hidResetPalmaStep*(handle: HidPalmaConnectionHandle): Result {.cdecl, + importc: "hidResetPalmaStep".} +## * +## @brief ResetPalmaStep +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidReadPalmaApplicationSection*(handle: HidPalmaConnectionHandle; inval0: S32; + size: U64): Result {.cdecl, + importc: "hidReadPalmaApplicationSection".} +## * +## @brief ReadPalmaApplicationSection +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] inval0 First input value. +## @param[in] size This must be within the size of \ref HidPalmaApplicationSectionAccessBuffer. +## + +proc hidWritePalmaApplicationSection*(handle: HidPalmaConnectionHandle; + inval0: S32; size: U64; buf: ptr HidPalmaApplicationSectionAccessBuffer): Result {. + cdecl, importc: "hidWritePalmaApplicationSection".} +## * +## @brief WritePalmaApplicationSection +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] inval0 First input value. +## @param[in] size Size of the data in \ref HidPalmaApplicationSectionAccessBuffer. +## @param[in] buf \ref HidPalmaApplicationSectionAccessBuffer +## + +proc hidReadPalmaUniqueCode*(handle: HidPalmaConnectionHandle): Result {.cdecl, + importc: "hidReadPalmaUniqueCode".} +## * +## @brief ReadPalmaUniqueCode +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidSetPalmaUniqueCodeInvalid*(handle: HidPalmaConnectionHandle): Result {. + cdecl, importc: "hidSetPalmaUniqueCodeInvalid".} +## * +## @brief SetPalmaUniqueCodeInvalid +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidWritePalmaActivityEntry*(handle: HidPalmaConnectionHandle; unk: U16; + entry: ptr HidPalmaActivityEntry): Result {.cdecl, + importc: "hidWritePalmaActivityEntry".} +## * +## @brief WritePalmaActivityEntry +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] unk Unknown +## @param[in] entry \ref HidPalmaActivityEntry +## + +proc hidWritePalmaRgbLedPatternEntry*(handle: HidPalmaConnectionHandle; unk: U16; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "hidWritePalmaRgbLedPatternEntry".} +## * +## @brief WritePalmaRgbLedPatternEntry +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] unk Unknown +## @param[in] buffer Input buffer. +## @param[in] size Input buffer size. +## + +proc hidWritePalmaWaveEntry*(handle: HidPalmaConnectionHandle; + waveSet: HidPalmaWaveSet; unk: U16; buffer: pointer; + tmemSize: csize_t; size: csize_t): Result {.cdecl, + importc: "hidWritePalmaWaveEntry".} +## * +## @brief WritePalmaWaveEntry +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] wave_set \ref HidPalmaWaveSet +## @param[in] unk Unknown +## @param[in] buffer TransferMemory buffer, must be 0x1000-byte aligned. +## @param[in] tmem_size TransferMemory buffer size, must be 0x1000-byte aligned. +## @param[in] size Actual size of the data in the buffer. +## + +proc hidSetPalmaDataBaseIdentificationVersion*(handle: HidPalmaConnectionHandle; + version: S32): Result {.cdecl, + importc: "hidSetPalmaDataBaseIdentificationVersion".} +## * +## @brief SetPalmaDataBaseIdentificationVersion +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] version Version +## + +proc hidGetPalmaDataBaseIdentificationVersion*(handle: HidPalmaConnectionHandle): Result {. + cdecl, importc: "hidGetPalmaDataBaseIdentificationVersion".} +## * +## @brief GetPalmaDataBaseIdentificationVersion +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidSuspendPalmaFeature*(handle: HidPalmaConnectionHandle; features: U32): Result {. + cdecl, importc: "hidSuspendPalmaFeature".} +## * +## @brief SuspendPalmaFeature +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] features Bitfield of \ref HidPalmaFeature. +## + +proc hidReadPalmaPlayLog*(handle: HidPalmaConnectionHandle; unk: U16): Result {.cdecl, + importc: "hidReadPalmaPlayLog".} +## * +## @brief ReadPalmaPlayLog +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.1.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] unk Unknown +## + +proc hidResetPalmaPlayLog*(handle: HidPalmaConnectionHandle; unk: U16): Result {. + cdecl, importc: "hidResetPalmaPlayLog".} +## * +## @brief ResetPalmaPlayLog +## @note See \ref hidGetPalmaOperationInfo. +## @note Only available on [5.1.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[in] unk Unknown +## + +proc hidSetIsPalmaAllConnectable*(flag: bool): Result {.cdecl, + importc: "hidSetIsPalmaAllConnectable".} +## * +## @brief Sets whether any Palma can connect. +## @note Only available on [5.1.0+]. +## @param[in] flag Flag +## + +proc hidSetIsPalmaPairedConnectable*(flag: bool): Result {.cdecl, + importc: "hidSetIsPalmaPairedConnectable".} +## * +## @brief Sets whether paired Palma can connect. +## @note Only available on [5.1.0+]. +## @param[in] flag Flag +## + +proc hidPairPalma*(handle: HidPalmaConnectionHandle): Result {.cdecl, + importc: "hidPairPalma".} +## * +## @brief PairPalma +## @note Only available on [5.1.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidCancelWritePalmaWaveEntry*(handle: HidPalmaConnectionHandle): Result {. + cdecl, importc: "hidCancelWritePalmaWaveEntry".} +## * +## @brief CancelWritePalmaWaveEntry +## @note Only available on [7.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## + +proc hidEnablePalmaBoostMode*(flag: bool): Result {.cdecl, + importc: "hidEnablePalmaBoostMode".} +## * +## @brief EnablePalmaBoostMode +## @note Only available on [5.1.0+]. Uses cmd EnablePalmaBoostMode on [8.0.0+], otherwise cmd SetPalmaBoostMode is used. +## @param[in] flag Flag +## + +proc hidGetPalmaBluetoothAddress*(handle: HidPalmaConnectionHandle; + `out`: ptr BtdrvAddress): Result {.cdecl, + importc: "hidGetPalmaBluetoothAddress".} +## * +## @brief GetPalmaBluetoothAddress +## @note Only available on [8.0.0+]. +## @param[in] handle \ref HidPalmaConnectionHandle +## @param[out] out \ref BtdrvAddress +## + +proc hidSetDisallowedPalmaConnection*(addrs: ptr BtdrvAddress; count: S32): Result {. + cdecl, importc: "hidSetDisallowedPalmaConnection".} +## * +## @brief SetDisallowedPalmaConnection +## @note Only available on [8.0.0+]. +## @param[in] addrs Input array of \ref BtdrvAddress. +## @param[in] count Total entries in the addrs array. +## + +proc hidSetNpadCommunicationMode*(mode: HidNpadCommunicationMode): Result {.cdecl, + importc: "hidSetNpadCommunicationMode".} +## /@} +## * +## @brief SetNpadCommunicationMode +## @note [2.0.0+] Stubbed, just returns 0. +## @param[in] mode \ref HidNpadCommunicationMode +## + +proc hidGetNpadCommunicationMode*(`out`: ptr HidNpadCommunicationMode): Result {. + cdecl, importc: "hidGetNpadCommunicationMode".} +## * +## @brief GetNpadCommunicationMode +## @note [2.0.0+] Stubbed, always returns output mode ::HidNpadCommunicationMode_Default. +## @param[out] out \ref HidNpadCommunicationMode +## + +proc hidSetTouchScreenConfiguration*(config: ptr HidTouchScreenConfigurationForNx): Result {. + cdecl, importc: "hidSetTouchScreenConfiguration".} +## * +## @brief SetTouchScreenConfiguration +## @note Only available on [9.0.0+]. +## @param[in] config \ref HidTouchScreenConfigurationForNx +## + +proc hidIsFirmwareUpdateNeededForNotification*(`out`: ptr bool): Result {.cdecl, + importc: "hidIsFirmwareUpdateNeededForNotification".} +## * +## @brief IsFirmwareUpdateNeededForNotification +## @note Only available on [9.0.0+]. +## @param[out] out Output flag. +## + diff --git a/src/libnx/wrapper/switch/services/hidbus.h b/src/libnx/wrapper/switch/services/hidbus.h new file mode 100644 index 0000000..42c0e6c --- /dev/null +++ b/src/libnx/wrapper/switch/services/hidbus.h @@ -0,0 +1,219 @@ +/** + * @file hidbus.h + * @brief hidbus service IPC wrapper, for using external devices attached to HID controllers. See also: https://switchbrew.org/wiki/HID_services#hidbus + * @note Only available on [5.0.0+]. + * @author yellows8 + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/hid.h" +#include "../sf/service.h" + +/// BusType +typedef enum { + HidbusBusType_LeftJoyRail = 0, ///< LeftJoyRail + HidbusBusType_RightJoyRail = 1, ///< RightJoyRail + HidbusBusType_RightLarkRail = 2, ///< [6.0.0+] RightLarkRail (for microphone). +} HidbusBusType; + +/// JoyPollingMode +typedef enum { + HidbusJoyPollingMode_SixAxisSensorDisable = 0, ///< SixAxisSensorDisable + HidbusJoyPollingMode_SixAxisSensorEnable = 1, ///< JoyEnableSixAxisPollingData + HidbusJoyPollingMode_ButtonOnly = 2, ///< [6.0.0+] ButtonOnly +} HidbusJoyPollingMode; + +/// BusHandle +typedef struct { + u32 abstracted_pad_id; ///< AbstractedPadId + u8 internal_index; ///< InternalIndex + u8 player_number; ///< PlayerNumber + u8 bus_type_id; ///< BusTypeId + u8 is_valid; ///< IsValid +} HidbusBusHandle; + +/// JoyPollingReceivedData +typedef struct { + u8 data[0x30]; ///< Data. + u64 out_size; ///< Size of data. + u64 sampling_number; ///< SamplingNumber +} HidbusJoyPollingReceivedData; + +/// HidbusDataAccessorHeader +typedef struct { + Result res; ///< Result. + u32 pad; ///< Padding. + u8 unused[0x18]; ///< Initialized sysmodule-side, not used by sdknso. + u64 latest_entry; ///< Latest entry. + u64 total_entries; ///< Total entries. +} HidbusDataAccessorHeader; + +/// HidbusJoyDisableSixAxisPollingDataAccessorEntryData +typedef struct { + u8 data[0x26]; ///< Data. + u8 out_size; ///< Size of data. + u8 pad; ///< Padding. + u64 sampling_number; ///< SamplingNumber +} HidbusJoyDisableSixAxisPollingDataAccessorEntryData; + +/// HidbusJoyDisableSixAxisPollingDataAccessorEntry +typedef struct { + u64 sampling_number; ///< SamplingNumber + HidbusJoyDisableSixAxisPollingDataAccessorEntryData data; ///< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntryData +} HidbusJoyDisableSixAxisPollingDataAccessorEntry; + +/// HidbusJoyEnableSixAxisPollingDataAccessorEntryData +typedef struct { + u8 data[0x8]; ///< Data. + u8 out_size; ///< Size of data. + u8 pad[7]; ///< Padding. + u64 sampling_number; ///< SamplingNumber +} HidbusJoyEnableSixAxisPollingDataAccessorEntryData; + +/// HidbusJoyEnableSixAxisPollingDataAccessorEntry +typedef struct { + u64 sampling_number; ///< SamplingNumber + HidbusJoyEnableSixAxisPollingDataAccessorEntryData data; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData +} HidbusJoyEnableSixAxisPollingDataAccessorEntry; + +/// HidbusJoyButtonOnlyPollingDataAccessorEntryData +typedef struct { + u8 data[0x2c]; ///< Data. + u8 out_size; ///< Size of data. + u8 pad[3]; ///< Padding. + u64 sampling_number; ///< SamplingNumber +} HidbusJoyButtonOnlyPollingDataAccessorEntryData; + +/// HidbusJoyButtonOnlyPollingDataAccessorEntry +typedef struct { + u64 sampling_number; ///< SamplingNumber + HidbusJoyButtonOnlyPollingDataAccessorEntryData data; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData +} HidbusJoyButtonOnlyPollingDataAccessorEntry; + +/// HidbusJoyDisableSixAxisPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyDisableSixAxisPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntry +} HidbusJoyDisableSixAxisPollingDataAccessor; + +/// HidbusJoyEnableSixAxisPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyEnableSixAxisPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntry +} HidbusJoyEnableSixAxisPollingDataAccessor; + +/// HidbusJoyButtonOnlyPollingDataAccessor +typedef struct { + HidbusDataAccessorHeader hdr; ///< \ref HidbusDataAccessorHeader + HidbusJoyButtonOnlyPollingDataAccessorEntry entries[0xb]; ///< \ref HidbusJoyButtonOnlyPollingDataAccessorEntry +} HidbusJoyButtonOnlyPollingDataAccessor; + +/// Common data for HidbusStatusManagerEntry*. +typedef struct { + u8 is_connected; ///< IsConnected + u8 pad[3]; ///< Padding. + Result is_connected_result; ///< IsConnectedResult + u8 is_enabled; ///< Flag indicating whether a device is enabled (\ref hidbusEnableExternalDevice). + u8 is_in_focus; ///< Flag indicating whether this entry is valid. + u8 is_polling_mode; ///< Flag indicating whether polling is enabled (\ref hidbusEnableJoyPollingReceiveMode). + u8 reserved; ///< Reserved + u32 polling_mode; ///< \ref HidbusJoyPollingMode +} HidbusStatusManagerEntryCommon; + +/// HidbusStatusManagerEntry on 5.x. +typedef struct { + HidbusStatusManagerEntryCommon common; ///< \ref HidbusStatusManagerEntryCommon + u8 unk_x10[0xf0]; ///< Ignored by official sw. +} HidbusStatusManagerEntryV5; + +/// HidbusStatusManagerEntry +typedef struct { + HidbusStatusManagerEntryCommon common; ///< \ref HidbusStatusManagerEntryCommon + u8 unk_x10[0x70]; ///< Ignored by official sw. +} HidbusStatusManagerEntry; + +/// StatusManager on 5.x. +typedef struct { + HidbusStatusManagerEntryV5 entries[0x10]; ///< \ref HidbusStatusManagerEntryV5 +} HidbusStatusManagerV5; + +/// StatusManager +typedef struct { + HidbusStatusManagerEntry entries[0x13]; ///< \ref HidbusStatusManagerEntry + u8 unused[0x680]; ///< Unused. +} HidbusStatusManager; + +/// Gets the Service object for the actual hidbus service session. This object must be closed by the user once finished using cmds with this. +Result hidbusGetServiceSession(Service* srv_out); + +/// Gets the SharedMemory addr (\ref HidbusStatusManagerV5 on 5.x, otherwise \ref HidbusStatusManager). Only valid when at least one BusHandle is currently initialized (\ref hidbusInitialize). +void* hidbusGetSharedmemAddr(void); + +/** + * @brief GetBusHandle + * @param[out] handle \ref HidbusBusHandle + * @param[out] flag Output flag indicating whether the handle is valid. + * @param[in] id \ref HidNpadIdType + * @param[in] bus_type \ref HidbusBusType + */ +Result hidbusGetBusHandle(HidbusBusHandle *handle, bool *flag, HidNpadIdType id, HidbusBusType bus_type); + +/** + * @brief Initialize + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusInitialize(HidbusBusHandle handle); + +/** + * @brief Finalize + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusFinalize(HidbusBusHandle handle); + +/** + * @brief EnableExternalDevice + * @note This uses \ref hidLaShowControllerFirmwareUpdate if needed. + * @param[in] handle \ref HidbusBusHandle + * @param[in] flag Whether to enable the device (true = enable, false = disable). When false, this will internally use \ref hidbusDisableJoyPollingReceiveMode if needed. + * @param[in] device_id ExternalDeviceId which must match the connected device. Only used when flag is set. + */ +Result hidbusEnableExternalDevice(HidbusBusHandle handle, bool flag, u32 device_id); + +/** + * @brief SendAndReceive + * @param[in] handle \ref HidbusBusHandle + * @param[in] inbuf Input buffer, containing the command data. + * @param[in] inbuf_size Input buffer size, must be <0x26. + * @param[out] outbuf Output buffer, containing the command reply data. + * @param[in] outbuf_size Output buffer max size. + * @param[out] out_size Actual output size. + */ +Result hidbusSendAndReceive(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* outbuf, size_t outbuf_size, u64 *out_size); + +/** + * @brief EnableJoyPollingReceiveMode + * @param[in] handle \ref HidbusBusHandle + * @param[in] inbuf Input buffer, containing the command data. + * @param[in] inbuf_size Input buffer size, must be <0x26. + * @param[out] workbuf TransferMemory buffer, must be 0x1000-byte aligned. This buffer must not be written to until after \ref hidbusDisableJoyPollingReceiveMode is used. + * @param[in] workbuf_size TransferMemory buffer size, must be 0x1000-byte aligned. + * @param[in] polling_mode \ref HidbusJoyPollingMode + */ +Result hidbusEnableJoyPollingReceiveMode(HidbusBusHandle handle, const void* inbuf, size_t inbuf_size, void* workbuf, size_t workbuf_size, HidbusJoyPollingMode polling_mode); + +/** + * @brief DisableJoyPollingReceiveMode + * @note This can also be used via \ref hidbusEnableExternalDevice with flag=false. + * @param[in] handle \ref HidbusBusHandle + */ +Result hidbusDisableJoyPollingReceiveMode(HidbusBusHandle handle); + +/** + * @brief GetJoyPollingReceivedData + * @param[in] handle \ref HidbusBusHandle + * @param[out] recv_data Output array of \ref HidbusJoyPollingReceivedData. + * @param[in] count Total entries for the recv_data array. The maximum is 0xa. Official apps use range 0x1-0x9. + */ +Result hidbusGetJoyPollingReceivedData(HidbusBusHandle handle, HidbusJoyPollingReceivedData *recv_data, s32 count); + diff --git a/src/libnx/wrapper/switch/services/hidbus.nim b/src/libnx/wrapper/switch/services/hidbus.nim new file mode 100644 index 0000000..3b6797b --- /dev/null +++ b/src/libnx/wrapper/switch/services/hidbus.nim @@ -0,0 +1,271 @@ +## * +## @file hidbus.h +## @brief hidbus service IPC wrapper, for using external devices attached to HID controllers. See also: https://switchbrew.org/wiki/HID_services#hidbus +## @note Only available on [5.0.0+]. +## @author yellows8 +## + +import + ../types, ../services/hid, ../sf/service + +## / BusType + +type + HidbusBusType* = enum + HidbusBusTypeLeftJoyRail = 0, ## /< LeftJoyRail + HidbusBusTypeRightJoyRail = 1, ## /< RightJoyRail + HidbusBusTypeRightLarkRail = 2 ## /< [6.0.0+] RightLarkRail (for microphone). + + +## / JoyPollingMode + +type + HidbusJoyPollingMode* = enum + HidbusJoyPollingModeSixAxisSensorDisable = 0, ## /< SixAxisSensorDisable + HidbusJoyPollingModeSixAxisSensorEnable = 1, ## /< JoyEnableSixAxisPollingData + HidbusJoyPollingModeButtonOnly = 2 ## /< [6.0.0+] ButtonOnly + + +## / BusHandle + +type + HidbusBusHandle* {.bycopy.} = object + abstractedPadId*: U32 ## /< AbstractedPadId + internalIndex*: U8 ## /< InternalIndex + playerNumber*: U8 ## /< PlayerNumber + busTypeId*: U8 ## /< BusTypeId + isValid*: U8 ## /< IsValid + + +## / JoyPollingReceivedData + +type + HidbusJoyPollingReceivedData* {.bycopy.} = object + data*: array[0x30, U8] ## /< Data. + outSize*: U64 ## /< Size of data. + samplingNumber*: U64 ## /< SamplingNumber + + +## / HidbusDataAccessorHeader + +type + HidbusDataAccessorHeader* {.bycopy.} = object + res*: Result ## /< Result. + pad*: U32 ## /< Padding. + unused*: array[0x18, U8] ## /< Initialized sysmodule-side, not used by sdknso. + latestEntry*: U64 ## /< Latest entry. + totalEntries*: U64 ## /< Total entries. + + +## / HidbusJoyDisableSixAxisPollingDataAccessorEntryData + +type + HidbusJoyDisableSixAxisPollingDataAccessorEntryData* {.bycopy.} = object + data*: array[0x26, U8] ## /< Data. + outSize*: U8 ## /< Size of data. + pad*: U8 ## /< Padding. + samplingNumber*: U64 ## /< SamplingNumber + + +## / HidbusJoyDisableSixAxisPollingDataAccessorEntry + +type + HidbusJoyDisableSixAxisPollingDataAccessorEntry* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + data*: HidbusJoyDisableSixAxisPollingDataAccessorEntryData ## /< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntryData + + +## / HidbusJoyEnableSixAxisPollingDataAccessorEntryData + +type + HidbusJoyEnableSixAxisPollingDataAccessorEntryData* {.bycopy.} = object + data*: array[0x8, U8] ## /< Data. + outSize*: U8 ## /< Size of data. + pad*: array[7, U8] ## /< Padding. + samplingNumber*: U64 ## /< SamplingNumber + + +## / HidbusJoyEnableSixAxisPollingDataAccessorEntry + +type + HidbusJoyEnableSixAxisPollingDataAccessorEntry* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + data*: HidbusJoyEnableSixAxisPollingDataAccessorEntryData ## /< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData + + +## / HidbusJoyButtonOnlyPollingDataAccessorEntryData + +type + HidbusJoyButtonOnlyPollingDataAccessorEntryData* {.bycopy.} = object + data*: array[0x2c, U8] ## /< Data. + outSize*: U8 ## /< Size of data. + pad*: array[3, U8] ## /< Padding. + samplingNumber*: U64 ## /< SamplingNumber + + +## / HidbusJoyButtonOnlyPollingDataAccessorEntry + +type + HidbusJoyButtonOnlyPollingDataAccessorEntry* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + data*: HidbusJoyButtonOnlyPollingDataAccessorEntryData ## /< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntryData + + +## / HidbusJoyDisableSixAxisPollingDataAccessor + +type + HidbusJoyDisableSixAxisPollingDataAccessor* {.bycopy.} = object + hdr*: HidbusDataAccessorHeader ## /< \ref HidbusDataAccessorHeader + entries*: array[0xb, HidbusJoyDisableSixAxisPollingDataAccessorEntry] ## /< \ref HidbusJoyDisableSixAxisPollingDataAccessorEntry + + +## / HidbusJoyEnableSixAxisPollingDataAccessor + +type + HidbusJoyEnableSixAxisPollingDataAccessor* {.bycopy.} = object + hdr*: HidbusDataAccessorHeader ## /< \ref HidbusDataAccessorHeader + entries*: array[0xb, HidbusJoyEnableSixAxisPollingDataAccessorEntry] ## /< \ref HidbusJoyEnableSixAxisPollingDataAccessorEntry + + +## / HidbusJoyButtonOnlyPollingDataAccessor + +type + HidbusJoyButtonOnlyPollingDataAccessor* {.bycopy.} = object + hdr*: HidbusDataAccessorHeader ## /< \ref HidbusDataAccessorHeader + entries*: array[0xb, HidbusJoyButtonOnlyPollingDataAccessorEntry] ## /< \ref HidbusJoyButtonOnlyPollingDataAccessorEntry + + +## / Common data for HidbusStatusManagerEntry*. + +type + HidbusStatusManagerEntryCommon* {.bycopy.} = object + isConnected*: U8 ## /< IsConnected + pad*: array[3, U8] ## /< Padding. + isConnectedResult*: Result ## /< IsConnectedResult + isEnabled*: U8 ## /< Flag indicating whether a device is enabled (\ref hidbusEnableExternalDevice). + isInFocus*: U8 ## /< Flag indicating whether this entry is valid. + isPollingMode*: U8 ## /< Flag indicating whether polling is enabled (\ref hidbusEnableJoyPollingReceiveMode). + reserved*: U8 ## /< Reserved + pollingMode*: U32 ## /< \ref HidbusJoyPollingMode + + +## / HidbusStatusManagerEntry on 5.x. + +type + HidbusStatusManagerEntryV5* {.bycopy.} = object + common*: HidbusStatusManagerEntryCommon ## /< \ref HidbusStatusManagerEntryCommon + unkX10*: array[0xf0, U8] ## /< Ignored by official sw. + + +## / HidbusStatusManagerEntry + +type + HidbusStatusManagerEntry* {.bycopy.} = object + common*: HidbusStatusManagerEntryCommon ## /< \ref HidbusStatusManagerEntryCommon + unkX10*: array[0x70, U8] ## /< Ignored by official sw. + + +## / StatusManager on 5.x. + +type + HidbusStatusManagerV5* {.bycopy.} = object + entries*: array[0x10, HidbusStatusManagerEntryV5] ## /< \ref HidbusStatusManagerEntryV5 + + +## / StatusManager + +type + HidbusStatusManager* {.bycopy.} = object + entries*: array[0x13, HidbusStatusManagerEntry] ## /< \ref HidbusStatusManagerEntry + unused*: array[0x680, U8] ## /< Unused. + + +## / Gets the Service object for the actual hidbus service session. This object must be closed by the user once finished using cmds with this. + +proc hidbusGetServiceSession*(srvOut: ptr Service): Result {.cdecl, + importc: "hidbusGetServiceSession".} +## / Gets the SharedMemory addr (\ref HidbusStatusManagerV5 on 5.x, otherwise \ref HidbusStatusManager). Only valid when at least one BusHandle is currently initialized (\ref hidbusInitialize). + +proc hidbusGetSharedmemAddr*(): pointer {.cdecl, importc: "hidbusGetSharedmemAddr".} +## * +## @brief GetBusHandle +## @param[out] handle \ref HidbusBusHandle +## @param[out] flag Output flag indicating whether the handle is valid. +## @param[in] id \ref HidNpadIdType +## @param[in] bus_type \ref HidbusBusType +## + +proc hidbusGetBusHandle*(handle: ptr HidbusBusHandle; flag: ptr bool; + id: HidNpadIdType; busType: HidbusBusType): Result {.cdecl, + importc: "hidbusGetBusHandle".} +## * +## @brief Initialize +## @param[in] handle \ref HidbusBusHandle +## + +proc hidbusInitialize*(handle: HidbusBusHandle): Result {.cdecl, + importc: "hidbusInitialize".} +## * +## @brief Finalize +## @param[in] handle \ref HidbusBusHandle +## + +proc hidbusFinalize*(handle: HidbusBusHandle): Result {.cdecl, + importc: "hidbusFinalize".} +## * +## @brief EnableExternalDevice +## @note This uses \ref hidLaShowControllerFirmwareUpdate if needed. +## @param[in] handle \ref HidbusBusHandle +## @param[in] flag Whether to enable the device (true = enable, false = disable). When false, this will internally use \ref hidbusDisableJoyPollingReceiveMode if needed. +## @param[in] device_id ExternalDeviceId which must match the connected device. Only used when flag is set. +## + +proc hidbusEnableExternalDevice*(handle: HidbusBusHandle; flag: bool; deviceId: U32): Result {. + cdecl, importc: "hidbusEnableExternalDevice".} +## * +## @brief SendAndReceive +## @param[in] handle \ref HidbusBusHandle +## @param[in] inbuf Input buffer, containing the command data. +## @param[in] inbuf_size Input buffer size, must be <0x26. +## @param[out] outbuf Output buffer, containing the command reply data. +## @param[in] outbuf_size Output buffer max size. +## @param[out] out_size Actual output size. +## + +proc hidbusSendAndReceive*(handle: HidbusBusHandle; inbuf: pointer; + inbufSize: csize_t; outbuf: pointer; outbufSize: csize_t; + outSize: ptr U64): Result {.cdecl, + importc: "hidbusSendAndReceive".} +## * +## @brief EnableJoyPollingReceiveMode +## @param[in] handle \ref HidbusBusHandle +## @param[in] inbuf Input buffer, containing the command data. +## @param[in] inbuf_size Input buffer size, must be <0x26. +## @param[out] workbuf TransferMemory buffer, must be 0x1000-byte aligned. This buffer must not be written to until after \ref hidbusDisableJoyPollingReceiveMode is used. +## @param[in] workbuf_size TransferMemory buffer size, must be 0x1000-byte aligned. +## @param[in] polling_mode \ref HidbusJoyPollingMode +## + +proc hidbusEnableJoyPollingReceiveMode*(handle: HidbusBusHandle; inbuf: pointer; + inbufSize: csize_t; workbuf: pointer; + workbufSize: csize_t; + pollingMode: HidbusJoyPollingMode): Result {. + cdecl, importc: "hidbusEnableJoyPollingReceiveMode".} +## * +## @brief DisableJoyPollingReceiveMode +## @note This can also be used via \ref hidbusEnableExternalDevice with flag=false. +## @param[in] handle \ref HidbusBusHandle +## + +proc hidbusDisableJoyPollingReceiveMode*(handle: HidbusBusHandle): Result {.cdecl, + importc: "hidbusDisableJoyPollingReceiveMode".} +## * +## @brief GetJoyPollingReceivedData +## @param[in] handle \ref HidbusBusHandle +## @param[out] recv_data Output array of \ref HidbusJoyPollingReceivedData. +## @param[in] count Total entries for the recv_data array. The maximum is 0xa. Official apps use range 0x1-0x9. +## + +proc hidbusGetJoyPollingReceivedData*(handle: HidbusBusHandle; recvData: ptr HidbusJoyPollingReceivedData; + count: S32): Result {.cdecl, + importc: "hidbusGetJoyPollingReceivedData".} diff --git a/src/libnx/wrapper/switch/services/hiddbg.h b/src/libnx/wrapper/switch/services/hiddbg.h new file mode 100644 index 0000000..b6b0d7a --- /dev/null +++ b/src/libnx/wrapper/switch/services/hiddbg.h @@ -0,0 +1,482 @@ +/** + * @file hiddbg.h + * @brief hid:dbg service IPC wrapper. + * @author yellows8 + */ +#pragma once +#include "../types.h" +#include "../services/hid.h" +#include "../services/hidsys.h" +#include "../sf/service.h" + +/// HiddbgNpadButton. For the remaining buttons, see \ref HidNpadButton. +typedef enum { + HiddbgNpadButton_Home = BIT(18), ///< HOME button + HiddbgNpadButton_Capture = BIT(19), ///< Capture button +} HiddbgNpadButton; + +/// HdlsAttribute +typedef enum { + HiddbgHdlsAttribute_HasVirtualSixAxisSensorAcceleration = BIT(0), ///< HasVirtualSixAxisSensorAcceleration + HiddbgHdlsAttribute_HasVirtualSixAxisSensorAngle = BIT(1), ///< HasVirtualSixAxisSensorAngle +} HiddbgHdlsAttribute; + +/// State for overriding \ref HidDebugPadState. +typedef struct { + u32 attributes; ///< Bitfield of \ref HidDebugPadAttribute. + u32 buttons; ///< Bitfield of \ref HidDebugPadButton. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR +} HiddbgDebugPadAutoPilotState; + +/// State for overriding \ref HidMouseState. +typedef struct { + s32 x; ///< X + s32 y; ///< Y + s32 delta_x; ///< DeltaX + s32 delta_y; ///< DeltaY + s32 wheel_delta; ///< WheelDelta + u32 buttons; ///< Bitfield of \ref HidMouseButton. + u32 attributes; ///< Bitfield of \ref HidMouseAttribute. +} HiddbgMouseAutoPilotState; + +/// State for overriding \ref HidKeyboardState. +typedef struct { + u64 modifiers; ///< Bitfield of \ref HidKeyboardModifier. + u64 keys[4]; +} HiddbgKeyboardAutoPilotState; + +/// State for overriding SleepButtonState. +typedef struct { + u64 buttons; ///< Bitfield of buttons, only bit0 is used. +} HiddbgSleepButtonAutoPilotState; + +/// HdlsHandle +typedef struct { + u64 handle; ///< Handle +} HiddbgHdlsHandle; + +/// HdlsSessionId, returned by \ref hiddbgAttachHdlsWorkBuffer. +typedef struct { + u64 id; ///< Id +} HiddbgHdlsSessionId; + +/// HdlsDeviceInfo, for [7.0.0-8.1.0]. +typedef struct { + u32 deviceTypeInternal; ///< Only one bit can be set. BIT(N*4+0) = Pro-Controller, BIT(N*4+1) = Joy-Con Left, BIT(N*4+2) = Joy-Con Right, BIT(N*4+3) = invalid. Where N is 0-1. BIT(8-10) = Pro-Controller, BIT(11) = Famicom-Controller, BIT(12) = Famicom-Controller II with microphone, BIT(13) = NES-Controller(DeviceType=0x200), BIT(14) = NES-Controller(DeviceType=0x400), BIT(15-16) = invalid, BIT(17) = unknown(DeviceType=0x8000), BIT(18-20) = invalid, BIT(21-23) = unknown(DeviceType=0x80000000). + u32 singleColorBody; ///< RGBA Single Body Color. + u32 singleColorButtons; ///< RGBA Single Buttons Color. + u8 npadInterfaceType; ///< \ref HidNpadInterfaceType. Additional type field used with the above type field (only applies to type bit0-bit2 and bit21), if the value doesn't match one of the following a default is used. Type Pro-Controller: value 0x3 indicates that the controller is connected via USB. Type BIT(21): value 0x3 = unknown. When value is 0x2, state is merged with an existing controller (when the type value is compatible with this). Otherwise, it's a dedicated controller. + u8 pad[0x3]; ///< Padding. +} HiddbgHdlsDeviceInfoV7; + +/// HdlsDeviceInfo, for [9.0.0+]. Converted to/from \ref HiddbgHdlsDeviceInfoV7 on prior sysvers. +typedef struct { + u8 deviceType; ///< \ref HidDeviceType + u8 npadInterfaceType; ///< \ref HidNpadInterfaceType. Additional type field used with the above type field (only applies to ::HidDeviceType_JoyRight1, ::HidDeviceType_JoyLeft2, ::HidDeviceType_FullKey3, and ::HidDeviceType_System19), if the value doesn't match one of the following a default is used. ::HidDeviceType_FullKey3: ::HidNpadInterfaceType_USB indicates that the controller is connected via USB. :::HidDeviceType_System19: ::HidNpadInterfaceType_USB = unknown. When value is ::HidNpadInterfaceType_Rail, state is merged with an existing controller (with ::HidDeviceType_JoyRight1 / ::HidDeviceType_JoyLeft2). Otherwise, it's a dedicated controller. + u8 pad[0x2]; ///< Padding. + u32 singleColorBody; ///< RGBA Single Body Color. + u32 singleColorButtons; ///< RGBA Single Buttons Color. + u32 colorLeftGrip; ///< [9.0.0+] RGBA Left Grip Color. + u32 colorRightGrip; ///< [9.0.0+] RGBA Right Grip Color. +} HiddbgHdlsDeviceInfo; + +/// HdlsState, for [7.0.0-8.1.0]. +typedef struct { + u8 is_powered; ///< IsPowered for the main PowerInfo, see \ref HidNpadSystemProperties. + u8 flags; ///< ORRed with IsPowered to set the value of the first byte for \ref HidNpadSystemProperties. For example, value 1 here will set IsCharging for the main PowerInfo. + u8 unk_x2[0x6]; ///< Unknown + u32 battery_level; ///< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + u32 buttons; ///< See \ref HiddbgNpadButton. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + u8 indicator; ///< Indicator. Unused for input. Set with output from \ref hiddbgDumpHdlsStates. Not set by \ref hiddbgGetAbstractedPadsState. + u8 padding[0x3]; ///< Padding +} HiddbgHdlsStateV7; + +/// HdlsState, for [9.0.0-11.0.1]. +typedef struct { + u32 battery_level; ///< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + u32 flags; ///< Used to set the main PowerInfo for \ref HidNpadSystemProperties. BIT(0) -> IsPowered, BIT(1) -> IsCharging. + u64 buttons; ///< See \ref HiddbgNpadButton. [9.0.0+] Masked with 0xfffffffff00fffff. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + u8 indicator; ///< Indicator. Unused for input. Set with output from \ref hiddbgDumpHdlsStates. + u8 padding[0x3]; ///< Padding +} HiddbgHdlsStateV9; + +/// HdlsState, for [12.0.0+]. +typedef struct { + u32 battery_level; ///< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + u32 flags; ///< Used to set the main PowerInfo for \ref HidNpadSystemProperties. BIT(0) -> IsPowered, BIT(1) -> IsCharging. + u64 buttons; ///< See \ref HiddbgNpadButton. [9.0.0+] Masked with 0xfffffffff00fffff. + HidAnalogStickState analog_stick_l; ///< AnalogStickL + HidAnalogStickState analog_stick_r; ///< AnalogStickR + HidVector six_axis_sensor_acceleration; ///< VirtualSixAxisSensorAcceleration + HidVector six_axis_sensor_angle; ///< VirtualSixAxisSensorAngle + u32 attribute; ///< Bitfield of \ref HiddbgHdlsAttribute. + u8 indicator; ///< Indicator. Unused for input. + u8 padding[0x3]; ///< Padding +} HiddbgHdlsState; + +/// HdlsNpadAssignmentEntry +typedef struct { + HiddbgHdlsHandle handle; ///< \ref HiddbgHdlsHandle + u32 unk_x8; ///< Unknown + u32 unk_xc; ///< Unknown + u64 unk_x10; ///< Unknown + u8 unk_x18; ///< Unknown + u8 pad[0x7]; ///< Padding +} HiddbgHdlsNpadAssignmentEntry; + +/// HdlsNpadAssignment. Same controllers as \ref HiddbgHdlsStateList, with different entry data. +typedef struct { + s32 total_entries; ///< Total entries for the below entries. + u32 pad; ///< Padding + HiddbgHdlsNpadAssignmentEntry entries[0x10]; ///< \ref HiddbgHdlsNpadAssignmentEntry +} HiddbgHdlsNpadAssignment; + +/// HdlsStateListEntryV7, for [7.0.0-8.1.0]. +typedef struct { + HiddbgHdlsHandle handle; ///< \ref HiddbgHdlsHandle + HiddbgHdlsDeviceInfoV7 device; ///< \ref HiddbgHdlsDeviceInfoV7. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + HiddbgHdlsStateV7 state; ///< \ref HiddbgHdlsStateV7 +} HiddbgHdlsStateListEntryV7; + +/// HdlsStateListV7, for [7.0.0-8.1.0]. This contains a list of all controllers, including non-virtual controllers. +typedef struct { + s32 total_entries; ///< Total entries for the below entries. + u32 pad; ///< Padding + HiddbgHdlsStateListEntryV7 entries[0x10]; ///< \ref HiddbgHdlsStateListEntryV7 +} HiddbgHdlsStateListV7; + +/// HdlsStateListEntry, for [9.0.0-11.0.1]. +typedef struct { + HiddbgHdlsHandle handle; ///< \ref HiddbgHdlsHandle + HiddbgHdlsDeviceInfo device; ///< \ref HiddbgHdlsDeviceInfo. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + alignas(8) HiddbgHdlsStateV9 state; ///< \ref HiddbgHdlsStateV9 +} HiddbgHdlsStateListEntryV9; + +/// HdlsStateList, for [9.0.0-11.0.1]. +typedef struct { + s32 total_entries; ///< Total entries for the below entries. + u32 pad; ///< Padding + HiddbgHdlsStateListEntryV9 entries[0x10]; ///< \ref HiddbgHdlsStateListEntryV9 +} HiddbgHdlsStateListV9; + +/// HdlsStateListEntry, for [12.0.0+]. +typedef struct { + HiddbgHdlsHandle handle; ///< \ref HiddbgHdlsHandle + HiddbgHdlsDeviceInfo device; ///< \ref HiddbgHdlsDeviceInfo. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + alignas(8) HiddbgHdlsState state; ///< \ref HiddbgHdlsState +} HiddbgHdlsStateListEntry; + +/// HdlsStateList, for [12.0.0+]. +/// This contains a list of all controllers, including non-virtual controllers. +typedef struct { + s32 total_entries; ///< Total entries for the below entries. + u32 pad; ///< Padding + HiddbgHdlsStateListEntry entries[0x10]; ///< \ref HiddbgHdlsStateListEntry +} HiddbgHdlsStateList; + +/// AbstractedPadHandle +typedef struct { + u64 handle; ///< Handle +} HiddbgAbstractedPadHandle; + +/// AbstractedPadState +typedef struct { + u32 type; ///< Type. Converted to HiddbgHdlsDeviceInfoV7::type internally by \ref hiddbgSetAutoPilotVirtualPadState. BIT(0) -> BIT(0), BIT(1) -> BIT(15), BIT(2-3) -> BIT(1-2), BIT(4-5) -> BIT(1-2), BIT(6) -> BIT(3). BIT(7-11) -> BIT(11-15), BIT(12-14) -> BIT(12-14), BIT(15) -> BIT(17), BIT(31) -> BIT(21). + u8 flags; ///< Flags. Only bit0 is used by \ref hiddbgSetAutoPilotVirtualPadState, when clear it will skip using the rest of the input and run \ref hiddbgUnsetAutoPilotVirtualPadState internally. + u8 pad[0x3]; ///< Padding + + u32 singleColorBody; ///< RGBA Single Body Color + u32 singleColorButtons; ///< RGBA Single Buttons Color + u8 npadInterfaceType; ///< See HiddbgHdlsDeviceInfo::npadInterfaceType. + u8 pad2[0x3]; ///< Padding + + HiddbgHdlsStateV7 state; ///< State + + u8 unused[0x60]; ///< Unused with \ref hiddbgSetAutoPilotVirtualPadState. Not set by \ref hiddbgGetAbstractedPadsState. +} HiddbgAbstractedPadState; + +/// Initialize hiddbg. +Result hiddbgInitialize(void); + +/// Exit hiddbg. +void hiddbgExit(void); + +/// Gets the Service object for the actual hiddbg service session. +Service* hiddbgGetServiceSession(void); + +/** + * @brief SetDebugPadAutoPilotState + * @param[in] state \ref HiddbgDebugPadAutoPilotState + */ +Result hiddbgSetDebugPadAutoPilotState(const HiddbgDebugPadAutoPilotState *state); + +/** + * @brief UnsetDebugPadAutoPilotState + */ +Result hiddbgUnsetDebugPadAutoPilotState(void); + +/** + * @brief SetTouchScreenAutoPilotState + * @param[in] states Input array of \ref HiddbgMouseAutoPilotState. + * @param[in] count Total entries in the states array. Max is 16. + */ +Result hiddbgSetTouchScreenAutoPilotState(const HidTouchState *states, s32 count); + +/** + * @brief UnsetTouchScreenAutoPilotState + */ +Result hiddbgUnsetTouchScreenAutoPilotState(void); + +/** + * @brief SetMouseAutoPilotState + * @param[in] state \ref HiddbgMouseAutoPilotState + */ +Result hiddbgSetMouseAutoPilotState(const HiddbgMouseAutoPilotState *state); + +/** + * @brief UnsetMouseAutoPilotState + */ +Result hiddbgUnsetMouseAutoPilotState(void); + +/** + * @brief SetKeyboardAutoPilotState + * @param[in] state \ref HiddbgKeyboardAutoPilotState + */ +Result hiddbgSetKeyboardAutoPilotState(const HiddbgKeyboardAutoPilotState *state); + +/** + * @brief UnsetKeyboardAutoPilotState + */ +Result hiddbgUnsetKeyboardAutoPilotState(void); + +/** + * @brief Deactivates the HomeButton. + */ +Result hiddbgDeactivateHomeButton(void); + +/** + * @brief SetSleepButtonAutoPilotState + * @param[in] state \ref HiddbgSleepButtonAutoPilotState + */ +Result hiddbgSetSleepButtonAutoPilotState(const HiddbgSleepButtonAutoPilotState *state); + +/** + * @brief UnsetSleepButtonAutoPilotState + */ +Result hiddbgUnsetSleepButtonAutoPilotState(void); + +/** + * @brief Writes the input RGB colors to the spi-flash for the specified UniquePad (offset 0x6050 size 0x6). + * @note Only available with [3.0.0+]. + * @param[in] colorBody RGB body color. + * @param[in] colorButtons RGB buttons color. + * @param[in] unique_pad_id \ref HidsysUniquePadId + */ +Result hiddbgUpdateControllerColor(u32 colorBody, u32 colorButtons, HidsysUniquePadId unique_pad_id); + +/** + * @brief Writes the input RGB colors followed by inval to the spi-flash for the specified UniquePad (offset 0x6050 size 0xD). + * @note Only available with [5.0.0+]. + * @param[in] colorBody RGB body color. + * @param[in] colorButtons RGB buttons color. + * @param[in] colorLeftGrip RGB left grip color. + * @param[in] colorRightGrip RGB right grip color. + * @param[in] inval Input value. + * @param[in] unique_pad_id \ref HidsysUniquePadId + */ +Result hiddbgUpdateDesignInfo(u32 colorBody, u32 colorButtons, u32 colorLeftGrip, u32 colorRightGrip, u8 inval, HidsysUniquePadId unique_pad_id); + +/** + * @brief Get the OperationEvent for the specified UniquePad. + * @note The Event must be closed by the user once finished with it. + * @note Only available with [6.0.0+]. + * @param[out] out_event Output Event. + * @param[in] autoclear The autoclear for the Event. + * @param[in] unique_pad_id \ref HidsysUniquePadId +**/ +Result hiddbgAcquireOperationEventHandle(Event* out_event, bool autoclear, HidsysUniquePadId unique_pad_id); + +/** + * @brief Reads spi-flash for the specified UniquePad. + * @note This also uses \ref hiddbgAcquireOperationEventHandle to wait for the operation to finish, then \ref hiddbgGetOperationResult is used. + * @note Only available with [6.0.0+]. + * @param[in] offset Offset in spi-flash. + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size. + * @param[in] unique_pad_id \ref HidsysUniquePadId +**/ +Result hiddbgReadSerialFlash(u32 offset, void* buffer, size_t size, HidsysUniquePadId unique_pad_id); + +/** + * @brief Writes spi-flash for the specified UniquePad. + * @note This also uses \ref hiddbgAcquireOperationEventHandle to wait for the operation to finish, then \ref hiddbgGetOperationResult is used. + * @note Only available with [6.0.0+]. + * @param[in] offset Offset in spi-flash. + * @param[in] buffer Input buffer, must be 0x1000-byte aligned. + * @param[in] tmem_size Size of the buffer, must be 0x1000-byte aligned. + * @param[in] size Actual transfer size. + * @param[in] unique_pad_id \ref HidsysUniquePadId +**/ +Result hiddbgWriteSerialFlash(u32 offset, void* buffer, size_t tmem_size, size_t size, HidsysUniquePadId unique_pad_id); + +/** + * @brief Get the Result for the Operation and handles cleanup, for the specified UniquePad. + * @note Only available with [6.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId +**/ +Result hiddbgGetOperationResult(HidsysUniquePadId unique_pad_id); + +/** + * @brief Gets the internal DeviceType for the specified controller. + * @note Only available with [6.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Pre-9.0.0 this is an u32, with [9.0.0+] it's an u8. +**/ +Result hiddbgGetUniquePadDeviceTypeSetInternal(HidsysUniquePadId unique_pad_id, u32 *out); + +/** @name AbstractedPad + * This is for virtual HID controllers. Only use this on pre-7.0.0, Hdls should be used otherwise. + */ +///@{ + +/** + * @brief Gets a list of \ref HiddbgAbstractedPadHandle. + * @note Only available with [5.0.0-8.1.0]. + * @param[out] handles Output array of \ref HiddbgAbstractedPadHandle. + * @param[in] count Max number of entries for the handles array. + * @param[out] total_out Total output entries. + */ +Result hiddbgGetAbstractedPadHandles(HiddbgAbstractedPadHandle *handles, s32 count, s32 *total_out); + +/** + * @brief Gets the state for the specified \ref HiddbgAbstractedPadHandle. + * @note Only available with [5.0.0-8.1.0]. + * @param[in] handle \ref HiddbgAbstractedPadHandle + * @param[out] state \ref HiddbgAbstractedPadState + */ +Result hiddbgGetAbstractedPadState(HiddbgAbstractedPadHandle handle, HiddbgAbstractedPadState *state); + +/** + * @brief Similar to \ref hiddbgGetAbstractedPadHandles except this also returns the state for each pad in output array states. + * @note Only available with [5.0.0-8.1.0]. + * @param[out] handles Output array of \ref HiddbgAbstractedPadHandle. + * @param[out] states Output array of \ref HiddbgAbstractedPadState. + * @param[in] count Max number of entries for the handles/states arrays. + * @param[out] total_out Total output entries. + */ +Result hiddbgGetAbstractedPadsState(HiddbgAbstractedPadHandle *handles, HiddbgAbstractedPadState *states, s32 count, s32 *total_out); + +/** + * @brief Sets AutoPilot state for the specified pad. + * @note Only available with [5.0.0-8.1.0]. + * @param[in] AbstractedVirtualPadId This can be any unique value as long as it's within bounds. For example, 0-7 is usable. + * @param[in] state \ref HiddbgAbstractedPadState + */ +Result hiddbgSetAutoPilotVirtualPadState(s8 AbstractedVirtualPadId, const HiddbgAbstractedPadState *state); + +/** + * @brief Clears AutoPilot state for the specified pad set by \ref hiddbgSetAutoPilotVirtualPadState. + * @note Only available with [5.0.0-8.1.0]. + * @param[in] AbstractedVirtualPadId Id from \ref hiddbgSetAutoPilotVirtualPadState. + */ +Result hiddbgUnsetAutoPilotVirtualPadState(s8 AbstractedVirtualPadId); + +/** + * @brief Clears AutoPilot state for all pads set by \ref hiddbgSetAutoPilotVirtualPadState. + */ +Result hiddbgUnsetAllAutoPilotVirtualPadState(void); + +///@} + +/** @name Hdls + * This is for virtual HID controllers. + */ +///@{ + +/** + * @brief Initialize Hdls. + * @note Only available with [7.0.0+]. + * @param[out] session_id [13.0.0+] \ref HiddbgHdlsSessionId + */ +Result hiddbgAttachHdlsWorkBuffer(HiddbgHdlsSessionId *session_id); + +/** + * @brief Exit Hdls, must be called at some point prior to \ref hiddbgExit. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + */ +Result hiddbgReleaseHdlsWorkBuffer(HiddbgHdlsSessionId session_id); + +/** + * @brief Checks if the given device is still attached. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + * @param[in] handle \ref HiddbgHdlsHandle + * @param[out] out Whether the device is attached. + */ +Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsSessionId session_id, HiddbgHdlsHandle handle, bool *out); + +/** + * @brief Gets state for \ref HiddbgHdlsNpadAssignment. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + * @param[out] state \ref HiddbgHdlsNpadAssignment + */ +Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, HiddbgHdlsNpadAssignment *state); + +/** + * @brief Gets state for \ref HiddbgHdlsStateList. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + * @param[out] state \ref HiddbgHdlsStateList + */ +Result hiddbgDumpHdlsStates(HiddbgHdlsSessionId session_id, HiddbgHdlsStateList *state); + +/** + * @brief Sets state for \ref HiddbgHdlsNpadAssignment. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + * @param[in] state \ref HiddbgHdlsNpadAssignment + * @param[in] flag Flag + */ +Result hiddbgApplyHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, const HiddbgHdlsNpadAssignment *state, bool flag); + +/** + * @brief Sets state for \ref HiddbgHdlsStateList. + * @note The \ref HiddbgHdlsState will be applied for each \ref HiddbgHdlsHandle. If a \ref HiddbgHdlsHandle is not found, code similar to \ref hiddbgAttachHdlsVirtualDevice will run with the \ref HiddbgHdlsDeviceInfo, then it will continue with applying state with the new device. + * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId + * @param[in] state \ref HiddbgHdlsStateList + */ +Result hiddbgApplyHdlsStateList(HiddbgHdlsSessionId session_id, const HiddbgHdlsStateList *state); + +/** + * @brief Attach a device with the input info. + * @note Only available with [7.0.0+]. + * @param[out] handle \ref HiddbgHdlsHandle + * @param[in] info \ref HiddbgHdlsDeviceInfo + */ +Result hiddbgAttachHdlsVirtualDevice(HiddbgHdlsHandle *handle, const HiddbgHdlsDeviceInfo *info); + +/** + * @brief Detach the specified device. + * @note Only available with [7.0.0+]. + * @param[in] handle \ref HiddbgHdlsHandle + */ +Result hiddbgDetachHdlsVirtualDevice(HiddbgHdlsHandle handle); + +/** + * @brief Sets state for the specified device. + * @note Only available with [7.0.0+]. + * @param[in] handle \ref HiddbgHdlsHandle + * @param[in] state \ref HiddbgHdlsState + */ +Result hiddbgSetHdlsState(HiddbgHdlsHandle handle, const HiddbgHdlsState *state); + +///@} + diff --git a/src/libnx/wrapper/switch/services/hiddbg.nim b/src/libnx/wrapper/switch/services/hiddbg.nim new file mode 100644 index 0000000..e0a3aa9 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hiddbg.nim @@ -0,0 +1,572 @@ +## * +## @file hiddbg.h +## @brief hid:dbg service IPC wrapper. +## @author yellows8 +## + +import + ../types, ../services/hid, ../services/hidsys, ../sf/service, ../kernel/event + +## / HiddbgNpadButton. For the remaining buttons, see \ref HidNpadButton. + +type + HiddbgNpadButton* = enum + HiddbgNpadButtonHome = bit(18), ## /< HOME button + HiddbgNpadButtonCapture = bit(19) ## /< Capture button + + +## / HdlsAttribute + +type + HiddbgHdlsAttribute* = enum + HiddbgHdlsAttributeHasVirtualSixAxisSensorAcceleration = bit(0), ## /< HasVirtualSixAxisSensorAcceleration + HiddbgHdlsAttributeHasVirtualSixAxisSensorAngle = bit(1) ## /< HasVirtualSixAxisSensorAngle + + +## / State for overriding \ref HidDebugPadState. + +type + HiddbgDebugPadAutoPilotState* {.bycopy.} = object + attributes*: U32 ## /< Bitfield of \ref HidDebugPadAttribute. + buttons*: U32 ## /< Bitfield of \ref HidDebugPadButton. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + + +## / State for overriding \ref HidMouseState. + +type + HiddbgMouseAutoPilotState* {.bycopy.} = object + x*: S32 ## /< X + y*: S32 ## /< Y + deltaX*: S32 ## /< DeltaX + deltaY*: S32 ## /< DeltaY + wheelDelta*: S32 ## /< WheelDelta + buttons*: U32 ## /< Bitfield of \ref HidMouseButton. + attributes*: U32 ## /< Bitfield of \ref HidMouseAttribute. + + +## / State for overriding \ref HidKeyboardState. + +type + HiddbgKeyboardAutoPilotState* {.bycopy.} = object + modifiers*: U64 ## /< Bitfield of \ref HidKeyboardModifier. + keys*: array[4, U64] + + +## / State for overriding SleepButtonState. + +type + HiddbgSleepButtonAutoPilotState* {.bycopy.} = object + buttons*: U64 ## /< Bitfield of buttons, only bit0 is used. + + +## / HdlsHandle + +type + HiddbgHdlsHandle* {.bycopy.} = object + handle*: U64 ## /< Handle + + +## / HdlsSessionId, returned by \ref hiddbgAttachHdlsWorkBuffer. + +type + HiddbgHdlsSessionId* {.bycopy.} = object + id*: U64 ## /< Id + + +## / HdlsDeviceInfo, for [7.0.0-8.1.0]. + +type + HiddbgHdlsDeviceInfoV7* {.bycopy.} = object + deviceTypeInternal*: U32 ## /< Only one bit can be set. BIT(N*4+0) = Pro-Controller, BIT(N*4+1) = Joy-Con Left, BIT(N*4+2) = Joy-Con Right, BIT(N*4+3) = invalid. Where N is 0-1. BIT(8-10) = Pro-Controller, BIT(11) = Famicom-Controller, BIT(12) = Famicom-Controller II with microphone, BIT(13) = NES-Controller(DeviceType=0x200), BIT(14) = NES-Controller(DeviceType=0x400), BIT(15-16) = invalid, BIT(17) = unknown(DeviceType=0x8000), BIT(18-20) = invalid, BIT(21-23) = unknown(DeviceType=0x80000000). + singleColorBody*: U32 ## /< RGBA Single Body Color. + singleColorButtons*: U32 ## /< RGBA Single Buttons Color. + npadInterfaceType*: U8 ## /< \ref HidNpadInterfaceType. Additional type field used with the above type field (only applies to type bit0-bit2 and bit21), if the value doesn't match one of the following a default is used. Type Pro-Controller: value 0x3 indicates that the controller is connected via USB. Type BIT(21): value 0x3 = unknown. When value is 0x2, state is merged with an existing controller (when the type value is compatible with this). Otherwise, it's a dedicated controller. + pad*: array[0x3, U8] ## /< Padding. + + +## / HdlsDeviceInfo, for [9.0.0+]. Converted to/from \ref HiddbgHdlsDeviceInfoV7 on prior sysvers. + +type + HiddbgHdlsDeviceInfo* {.bycopy.} = object + deviceType*: U8 ## /< \ref HidDeviceType + npadInterfaceType*: U8 ## /< \ref HidNpadInterfaceType. Additional type field used with the above type field (only applies to ::HidDeviceType_JoyRight1, ::HidDeviceType_JoyLeft2, ::HidDeviceType_FullKey3, and ::HidDeviceType_System19), if the value doesn't match one of the following a default is used. ::HidDeviceType_FullKey3: ::HidNpadInterfaceType_USB indicates that the controller is connected via USB. :::HidDeviceType_System19: ::HidNpadInterfaceType_USB = unknown. When value is ::HidNpadInterfaceType_Rail, state is merged with an existing controller (with ::HidDeviceType_JoyRight1 / ::HidDeviceType_JoyLeft2). Otherwise, it's a dedicated controller. + pad*: array[0x2, U8] ## /< Padding. + singleColorBody*: U32 ## /< RGBA Single Body Color. + singleColorButtons*: U32 ## /< RGBA Single Buttons Color. + colorLeftGrip*: U32 ## /< [9.0.0+] RGBA Left Grip Color. + colorRightGrip*: U32 ## /< [9.0.0+] RGBA Right Grip Color. + + +## / HdlsState, for [7.0.0-8.1.0]. + +type + HiddbgHdlsStateV7* {.bycopy.} = object + isPowered*: U8 ## /< IsPowered for the main PowerInfo, see \ref HidNpadSystemProperties. + flags*: U8 ## /< ORRed with IsPowered to set the value of the first byte for \ref HidNpadSystemProperties. For example, value 1 here will set IsCharging for the main PowerInfo. + unkX2*: array[0x6, U8] ## /< Unknown + batteryLevel*: U32 ## /< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + buttons*: U32 ## /< See \ref HiddbgNpadButton. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + indicator*: U8 ## /< Indicator. Unused for input. Set with output from \ref hiddbgDumpHdlsStates. Not set by \ref hiddbgGetAbstractedPadsState. + padding*: array[0x3, U8] ## /< Padding + + +## / HdlsState, for [9.0.0-11.0.1]. + +type + HiddbgHdlsStateV9* {.bycopy.} = object + batteryLevel*: U32 ## /< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + flags*: U32 ## /< Used to set the main PowerInfo for \ref HidNpadSystemProperties. BIT(0) -> IsPowered, BIT(1) -> IsCharging. + buttons*: U64 ## /< See \ref HiddbgNpadButton. [9.0.0+] Masked with 0xfffffffff00fffff. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + indicator*: U8 ## /< Indicator. Unused for input. Set with output from \ref hiddbgDumpHdlsStates. + padding*: array[0x3, U8] ## /< Padding + + +## / HdlsState, for [12.0.0+]. + +type + HiddbgHdlsState* {.bycopy.} = object + batteryLevel*: U32 ## /< BatteryLevel for the main PowerInfo, see \ref HidPowerInfo. + flags*: U32 ## /< Used to set the main PowerInfo for \ref HidNpadSystemProperties. BIT(0) -> IsPowered, BIT(1) -> IsCharging. + buttons*: U64 ## /< See \ref HiddbgNpadButton. [9.0.0+] Masked with 0xfffffffff00fffff. + analogStickL*: HidAnalogStickState ## /< AnalogStickL + analogStickR*: HidAnalogStickState ## /< AnalogStickR + sixAxisSensorAcceleration*: HidVector ## /< VirtualSixAxisSensorAcceleration + sixAxisSensorAngle*: HidVector ## /< VirtualSixAxisSensorAngle + attribute*: U32 ## /< Bitfield of \ref HiddbgHdlsAttribute. + indicator*: U8 ## /< Indicator. Unused for input. + padding*: array[0x3, U8] ## /< Padding + + +## / HdlsNpadAssignmentEntry + +type + HiddbgHdlsNpadAssignmentEntry* {.bycopy.} = object + handle*: HiddbgHdlsHandle ## /< \ref HiddbgHdlsHandle + unkX8*: U32 ## /< Unknown + unkXc*: U32 ## /< Unknown + unkX10*: U64 ## /< Unknown + unkX18*: U8 ## /< Unknown + pad*: array[0x7, U8] ## /< Padding + + +## / HdlsNpadAssignment. Same controllers as \ref HiddbgHdlsStateList, with different entry data. + +type + HiddbgHdlsNpadAssignment* {.bycopy.} = object + totalEntries*: S32 ## /< Total entries for the below entries. + pad*: U32 ## /< Padding + entries*: array[0x10, HiddbgHdlsNpadAssignmentEntry] ## /< \ref HiddbgHdlsNpadAssignmentEntry + + +## / HdlsStateListEntryV7, for [7.0.0-8.1.0]. + +type + HiddbgHdlsStateListEntryV7* {.bycopy.} = object + handle*: HiddbgHdlsHandle ## /< \ref HiddbgHdlsHandle + device*: HiddbgHdlsDeviceInfoV7 ## /< \ref HiddbgHdlsDeviceInfoV7. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + state*: HiddbgHdlsStateV7 ## /< \ref HiddbgHdlsStateV7 + + +## / HdlsStateListV7, for [7.0.0-8.1.0]. This contains a list of all controllers, including non-virtual controllers. + +type + HiddbgHdlsStateListV7* {.bycopy.} = object + totalEntries*: S32 ## /< Total entries for the below entries. + pad*: U32 ## /< Padding + entries*: array[0x10, HiddbgHdlsStateListEntryV7] ## /< \ref HiddbgHdlsStateListEntryV7 + + +## / HdlsStateListEntry, for [9.0.0-11.0.1]. + +type + HiddbgHdlsStateListEntryV9* {.bycopy.} = object + handle*: HiddbgHdlsHandle ## /< \ref HiddbgHdlsHandle + device*: HiddbgHdlsDeviceInfo ## /< \ref HiddbgHdlsDeviceInfo. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + state*: HiddbgHdlsStateV9 ## /< \ref HiddbgHdlsStateV9 + + +## / HdlsStateList, for [9.0.0-11.0.1]. + +type + HiddbgHdlsStateListV9* {.bycopy.} = object + totalEntries*: S32 ## /< Total entries for the below entries. + pad*: U32 ## /< Padding + entries*: array[0x10, HiddbgHdlsStateListEntryV9] ## /< \ref HiddbgHdlsStateListEntryV9 + + +## / HdlsStateListEntry, for [12.0.0+]. + +type + HiddbgHdlsStateListEntry* {.bycopy.} = object + handle*: HiddbgHdlsHandle ## /< \ref HiddbgHdlsHandle + device*: HiddbgHdlsDeviceInfo ## /< \ref HiddbgHdlsDeviceInfo. With \ref hiddbgApplyHdlsStateList this is only used when creating new devices. + state*: HiddbgHdlsState ## /< \ref HiddbgHdlsState + + +## / HdlsStateList, for [12.0.0+]. +## / This contains a list of all controllers, including non-virtual controllers. + +type + HiddbgHdlsStateList* {.bycopy.} = object + totalEntries*: S32 ## /< Total entries for the below entries. + pad*: U32 ## /< Padding + entries*: array[0x10, HiddbgHdlsStateListEntry] ## /< \ref HiddbgHdlsStateListEntry + + +## / AbstractedPadHandle + +type + HiddbgAbstractedPadHandle* {.bycopy.} = object + handle*: U64 ## /< Handle + + +## / AbstractedPadState + +type + HiddbgAbstractedPadState* {.bycopy.} = object + `type`*: U32 ## /< Type. Converted to HiddbgHdlsDeviceInfoV7::type internally by \ref hiddbgSetAutoPilotVirtualPadState. BIT(0) -> BIT(0), BIT(1) -> BIT(15), BIT(2-3) -> BIT(1-2), BIT(4-5) -> BIT(1-2), BIT(6) -> BIT(3). BIT(7-11) -> BIT(11-15), BIT(12-14) -> BIT(12-14), BIT(15) -> BIT(17), BIT(31) -> BIT(21). + flags*: U8 ## /< Flags. Only bit0 is used by \ref hiddbgSetAutoPilotVirtualPadState, when clear it will skip using the rest of the input and run \ref hiddbgUnsetAutoPilotVirtualPadState internally. + pad*: array[0x3, U8] ## /< Padding + singleColorBody*: U32 ## /< RGBA Single Body Color + singleColorButtons*: U32 ## /< RGBA Single Buttons Color + npadInterfaceType*: U8 ## /< See HiddbgHdlsDeviceInfo::npadInterfaceType. + pad2*: array[0x3, U8] ## /< Padding + state*: HiddbgHdlsStateV7 ## /< State + unused*: array[0x60, U8] ## /< Unused with \ref hiddbgSetAutoPilotVirtualPadState. Not set by \ref hiddbgGetAbstractedPadsState. + +proc hiddbgInitialize*(): Result {.cdecl, importc: "hiddbgInitialize".} +## / Initialize hiddbg. + +proc hiddbgExit*() {.cdecl, importc: "hiddbgExit".} +## / Exit hiddbg. + +proc hiddbgGetServiceSession*(): ptr Service {.cdecl, + importc: "hiddbgGetServiceSession".} +## / Gets the Service object for the actual hiddbg service session. + +proc hiddbgSetDebugPadAutoPilotState*(state: ptr HiddbgDebugPadAutoPilotState): Result {. + cdecl, importc: "hiddbgSetDebugPadAutoPilotState".} +## * +## @brief SetDebugPadAutoPilotState +## @param[in] state \ref HiddbgDebugPadAutoPilotState +## + +proc hiddbgUnsetDebugPadAutoPilotState*(): Result {.cdecl, + importc: "hiddbgUnsetDebugPadAutoPilotState".} +## * +## @brief UnsetDebugPadAutoPilotState +## + +proc hiddbgSetTouchScreenAutoPilotState*(states: ptr HidTouchState; count: S32): Result {. + cdecl, importc: "hiddbgSetTouchScreenAutoPilotState".} +## * +## @brief SetTouchScreenAutoPilotState +## @param[in] states Input array of \ref HiddbgMouseAutoPilotState. +## @param[in] count Total entries in the states array. Max is 16. +## + +proc hiddbgUnsetTouchScreenAutoPilotState*(): Result {.cdecl, + importc: "hiddbgUnsetTouchScreenAutoPilotState".} +## * +## @brief UnsetTouchScreenAutoPilotState +## + +proc hiddbgSetMouseAutoPilotState*(state: ptr HiddbgMouseAutoPilotState): Result {. + cdecl, importc: "hiddbgSetMouseAutoPilotState".} +## * +## @brief SetMouseAutoPilotState +## @param[in] state \ref HiddbgMouseAutoPilotState +## + +proc hiddbgUnsetMouseAutoPilotState*(): Result {.cdecl, + importc: "hiddbgUnsetMouseAutoPilotState".} +## * +## @brief UnsetMouseAutoPilotState +## + +proc hiddbgSetKeyboardAutoPilotState*(state: ptr HiddbgKeyboardAutoPilotState): Result {. + cdecl, importc: "hiddbgSetKeyboardAutoPilotState".} +## * +## @brief SetKeyboardAutoPilotState +## @param[in] state \ref HiddbgKeyboardAutoPilotState +## + +proc hiddbgUnsetKeyboardAutoPilotState*(): Result {.cdecl, + importc: "hiddbgUnsetKeyboardAutoPilotState".} +## * +## @brief UnsetKeyboardAutoPilotState +## + +proc hiddbgDeactivateHomeButton*(): Result {.cdecl, + importc: "hiddbgDeactivateHomeButton".} +## * +## @brief Deactivates the HomeButton. +## + +proc hiddbgSetSleepButtonAutoPilotState*(state: ptr HiddbgSleepButtonAutoPilotState): Result {. + cdecl, importc: "hiddbgSetSleepButtonAutoPilotState".} +## * +## @brief SetSleepButtonAutoPilotState +## @param[in] state \ref HiddbgSleepButtonAutoPilotState +## + +proc hiddbgUnsetSleepButtonAutoPilotState*(): Result {.cdecl, + importc: "hiddbgUnsetSleepButtonAutoPilotState".} +## * +## @brief UnsetSleepButtonAutoPilotState +## + +proc hiddbgUpdateControllerColor*(colorBody: U32; colorButtons: U32; + uniquePadId: HidsysUniquePadId): Result {.cdecl, + importc: "hiddbgUpdateControllerColor".} +## * +## @brief Writes the input RGB colors to the spi-flash for the specified UniquePad (offset 0x6050 size 0x6). +## @note Only available with [3.0.0+]. +## @param[in] colorBody RGB body color. +## @param[in] colorButtons RGB buttons color. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgUpdateDesignInfo*(colorBody: U32; colorButtons: U32; colorLeftGrip: U32; + colorRightGrip: U32; inval: U8; + uniquePadId: HidsysUniquePadId): Result {.cdecl, + importc: "hiddbgUpdateDesignInfo".} +## * +## @brief Writes the input RGB colors followed by inval to the spi-flash for the specified UniquePad (offset 0x6050 size 0xD). +## @note Only available with [5.0.0+]. +## @param[in] colorBody RGB body color. +## @param[in] colorButtons RGB buttons color. +## @param[in] colorLeftGrip RGB left grip color. +## @param[in] colorRightGrip RGB right grip color. +## @param[in] inval Input value. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgAcquireOperationEventHandle*(outEvent: ptr Event; autoclear: bool; + uniquePadId: HidsysUniquePadId): Result {. + cdecl, importc: "hiddbgAcquireOperationEventHandle".} +## * +## @brief Get the OperationEvent for the specified UniquePad. +## @note The Event must be closed by the user once finished with it. +## @note Only available with [6.0.0+]. +## @param[out] out_event Output Event. +## @param[in] autoclear The autoclear for the Event. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgReadSerialFlash*(offset: U32; buffer: pointer; size: csize_t; + uniquePadId: HidsysUniquePadId): Result {.cdecl, + importc: "hiddbgReadSerialFlash".} +## * +## @brief Reads spi-flash for the specified UniquePad. +## @note This also uses \ref hiddbgAcquireOperationEventHandle to wait for the operation to finish, then \ref hiddbgGetOperationResult is used. +## @note Only available with [6.0.0+]. +## @param[in] offset Offset in spi-flash. +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgWriteSerialFlash*(offset: U32; buffer: pointer; tmemSize: csize_t; + size: csize_t; uniquePadId: HidsysUniquePadId): Result {. + cdecl, importc: "hiddbgWriteSerialFlash".} +## * +## @brief Writes spi-flash for the specified UniquePad. +## @note This also uses \ref hiddbgAcquireOperationEventHandle to wait for the operation to finish, then \ref hiddbgGetOperationResult is used. +## @note Only available with [6.0.0+]. +## @param[in] offset Offset in spi-flash. +## @param[in] buffer Input buffer, must be 0x1000-byte aligned. +## @param[in] tmem_size Size of the buffer, must be 0x1000-byte aligned. +## @param[in] size Actual transfer size. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgGetOperationResult*(uniquePadId: HidsysUniquePadId): Result {.cdecl, + importc: "hiddbgGetOperationResult".} +## * +## @brief Get the Result for the Operation and handles cleanup, for the specified UniquePad. +## @note Only available with [6.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hiddbgGetUniquePadDeviceTypeSetInternal*(uniquePadId: HidsysUniquePadId; + `out`: ptr U32): Result {.cdecl, + importc: "hiddbgGetUniquePadDeviceTypeSetInternal".} +## * +## @brief Gets the internal DeviceType for the specified controller. +## @note Only available with [6.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Pre-9.0.0 this is an u32, with [9.0.0+] it's an u8. +## + +proc hiddbgGetAbstractedPadHandles*(handles: ptr HiddbgAbstractedPadHandle; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "hiddbgGetAbstractedPadHandles".} +## * @name AbstractedPad +## This is for virtual HID controllers. Only use this on pre-7.0.0, Hdls should be used otherwise. +## +## /@{ +## * +## @brief Gets a list of \ref HiddbgAbstractedPadHandle. +## @note Only available with [5.0.0-8.1.0]. +## @param[out] handles Output array of \ref HiddbgAbstractedPadHandle. +## @param[in] count Max number of entries for the handles array. +## @param[out] total_out Total output entries. +## + +proc hiddbgGetAbstractedPadState*(handle: HiddbgAbstractedPadHandle; + state: ptr HiddbgAbstractedPadState): Result {. + cdecl, importc: "hiddbgGetAbstractedPadState".} +## * +## @brief Gets the state for the specified \ref HiddbgAbstractedPadHandle. +## @note Only available with [5.0.0-8.1.0]. +## @param[in] handle \ref HiddbgAbstractedPadHandle +## @param[out] state \ref HiddbgAbstractedPadState +## + +proc hiddbgGetAbstractedPadsState*(handles: ptr HiddbgAbstractedPadHandle; + states: ptr HiddbgAbstractedPadState; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "hiddbgGetAbstractedPadsState".} +## * +## @brief Similar to \ref hiddbgGetAbstractedPadHandles except this also returns the state for each pad in output array states. +## @note Only available with [5.0.0-8.1.0]. +## @param[out] handles Output array of \ref HiddbgAbstractedPadHandle. +## @param[out] states Output array of \ref HiddbgAbstractedPadState. +## @param[in] count Max number of entries for the handles/states arrays. +## @param[out] total_out Total output entries. +## + +proc hiddbgSetAutoPilotVirtualPadState*(abstractedVirtualPadId: S8; + state: ptr HiddbgAbstractedPadState): Result {. + cdecl, importc: "hiddbgSetAutoPilotVirtualPadState".} +## * +## @brief Sets AutoPilot state for the specified pad. +## @note Only available with [5.0.0-8.1.0]. +## @param[in] AbstractedVirtualPadId This can be any unique value as long as it's within bounds. For example, 0-7 is usable. +## @param[in] state \ref HiddbgAbstractedPadState +## + +proc hiddbgUnsetAutoPilotVirtualPadState*(abstractedVirtualPadId: S8): Result {. + cdecl, importc: "hiddbgUnsetAutoPilotVirtualPadState".} +## * +## @brief Clears AutoPilot state for the specified pad set by \ref hiddbgSetAutoPilotVirtualPadState. +## @note Only available with [5.0.0-8.1.0]. +## @param[in] AbstractedVirtualPadId Id from \ref hiddbgSetAutoPilotVirtualPadState. +## + +proc hiddbgUnsetAllAutoPilotVirtualPadState*(): Result {.cdecl, + importc: "hiddbgUnsetAllAutoPilotVirtualPadState".} +## * +## @brief Clears AutoPilot state for all pads set by \ref hiddbgSetAutoPilotVirtualPadState. +## + +proc hiddbgAttachHdlsWorkBuffer*(sessionId: ptr HiddbgHdlsSessionId): Result {.cdecl, + importc: "hiddbgAttachHdlsWorkBuffer".} +## /@} +## * @name Hdls +## This is for virtual HID controllers. +## +## /@{ +## * +## @brief Initialize Hdls. +## @note Only available with [7.0.0+]. +## @param[out] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## + +proc hiddbgReleaseHdlsWorkBuffer*(sessionId: HiddbgHdlsSessionId): Result {.cdecl, + importc: "hiddbgReleaseHdlsWorkBuffer".} +## * +## @brief Exit Hdls, must be called at some point prior to \ref hiddbgExit. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## + +proc hiddbgIsHdlsVirtualDeviceAttached*(sessionId: HiddbgHdlsSessionId; + handle: HiddbgHdlsHandle; `out`: ptr bool): Result {. + cdecl, importc: "hiddbgIsHdlsVirtualDeviceAttached".} +## * +## @brief Checks if the given device is still attached. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## @param[in] handle \ref HiddbgHdlsHandle +## @param[out] out Whether the device is attached. +## + +proc hiddbgDumpHdlsNpadAssignmentState*(sessionId: HiddbgHdlsSessionId; + state: ptr HiddbgHdlsNpadAssignment): Result {. + cdecl, importc: "hiddbgDumpHdlsNpadAssignmentState".} +## * +## @brief Gets state for \ref HiddbgHdlsNpadAssignment. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## @param[out] state \ref HiddbgHdlsNpadAssignment +## + +proc hiddbgDumpHdlsStates*(sessionId: HiddbgHdlsSessionId; + state: ptr HiddbgHdlsStateList): Result {.cdecl, + importc: "hiddbgDumpHdlsStates".} +## * +## @brief Gets state for \ref HiddbgHdlsStateList. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## @param[out] state \ref HiddbgHdlsStateList +## + +proc hiddbgApplyHdlsNpadAssignmentState*(sessionId: HiddbgHdlsSessionId; + state: ptr HiddbgHdlsNpadAssignment; + flag: bool): Result {.cdecl, + importc: "hiddbgApplyHdlsNpadAssignmentState".} +## * +## @brief Sets state for \ref HiddbgHdlsNpadAssignment. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## @param[in] state \ref HiddbgHdlsNpadAssignment +## @param[in] flag Flag +## + +proc hiddbgApplyHdlsStateList*(sessionId: HiddbgHdlsSessionId; + state: ptr HiddbgHdlsStateList): Result {.cdecl, + importc: "hiddbgApplyHdlsStateList".} +## * +## @brief Sets state for \ref HiddbgHdlsStateList. +## @note The \ref HiddbgHdlsState will be applied for each \ref HiddbgHdlsHandle. If a \ref HiddbgHdlsHandle is not found, code similar to \ref hiddbgAttachHdlsVirtualDevice will run with the \ref HiddbgHdlsDeviceInfo, then it will continue with applying state with the new device. +## @note Only available with [7.0.0+]. +## @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId +## @param[in] state \ref HiddbgHdlsStateList +## + +proc hiddbgAttachHdlsVirtualDevice*(handle: ptr HiddbgHdlsHandle; + info: ptr HiddbgHdlsDeviceInfo): Result {.cdecl, + importc: "hiddbgAttachHdlsVirtualDevice".} +## * +## @brief Attach a device with the input info. +## @note Only available with [7.0.0+]. +## @param[out] handle \ref HiddbgHdlsHandle +## @param[in] info \ref HiddbgHdlsDeviceInfo +## + +proc hiddbgDetachHdlsVirtualDevice*(handle: HiddbgHdlsHandle): Result {.cdecl, + importc: "hiddbgDetachHdlsVirtualDevice".} +## * +## @brief Detach the specified device. +## @note Only available with [7.0.0+]. +## @param[in] handle \ref HiddbgHdlsHandle +## + +proc hiddbgSetHdlsState*(handle: HiddbgHdlsHandle; state: ptr HiddbgHdlsState): Result {. + cdecl, importc: "hiddbgSetHdlsState".} +## * +## @brief Sets state for the specified device. +## @note Only available with [7.0.0+]. +## @param[in] handle \ref HiddbgHdlsHandle +## @param[in] state \ref HiddbgHdlsState +## + +## /@} diff --git a/src/libnx/wrapper/switch/services/hidsys.h b/src/libnx/wrapper/switch/services/hidsys.h new file mode 100644 index 0000000..36f1313 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hidsys.h @@ -0,0 +1,967 @@ +/** + * @file hidsys.h + * @brief hid:sys service IPC wrapper. + * @author exelix, yellows8, ndeadly + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/hid.h" +#include "../services/btdrv_types.h" +#include "../sf/service.h" + +/// Selects what button to map to. +typedef enum { + HidcfgDigitalButtonAssignment_A = 0, ///< A + HidcfgDigitalButtonAssignment_B = 1, ///< B + HidcfgDigitalButtonAssignment_X = 2, ///< X + HidcfgDigitalButtonAssignment_Y = 3, ///< Y + HidcfgDigitalButtonAssignment_StickL = 4, ///< Left Stick Button + HidcfgDigitalButtonAssignment_StickR = 5, ///< Right Stick Button + HidcfgDigitalButtonAssignment_L = 6, ///< L + HidcfgDigitalButtonAssignment_R = 7, ///< R + HidcfgDigitalButtonAssignment_ZL = 8, ///< ZL + HidcfgDigitalButtonAssignment_ZR = 9, ///< ZR + HidcfgDigitalButtonAssignment_Select = 10, ///< Select / Minus + HidcfgDigitalButtonAssignment_Start = 11, ///< Start / Plus + HidcfgDigitalButtonAssignment_Left = 12, ///< Left + HidcfgDigitalButtonAssignment_Up = 13, ///< Up + HidcfgDigitalButtonAssignment_Right = 14, ///< Right + HidcfgDigitalButtonAssignment_Down = 15, ///< Down + HidcfgDigitalButtonAssignment_LeftSL = 16, ///< SL on Left controller. + HidcfgDigitalButtonAssignment_LeftSR = 17, ///< SR on Left controller. + HidcfgDigitalButtonAssignment_RightSL = 18, ///< SL on Right controller. + HidcfgDigitalButtonAssignment_RightSR = 19, ///< SR on Right controller. + HidcfgDigitalButtonAssignment_HomeButton = 20, ///< HomeButton + HidcfgDigitalButtonAssignment_CaptureButton = 21, ///< CaptureButton + HidcfgDigitalButtonAssignment_Invalid = 22, ///< Invalid / Disabled +} HidcfgDigitalButtonAssignment; + +/// AnalogStickRotation +typedef enum { + HidcfgAnalogStickRotation_None = 0, ///< None + HidcfgAnalogStickRotation_Clockwise90 = 1, ///< Clockwise90 + HidcfgAnalogStickRotation_Anticlockwise90 = 2, ///< Anticlockwise90 +} HidcfgAnalogStickRotation; + +/// UniquePadType +typedef enum { + HidsysUniquePadType_Embedded = 0, ///< Embedded + HidsysUniquePadType_FullKeyController = 1, ///< FullKeyController + HidsysUniquePadType_RightController = 2, ///< RightController + HidsysUniquePadType_LeftController = 3, ///< LeftController + HidsysUniquePadType_DebugPadController = 4, ///< DebugPadController +} HidsysUniquePadType; + +/// UniquePadId for a controller. +typedef struct { + u64 id; ///< UniquePadId +} HidsysUniquePadId; + +/// UniquePadSerialNumber +typedef struct { + char serial_number[0x10]; ///< SerialNumber +} HidsysUniquePadSerialNumber; + +/// Mini Cycle struct for \ref HidsysNotificationLedPattern. +typedef struct { + u8 ledIntensity; ///< Mini Cycle X LED Intensity. + u8 transitionSteps; ///< Fading Transition Steps to Mini Cycle X (Uses PWM). Value 0x0: Instant. Each step duration is based on HidsysNotificationLedPattern::baseMiniCycleDuration. + u8 finalStepDuration; ///< Final Step Duration Multiplier of Mini Cycle X. Value 0x0: 12.5ms, 0x1 - xF: 1x - 15x. Value is a Multiplier of HidsysNotificationLedPattern::baseMiniCycleDuration. + u8 pad; +} HidsysNotificationLedPatternCycle; + +/// Structure for \ref hidsysSetNotificationLedPattern. +/// See also: https://switchbrew.org/wiki/HID_services#NotificationLedPattern +/// Only the low 4bits of each used byte in this struct is used. +typedef struct { + u8 baseMiniCycleDuration; ///< Mini Cycle Base Duration. Value 0x1-0xF: 12.5ms - 187.5ms. Value 0x0 = 0ms/OFF. + u8 totalMiniCycles; ///< Number of Mini Cycles + 1. Value 0x0-0xF: 1 - 16 mini cycles. + u8 totalFullCycles; ///< Number of Full Cycles. Value 0x1-0xF: 1 - 15 full cycles. Value 0x0 is repeat forever, but if baseMiniCycleDuration is set to 0x0, it does the 1st Mini Cycle with a 12.5ms step duration and then the LED stays on with startIntensity. + u8 startIntensity; ///< LED Start Intensity. Value 0x0=0% - 0xF=100%. + + HidsysNotificationLedPatternCycle miniCycles[16]; ///< Mini Cycles + + u8 unk_x44[0x2]; ///< Unknown + u8 pad_x46[0x2]; ///< Padding +} HidsysNotificationLedPattern; + +/// ButtonConfigEmbedded +typedef struct { + u8 unk_x0[0x2C8]; +} HidsysButtonConfigEmbedded; + +/// ButtonConfigFull +typedef struct { + u8 unk_x0[0x2C8]; +} HidsysButtonConfigFull; + +/// ButtonConfigLeft +typedef struct { + u8 unk_x0[0x1C8]; +} HidsysButtonConfigLeft; + +/// ButtonConfigRight +typedef struct { + u8 unk_x0[0x1A0]; +} HidsysButtonConfigRight; + +/// AnalogStickAssignment +typedef struct { + u32 rotation; ///< \ref HidcfgAnalogStickRotation + u8 is_paired_stick_assigned; ///< IsPairedStickAssigned + u8 reserved[3]; ///< Reserved +} HidcfgAnalogStickAssignment; + +/// ButtonConfigEmbedded +typedef struct { + u32 hardware_button_left; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + u32 hardware_button_up; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + u32 hardware_button_right; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + u32 hardware_button_down; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + u32 hardware_button_a; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonA + u32 hardware_button_b; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonB + u32 hardware_button_x; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonX + u32 hardware_button_y; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonY + u32 hardware_button_stick_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + u32 hardware_button_stick_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + u32 hardware_button_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonL + u32 hardware_button_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonR + u32 hardware_button_zl; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + u32 hardware_button_zr; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + u32 hardware_button_select; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + u32 hardware_button_start; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + u32 hardware_button_capture; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + HidcfgAnalogStickAssignment hardware_stick_l; ///< HardwareStickL + HidcfgAnalogStickAssignment hardware_stick_r; ///< HardwareStickR +} HidcfgButtonConfigEmbedded; + +/// ButtonConfigFull +typedef struct { + u32 hardware_button_left; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + u32 hardware_button_up; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + u32 hardware_button_right; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + u32 hardware_button_down; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + u32 hardware_button_a; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonA + u32 hardware_button_b; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonB + u32 hardware_button_x; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonX + u32 hardware_button_y; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonY + u32 hardware_button_stick_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + u32 hardware_button_stick_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + u32 hardware_button_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonL + u32 hardware_button_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonR + u32 hardware_button_zl; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + u32 hardware_button_zr; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + u32 hardware_button_select; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + u32 hardware_button_start; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + u32 hardware_button_capture; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + HidcfgAnalogStickAssignment hardware_stick_l; ///< HardwareStickL + HidcfgAnalogStickAssignment hardware_stick_r; ///< HardwareStickR +} HidcfgButtonConfigFull; + +/// ButtonConfigLeft +typedef struct { + u32 hardware_button_left; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + u32 hardware_button_up; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + u32 hardware_button_right; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + u32 hardware_button_down; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + u32 hardware_button_stick_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + u32 hardware_button_l; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonL + u32 hardware_button_zl; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + u32 hardware_button_select; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + u32 hardware_button_left_sl; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonLeftSL + u32 hardware_button_left_sr; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonLeftSR + u32 hardware_button_capture; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + HidcfgAnalogStickAssignment hardware_stick_l; ///< HardwareStickL +} HidcfgButtonConfigLeft; + +/// ButtonConfigRight +typedef struct { + u32 hardware_button_a; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonA + u32 hardware_button_b; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonB + u32 hardware_button_x; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonX + u32 hardware_button_y; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonY + u32 hardware_button_stick_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + u32 hardware_button_r; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonR + u32 hardware_button_zr; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + u32 hardware_button_start; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + u32 hardware_button_right_sl; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonRightSL + u32 hardware_button_right_sr; ///< \ref HidcfgDigitalButtonAssignment HardwareButtonRightSR + HidcfgAnalogStickAssignment hardware_stick_r; ///< HardwareStickR +} HidcfgButtonConfigRight; + +/// StorageName +typedef struct { + u8 name[0x81]; ///< UTF-8 NUL-terminated name string. +} HidcfgStorageName; + +/// Initialize hidsys. +Result hidsysInitialize(void); + +/// Exit hidsys. +void hidsysExit(void); + +/// Gets the Service object for the actual hidsys service session. +Service* hidsysGetServiceSession(void); + +/** + * @brief SendKeyboardLockKeyEvent + * @param[in] events Bitfield of \ref HidKeyboardLockKeyEvent. + */ +Result hidsysSendKeyboardLockKeyEvent(u32 events); + +/** + * @brief Gets an Event which is signaled when HidHomeButtonState is updated. + * @note The Event must be closed by the user once finished with it. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. + * @param[out] out_event Output Event. + * @param[in] Event autoclear. +**/ +Result hidsysAcquireHomeButtonEventHandle(Event* out_event, bool autoclear); + +/** + * @brief Activates the HomeButton sharedmem. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. +**/ +Result hidsysActivateHomeButton(void); + +/** + * @brief Gets an Event which is signaled when HidSleepButtonState is updated. + * @note The Event must be closed by the user once finished with it. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. + * @param[out] out_event Output Event. + * @param[in] Event autoclear. +**/ +Result hidsysAcquireSleepButtonEventHandle(Event* out_event, bool autoclear); + +/** + * @brief Activates the SleepButton sharedmem. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. +**/ +Result hidsysActivateSleepButton(void); + +/** + * @brief Gets an Event which is signaled when HidCaptureButtonState is updated. + * @note The Event must be closed by the user once finished with it. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. + * @param[out] out_event Output Event. + * @param[in] Event autoclear. +**/ +Result hidsysAcquireCaptureButtonEventHandle(Event* out_event, bool autoclear); + +/** + * @brief Activates the CaptureButton sharedmem. + * @note This generally shouldn't be used, since AM-sysmodule uses it internally. +**/ +Result hidsysActivateCaptureButton(void); + +/** + * @brief Gets the SupportedNpadStyleSet for the CallerApplet. applet must be initialized in order to use this (uses \ref appletGetAppletResourceUserIdOfCallerApplet). + * @note Only available on [6.0.0+]. + * @param[out] out Bitmask of \ref HidNpadStyleTag. + */ +Result hidsysGetSupportedNpadStyleSetOfCallerApplet(u32 *out); + +/** + * @brief Gets the \ref HidNpadInterfaceType for the specified controller. + * @note Only available on [10.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out \ref HidNpadInterfaceType + */ +Result hidsysGetNpadInterfaceType(HidNpadIdType id, u8 *out); + +/** + * @brief GetNpadLeftRightInterfaceType + * @note Only available on [10.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out0 \ref HidNpadInterfaceType + * @param[out] out1 \ref HidNpadInterfaceType + */ +Result hidsysGetNpadLeftRightInterfaceType(HidNpadIdType id, u8 *out0, u8 *out1); + +/** + * @brief HasBattery + * @note Only available on [10.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out Output flag. + */ +Result hidsysHasBattery(HidNpadIdType id, bool *out); + +/** + * @brief HasLeftRightBattery + * @note Only available on [10.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] out0 Output flag. + * @param[out] out1 Output flag. + */ +Result hidsysHasLeftRightBattery(HidNpadIdType id, bool *out0, bool *out1); + +/** + * @brief Gets the UniquePadIds for the specified controller. + * @note Only available on [3.0.0+]. + * @param[in] id \ref HidNpadIdType + * @param[out] unique_pad_ids Output array of \ref HidsysUniquePadId. + * @param[in] count Max number of entries for the unique_pad_ids array. + * @param[out] total_out Total output array entries. Optional, can be NULL. + */ +Result hidsysGetUniquePadsFromNpad(HidNpadIdType id, HidsysUniquePadId *unique_pad_ids, s32 count, s32 *total_out); + +/** + * @brief EnableAppletToGetInput + * @param[in] enable Input flag. +**/ +Result hidsysEnableAppletToGetInput(bool enable); + +/** + * @brief AcquireUniquePadConnectionEventHandle + * @param[out] out_event Output Event. + */ +Result hidsysAcquireUniquePadConnectionEventHandle(Event *out_event); + +/** + * @brief Gets a list of all UniquePadIds. + * @param[out] unique_pad_ids Output array of \ref HidsysUniquePadId. + * @param[in] count Max number of entries for the unique_pad_ids array. + * @param[out] total_out Total output array entries. Optional, can be NULL. + */ +Result hidsysGetUniquePadIds(HidsysUniquePadId *unique_pad_ids, s32 count, s32 *total_out); + +/** + * @brief GetUniquePadBluetoothAddress + * @note Only available on [3.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] address \ref BtdrvAddress + */ +Result hidsysGetUniquePadBluetoothAddress(HidsysUniquePadId unique_pad_id, BtdrvAddress *address); + +/** + * @brief DisconnectUniquePad + * @note Only available on [3.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + */ +Result hidsysDisconnectUniquePad(HidsysUniquePadId unique_pad_id); + +/** + * @brief GetUniquePadType + * @note Only available on [5.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] pad_type \ref HidsysUniquePadType + */ +Result hidsysGetUniquePadType(HidsysUniquePadId unique_pad_id, HidsysUniquePadType *pad_type); + +/** + * @brief GetUniquePadInterface + * @note Only available on [5.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] interface \ref HidNpadInterfaceType + */ +Result hidsysGetUniquePadInterface(HidsysUniquePadId unique_pad_id, HidNpadInterfaceType *interface); + +/** + * @brief Gets the \ref HidsysUniquePadSerialNumber. + * @note Only available on [5.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] serial \ref HidsysUniquePadSerialNumber + */ +Result hidsysGetUniquePadSerialNumber(HidsysUniquePadId unique_pad_id, HidsysUniquePadSerialNumber *serial); + +/** + * @brief GetUniquePadControllerNumber + * @note Only available on [5.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] number Controller number. + */ +Result hidsysGetUniquePadControllerNumber(HidsysUniquePadId unique_pad_id, u64 *number); + +/** + * @brief Sets the HOME-button notification LED pattern, for the specified controller. + * @note Generally this should only be used if \ref hidsysSetNotificationLedPatternWithTimeout is not usable. + * @note Only available on [7.0.0+]. + * @param[in] pattern \ref HidsysNotificationLedPattern + * @param[in] unique_pad_id \ref HidsysUniquePadId + */ +Result hidsysSetNotificationLedPattern(const HidsysNotificationLedPattern *pattern, HidsysUniquePadId unique_pad_id); + +/** + * @brief Sets the HOME-button notification LED pattern, for the specified controller. The LED will automatically be disabled once the specified timeout occurs. + * @note Only available on [9.0.0+], and with controllers which have the [9.0.0+] firmware installed. + * @param[in] pattern \ref HidsysNotificationLedPattern + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] timeout Timeout in nanoseconds. + */ +Result hidsysSetNotificationLedPatternWithTimeout(const HidsysNotificationLedPattern *pattern, HidsysUniquePadId unique_pad_id, u64 timeout); + +/** + * @brief IsUsbFullKeyControllerEnabled + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result hidsysIsUsbFullKeyControllerEnabled(bool *out); + +/** + * @brief EnableUsbFullKeyController + * @note Only available on [3.0.0+]. + * @param[in] flag Flag + */ +Result hidsysEnableUsbFullKeyController(bool flag); + +/** + * @brief IsUsbConnected + * @note Only available on [3.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output flag. + */ +Result hidsysIsUsbConnected(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief IsFirmwareUpdateNeededForNotification + * @note Only available on [9.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output flag. + */ +Result hidsysIsFirmwareUpdateNeededForNotification(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief Legacy IsButtonConfigSupported. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigSupported instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output bool flag. + */ +Result hidsysLegacyIsButtonConfigSupported(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief IsButtonConfigSupported + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigSupported instead. + * @param[in] addr \ref BtdrvAddress + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigSupported(BtdrvAddress addr, bool *out); + +/** + * @brief IsButtonConfigEmbeddedSupported + * @note Only available on [11.0.0+]. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigEmbeddedSupported(bool *out); + +/** + * @brief Legacy DeleteButtonConfig. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysDeleteButtonConfig instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + */ +Result hidsysLegacyDeleteButtonConfig(HidsysUniquePadId unique_pad_id); + +/** + * @brief DeleteButtonConfig + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyDeleteButtonConfig instead. + * @param[in] addr \ref BtdrvAddress + */ +Result hidsysDeleteButtonConfig(BtdrvAddress addr); + +/** + * @brief DeleteButtonConfigEmbedded + * @note Only available on [11.0.0+]. + */ +Result hidsysDeleteButtonConfigEmbedded(void); + +/** + * @brief Legacy SetButtonConfigEnabled. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEnabled instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] flag Input flag. + */ +Result hidsysLegacySetButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool flag); + +/** + * @brief SetButtonConfigEnabled + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEnabled instead. + * @param[in] addr \ref BtdrvAddress + * @param[in] flag Input flag. + */ +Result hidsysSetButtonConfigEnabled(BtdrvAddress addr, bool flag); + +/** + * @brief SetButtonConfigEmbeddedEnabled + * @note Only available on [11.0.0+]. + * @param[in] flag Input flag. + */ +Result hidsysSetButtonConfigEmbeddedEnabled(bool flag); + +/** + * @brief Legacy IsButtonConfigEnabled. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigEnabled instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output bool flag. + */ +Result hidsysLegacyIsButtonConfigEnabled(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief IsButtonConfigEnabled + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigEnabled instead. + * @param[in] addr \ref BtdrvAddress + * @param[in] out Output bool flag. + */ +Result hidsysIsButtonConfigEnabled(BtdrvAddress addr, bool *out); + +/** + * @brief IsButtonConfigEmbeddedEnabled + * @note Only available on [11.0.0+]. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigEmbeddedEnabled(bool *out); + +/** + * @brief Legacy SetButtonConfigEmbedded. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEmbedded instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidsysButtonConfigEmbedded + */ +Result hidsysLegacySetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, const HidsysButtonConfigEmbedded *config); + +/** + * @brief SetButtonConfigEmbedded + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEmbedded instead. + * @param[in] config \ref HidsysButtonConfigEmbedded + */ +Result hidsysSetButtonConfigEmbedded(const HidsysButtonConfigEmbedded *config); + +/** + * @brief Legacy SetButtonConfigFull. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigFull instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidsysButtonConfigFull + */ +Result hidsysLegacySetButtonConfigFull(HidsysUniquePadId unique_pad_id, const HidsysButtonConfigFull *config); + +/** + * @brief SetButtonConfigFull + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigFull instead. + * @param[in] addr \ref BtdrvAddress + * @param[in] config \ref HidsysButtonConfigFull + */ +Result hidsysSetButtonConfigFull(BtdrvAddress addr, const HidsysButtonConfigFull *config); + +/** + * @brief Legacy SetButtonConfigLeft. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigLeft instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidsysButtonConfigLeft + */ +Result hidsysLegacySetButtonConfigLeft(HidsysUniquePadId unique_pad_id, const HidsysButtonConfigLeft *config); + +/** + * @brief SetButtonConfigLeft + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigLeft instead. + * @param[in] addr \ref BtdrvAddress + * @param[in] config \ref HidsysButtonConfigLeft + */ +Result hidsysSetButtonConfigLeft(BtdrvAddress addr, const HidsysButtonConfigLeft *config); + +/** + * @brief Legacy SetButtonConfigRight. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigRight instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidsysButtonConfigRight + */ +Result hidsysLegacySetButtonConfigRight(HidsysUniquePadId unique_pad_id, const HidsysButtonConfigRight *config); + +/** + * @brief SetButtonConfigRight + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigRight instead. + * @param[in] addr \ref BtdrvAddress + * @param[in] config \ref HidsysButtonConfigRight + */ +Result hidsysSetButtonConfigRight(BtdrvAddress addr, const HidsysButtonConfigRight *config); + +/** + * @brief Legacy GetButtonConfigEmbedded. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigEmbedded instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidsysButtonConfigEmbedded + */ +Result hidsysLegacyGetButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, HidsysButtonConfigEmbedded *config); + +/** + * @brief GetButtonConfigEmbedded + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigEmbedded instead. + * @param[out] config \ref HidsysButtonConfigEmbedded + */ +Result hidsysGetButtonConfigEmbedded(HidsysButtonConfigEmbedded *config); + +/** + * @brief Legacy GetButtonConfigFull. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigFull instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidsysButtonConfigFull + */ +Result hidsysLegacyGetButtonConfigFull(HidsysUniquePadId unique_pad_id, HidsysButtonConfigFull *config); + +/** + * @brief GetButtonConfigFull + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigFull instead. + * @param[in] addr \ref BtdrvAddress + * @param[out] config \ref HidsysButtonConfigFull + */ +Result hidsysGetButtonConfigFull(BtdrvAddress addr, HidsysButtonConfigFull *config); + +/** + * @brief Legacy GetButtonConfigLeft. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigLeft instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidsysButtonConfigLeft + */ +Result hidsysLegacyGetButtonConfigLeft(HidsysUniquePadId unique_pad_id, HidsysButtonConfigLeft *config); + +/** + * @brief GetButtonConfigLeft + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigLeft instead. + * @param[in] addr \ref BtdrvAddress + * @param[out] config \ref HidsysButtonConfigLeft + */ +Result hidsysGetButtonConfigLeft(BtdrvAddress addr, HidsysButtonConfigLeft *config); + +/** + * @brief Legacy GetButtonConfigRight. + * @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigRight instead. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidsysButtonConfigRight + */ +Result hidsysLegacyGetButtonConfigRight(HidsysUniquePadId unique_pad_id, HidsysButtonConfigRight *config); + +/** + * @brief GetButtonConfigRight + * @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigRight instead. + * @param[in] addr \ref BtdrvAddress + * @param[out] config \ref HidsysButtonConfigRight + */ +Result hidsysGetButtonConfigRight(BtdrvAddress addr, HidsysButtonConfigRight *config); + +/** + * @brief IsCustomButtonConfigSupported + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output bool flag. + */ +Result hidsysIsCustomButtonConfigSupported(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief IsDefaultButtonConfigEmbedded + * @note Only available on [10.0.0+]. + * @param[in] config \ref HidcfgButtonConfigEmbedded + * @param[out] out Output bool flag. + */ +Result hidsysIsDefaultButtonConfigEmbedded(const HidcfgButtonConfigEmbedded *config, bool *out); + +/** + * @brief IsDefaultButtonConfigFull + * @note Only available on [10.0.0+]. + * @param[in] config \ref HidcfgButtonConfigFull + * @param[out] out Output bool flag. + */ +Result hidsysIsDefaultButtonConfigFull(const HidcfgButtonConfigFull *config, bool *out); + +/** + * @brief IsDefaultButtonConfigLeft + * @note Only available on [10.0.0+]. + * @param[in] config \ref HidcfgButtonConfigLeft + * @param[out] out Output bool flag. + */ +Result hidsysIsDefaultButtonConfigLeft(const HidcfgButtonConfigLeft *config, bool *out); + +/** + * @brief IsDefaultButtonConfigRight + * @note Only available on [10.0.0+]. + * @param[in] config \ref HidcfgButtonConfigRight + * @param[out] out Output bool flag. + */ +Result hidsysIsDefaultButtonConfigRight(const HidcfgButtonConfigRight *config, bool *out); + +/** + * @brief IsButtonConfigStorageEmbeddedEmpty + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigStorageEmbeddedEmpty(s32 index, bool *out); + +/** + * @brief IsButtonConfigStorageFullEmpty + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigStorageFullEmpty(s32 index, bool *out); + +/** + * @brief IsButtonConfigStorageLeftEmpty + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigStorageLeftEmpty(s32 index, bool *out); + +/** + * @brief IsButtonConfigStorageRightEmpty + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] out Output bool flag. + */ +Result hidsysIsButtonConfigStorageRightEmpty(s32 index, bool *out); + +/** + * @brief GetButtonConfigStorageEmbeddedDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigEmbedded + */ +Result hidsysGetButtonConfigStorageEmbeddedDeprecated(s32 index, HidcfgButtonConfigEmbedded *config); + +/** + * @brief GetButtonConfigStorageFullDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigFull + */ +Result hidsysGetButtonConfigStorageFullDeprecated(s32 index, HidcfgButtonConfigFull *config); + +/** + * @brief GetButtonConfigStorageLeftDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigLeft + */ +Result hidsysGetButtonConfigStorageLeftDeprecated(s32 index, HidcfgButtonConfigLeft *config); + +/** + * @brief GetButtonConfigStorageRightDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigRight + */ +Result hidsysGetButtonConfigStorageRightDeprecated(s32 index, HidcfgButtonConfigRight *config); + +/** + * @brief SetButtonConfigStorageEmbeddedDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigEmbedded + */ +Result hidsysSetButtonConfigStorageEmbeddedDeprecated(s32 index, const HidcfgButtonConfigEmbedded *config); + +/** + * @brief SetButtonConfigStorageFullDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigFull + */ +Result hidsysSetButtonConfigStorageFullDeprecated(s32 index, const HidcfgButtonConfigFull *config); + +/** + * @brief SetButtonConfigStorageLeftDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigLeft + */ +Result hidsysSetButtonConfigStorageLeftDeprecated(s32 index, const HidcfgButtonConfigLeft *config); + +/** + * @brief SetButtonConfigStorageRightDeprecated + * @note Only available on [10.0.0-12.1.0]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigRight + */ +Result hidsysSetButtonConfigStorageRightDeprecated(s32 index, const HidcfgButtonConfigRight *config); + +/** + * @brief DeleteButtonConfigStorageEmbedded + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + */ +Result hidsysDeleteButtonConfigStorageEmbedded(s32 index); + +/** + * @brief DeleteButtonConfigStorageFull + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + */ +Result hidsysDeleteButtonConfigStorageFull(s32 index); + +/** + * @brief DeleteButtonConfigStorageLeft + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + */ +Result hidsysDeleteButtonConfigStorageLeft(s32 index); + +/** + * @brief DeleteButtonConfigStorageRight + * @note Only available on [10.0.0+]. + * @param[in] index Array index, should be 0-4. + */ +Result hidsysDeleteButtonConfigStorageRight(s32 index); + +/** + * @brief IsUsingCustomButtonConfig + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] out Output bool flag. + */ +Result hidsysIsUsingCustomButtonConfig(HidsysUniquePadId unique_pad_id, bool *out); + +/** + * @brief IsAnyCustomButtonConfigEnabled + * @note Only available on [10.0.0+]. + * @param[out] out Output bool flag. + */ +Result hidsysIsAnyCustomButtonConfigEnabled(bool *out); + +/** + * @brief SetAllCustomButtonConfigEnabled + * @note Only available on [10.0.0+]. + * @param[in] AppletResourceUserId AppletResourceUserId + * @param[in] flag Input bool flag. + */ +Result hidsysSetAllCustomButtonConfigEnabled(u64 AppletResourceUserId, bool flag); + +/** + * @brief SetAllDefaultButtonConfig + * @note Only available on [10.0.0+]. + */ +Result hidsysSetAllDefaultButtonConfig(void); + +/** + * @brief SetHidButtonConfigEmbedded + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidcfgButtonConfigEmbedded + */ +Result hidsysSetHidButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, const HidcfgButtonConfigEmbedded *config); + +/** + * @brief SetHidButtonConfigFull + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidcfgButtonConfigFull + */ +Result hidsysSetHidButtonConfigFull(HidsysUniquePadId unique_pad_id, const HidcfgButtonConfigFull *config); + +/** + * @brief SetHidButtonConfigLeft + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidcfgButtonConfigLeft + */ +Result hidsysSetHidButtonConfigLeft(HidsysUniquePadId unique_pad_id, const HidcfgButtonConfigLeft *config); + +/** + * @brief SetHidButtonConfigRight + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[in] config \ref HidcfgButtonConfigRight + */ +Result hidsysSetHidButtonConfigRight(HidsysUniquePadId unique_pad_id, const HidcfgButtonConfigRight *config); + +/** + * @brief GetHidButtonConfigEmbedded + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidcfgButtonConfigEmbedded + */ +Result hidsysGetHidButtonConfigEmbedded(HidsysUniquePadId unique_pad_id, HidcfgButtonConfigEmbedded *config); + +/** + * @brief GetHidButtonConfigFull + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidcfgButtonConfigFull + */ +Result hidsysGetHidButtonConfigFull(HidsysUniquePadId unique_pad_id, HidcfgButtonConfigFull *config); + +/** + * @brief GetHidButtonConfigLeft + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidcfgButtonConfigLeft + */ +Result hidsysGetHidButtonConfigLeft(HidsysUniquePadId unique_pad_id, HidcfgButtonConfigLeft *config); + +/** + * @brief GetHidButtonConfigRight + * @note Only available on [10.0.0+]. + * @param[in] unique_pad_id \ref HidsysUniquePadId + * @param[out] config \ref HidcfgButtonConfigRight + */ +Result hidsysGetHidButtonConfigRight(HidsysUniquePadId unique_pad_id, HidcfgButtonConfigRight *config); + +/** + * @brief GetButtonConfigStorageEmbedded + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigEmbedded + * @param[out] name \ref HidcfgStorageName + */ +Result hidsysGetButtonConfigStorageEmbedded(s32 index, HidcfgButtonConfigEmbedded *config, HidcfgStorageName *name); + +/** + * @brief GetButtonConfigStorageFull + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigFull + * @param[out] name \ref HidcfgStorageName + */ +Result hidsysGetButtonConfigStorageFull(s32 index, HidcfgButtonConfigFull *config, HidcfgStorageName *name); + +/** + * @brief GetButtonConfigStorageLeft + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigLeft + * @param[out] name \ref HidcfgStorageName + */ +Result hidsysGetButtonConfigStorageLeft(s32 index, HidcfgButtonConfigLeft *config, HidcfgStorageName *name); + +/** + * @brief GetButtonConfigStorageRight + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[out] config \ref HidcfgButtonConfigRight + * @param[out] name \ref HidcfgStorageName + */ +Result hidsysGetButtonConfigStorageRight(s32 index, HidcfgButtonConfigRight *config, HidcfgStorageName *name); + +/** + * @brief SetButtonConfigStorageEmbedded + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigEmbedded + * @param[in] name \ref HidcfgStorageName + */ +Result hidsysSetButtonConfigStorageEmbedded(s32 index, const HidcfgButtonConfigEmbedded *config, const HidcfgStorageName *name); + +/** + * @brief SetButtonConfigStorageFull + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigFull + * @param[in] name \ref HidcfgStorageName + */ +Result hidsysSetButtonConfigStorageFull(s32 index, const HidcfgButtonConfigFull *config, const HidcfgStorageName *name); + +/** + * @brief SetButtonConfigStorageLeft + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigLeft + * @param[in] name \ref HidcfgStorageName + */ +Result hidsysSetButtonConfigStorageLeft(s32 index, const HidcfgButtonConfigLeft *config, const HidcfgStorageName *name); + +/** + * @brief SetButtonConfigStorageRight + * @note Only available on [11.0.0+]. + * @param[in] index Array index, should be 0-4. + * @param[in] config \ref HidcfgButtonConfigRight + * @param[in] name \ref HidcfgStorageName + */ +Result hidsysSetButtonConfigStorageRight(s32 index, const HidcfgButtonConfigRight *config, const HidcfgStorageName *name); + diff --git a/src/libnx/wrapper/switch/services/hidsys.nim b/src/libnx/wrapper/switch/services/hidsys.nim new file mode 100644 index 0000000..6a4c1c3 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hidsys.nim @@ -0,0 +1,1153 @@ +## * +## @file hidsys.h +## @brief hid:sys service IPC wrapper. +## @author exelix, yellows8, ndeadly +## + +import + ../types, ../kernel/event, ../services/hid, ../services/btdrv_types, ../sf/service + +## / Selects what button to map to. + +type + HidcfgDigitalButtonAssignment* = enum + HidcfgDigitalButtonAssignmentA = 0, ## /< A + HidcfgDigitalButtonAssignmentB = 1, ## /< B + HidcfgDigitalButtonAssignmentX = 2, ## /< X + HidcfgDigitalButtonAssignmentY = 3, ## /< Y + HidcfgDigitalButtonAssignmentStickL = 4, ## /< Left Stick Button + HidcfgDigitalButtonAssignmentStickR = 5, ## /< Right Stick Button + HidcfgDigitalButtonAssignmentL = 6, ## /< L + HidcfgDigitalButtonAssignmentR = 7, ## /< R + HidcfgDigitalButtonAssignmentZL = 8, ## /< ZL + HidcfgDigitalButtonAssignmentZR = 9, ## /< ZR + HidcfgDigitalButtonAssignmentSelect = 10, ## /< Select / Minus + HidcfgDigitalButtonAssignmentStart = 11, ## /< Start / Plus + HidcfgDigitalButtonAssignmentLeft = 12, ## /< Left + HidcfgDigitalButtonAssignmentUp = 13, ## /< Up + HidcfgDigitalButtonAssignmentRight = 14, ## /< Right + HidcfgDigitalButtonAssignmentDown = 15, ## /< Down + HidcfgDigitalButtonAssignmentLeftSL = 16, ## /< SL on Left controller. + HidcfgDigitalButtonAssignmentLeftSR = 17, ## /< SR on Left controller. + HidcfgDigitalButtonAssignmentRightSL = 18, ## /< SL on Right controller. + HidcfgDigitalButtonAssignmentRightSR = 19, ## /< SR on Right controller. + HidcfgDigitalButtonAssignmentHomeButton = 20, ## /< HomeButton + HidcfgDigitalButtonAssignmentCaptureButton = 21, ## /< CaptureButton + HidcfgDigitalButtonAssignmentInvalid = 22 ## /< Invalid / Disabled + + +## / AnalogStickRotation + +type + HidcfgAnalogStickRotation* = enum + HidcfgAnalogStickRotationNone = 0, ## /< None + HidcfgAnalogStickRotationClockwise90 = 1, ## /< Clockwise90 + HidcfgAnalogStickRotationAnticlockwise90 = 2 ## /< Anticlockwise90 + + +## / UniquePadType + +type + HidsysUniquePadType* = enum + HidsysUniquePadTypeEmbedded = 0, ## /< Embedded + HidsysUniquePadTypeFullKeyController = 1, ## /< FullKeyController + HidsysUniquePadTypeRightController = 2, ## /< RightController + HidsysUniquePadTypeLeftController = 3, ## /< LeftController + HidsysUniquePadTypeDebugPadController = 4 ## /< DebugPadController + + +## / UniquePadId for a controller. + +type + HidsysUniquePadId* {.bycopy.} = object + id*: U64 ## /< UniquePadId + + +## / UniquePadSerialNumber + +type + HidsysUniquePadSerialNumber* {.bycopy.} = object + serialNumber*: array[0x10, char] ## /< SerialNumber + + +## / Mini Cycle struct for \ref HidsysNotificationLedPattern. + +type + HidsysNotificationLedPatternCycle* {.bycopy.} = object + ledIntensity*: U8 ## /< Mini Cycle X LED Intensity. + transitionSteps*: U8 ## /< Fading Transition Steps to Mini Cycle X (Uses PWM). Value 0x0: Instant. Each step duration is based on HidsysNotificationLedPattern::baseMiniCycleDuration. + finalStepDuration*: U8 ## /< Final Step Duration Multiplier of Mini Cycle X. Value 0x0: 12.5ms, 0x1 - xF: 1x - 15x. Value is a Multiplier of HidsysNotificationLedPattern::baseMiniCycleDuration. + pad*: U8 + + +## / Structure for \ref hidsysSetNotificationLedPattern. +## / See also: https://switchbrew.org/wiki/HID_services#NotificationLedPattern +## / Only the low 4bits of each used byte in this struct is used. + +type + HidsysNotificationLedPattern* {.bycopy.} = object + baseMiniCycleDuration*: U8 ## /< Mini Cycle Base Duration. Value 0x1-0xF: 12.5ms - 187.5ms. Value 0x0 = 0ms/OFF. + totalMiniCycles*: U8 ## /< Number of Mini Cycles + 1. Value 0x0-0xF: 1 - 16 mini cycles. + totalFullCycles*: U8 ## /< Number of Full Cycles. Value 0x1-0xF: 1 - 15 full cycles. Value 0x0 is repeat forever, but if baseMiniCycleDuration is set to 0x0, it does the 1st Mini Cycle with a 12.5ms step duration and then the LED stays on with startIntensity. + startIntensity*: U8 ## /< LED Start Intensity. Value 0x0=0% - 0xF=100%. + miniCycles*: array[16, HidsysNotificationLedPatternCycle] ## /< Mini Cycles + unkX44*: array[0x2, U8] ## /< Unknown + padX46*: array[0x2, U8] ## /< Padding + + +## / ButtonConfigEmbedded + +type + HidsysButtonConfigEmbedded* {.bycopy.} = object + unkX0*: array[0x2C8, U8] + + +## / ButtonConfigFull + +type + HidsysButtonConfigFull* {.bycopy.} = object + unkX0*: array[0x2C8, U8] + + +## / ButtonConfigLeft + +type + HidsysButtonConfigLeft* {.bycopy.} = object + unkX0*: array[0x1C8, U8] + + +## / ButtonConfigRight + +type + HidsysButtonConfigRight* {.bycopy.} = object + unkX0*: array[0x1A0, U8] + + +## / AnalogStickAssignment + +type + HidcfgAnalogStickAssignment* {.bycopy.} = object + rotation*: U32 ## /< \ref HidcfgAnalogStickRotation + isPairedStickAssigned*: U8 ## /< IsPairedStickAssigned + reserved*: array[3, U8] ## /< Reserved + + +## / ButtonConfigEmbedded + +type + HidcfgButtonConfigEmbedded* {.bycopy.} = object + hardwareButtonLeft*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + hardwareButtonUp*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + hardwareButtonRight*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + hardwareButtonDown*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + hardwareButtonA*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonA + hardwareButtonB*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonB + hardwareButtonX*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonX + hardwareButtonY*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonY + hardwareButtonStickL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + hardwareButtonStickR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + hardwareButtonL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonL + hardwareButtonR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonR + hardwareButtonZl*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + hardwareButtonZr*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + hardwareButtonSelect*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + hardwareButtonStart*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + hardwareButtonCapture*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + hardwareStickL*: HidcfgAnalogStickAssignment ## /< HardwareStickL + hardwareStickR*: HidcfgAnalogStickAssignment ## /< HardwareStickR + + +## / ButtonConfigFull + +type + HidcfgButtonConfigFull* {.bycopy.} = object + hardwareButtonLeft*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + hardwareButtonUp*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + hardwareButtonRight*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + hardwareButtonDown*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + hardwareButtonA*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonA + hardwareButtonB*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonB + hardwareButtonX*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonX + hardwareButtonY*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonY + hardwareButtonStickL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + hardwareButtonStickR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + hardwareButtonL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonL + hardwareButtonR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonR + hardwareButtonZl*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + hardwareButtonZr*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + hardwareButtonSelect*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + hardwareButtonStart*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + hardwareButtonCapture*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + hardwareStickL*: HidcfgAnalogStickAssignment ## /< HardwareStickL + hardwareStickR*: HidcfgAnalogStickAssignment ## /< HardwareStickR + + +## / ButtonConfigLeft + +type + HidcfgButtonConfigLeft* {.bycopy.} = object + hardwareButtonLeft*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonLeft + hardwareButtonUp*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonUp + hardwareButtonRight*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonRight + hardwareButtonDown*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonDown + hardwareButtonStickL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickL + hardwareButtonL*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonL + hardwareButtonZl*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZL + hardwareButtonSelect*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonSelect + hardwareButtonLeftSl*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonLeftSL + hardwareButtonLeftSr*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonLeftSR + hardwareButtonCapture*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonCapture + hardwareStickL*: HidcfgAnalogStickAssignment ## /< HardwareStickL + + +## / ButtonConfigRight + +type + HidcfgButtonConfigRight* {.bycopy.} = object + hardwareButtonA*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonA + hardwareButtonB*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonB + hardwareButtonX*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonX + hardwareButtonY*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonY + hardwareButtonStickR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStickR + hardwareButtonR*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonR + hardwareButtonZr*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonZR + hardwareButtonStart*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonStart + hardwareButtonRightSl*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonRightSL + hardwareButtonRightSr*: U32 ## /< \ref HidcfgDigitalButtonAssignment HardwareButtonRightSR + hardwareStickR*: HidcfgAnalogStickAssignment ## /< HardwareStickR + + +## / StorageName + +type + HidcfgStorageName* {.bycopy.} = object + name*: array[0x81, U8] ## /< UTF-8 NUL-terminated name string. + +proc hidsysInitialize*(): Result {.cdecl, importc: "hidsysInitialize".} +## / Initialize hidsys. + +proc hidsysExit*() {.cdecl, importc: "hidsysExit".} +## / Exit hidsys. + +proc hidsysGetServiceSession*(): ptr Service {.cdecl, + importc: "hidsysGetServiceSession".} +## / Gets the Service object for the actual hidsys service session. + +proc hidsysSendKeyboardLockKeyEvent*(events: U32): Result {.cdecl, + importc: "hidsysSendKeyboardLockKeyEvent".} +## * +## @brief SendKeyboardLockKeyEvent +## @param[in] events Bitfield of \ref HidKeyboardLockKeyEvent. +## + +proc hidsysAcquireHomeButtonEventHandle*(outEvent: ptr Event; autoclear: bool): Result {. + cdecl, importc: "hidsysAcquireHomeButtonEventHandle".} +## * +## @brief Gets an Event which is signaled when HidHomeButtonState is updated. +## @note The Event must be closed by the user once finished with it. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## @param[out] out_event Output Event. +## @param[in] Event autoclear. +## + +proc hidsysActivateHomeButton*(): Result {.cdecl, + importc: "hidsysActivateHomeButton".} +## * +## @brief Activates the HomeButton sharedmem. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## + +proc hidsysAcquireSleepButtonEventHandle*(outEvent: ptr Event; autoclear: bool): Result {. + cdecl, importc: "hidsysAcquireSleepButtonEventHandle".} +## * +## @brief Gets an Event which is signaled when HidSleepButtonState is updated. +## @note The Event must be closed by the user once finished with it. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## @param[out] out_event Output Event. +## @param[in] Event autoclear. +## + +proc hidsysActivateSleepButton*(): Result {.cdecl, + importc: "hidsysActivateSleepButton".} +## * +## @brief Activates the SleepButton sharedmem. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## + +proc hidsysAcquireCaptureButtonEventHandle*(outEvent: ptr Event; autoclear: bool): Result {. + cdecl, importc: "hidsysAcquireCaptureButtonEventHandle".} +## * +## @brief Gets an Event which is signaled when HidCaptureButtonState is updated. +## @note The Event must be closed by the user once finished with it. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## @param[out] out_event Output Event. +## @param[in] Event autoclear. +## + +proc hidsysActivateCaptureButton*(): Result {.cdecl, + importc: "hidsysActivateCaptureButton".} +## * +## @brief Activates the CaptureButton sharedmem. +## @note This generally shouldn't be used, since AM-sysmodule uses it internally. +## + +proc hidsysGetSupportedNpadStyleSetOfCallerApplet*(`out`: ptr U32): Result {.cdecl, + importc: "hidsysGetSupportedNpadStyleSetOfCallerApplet".} +## * +## @brief Gets the SupportedNpadStyleSet for the CallerApplet. applet must be initialized in order to use this (uses \ref appletGetAppletResourceUserIdOfCallerApplet). +## @note Only available on [6.0.0+]. +## @param[out] out Bitmask of \ref HidNpadStyleTag. +## + +proc hidsysGetNpadInterfaceType*(id: HidNpadIdType; `out`: ptr U8): Result {.cdecl, + importc: "hidsysGetNpadInterfaceType".} +## * +## @brief Gets the \ref HidNpadInterfaceType for the specified controller. +## @note Only available on [10.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out \ref HidNpadInterfaceType +## + +proc hidsysGetNpadLeftRightInterfaceType*(id: HidNpadIdType; out0: ptr U8; + out1: ptr U8): Result {.cdecl, importc: "hidsysGetNpadLeftRightInterfaceType".} +## * +## @brief GetNpadLeftRightInterfaceType +## @note Only available on [10.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out0 \ref HidNpadInterfaceType +## @param[out] out1 \ref HidNpadInterfaceType +## + +proc hidsysHasBattery*(id: HidNpadIdType; `out`: ptr bool): Result {.cdecl, + importc: "hidsysHasBattery".} +## * +## @brief HasBattery +## @note Only available on [10.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out Output flag. +## + +proc hidsysHasLeftRightBattery*(id: HidNpadIdType; out0: ptr bool; out1: ptr bool): Result {. + cdecl, importc: "hidsysHasLeftRightBattery".} +## * +## @brief HasLeftRightBattery +## @note Only available on [10.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] out0 Output flag. +## @param[out] out1 Output flag. +## + +proc hidsysGetUniquePadsFromNpad*(id: HidNpadIdType; + uniquePadIds: ptr HidsysUniquePadId; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "hidsysGetUniquePadsFromNpad".} +## * +## @brief Gets the UniquePadIds for the specified controller. +## @note Only available on [3.0.0+]. +## @param[in] id \ref HidNpadIdType +## @param[out] unique_pad_ids Output array of \ref HidsysUniquePadId. +## @param[in] count Max number of entries for the unique_pad_ids array. +## @param[out] total_out Total output array entries. Optional, can be NULL. +## + +proc hidsysEnableAppletToGetInput*(enable: bool): Result {.cdecl, + importc: "hidsysEnableAppletToGetInput".} +## * +## @brief EnableAppletToGetInput +## @param[in] enable Input flag. +## + +proc hidsysAcquireUniquePadConnectionEventHandle*(outEvent: ptr Event): Result {. + cdecl, importc: "hidsysAcquireUniquePadConnectionEventHandle".} +## * +## @brief AcquireUniquePadConnectionEventHandle +## @param[out] out_event Output Event. +## + +proc hidsysGetUniquePadIds*(uniquePadIds: ptr HidsysUniquePadId; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "hidsysGetUniquePadIds".} +## * +## @brief Gets a list of all UniquePadIds. +## @param[out] unique_pad_ids Output array of \ref HidsysUniquePadId. +## @param[in] count Max number of entries for the unique_pad_ids array. +## @param[out] total_out Total output array entries. Optional, can be NULL. +## + +proc hidsysGetUniquePadBluetoothAddress*(uniquePadId: HidsysUniquePadId; + address: ptr BtdrvAddress): Result {.cdecl, + importc: "hidsysGetUniquePadBluetoothAddress".} +## * +## @brief GetUniquePadBluetoothAddress +## @note Only available on [3.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] address \ref BtdrvAddress +## + +proc hidsysDisconnectUniquePad*(uniquePadId: HidsysUniquePadId): Result {.cdecl, + importc: "hidsysDisconnectUniquePad".} +## * +## @brief DisconnectUniquePad +## @note Only available on [3.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hidsysGetUniquePadType*(uniquePadId: HidsysUniquePadId; + padType: ptr HidsysUniquePadType): Result {.cdecl, + importc: "hidsysGetUniquePadType".} +## * +## @brief GetUniquePadType +## @note Only available on [5.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] pad_type \ref HidsysUniquePadType +## + +proc hidsysGetUniquePadInterface*(uniquePadId: HidsysUniquePadId; + `interface`: ptr HidNpadInterfaceType): Result {. + cdecl, importc: "hidsysGetUniquePadInterface".} +## * +## @brief GetUniquePadInterface +## @note Only available on [5.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] interface \ref HidNpadInterfaceType +## + +proc hidsysGetUniquePadSerialNumber*(uniquePadId: HidsysUniquePadId; + serial: ptr HidsysUniquePadSerialNumber): Result {. + cdecl, importc: "hidsysGetUniquePadSerialNumber".} +## * +## @brief Gets the \ref HidsysUniquePadSerialNumber. +## @note Only available on [5.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] serial \ref HidsysUniquePadSerialNumber +## + +proc hidsysGetUniquePadControllerNumber*(uniquePadId: HidsysUniquePadId; + number: ptr U64): Result {.cdecl, + importc: "hidsysGetUniquePadControllerNumber".} +## * +## @brief GetUniquePadControllerNumber +## @note Only available on [5.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] number Controller number. +## + +proc hidsysSetNotificationLedPattern*(pattern: ptr HidsysNotificationLedPattern; + uniquePadId: HidsysUniquePadId): Result {. + cdecl, importc: "hidsysSetNotificationLedPattern".} +## * +## @brief Sets the HOME-button notification LED pattern, for the specified controller. +## @note Generally this should only be used if \ref hidsysSetNotificationLedPatternWithTimeout is not usable. +## @note Only available on [7.0.0+]. +## @param[in] pattern \ref HidsysNotificationLedPattern +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hidsysSetNotificationLedPatternWithTimeout*( + pattern: ptr HidsysNotificationLedPattern; uniquePadId: HidsysUniquePadId; + timeout: U64): Result {.cdecl, + importc: "hidsysSetNotificationLedPatternWithTimeout".} +## * +## @brief Sets the HOME-button notification LED pattern, for the specified controller. The LED will automatically be disabled once the specified timeout occurs. +## @note Only available on [9.0.0+], and with controllers which have the [9.0.0+] firmware installed. +## @param[in] pattern \ref HidsysNotificationLedPattern +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] timeout Timeout in nanoseconds. +## + +proc hidsysIsUsbFullKeyControllerEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "hidsysIsUsbFullKeyControllerEnabled".} +## * +## @brief IsUsbFullKeyControllerEnabled +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc hidsysEnableUsbFullKeyController*(flag: bool): Result {.cdecl, + importc: "hidsysEnableUsbFullKeyController".} +## * +## @brief EnableUsbFullKeyController +## @note Only available on [3.0.0+]. +## @param[in] flag Flag +## + +proc hidsysIsUsbConnected*(uniquePadId: HidsysUniquePadId; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsUsbConnected".} +## * +## @brief IsUsbConnected +## @note Only available on [3.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output flag. +## + +proc hidsysIsFirmwareUpdateNeededForNotification*(uniquePadId: HidsysUniquePadId; + `out`: ptr bool): Result {.cdecl, importc: "hidsysIsFirmwareUpdateNeededForNotification".} +## * +## @brief IsFirmwareUpdateNeededForNotification +## @note Only available on [9.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output flag. +## + +proc hidsysLegacyIsButtonConfigSupported*(uniquePadId: HidsysUniquePadId; + `out`: ptr bool): Result {.cdecl, importc: "hidsysLegacyIsButtonConfigSupported".} +## * +## @brief Legacy IsButtonConfigSupported. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigSupported instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigSupported*(`addr`: BtdrvAddress; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigSupported".} +## * +## @brief IsButtonConfigSupported +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigSupported instead. +## @param[in] addr \ref BtdrvAddress +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigEmbeddedSupported*(`out`: ptr bool): Result {.cdecl, + importc: "hidsysIsButtonConfigEmbeddedSupported".} +## * +## @brief IsButtonConfigEmbeddedSupported +## @note Only available on [11.0.0+]. +## @param[out] out Output bool flag. +## + +proc hidsysLegacyDeleteButtonConfig*(uniquePadId: HidsysUniquePadId): Result {. + cdecl, importc: "hidsysLegacyDeleteButtonConfig".} +## * +## @brief Legacy DeleteButtonConfig. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysDeleteButtonConfig instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## + +proc hidsysDeleteButtonConfig*(`addr`: BtdrvAddress): Result {.cdecl, + importc: "hidsysDeleteButtonConfig".} +## * +## @brief DeleteButtonConfig +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyDeleteButtonConfig instead. +## @param[in] addr \ref BtdrvAddress +## + +proc hidsysDeleteButtonConfigEmbedded*(): Result {.cdecl, + importc: "hidsysDeleteButtonConfigEmbedded".} +## * +## @brief DeleteButtonConfigEmbedded +## @note Only available on [11.0.0+]. +## + +proc hidsysLegacySetButtonConfigEnabled*(uniquePadId: HidsysUniquePadId; flag: bool): Result {. + cdecl, importc: "hidsysLegacySetButtonConfigEnabled".} +## * +## @brief Legacy SetButtonConfigEnabled. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEnabled instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] flag Input flag. +## + +proc hidsysSetButtonConfigEnabled*(`addr`: BtdrvAddress; flag: bool): Result {.cdecl, + importc: "hidsysSetButtonConfigEnabled".} +## * +## @brief SetButtonConfigEnabled +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEnabled instead. +## @param[in] addr \ref BtdrvAddress +## @param[in] flag Input flag. +## + +proc hidsysSetButtonConfigEmbeddedEnabled*(flag: bool): Result {.cdecl, + importc: "hidsysSetButtonConfigEmbeddedEnabled".} +## * +## @brief SetButtonConfigEmbeddedEnabled +## @note Only available on [11.0.0+]. +## @param[in] flag Input flag. +## + +proc hidsysLegacyIsButtonConfigEnabled*(uniquePadId: HidsysUniquePadId; + `out`: ptr bool): Result {.cdecl, + importc: "hidsysLegacyIsButtonConfigEnabled".} +## * +## @brief Legacy IsButtonConfigEnabled. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysIsButtonConfigEnabled instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigEnabled*(`addr`: BtdrvAddress; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigEnabled".} +## * +## @brief IsButtonConfigEnabled +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyIsButtonConfigEnabled instead. +## @param[in] addr \ref BtdrvAddress +## @param[in] out Output bool flag. +## + +proc hidsysIsButtonConfigEmbeddedEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "hidsysIsButtonConfigEmbeddedEnabled".} +## * +## @brief IsButtonConfigEmbeddedEnabled +## @note Only available on [11.0.0+]. +## @param[out] out Output bool flag. +## + +proc hidsysLegacySetButtonConfigEmbedded*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigEmbedded): Result {.cdecl, + importc: "hidsysLegacySetButtonConfigEmbedded".} +## * +## @brief Legacy SetButtonConfigEmbedded. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigEmbedded instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidsysButtonConfigEmbedded +## + +proc hidsysSetButtonConfigEmbedded*(config: ptr HidsysButtonConfigEmbedded): Result {. + cdecl, importc: "hidsysSetButtonConfigEmbedded".} +## * +## @brief SetButtonConfigEmbedded +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigEmbedded instead. +## @param[in] config \ref HidsysButtonConfigEmbedded +## + +proc hidsysLegacySetButtonConfigFull*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigFull): Result {. + cdecl, importc: "hidsysLegacySetButtonConfigFull".} +## * +## @brief Legacy SetButtonConfigFull. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigFull instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidsysButtonConfigFull +## + +proc hidsysSetButtonConfigFull*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigFull): Result {.cdecl, + importc: "hidsysSetButtonConfigFull".} +## * +## @brief SetButtonConfigFull +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigFull instead. +## @param[in] addr \ref BtdrvAddress +## @param[in] config \ref HidsysButtonConfigFull +## + +proc hidsysLegacySetButtonConfigLeft*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigLeft): Result {. + cdecl, importc: "hidsysLegacySetButtonConfigLeft".} +## * +## @brief Legacy SetButtonConfigLeft. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigLeft instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidsysButtonConfigLeft +## + +proc hidsysSetButtonConfigLeft*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigLeft): Result {.cdecl, + importc: "hidsysSetButtonConfigLeft".} +## * +## @brief SetButtonConfigLeft +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigLeft instead. +## @param[in] addr \ref BtdrvAddress +## @param[in] config \ref HidsysButtonConfigLeft +## + +proc hidsysLegacySetButtonConfigRight*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigRight): Result {. + cdecl, importc: "hidsysLegacySetButtonConfigRight".} +## * +## @brief Legacy SetButtonConfigRight. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysSetButtonConfigRight instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidsysButtonConfigRight +## + +proc hidsysSetButtonConfigRight*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigRight): Result {. + cdecl, importc: "hidsysSetButtonConfigRight".} +## * +## @brief SetButtonConfigRight +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacySetButtonConfigRight instead. +## @param[in] addr \ref BtdrvAddress +## @param[in] config \ref HidsysButtonConfigRight +## + +proc hidsysLegacyGetButtonConfigEmbedded*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigEmbedded): Result {.cdecl, + importc: "hidsysLegacyGetButtonConfigEmbedded".} +## * +## @brief Legacy GetButtonConfigEmbedded. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigEmbedded instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidsysButtonConfigEmbedded +## + +proc hidsysGetButtonConfigEmbedded*(config: ptr HidsysButtonConfigEmbedded): Result {. + cdecl, importc: "hidsysGetButtonConfigEmbedded".} +## * +## @brief GetButtonConfigEmbedded +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigEmbedded instead. +## @param[out] config \ref HidsysButtonConfigEmbedded +## + +proc hidsysLegacyGetButtonConfigFull*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigFull): Result {. + cdecl, importc: "hidsysLegacyGetButtonConfigFull".} +## * +## @brief Legacy GetButtonConfigFull. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigFull instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidsysButtonConfigFull +## + +proc hidsysGetButtonConfigFull*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigFull): Result {.cdecl, + importc: "hidsysGetButtonConfigFull".} +## * +## @brief GetButtonConfigFull +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigFull instead. +## @param[in] addr \ref BtdrvAddress +## @param[out] config \ref HidsysButtonConfigFull +## + +proc hidsysLegacyGetButtonConfigLeft*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigLeft): Result {. + cdecl, importc: "hidsysLegacyGetButtonConfigLeft".} +## * +## @brief Legacy GetButtonConfigLeft. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigLeft instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidsysButtonConfigLeft +## + +proc hidsysGetButtonConfigLeft*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigLeft): Result {.cdecl, + importc: "hidsysGetButtonConfigLeft".} +## * +## @brief GetButtonConfigLeft +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigLeft instead. +## @param[in] addr \ref BtdrvAddress +## @param[out] config \ref HidsysButtonConfigLeft +## + +proc hidsysLegacyGetButtonConfigRight*(uniquePadId: HidsysUniquePadId; + config: ptr HidsysButtonConfigRight): Result {. + cdecl, importc: "hidsysLegacyGetButtonConfigRight".} +## * +## @brief Legacy GetButtonConfigRight. +## @note Only available on [10.0.0-10.2.0]. On [11.0.0+], use \ref hidsysGetButtonConfigRight instead. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidsysButtonConfigRight +## + +proc hidsysGetButtonConfigRight*(`addr`: BtdrvAddress; + config: ptr HidsysButtonConfigRight): Result {. + cdecl, importc: "hidsysGetButtonConfigRight".} +## * +## @brief GetButtonConfigRight +## @note Only available on [11.0.0+]. On [10.0.0-10.2.0], use \ref hidsysLegacyGetButtonConfigRight instead. +## @param[in] addr \ref BtdrvAddress +## @param[out] config \ref HidsysButtonConfigRight +## + +proc hidsysIsCustomButtonConfigSupported*(uniquePadId: HidsysUniquePadId; + `out`: ptr bool): Result {.cdecl, importc: "hidsysIsCustomButtonConfigSupported".} +## * +## @brief IsCustomButtonConfigSupported +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output bool flag. +## + +proc hidsysIsDefaultButtonConfigEmbedded*(config: ptr HidcfgButtonConfigEmbedded; + `out`: ptr bool): Result {.cdecl, importc: "hidsysIsDefaultButtonConfigEmbedded".} +## * +## @brief IsDefaultButtonConfigEmbedded +## @note Only available on [10.0.0+]. +## @param[in] config \ref HidcfgButtonConfigEmbedded +## @param[out] out Output bool flag. +## + +proc hidsysIsDefaultButtonConfigFull*(config: ptr HidcfgButtonConfigFull; + `out`: ptr bool): Result {.cdecl, + importc: "hidsysIsDefaultButtonConfigFull".} +## * +## @brief IsDefaultButtonConfigFull +## @note Only available on [10.0.0+]. +## @param[in] config \ref HidcfgButtonConfigFull +## @param[out] out Output bool flag. +## + +proc hidsysIsDefaultButtonConfigLeft*(config: ptr HidcfgButtonConfigLeft; + `out`: ptr bool): Result {.cdecl, + importc: "hidsysIsDefaultButtonConfigLeft".} +## * +## @brief IsDefaultButtonConfigLeft +## @note Only available on [10.0.0+]. +## @param[in] config \ref HidcfgButtonConfigLeft +## @param[out] out Output bool flag. +## + +proc hidsysIsDefaultButtonConfigRight*(config: ptr HidcfgButtonConfigRight; + `out`: ptr bool): Result {.cdecl, + importc: "hidsysIsDefaultButtonConfigRight".} +## * +## @brief IsDefaultButtonConfigRight +## @note Only available on [10.0.0+]. +## @param[in] config \ref HidcfgButtonConfigRight +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigStorageEmbeddedEmpty*(index: S32; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigStorageEmbeddedEmpty".} +## * +## @brief IsButtonConfigStorageEmbeddedEmpty +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigStorageFullEmpty*(index: S32; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigStorageFullEmpty".} +## * +## @brief IsButtonConfigStorageFullEmpty +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigStorageLeftEmpty*(index: S32; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigStorageLeftEmpty".} +## * +## @brief IsButtonConfigStorageLeftEmpty +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] out Output bool flag. +## + +proc hidsysIsButtonConfigStorageRightEmpty*(index: S32; `out`: ptr bool): Result {. + cdecl, importc: "hidsysIsButtonConfigStorageRightEmpty".} +## * +## @brief IsButtonConfigStorageRightEmpty +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] out Output bool flag. +## + +proc hidsysGetButtonConfigStorageEmbeddedDeprecated*(index: S32; + config: ptr HidcfgButtonConfigEmbedded): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageEmbeddedDeprecated".} +## * +## @brief GetButtonConfigStorageEmbeddedDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigEmbedded +## + +proc hidsysGetButtonConfigStorageFullDeprecated*(index: S32; + config: ptr HidcfgButtonConfigFull): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageFullDeprecated".} +## * +## @brief GetButtonConfigStorageFullDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigFull +## + +proc hidsysGetButtonConfigStorageLeftDeprecated*(index: S32; + config: ptr HidcfgButtonConfigLeft): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageLeftDeprecated".} +## * +## @brief GetButtonConfigStorageLeftDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigLeft +## + +proc hidsysGetButtonConfigStorageRightDeprecated*(index: S32; + config: ptr HidcfgButtonConfigRight): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageRightDeprecated".} +## * +## @brief GetButtonConfigStorageRightDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigRight +## + +proc hidsysSetButtonConfigStorageEmbeddedDeprecated*(index: S32; + config: ptr HidcfgButtonConfigEmbedded): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageEmbeddedDeprecated".} +## * +## @brief SetButtonConfigStorageEmbeddedDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigEmbedded +## + +proc hidsysSetButtonConfigStorageFullDeprecated*(index: S32; + config: ptr HidcfgButtonConfigFull): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageFullDeprecated".} +## * +## @brief SetButtonConfigStorageFullDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigFull +## + +proc hidsysSetButtonConfigStorageLeftDeprecated*(index: S32; + config: ptr HidcfgButtonConfigLeft): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageLeftDeprecated".} +## * +## @brief SetButtonConfigStorageLeftDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigLeft +## + +proc hidsysSetButtonConfigStorageRightDeprecated*(index: S32; + config: ptr HidcfgButtonConfigRight): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageRightDeprecated".} +## * +## @brief SetButtonConfigStorageRightDeprecated +## @note Only available on [10.0.0-12.1.0]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigRight +## + +proc hidsysDeleteButtonConfigStorageEmbedded*(index: S32): Result {.cdecl, + importc: "hidsysDeleteButtonConfigStorageEmbedded".} +## * +## @brief DeleteButtonConfigStorageEmbedded +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## + +proc hidsysDeleteButtonConfigStorageFull*(index: S32): Result {.cdecl, + importc: "hidsysDeleteButtonConfigStorageFull".} +## * +## @brief DeleteButtonConfigStorageFull +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## + +proc hidsysDeleteButtonConfigStorageLeft*(index: S32): Result {.cdecl, + importc: "hidsysDeleteButtonConfigStorageLeft".} +## * +## @brief DeleteButtonConfigStorageLeft +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## + +proc hidsysDeleteButtonConfigStorageRight*(index: S32): Result {.cdecl, + importc: "hidsysDeleteButtonConfigStorageRight".} +## * +## @brief DeleteButtonConfigStorageRight +## @note Only available on [10.0.0+]. +## @param[in] index Array index, should be 0-4. +## + +proc hidsysIsUsingCustomButtonConfig*(uniquePadId: HidsysUniquePadId; + `out`: ptr bool): Result {.cdecl, + importc: "hidsysIsUsingCustomButtonConfig".} +## * +## @brief IsUsingCustomButtonConfig +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] out Output bool flag. +## + +proc hidsysIsAnyCustomButtonConfigEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "hidsysIsAnyCustomButtonConfigEnabled".} +## * +## @brief IsAnyCustomButtonConfigEnabled +## @note Only available on [10.0.0+]. +## @param[out] out Output bool flag. +## + +proc hidsysSetAllCustomButtonConfigEnabled*(appletResourceUserId: U64; flag: bool): Result {. + cdecl, importc: "hidsysSetAllCustomButtonConfigEnabled".} +## * +## @brief SetAllCustomButtonConfigEnabled +## @note Only available on [10.0.0+]. +## @param[in] AppletResourceUserId AppletResourceUserId +## @param[in] flag Input bool flag. +## + +proc hidsysSetAllDefaultButtonConfig*(): Result {.cdecl, + importc: "hidsysSetAllDefaultButtonConfig".} +## * +## @brief SetAllDefaultButtonConfig +## @note Only available on [10.0.0+]. +## + +proc hidsysSetHidButtonConfigEmbedded*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigEmbedded): Result {. + cdecl, importc: "hidsysSetHidButtonConfigEmbedded".} +## * +## @brief SetHidButtonConfigEmbedded +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidcfgButtonConfigEmbedded +## + +proc hidsysSetHidButtonConfigFull*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigFull): Result {. + cdecl, importc: "hidsysSetHidButtonConfigFull".} +## * +## @brief SetHidButtonConfigFull +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidcfgButtonConfigFull +## + +proc hidsysSetHidButtonConfigLeft*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigLeft): Result {. + cdecl, importc: "hidsysSetHidButtonConfigLeft".} +## * +## @brief SetHidButtonConfigLeft +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidcfgButtonConfigLeft +## + +proc hidsysSetHidButtonConfigRight*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigRight): Result {. + cdecl, importc: "hidsysSetHidButtonConfigRight".} +## * +## @brief SetHidButtonConfigRight +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[in] config \ref HidcfgButtonConfigRight +## + +proc hidsysGetHidButtonConfigEmbedded*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigEmbedded): Result {. + cdecl, importc: "hidsysGetHidButtonConfigEmbedded".} +## * +## @brief GetHidButtonConfigEmbedded +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidcfgButtonConfigEmbedded +## + +proc hidsysGetHidButtonConfigFull*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigFull): Result {. + cdecl, importc: "hidsysGetHidButtonConfigFull".} +## * +## @brief GetHidButtonConfigFull +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidcfgButtonConfigFull +## + +proc hidsysGetHidButtonConfigLeft*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigLeft): Result {. + cdecl, importc: "hidsysGetHidButtonConfigLeft".} +## * +## @brief GetHidButtonConfigLeft +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidcfgButtonConfigLeft +## + +proc hidsysGetHidButtonConfigRight*(uniquePadId: HidsysUniquePadId; + config: ptr HidcfgButtonConfigRight): Result {. + cdecl, importc: "hidsysGetHidButtonConfigRight".} +## * +## @brief GetHidButtonConfigRight +## @note Only available on [10.0.0+]. +## @param[in] unique_pad_id \ref HidsysUniquePadId +## @param[out] config \ref HidcfgButtonConfigRight +## + +proc hidsysGetButtonConfigStorageEmbedded*(index: S32; + config: ptr HidcfgButtonConfigEmbedded; name: ptr HidcfgStorageName): Result {. + cdecl, importc: "hidsysGetButtonConfigStorageEmbedded".} +## * +## @brief GetButtonConfigStorageEmbedded +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigEmbedded +## @param[out] name \ref HidcfgStorageName +## + +proc hidsysGetButtonConfigStorageFull*(index: S32; + config: ptr HidcfgButtonConfigFull; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageFull".} +## * +## @brief GetButtonConfigStorageFull +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigFull +## @param[out] name \ref HidcfgStorageName +## + +proc hidsysGetButtonConfigStorageLeft*(index: S32; + config: ptr HidcfgButtonConfigLeft; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageLeft".} +## * +## @brief GetButtonConfigStorageLeft +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigLeft +## @param[out] name \ref HidcfgStorageName +## + +proc hidsysGetButtonConfigStorageRight*(index: S32; + config: ptr HidcfgButtonConfigRight; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysGetButtonConfigStorageRight".} +## * +## @brief GetButtonConfigStorageRight +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[out] config \ref HidcfgButtonConfigRight +## @param[out] name \ref HidcfgStorageName +## + +proc hidsysSetButtonConfigStorageEmbedded*(index: S32; + config: ptr HidcfgButtonConfigEmbedded; name: ptr HidcfgStorageName): Result {. + cdecl, importc: "hidsysSetButtonConfigStorageEmbedded".} +## * +## @brief SetButtonConfigStorageEmbedded +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigEmbedded +## @param[in] name \ref HidcfgStorageName +## + +proc hidsysSetButtonConfigStorageFull*(index: S32; + config: ptr HidcfgButtonConfigFull; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageFull".} +## * +## @brief SetButtonConfigStorageFull +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigFull +## @param[in] name \ref HidcfgStorageName +## + +proc hidsysSetButtonConfigStorageLeft*(index: S32; + config: ptr HidcfgButtonConfigLeft; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageLeft".} +## * +## @brief SetButtonConfigStorageLeft +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigLeft +## @param[in] name \ref HidcfgStorageName +## + +proc hidsysSetButtonConfigStorageRight*(index: S32; + config: ptr HidcfgButtonConfigRight; + name: ptr HidcfgStorageName): Result {.cdecl, + importc: "hidsysSetButtonConfigStorageRight".} +## * +## @brief SetButtonConfigStorageRight +## @note Only available on [11.0.0+]. +## @param[in] index Array index, should be 0-4. +## @param[in] config \ref HidcfgButtonConfigRight +## @param[in] name \ref HidcfgStorageName +## + diff --git a/src/libnx/wrapper/switch/services/htcs.h b/src/libnx/wrapper/switch/services/htcs.h new file mode 100644 index 0000000..cea2777 --- /dev/null +++ b/src/libnx/wrapper/switch/services/htcs.h @@ -0,0 +1,150 @@ +/** + * @file htcs.h + * @brief HTC sockets (htcs) service IPC wrapper. Please use <> instead. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../sf/service.h" + +#define HTCS_PEER_NAME_MAX 32 +#define HTCS_PORT_NAME_MAX 32 + +#define HTCS_SESSION_COUNT_MAX 0x10 +#define HTCS_SOCKET_COUNT_MAX 40 +#define HTCS_FD_SET_SIZE HTCS_SOCKET_COUNT_MAX + +typedef uint16_t HtcsAddressFamilyType; + +typedef struct { + char name[HTCS_PEER_NAME_MAX]; +} HtcsPeerName; + +typedef struct { + char name[HTCS_PORT_NAME_MAX]; +} HtcsPortName; + +typedef struct { + HtcsAddressFamilyType family; + HtcsPeerName peer_name; + HtcsPortName port_name; +} HtcsSockAddr; + +typedef struct { + s64 tv_sec; + s64 tv_usec; +} HtcsTimeVal; + +typedef struct { + int fds[HTCS_FD_SET_SIZE]; +} HtcsFdSet; + +typedef enum { + HTCS_ENONE = 0, + HTCS_EACCES = 2, + HTCS_EADDRINUSE = 3, + HTCS_EADDRNOTAVAIL = 4, + HTCS_EAGAIN = 6, + HTCS_EALREADY = 7, + HTCS_EBADF = 8, + HTCS_EBUSY = 10, + HTCS_ECONNABORTED = 13, + HTCS_ECONNREFUSED = 14, + HTCS_ECONNRESET = 15, + HTCS_EDESTADDRREQ = 17, + HTCS_EFAULT = 21, + HTCS_EINPROGRESS = 26, + HTCS_EINTR = 27, + HTCS_EINVAL = 28, + HTCS_EIO = 29, + HTCS_EISCONN = 30, + HTCS_EMFILE = 33, + HTCS_EMSGSIZE = 35, + HTCS_ENETDOWN = 38, + HTCS_ENETRESET = 39, + HTCS_ENOBUFS = 42, + HTCS_ENOMEM = 49, + HTCS_ENOTCONN = 56, + HTCS_ETIMEDOUT = 76, + HTCS_EUNKNOWN = 79, + + HTCS_EWOULDBLOCK = HTCS_EAGAIN, +} HtcsSocketError; + +typedef enum { + HTCS_MSG_PEEK = 1, + HTCS_MSG_WAITALL = 2, +} HtcsMessageFlag; + +typedef enum { + HTCS_SHUT_RD = 0, + HTCS_SHUT_WR = 1, + HTCS_SHUT_RDWR = 2, +} HtcsShutdownType; + +typedef enum { + HTCS_F_GETFL = 3, + HTCS_F_SETFL = 4, +} HtcsFcntlOperation; + +typedef enum { + HTCS_O_NONBLOCK = 4, +} HtcsFcntlFlag; + +typedef enum { + HTCS_AF_HTCS = 0, +} HtcsAddressFamily; + +typedef struct { + Service s; +} HtcsSocket; + + +/// Initialize the HTCS service. +Result htcsInitialize(u32 num_sessions); + +/// Exit the HTCS service. +void htcsExit(void); + +/// Gets the Service object for the actual HTCS manager service session. +Service* htcsGetManagerServiceSession(void); + +/// Gets the Service object for the actual HTCS monitor service session. +Service* htcsGetMonitorServiceSession(void); + +/// Manager functionality. +Result htcsGetPeerNameAny(HtcsPeerName *out); +Result htcsGetDefaultHostName(HtcsPeerName *out); +Result htcsCreateSocket(s32 *out_err, HtcsSocket *out, bool enable_disconnection_emulation); +Result htcsStartSelect(u32 *out_task_id, Handle *out_event_handle, const s32 *read, size_t num_read, const s32 *write, size_t num_write, const s32 *except, size_t num_except, s64 tv_sec, s64 tv_usec); +Result htcsEndSelect(s32 *out_err, s32 *out_count, s32 *read, size_t num_read, s32 *write, size_t num_write, s32 *except, size_t num_except, u32 task_id); + +/// Socket functionality. +Result htcsSocketClose(HtcsSocket *s, s32 *out_err, s32 *out_res); +Result htcsSocketConnect(HtcsSocket *s, s32 *out_err, s32 *out_res, const HtcsSockAddr *address); +Result htcsSocketBind(HtcsSocket *s, s32 *out_err, s32 *out_res, const HtcsSockAddr *address); +Result htcsSocketListen(HtcsSocket *s, s32 *out_err, s32 *out_res, s32 backlog_count); +Result htcsSocketShutdown(HtcsSocket *s, s32 *out_err, s32 *out_res, s32 how); +Result htcsSocketFcntl(HtcsSocket *s, s32 *out_err, s32 *out_res, s32 command, s32 value); + +Result htcsSocketAcceptStart(HtcsSocket *s, u32 *out_task_id, Handle *out_event_handle); +Result htcsSocketAcceptResults(HtcsSocket *s, s32 *out_err, HtcsSocket *out_socket, HtcsSockAddr *out_address, u32 task_id); + +Result htcsSocketRecvStart(HtcsSocket *s, u32 *out_task_id, Handle *out_event_handle, s32 mem_size, s32 flags); +Result htcsSocketRecvResults(HtcsSocket *s, s32 *out_err, s64 *out_size, void *buffer, size_t buffer_size, u32 task_id); + +Result htcsSocketSendStart(HtcsSocket *s, u32 *out_task_id, Handle *out_event_handle, const void *buffer, size_t buffer_size, s32 flags); +Result htcsSocketSendResults(HtcsSocket *s, s32 *out_err, s64 *out_size, u32 task_id); + +Result htcsSocketStartSend(HtcsSocket *s, u32 *out_task_id, Handle *out_event_handle, s64 *out_max_size, s64 size, s32 flags); +Result htcsSocketContinueSend(HtcsSocket *s, s64 *out_size, bool *out_wait, const void *buffer, size_t buffer_size, u32 task_id); +Result htcsSocketEndSend(HtcsSocket *s, s32 *out_err, s64 *out_size, u32 task_id); + +Result htcsSocketStartRecv(HtcsSocket *s, u32 *out_task_id, Handle *out_event_handle, s64 size, s32 flags); +Result htcsSocketEndRecv(HtcsSocket *s, s32 *out_err, s64 *out_size, void *buffer, size_t buffer_size, u32 task_id); + +Result htcsSocketGetPrimitive(HtcsSocket *s, s32 *out); + +void htcsCloseSocket(HtcsSocket *s); diff --git a/src/libnx/wrapper/switch/services/htcs.nim b/src/libnx/wrapper/switch/services/htcs.nim new file mode 100644 index 0000000..834974e --- /dev/null +++ b/src/libnx/wrapper/switch/services/htcs.nim @@ -0,0 +1,152 @@ +## * +## @file htcs.h +## @brief HTC sockets (htcs) service IPC wrapper. Please use <> instead. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +const + HTCS_PEER_NAME_MAX* = 32 + HTCS_PORT_NAME_MAX* = 32 + HTCS_SESSION_COUNT_MAX* = 0x10 + HTCS_SOCKET_COUNT_MAX* = 40 + HTCS_FD_SET_SIZE* = Htcs_Socket_Count_Max + +type + HtcsAddressFamilyType* = uint16 + HtcsPeerName* {.bycopy.} = object + name*: array[Htcs_Peer_Name_Max, char] + + HtcsPortName* {.bycopy.} = object + name*: array[Htcs_Port_Name_Max, char] + + HtcsSockAddr* {.bycopy.} = object + family*: HtcsAddressFamilyType + peerName*: HtcsPeerName + portName*: HtcsPortName + + HtcsTimeVal* {.bycopy.} = object + tvSec*: S64 + tvUsec*: S64 + + HtcsFdSet* {.bycopy.} = object + fds*: array[Htcs_Fd_Set_Size, cint] + + HtcsSocketError* = enum + HTCS_ENONE = 0, HTCS_EACCES = 2, HTCS_EADDRINUSE = 3, HTCS_EADDRNOTAVAIL = 4, + HTCS_EAGAIN = 6, HTCS_EALREADY = 7, HTCS_EBADF = 8, HTCS_EBUSY = 10, + HTCS_ECONNABORTED = 13, HTCS_ECONNREFUSED = 14, HTCS_ECONNRESET = 15, + HTCS_EDESTADDRREQ = 17, HTCS_EFAULT = 21, HTCS_EINPROGRESS = 26, HTCS_EINTR = 27, + HTCS_EINVAL = 28, HTCS_EIO = 29, HTCS_EISCONN = 30, HTCS_EMFILE = 33, + HTCS_EMSGSIZE = 35, HTCS_ENETDOWN = 38, HTCS_ENETRESET = 39, HTCS_ENOBUFS = 42, + HTCS_ENOMEM = 49, HTCS_ENOTCONN = 56, HTCS_ETIMEDOUT = 76, HTCS_EUNKNOWN = 79, + HtcsMessageFlag* = enum + HTCS_MSG_PEEK = 1, HTCS_MSG_WAITALL = 2 + HtcsShutdownType* = enum + HTCS_SHUT_RD = 0, HTCS_SHUT_WR = 1, HTCS_SHUT_RDWR = 2 + HtcsFcntlOperation* = enum + HTCS_F_GETFL = 3, HTCS_F_SETFL = 4 + HtcsFcntlFlag* = enum + HTCS_O_NONBLOCK = 4 + HtcsAddressFamily* = enum + HTCS_AF_HTCS = 0 + HtcsSocket* {.bycopy.} = object + s*: Service + + +const HTCS_EWOULDBLOCK* = Htcs_Eagain + + + + + + + +proc htcsInitialize*(numSessions: U32): Result {.cdecl, importc: "htcsInitialize".} +## / Initialize the HTCS service. + +proc htcsExit*() {.cdecl, importc: "htcsExit".} +## / Exit the HTCS service. + +proc htcsGetManagerServiceSession*(): ptr Service {.cdecl, + importc: "htcsGetManagerServiceSession".} +## / Gets the Service object for the actual HTCS manager service session. + +proc htcsGetMonitorServiceSession*(): ptr Service {.cdecl, + importc: "htcsGetMonitorServiceSession".} +## / Gets the Service object for the actual HTCS monitor service session. + +proc htcsGetPeerNameAny*(`out`: ptr HtcsPeerName): Result {.cdecl, + importc: "htcsGetPeerNameAny".} +## / Manager functionality. +proc htcsGetDefaultHostName*(`out`: ptr HtcsPeerName): Result {.cdecl, + importc: "htcsGetDefaultHostName".} +proc htcsCreateSocket*(outErr: ptr S32; `out`: ptr HtcsSocket; + enableDisconnectionEmulation: bool): Result {.cdecl, + importc: "htcsCreateSocket".} +proc htcsStartSelect*(outTaskId: ptr U32; outEventHandle: ptr Handle; read: ptr S32; + numRead: csize_t; write: ptr S32; numWrite: csize_t; + `except`: ptr S32; numExcept: csize_t; tvSec: S64; tvUsec: S64): Result {. + cdecl, importc: "htcsStartSelect".} +proc htcsEndSelect*(outErr: ptr S32; outCount: ptr S32; read: ptr S32; numRead: csize_t; + write: ptr S32; numWrite: csize_t; `except`: ptr S32; + numExcept: csize_t; taskId: U32): Result {.cdecl, + importc: "htcsEndSelect".} + +## / Socket functionality. + +proc htcsSocketClose*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32): Result {.cdecl, + importc: "htcsSocketClose".} +proc htcsSocketConnect*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32; + address: ptr HtcsSockAddr): Result {.cdecl, + importc: "htcsSocketConnect".} +proc htcsSocketBind*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32; + address: ptr HtcsSockAddr): Result {.cdecl, + importc: "htcsSocketBind".} +proc htcsSocketListen*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32; + backlogCount: S32): Result {.cdecl, + importc: "htcsSocketListen".} +proc htcsSocketShutdown*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32; how: S32): Result {. + cdecl, importc: "htcsSocketShutdown".} +proc htcsSocketFcntl*(s: ptr HtcsSocket; outErr: ptr S32; outRes: ptr S32; command: S32; + value: S32): Result {.cdecl, importc: "htcsSocketFcntl".} +proc htcsSocketAcceptStart*(s: ptr HtcsSocket; outTaskId: ptr U32; + outEventHandle: ptr Handle): Result {.cdecl, + importc: "htcsSocketAcceptStart".} +proc htcsSocketAcceptResults*(s: ptr HtcsSocket; outErr: ptr S32; + outSocket: ptr HtcsSocket; + outAddress: ptr HtcsSockAddr; taskId: U32): Result {. + cdecl, importc: "htcsSocketAcceptResults".} +proc htcsSocketRecvStart*(s: ptr HtcsSocket; outTaskId: ptr U32; + outEventHandle: ptr Handle; memSize: S32; flags: S32): Result {. + cdecl, importc: "htcsSocketRecvStart".} +proc htcsSocketRecvResults*(s: ptr HtcsSocket; outErr: ptr S32; outSize: ptr S64; + buffer: pointer; bufferSize: csize_t; taskId: U32): Result {. + cdecl, importc: "htcsSocketRecvResults".} +proc htcsSocketSendStart*(s: ptr HtcsSocket; outTaskId: ptr U32; + outEventHandle: ptr Handle; buffer: pointer; + bufferSize: csize_t; flags: S32): Result {.cdecl, + importc: "htcsSocketSendStart".} +proc htcsSocketSendResults*(s: ptr HtcsSocket; outErr: ptr S32; outSize: ptr S64; + taskId: U32): Result {.cdecl, + importc: "htcsSocketSendResults".} +proc htcsSocketStartSend*(s: ptr HtcsSocket; outTaskId: ptr U32; + outEventHandle: ptr Handle; outMaxSize: ptr S64; size: S64; + flags: S32): Result {.cdecl, importc: "htcsSocketStartSend".} +proc htcsSocketContinueSend*(s: ptr HtcsSocket; outSize: ptr S64; outWait: ptr bool; + buffer: pointer; bufferSize: csize_t; taskId: U32): Result {. + cdecl, importc: "htcsSocketContinueSend".} +proc htcsSocketEndSend*(s: ptr HtcsSocket; outErr: ptr S32; outSize: ptr S64; taskId: U32): Result {. + cdecl, importc: "htcsSocketEndSend".} +proc htcsSocketStartRecv*(s: ptr HtcsSocket; outTaskId: ptr U32; + outEventHandle: ptr Handle; size: S64; flags: S32): Result {. + cdecl, importc: "htcsSocketStartRecv".} +proc htcsSocketEndRecv*(s: ptr HtcsSocket; outErr: ptr S32; outSize: ptr S64; + buffer: pointer; bufferSize: csize_t; taskId: U32): Result {. + cdecl, importc: "htcsSocketEndRecv".} +proc htcsSocketGetPrimitive*(s: ptr HtcsSocket; `out`: ptr S32): Result {.cdecl, + importc: "htcsSocketGetPrimitive".} +proc htcsCloseSocket*(s: ptr HtcsSocket) {.cdecl, importc: "htcsCloseSocket".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/hwopus.h b/src/libnx/wrapper/switch/services/hwopus.h new file mode 100644 index 0000000..a8a91ea --- /dev/null +++ b/src/libnx/wrapper/switch/services/hwopus.h @@ -0,0 +1,44 @@ +/** + * @file hwopus.h + * @brief Hardware Opus audio service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/tmem.h" + +typedef struct { + Service s; + TransferMemory tmem; + bool multistream; +} HwopusDecoder; + +/// This structure is the start of opusin for \ref hwopusDecodeInterleaved, with the actual opus packet following this. +/// These fields are big-endian. +typedef struct { + u32 size; ///< Size of the packet following this header. + u32 final_range; ///< Indicates the final range of the codec encoder's entropy coder. This can be left at zero. +} HwopusHeader; + +/// Used internally. +typedef struct { + s32 SampleRate; + s32 ChannelCount; + s32 TotalStreamCount; + s32 StereoStreamCount; + u8 channel_mapping[256]; +} HwopusMultistreamState; + +Result hwopusDecoderInitialize(HwopusDecoder* decoder, s32 SampleRate, s32 ChannelCount); +void hwopusDecoderExit(HwopusDecoder* decoder); + +/// Only available on [3.0.0+]. +/// See libopus multistream docs. +Result hwopusDecoderMultistreamInitialize(HwopusDecoder* decoder, s32 SampleRate, s32 ChannelCount, s32 TotalStreamCount, s32 StereoStreamCount, u8 *channel_mapping); + +/// Decodes opus data. +Result hwopusDecodeInterleaved(HwopusDecoder* decoder, s32 *DecodedDataSize, s32 *DecodedSampleCount, const void* opusin, size_t opusin_size, s16 *pcmbuf, size_t pcmbuf_size); + diff --git a/src/libnx/wrapper/switch/services/hwopus.nim b/src/libnx/wrapper/switch/services/hwopus.nim new file mode 100644 index 0000000..e580393 --- /dev/null +++ b/src/libnx/wrapper/switch/services/hwopus.nim @@ -0,0 +1,58 @@ +## * +## @file hwopus.h +## @brief Hardware Opus audio service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/tmem + +type + HwopusDecoder* {.bycopy.} = object + s*: Service + tmem*: TransferMemory + multistream*: bool + + +## / This structure is the start of opusin for \ref hwopusDecodeInterleaved, with the actual opus packet following this. +## / These fields are big-endian. + +type + HwopusHeader* {.bycopy.} = object + size*: U32 ## /< Size of the packet following this header. + finalRange*: U32 ## /< Indicates the final range of the codec encoder's entropy coder. This can be left at zero. + + +## / Used internally. + +type + HwopusMultistreamState* {.bycopy.} = object + sampleRate*: S32 + channelCount*: S32 + totalStreamCount*: S32 + stereoStreamCount*: S32 + channelMapping*: array[256, U8] + + +proc hwopusDecoderInitialize*(decoder: ptr HwopusDecoder; sampleRate: S32; + channelCount: S32): Result {.cdecl, + importc: "hwopusDecoderInitialize".} +proc hwopusDecoderExit*(decoder: ptr HwopusDecoder) {.cdecl, + importc: "hwopusDecoderExit".} +## / Only available on [3.0.0+]. +## / See libopus multistream docs. + +proc hwopusDecoderMultistreamInitialize*(decoder: ptr HwopusDecoder; + sampleRate: S32; channelCount: S32; + totalStreamCount: S32; + stereoStreamCount: S32; + channelMapping: ptr U8): Result {.cdecl, + importc: "hwopusDecoderMultistreamInitialize".} +## / Decodes opus data. + +proc hwopusDecodeInterleaved*(decoder: ptr HwopusDecoder; decodedDataSize: ptr S32; + decodedSampleCount: ptr S32; opusin: pointer; + opusinSize: csize_t; pcmbuf: ptr S16; + pcmbufSize: csize_t): Result {.cdecl, + importc: "hwopusDecodeInterleaved".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/i2c.h b/src/libnx/wrapper/switch/services/i2c.h new file mode 100644 index 0000000..d5b5ad4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/i2c.h @@ -0,0 +1,72 @@ +/** + * @file i2c.h + * @brief I2C service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + I2cDevice_DebugPad = 0, + I2cDevice_TouchPanel = 1, + I2cDevice_Tmp451 = 2, + I2cDevice_Nct72 = 3, + I2cDevice_Alc5639 = 4, + I2cDevice_Max77620Rtc = 5, + I2cDevice_Max77620Pmic = 6, + I2cDevice_Max77621Cpu = 7, + I2cDevice_Max77621Gpu = 8, + I2cDevice_Bq24193 = 9, + I2cDevice_Max17050 = 10, + I2cDevice_Bm92t30mwv = 11, + I2cDevice_Ina226Vdd15v0Hb = 12, + I2cDevice_Ina226VsysCpuDs = 13, + I2cDevice_Ina226VsysGpuDs = 14, + I2cDevice_Ina226VsysDdrDs = 15, + I2cDevice_Ina226VsysAp = 16, + I2cDevice_Ina226VsysBlDs = 17, + I2cDevice_Bh1730 = 18, + I2cDevice_Ina226VsysCore = 19, + I2cDevice_Ina226Soc1V8 = 20, + I2cDevice_Ina226Lpddr1V8 = 21, + I2cDevice_Ina226Reg1V32 = 22, + I2cDevice_Ina226Vdd3V3Sys = 23, + I2cDevice_HdmiDdc = 24, + I2cDevice_HdmiScdc = 25, + I2cDevice_HdmiHdcp = 26, + I2cDevice_Fan53528 = 27, + I2cDevice_Max77812_3 = 28, + I2cDevice_Max77812_2 = 29, + I2cDevice_Ina226VddDdr0V6 = 30, + + I2cDevice_Count, +} I2cDevice; + +typedef struct { + Service s; +} I2cSession; + +typedef enum { + I2cTransactionOption_Start = (1 << 0), + I2cTransactionOption_Stop = (1 << 1), + + I2cTransactionOption_All = I2cTransactionOption_Start | I2cTransactionOption_Stop, +} I2cTransactionOption; + +/// Initialize i2c. +Result i2cInitialize(void); + +/// Exit i2c. +void i2cExit(void); + +/// Gets the Service object for the actual i2c service session. +Service* i2cGetServiceSession(void); + +Result i2cOpenSession(I2cSession *out, I2cDevice dev); + +Result i2csessionSendAuto(I2cSession *s, const void *buf, size_t size, I2cTransactionOption option); +Result i2csessionReceiveAuto(I2cSession *s, void *buf, size_t size, I2cTransactionOption option); +Result i2csessionExecuteCommandList(I2cSession *s, void *dst, size_t dst_size, const void *cmd_list, size_t cmd_list_size); +void i2csessionClose(I2cSession *s); diff --git a/src/libnx/wrapper/switch/services/i2c.nim b/src/libnx/wrapper/switch/services/i2c.nim new file mode 100644 index 0000000..a427bb2 --- /dev/null +++ b/src/libnx/wrapper/switch/services/i2c.nim @@ -0,0 +1,55 @@ +## * +## @file i2c.h +## @brief I2C service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + I2cDevice* = enum + I2cDeviceDebugPad = 0, I2cDeviceTouchPanel = 1, I2cDeviceTmp451 = 2, + I2cDeviceNct72 = 3, I2cDeviceAlc5639 = 4, I2cDeviceMax77620Rtc = 5, + I2cDeviceMax77620Pmic = 6, I2cDeviceMax77621Cpu = 7, I2cDeviceMax77621Gpu = 8, + I2cDeviceBq24193 = 9, I2cDeviceMax17050 = 10, I2cDeviceBm92t30mwv = 11, + I2cDeviceIna226Vdd15v0Hb = 12, I2cDeviceIna226VsysCpuDs = 13, + I2cDeviceIna226VsysGpuDs = 14, I2cDeviceIna226VsysDdrDs = 15, + I2cDeviceIna226VsysAp = 16, I2cDeviceIna226VsysBlDs = 17, I2cDeviceBh1730 = 18, + I2cDeviceIna226VsysCore = 19, I2cDeviceIna226Soc1V8 = 20, + I2cDeviceIna226Lpddr1V8 = 21, I2cDeviceIna226Reg1V32 = 22, + I2cDeviceIna226Vdd3V3Sys = 23, I2cDeviceHdmiDdc = 24, I2cDeviceHdmiScdc = 25, + I2cDeviceHdmiHdcp = 26, I2cDeviceFan53528 = 27, I2cDeviceMax778123 = 28, + I2cDeviceMax778122 = 29, I2cDeviceIna226VddDdr0V6 = 30, I2cDeviceCount + I2cSession* {.bycopy.} = object + s*: Service + + I2cTransactionOption* = enum + I2cTransactionOptionStart = (1 shl 0), + I2cTransactionOptionStop = (1 shl 1), + I2cTransactionOptionAll = I2cTransactionOptionStart.cint or I2cTransactionOptionStop.cint + + + + +proc i2cInitialize*(): Result {.cdecl, importc: "i2cInitialize".} +## / Initialize i2c. + +proc i2cExit*() {.cdecl, importc: "i2cExit".} +## / Exit i2c. + +proc i2cGetServiceSession*(): ptr Service {.cdecl, importc: "i2cGetServiceSession".} +## / Gets the Service object for the actual i2c service session. +proc i2cOpenSession*(`out`: ptr I2cSession; dev: I2cDevice): Result {.cdecl, + importc: "i2cOpenSession".} +proc i2csessionSendAuto*(s: ptr I2cSession; buf: pointer; size: csize_t; + option: I2cTransactionOption): Result {.cdecl, + importc: "i2csessionSendAuto".} +proc i2csessionReceiveAuto*(s: ptr I2cSession; buf: pointer; size: csize_t; + option: I2cTransactionOption): Result {.cdecl, + importc: "i2csessionReceiveAuto".} +proc i2csessionExecuteCommandList*(s: ptr I2cSession; dst: pointer; dstSize: csize_t; + cmdList: pointer; cmdListSize: csize_t): Result {. + cdecl, importc: "i2csessionExecuteCommandList".} +proc i2csessionClose*(s: ptr I2cSession) {.cdecl, importc: "i2csessionClose".} diff --git a/src/libnx/wrapper/switch/services/ins.h b/src/libnx/wrapper/switch/services/ins.h new file mode 100644 index 0000000..aba7930 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ins.h @@ -0,0 +1,55 @@ +/** + * @file ins.h + * @brief INS services IPC wrapper. + * @author averne + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +/// Initialize ins:r. +Result insrInitialize(void); + +/// Exit ins:r. +void insrExit(void); + +/// Gets the Service object for the actual ins:r service session. +Service* insrGetServiceSession(void); + +/** + * @brief Retrieves the last system tick the event corresponding to the ID was signaled at. + * @param[in] id Ins request ID (should be 0..4). + * @param[out] tick. + * @return Result code. + * @note The tick is only updated once per second at minimum. + */ +Result insrGetLastTick(u32 id, u64 *tick); + +/** + * @brief Retrieves the event corresponding to the ID. + * @param[in] id Ins request ID (should be 0..4). + * @param[out] out. + * @return Result code. + * @note The event is only signaled once per second at minimum. + */ +Result insrGetReadableEvent(u32 id, Event *out); + +/// Initialize ins:s. +Result inssInitialize(void); + +/// Exit ins:s. +void inssExit(void); + +/// Gets the Service object for the actual ins:s service session. +Service* inssGetServiceSession(void); + +/** + * @brief Retrieves the event corresponding to the ID. + * @param[in] id Ins send ID (should be 0..11). + * @param[out] out. + * @return Result code. + * @note The returned event cannot be waited on, only signaled. Clearing is handled by the service. + */ +Result inssGetWritableEvent(u32 id, Event *out); diff --git a/src/libnx/wrapper/switch/services/ins.nim b/src/libnx/wrapper/switch/services/ins.nim new file mode 100644 index 0000000..b7964b7 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ins.nim @@ -0,0 +1,58 @@ +## * +## @file ins.h +## @brief INS services IPC wrapper. +## @author averne +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +## / Initialize ins:r. + +proc insrInitialize*(): Result {.cdecl, importc: "insrInitialize".} +## / Exit ins:r. + +proc insrExit*() {.cdecl, importc: "insrExit".} +## / Gets the Service object for the actual ins:r service session. + +proc insrGetServiceSession*(): ptr Service {.cdecl, importc: "insrGetServiceSession".} +## * +## @brief Retrieves the last system tick the event corresponding to the ID was signaled at. +## @param[in] id Ins request ID (should be 0..4). +## @param[out] tick. +## @return Result code. +## @note The tick is only updated once per second at minimum. +## + +proc insrGetLastTick*(id: U32; tick: ptr U64): Result {.cdecl, + importc: "insrGetLastTick".} +## * +## @brief Retrieves the event corresponding to the ID. +## @param[in] id Ins request ID (should be 0..4). +## @param[out] out. +## @return Result code. +## @note The event is only signaled once per second at minimum. +## + +proc insrGetReadableEvent*(id: U32; `out`: ptr Event): Result {.cdecl, + importc: "insrGetReadableEvent".} +## / Initialize ins:s. + +proc inssInitialize*(): Result {.cdecl, importc: "inssInitialize".} +## / Exit ins:s. + +proc inssExit*() {.cdecl, importc: "inssExit".} +## / Gets the Service object for the actual ins:s service session. + +proc inssGetServiceSession*(): ptr Service {.cdecl, importc: "inssGetServiceSession".} +## * +## @brief Retrieves the event corresponding to the ID. +## @param[in] id Ins send ID (should be 0..11). +## @param[out] out. +## @return Result code. +## @note The returned event cannot be waited on, only signaled. Clearing is handled by the service. +## + +proc inssGetWritableEvent*(id: U32; `out`: ptr Event): Result {.cdecl, + importc: "inssGetWritableEvent".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/irs.h b/src/libnx/wrapper/switch/services/irs.h new file mode 100644 index 0000000..95efd86 --- /dev/null +++ b/src/libnx/wrapper/switch/services/irs.h @@ -0,0 +1,574 @@ +/** + * @file irs.h + * @brief HID IR sensor (irs) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../sf/service.h" +#include "../services/hid.h" + +#define IRS_MAX_CAMERAS 0x9 + +/// IrCameraStatus +typedef enum { + IrsIrCameraStatus_Available = 0, ///< Available + IrsIrCameraStatus_Unsupported = 1, ///< Unsupported + IrsIrCameraStatus_Unconnected = 2, ///< Unconnected +} IrsIrCameraStatus; + +/// IrCameraInternalStatus +typedef enum { + IrsIrCameraInternalStatus_Stopped = 0, ///< Stopped + IrsIrCameraInternalStatus_FirmwareUpdateNeeded = 1, ///< FirmwareUpdateNeeded + IrsIrCameraInternalStatus_Unknown2 = 2, ///< Unknown + IrsIrCameraInternalStatus_Unknown3 = 3, ///< Unknown + IrsIrCameraInternalStatus_Unknown4 = 4, ///< Unknown + IrsIrCameraInternalStatus_FirmwareVersionRequested = 5, ///< FirmwareVersionRequested + IrsIrCameraInternalStatus_FirmwareVersionIsInvalid = 6, ///< FirmwareVersionIsInvalid + IrsIrCameraInternalStatus_Ready = 7, ///< [4.0.0+] Ready + IrsIrCameraInternalStatus_Setting = 8, ///< [4.0.0+] Setting +} IrsIrCameraInternalStatus; + +/// IrSensorMode +typedef enum { + IrsIrSensorMode_None = 0, ///< None + IrsIrSensorMode_MomentProcessor = 1, ///< MomentProcessor + IrsIrSensorMode_ClusteringProcessor = 2, ///< ClusteringProcessor + IrsIrSensorMode_ImageTransferProcessor = 3, ///< ImageTransferProcessor + IrsIrSensorMode_PointingProcessor = 4, ///< PointingProcessor + IrsIrSensorMode_TeraPluginProcessor = 5, ///< TeraPluginProcessor + IrsIrSensorMode_IrLedProcessor = 6, ///< IrLedProcessor (doesn't apply to IrsDeviceFormat::ir_sensor_mode) +} IrsIrSensorMode; + +/// ImageProcessorStatus +typedef enum { + IrsImageProcessorStatus_Stopped = 0, ///< Stopped + IrsImageProcessorStatus_Running = 1, ///< Running +} IrsImageProcessorStatus; + +/// ImageTransferProcessorFormat. IR Sensor image resolution. +typedef enum { + IrsImageTransferProcessorFormat_320x240 = 0, ///< 320x240 + IrsImageTransferProcessorFormat_160x120 = 1, ///< 160x120 + IrsImageTransferProcessorFormat_80x60 = 2, ///< 80x60 + IrsImageTransferProcessorFormat_40x30 = 3, ///< [4.0.0+] 40x30 + IrsImageTransferProcessorFormat_20x15 = 4, ///< [4.0.0+] 20x15 +} IrsImageTransferProcessorFormat; + +/// AdaptiveClusteringMode +typedef enum { + IrsAdaptiveClusteringMode_StaticFov = 0, ///< StaticFov + IrsAdaptiveClusteringMode_DynamicFov = 1, ///< DynamicFov +} IrsAdaptiveClusteringMode; + +/// AdaptiveClusteringTargetDistance +typedef enum { + IrsAdaptiveClusteringTargetDistance_Near = 0, ///< Near + IrsAdaptiveClusteringTargetDistance_Middle = 1, ///< Middle + IrsAdaptiveClusteringTargetDistance_Far = 2, ///< Far +} IrsAdaptiveClusteringTargetDistance; + +/// HandAnalysisMode +typedef enum { + IrsHandAnalysisMode_Silhouette = 1, ///< Silhouette + IrsHandAnalysisMode_Image = 2, ///< Image + IrsHandAnalysisMode_SilhouetteAndImage = 3, ///< SilhouetteAndImage + IrsHandAnalysisMode_SilhouetteOnly = 4, ///< [4.0.0+] SilhouetteOnly +} IrsHandAnalysisMode; + +/// Internal validation callblack. +typedef bool (*IrsValidationCb)(void* userdata, void* arg); + +/// IrCameraHandle +typedef struct { + u8 player_number; ///< PlayerNumber + u8 device_type; ///< DeviceType + u8 reserved[0x2]; ///< Reserved +} IrsIrCameraHandle; + +/// PackedMcuVersion +typedef struct { + u16 major_version; ///< MajorVersion + u16 minor_version; ///< MinorVersion +} IrsPackedMcuVersion; + +/// PackedFunctionLevel +typedef struct { + u8 ir_sensor_function_level; ///< IrSensorFunctionLevel + u8 reserved[0x3]; ///< Reserved +} IrsPackedFunctionLevel; + +/// Rect +typedef struct { + s16 x; ///< X + s16 y; ///< Y + s16 width; ///< Width + s16 height; ///< Height +} IrsRect; + +/// IrsMomentProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u32 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u32 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x7]; ///< Reserved. + IrsRect window_of_interest; ///< WindowOfInterest + u32 preprocess; ///< Preprocess + u32 preprocess_intensity_threshold; ///< PreprocessIntensityThreshold +} IrsMomentProcessorConfig; + +/// PackedMomentProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u8 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x5]; ///< Reserved. + IrsRect window_of_interest; ///< WindowOfInterest + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u8 preprocess; ///< Preprocess + u8 preprocess_intensity_threshold; ///< PreprocessIntensityThreshold + u8 reserved2[0x2]; ///< Reserved. +} IrsPackedMomentProcessorConfig; + +/// ClusteringProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u32 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u32 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x7]; ///< Reserved. + IrsRect window_of_interest; ///< WindowOfInterest + u32 object_pixel_count_min; ///< ObjectPixelCountMin + u32 object_pixel_count_max; ///< ObjectPixelCountMax + u32 object_intensity_min; ///< ObjectIntensityMin + u8 is_external_light_filter_enabled; ///< IsExternalLightFilterEnabled +} IrsClusteringProcessorConfig; + +/// PackedClusteringProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u8 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x5]; ///< Reserved. + IrsRect window_of_interest; ///< WindowOfInterest + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u32 object_pixel_count_min; ///< ObjectPixelCountMin + u32 object_pixel_count_max; ///< ObjectPixelCountMax + u8 object_intensity_min; ///< ObjectIntensityMin + u8 is_external_light_filter_enabled; ///< IsExternalLightFilterEnabled + u8 reserved2[0x2]; ///< Reserved. +} IrsPackedClusteringProcessorConfig; + +/// ImageTransferProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u32 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u32 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x7]; ///< Reserved. + u32 format; ///< \ref IrsImageTransferProcessorFormat +} IrsImageTransferProcessorConfig; + +/// ImageTransferProcessorExConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u32 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u32 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x7]; ///< Reserved. + u32 orig_format; ///< OrigFormat \ref IrsImageTransferProcessorFormat + u32 trimming_format; ///< TrimmingFormat \ref IrsImageTransferProcessorFormat + u16 trimming_start_x; ///< TrimmingStartX + u16 trimming_start_y; ///< TrimmingStartY + u8 is_external_light_filter_enabled; ///< IsExternalLightFilterEnabled +} IrsImageTransferProcessorExConfig; + +/// PackedImageTransferProcessorConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u8 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x5]; ///< Reserved. + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u8 format; ///< \ref IrsImageTransferProcessorFormat + u8 reserved2[0x3]; ///< Reserved. +} IrsPackedImageTransferProcessorConfig; + +/// PackedImageTransferProcessorExConfig +typedef struct { + u64 exposure_time; ///< IR Sensor exposure time in nanoseconds. + u8 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 gain; ///< IR sensor signal's digital gain. + u8 is_negative_image_used; ///< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + u8 reserved[0x5]; ///< Reserved. + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u8 orig_format; ///< OrigFormat \ref IrsImageTransferProcessorFormat + u8 trimming_format; ///< TrimmingFormat \ref IrsImageTransferProcessorFormat + u16 trimming_start_x; ///< TrimmingStartX + u16 trimming_start_y; ///< TrimmingStartY + u8 is_external_light_filter_enabled; ///< IsExternalLightFilterEnabled + u8 reserved2[0x5]; ///< Reserved. +} IrsPackedImageTransferProcessorExConfig; + +/// ImageTransferProcessorState +typedef struct { + u64 sampling_number; ///< SamplingNumber + u32 ambient_noise_level; ///< AmbientNoiseLevel + u8 reserved[0x4]; ///< Reserved +} IrsImageTransferProcessorState; + +/// PackedPointingProcessorConfig +typedef struct { + IrsRect window_of_interest; ///< WindowOfInterest + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion +} IrsPackedPointingProcessorConfig; + +/// TeraPluginProcessorConfig +typedef struct { + u8 mode; ///< Mode + u8 unk_x1; ///< [6.0.0+] Unknown + u8 unk_x2; ///< [6.0.0+] Unknown + u8 unk_x3; ///< [6.0.0+] Unknown +} IrsTeraPluginProcessorConfig; + +/// PackedTeraPluginProcessorConfig +typedef struct { + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u8 mode; ///< Mode + u8 unk_x5; ///< [6.0.0+] This is set to 0x2 | (IrsTeraPluginProcessorConfig::unk_x1 << 7). + u8 unk_x6; ///< [6.0.0+] IrsTeraPluginProcessorConfig::unk_x2 + u8 unk_x7; ///< [6.0.0+] IrsTeraPluginProcessorConfig::unk_x3 +} IrsPackedTeraPluginProcessorConfig; + +/// IrLedProcessorConfig +typedef struct { + u32 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. +} IrsIrLedProcessorConfig; + +/// PackedIrLedProcessorConfig +typedef struct { + IrsPackedMcuVersion required_mcu_version; ///< RequiredMcuVersion + u8 light_target; ///< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + u8 pad[0x3]; ///< Padding +} IrsPackedIrLedProcessorConfig; + +/// AdaptiveClusteringProcessorConfig +typedef struct { + u32 mode; ///< \ref IrsAdaptiveClusteringMode + u32 target_distance; ///< [6.0.0+] \ref IrsAdaptiveClusteringTargetDistance +} IrsAdaptiveClusteringProcessorConfig; + +/// HandAnalysisConfig +typedef struct { + u32 mode; ///< \ref IrsHandAnalysisMode +} IrsHandAnalysisConfig; + +/// MomentStatistic +typedef struct { + float average_intensity; ///< AverageIntensity + float centroid_x; ///< CentroidX + float centroid_y; ///< CentroidY +} IrsMomentStatistic; + +/// MomentProcessorState +typedef struct { + s64 sampling_number; ///< SamplingNumber + u64 timestamp; ///< TimeStamp + + u32 ambient_noise_level; ///< AmbientNoiseLevel + u8 reserved[0x4]; ///< Reserved + IrsMomentStatistic statistic[0x30]; ///< \ref IrsMomentStatistic +} IrsMomentProcessorState; + +/// ClusteringData +typedef struct { + float average_intensity; ///< AverageIntensity + float centroid_x; ///< CentroidX + float centroid_y; ///< CentroidY + u32 pixel_count; ///< PixelCount + u16 bound_x; ///< BoundX + u16 bound_y; ///< BoundY + u16 boundt_width; ///< BoundtWidth + u16 bound_height; ///< BoundHeight +} IrsClusteringData; + +/// ClusteringProcessorState +typedef struct { + s64 sampling_number; ///< SamplingNumber + u64 timestamp; ///< TimeStamp + + u8 object_count; ///< ObjectCount + u8 reserved[0x3]; ///< Reserved + u32 ambient_noise_level; ///< AmbientNoiseLevel + IrsClusteringData data[0x10]; ///< \ref IrsClusteringData +} IrsClusteringProcessorState; + +/// PointingProcessorMarkerState +typedef struct { + s64 sampling_number; ///< SamplingNumber + u64 timestamp; ///< TimeStamp + + struct { + u8 pointing_status; ///< PointingStatus + u8 reserved[0x3]; ///< Reserved + u8 unk_x4[0x4]; ///< Unknown + float unk_x8; ///< Unknown + float position_x; ///< PositionX + float position_y; ///< PositionY + float unk_x14; ///< Unknown + IrsRect window_of_interest; ///< WindowOfInterest + } data[3]; +} IrsPointingProcessorMarkerState; + +/// PointingProcessorState +typedef struct { + s64 sampling_number; ///< SamplingNumber + u64 timestamp; ///< TimeStamp + + u32 pointing_status; ///< PointingStatus + float position_x; ///< PositionX + float position_y; ///< PositionY + u8 reserved[0x4]; ///< Reserved +} IrsPointingProcessorState; + +/// TeraPluginProcessorState +typedef struct { + s64 sampling_number; ///< SamplingNumber + u64 timestamp; ///< TimeStamp + u32 ambient_noise_level; ///< AmbientNoiseLevel + u8 plugin_data[0x12c]; ///< PluginData +} IrsTeraPluginProcessorState; + +/// ProcessorState +typedef struct { + s64 start; ///< Start + u32 count; ///< Count + u32 pad; ///< Padding + + u8 data[0xe10]; ///< Contains an array of *ProcessorState, depending on IrsDeviceFormat::ir_sensor_mode. +} IrsProcessorState; + +/// DeviceFormat +typedef struct { + u32 ir_camera_status; ///< \ref IrsIrCameraStatus + u32 ir_camera_internal_status; ///< \ref IrsIrCameraInternalStatus + u32 ir_sensor_mode; ///< \ref IrsIrSensorMode + u32 pad; ///< Padding + + IrsProcessorState processor_state; ///< \ref IrsProcessorState +} IrsDeviceFormat; + +/// AruidFormat +typedef struct { + u64 ir_sensor_aruid; ///< IrSensorAruid + u32 ir_sensor_aruid_status; ///< IrSensorAruidStatus + u32 pad; ///< Padding +} IrsAruidFormat; + +/// StatusManager +typedef struct { + IrsDeviceFormat device_format[IRS_MAX_CAMERAS]; + IrsAruidFormat aruid_format[0x5]; +} IrsStatusManager; + +/// Initialize irs. +Result irsInitialize(void); + +/// Exit irs. +void irsExit(void); + +/// Gets the Service object for the actual irs service session. +Service* irsGetServiceSession(void); + +/// Gets the address of the SharedMemory (\ref IrsStatusManager). +void* irsGetSharedmemAddr(void); + +/// Gets the \ref IrsIrCameraHandle for the specified controller. +Result irsGetIrCameraHandle(IrsIrCameraHandle *handle, HidNpadIdType id); + +/// GetIrCameraStatus +Result irsGetIrCameraStatus(IrsIrCameraHandle handle, IrsIrCameraStatus *out); + +/// CheckFirmwareUpdateNecessity +/// When successful where the output flag is set, the user should use \ref hidLaShowControllerFirmwareUpdate. +/// Only available on [4.0.0+]. +Result irsCheckFirmwareUpdateNecessity(IrsIrCameraHandle handle, bool *out); + +/// GetImageProcessorStatus +/// Only available on [4.0.0+]. +Result irsGetImageProcessorStatus(IrsIrCameraHandle handle, IrsImageProcessorStatus *out); + +/// Stop the current Processor. +/// \ref irsExit calls this with all IrCameraHandles which were not already used with \ref irsStopImageProcessor. +Result irsStopImageProcessor(IrsIrCameraHandle handle); + +/// Stop the current Processor, async. +/// Only available on [4.0.0+]. +Result irsStopImageProcessorAsync(IrsIrCameraHandle handle); + +/** + * @brief Run the MomentProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunMomentProcessor(IrsIrCameraHandle handle, const IrsMomentProcessorConfig *config); + +/** + * @brief Gets the states for MomentProcessor or IrLedProcessor. + * @note The official GetIrLedProcessorState is essentially the same as this, except it uses hard-coded count=1 with output-array on stack, without returning that data. Hence we don't implement a seperate func for that. + * @param[in] handle \ref IrsIrCameraHandle + * @param[out] states Output array of \ref IrsMomentProcessorState. + * @param[in] count Size of the states array in entries. Must be 1-5. + * @param[out] total_out Total output entries. + */ +Result irsGetMomentProcessorStates(IrsIrCameraHandle handle, IrsMomentProcessorState *states, s32 count, s32 *total_out); + +/** + * @brief Calculates an \ref IrsMomentStatistic from the specified region in the input \ref IrsMomentProcessorState. + * @param[in] state \ref IrsMomentProcessorState + * @param[in] rect \ref IrsRect, containing the image width and height. + * @param[in] region_x Region x, must be 0-5 (clamped to this range otherwise). region_x = image_x/6. + * @param[in] region_y Region y, must be 0-7 (clamped to this range otherwise). region_y = image_y/8. + * @param[in] region_width Region width. region_x+region_width must be <=6 (clamped to this range otherwise). + * @param[in] region_height Region height. region_y+region_height must be <=8 (clamped to this range otherwise). + */ +IrsMomentStatistic irsCalculateMomentRegionStatistic(const IrsMomentProcessorState *state, IrsRect rect, s32 region_x, s32 region_y, s32 region_width, s32 region_height); + +/** + * @brief Run the ClusteringProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunClusteringProcessor(IrsIrCameraHandle handle, const IrsClusteringProcessorConfig *config); + +/** + * @brief Gets the states for ClusteringProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[out] states Output array of \ref IrsClusteringProcessorState. + * @param[in] count Size of the states array in entries. Must be 1-5. + * @param[out] total_out Total output entries. + */ +Result irsGetClusteringProcessorStates(IrsIrCameraHandle handle, IrsClusteringProcessorState *states, s32 count, s32 *total_out); + +/** + * @brief Run the ImageTransferProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + * @param[in] size Work-buffer size, must be 0x1000-byte aligned. + */ +Result irsRunImageTransferProcessor(IrsIrCameraHandle handle, const IrsImageTransferProcessorConfig *config, size_t size); + +/** + * @brief Run the ImageTransferExProcessor. + * @note Only available on [4.0.0+]. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + * @param[in] size Work-buffer size, must be 0x1000-byte aligned. + */ +Result irsRunImageTransferExProcessor(IrsIrCameraHandle handle, const IrsImageTransferProcessorExConfig *config, size_t size); + +/// GetImageTransferProcessorState +Result irsGetImageTransferProcessorState(IrsIrCameraHandle handle, void* buffer, size_t size, IrsImageTransferProcessorState *state); + +/** + * @brief Run the PointingProcessor. + * @param[in] handle \ref IrsIrCameraHandle + */ +Result irsRunPointingProcessor(IrsIrCameraHandle handle); + +/** + * @brief Gets the states for PointingProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[out] states Output array of \ref IrsPointingProcessorMarkerState. + * @param[in] count Size of the states array in entries. Must be 1-6. + * @param[out] total_out Total output entries. + */ +Result irsGetPointingProcessorMarkerStates(IrsIrCameraHandle handle, IrsPointingProcessorMarkerState *states, s32 count, s32 *total_out); + +/** + * @brief Gets the states for \ref IrsPointingProcessorState. + * @note This uses \ref irsGetPointingProcessorMarkerStates, then converts the output to \ref IrsPointingProcessorState. + * @param[in] handle \ref IrsIrCameraHandle + * @param[out] states Output array of \ref IrsPointingProcessorState. + * @param[in] count Size of the states array in entries. Must be 1-6. + * @param[out] total_out Total output entries. + */ +Result irsGetPointingProcessorStates(IrsIrCameraHandle handle, IrsPointingProcessorState *states, s32 count, s32 *total_out); + +/** + * @brief Run the TeraPluginProcessor. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunTeraPluginProcessor(IrsIrCameraHandle handle, const IrsTeraPluginProcessorConfig *config); + +/** + * @brief Gets the states for TeraPluginProcessor, filtered using the input params. + * @param[in] handle \ref IrsIrCameraHandle + * @param[out] states Output array of \ref IrsTeraPluginProcessorState. + * @param[in] count Size of the states array in entries. Must be 1-5. + * @param[in] sampling_number Minimum value for IrsTeraPluginProcessorState::sampling_number. + * @param[in] prefix_data Only used when prefix_bitcount is not 0. The first prefix_bitcount bits from prefix_data must match the first prefix_bitcount bits in IrsTeraPluginProcessorState::plugin_data. + * @param[in] prefix_bitcount Total bits for prefix_data. + * @param[out] total_out Total output entries. + */ +Result irsGetTeraPluginProcessorStates(IrsIrCameraHandle handle, IrsTeraPluginProcessorState *states, s32 count, s64 sampling_number, u32 prefix_data, u32 prefix_bitcount, s32 *total_out); + +/** + * @brief Run the IrLedProcessor. + * @note Only available on [4.0.0+]. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunIrLedProcessor(IrsIrCameraHandle handle, const IrsIrLedProcessorConfig *config); + +/** + * @brief Run the AdaptiveClusteringProcessor. + * @note Only available on [5.0.0+]. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunAdaptiveClusteringProcessor(IrsIrCameraHandle handle, const IrsAdaptiveClusteringProcessorConfig *config); + +/** + * @brief Run HandAnalysis. + * @param[in] handle \ref IrsIrCameraHandle + * @param[in] config Input config. + */ +Result irsRunHandAnalysis(IrsIrCameraHandle handle, const IrsHandAnalysisConfig *config); + +/** + * Gets the default configuration for MomentProcessor. + */ +void irsGetMomentProcessorDefaultConfig(IrsMomentProcessorConfig *config); + +/** + * Gets the default configuration for ClusteringProcessor. + */ +void irsGetClusteringProcessorDefaultConfig(IrsClusteringProcessorConfig *config); + +/** + * Gets the default configuration for ImageTransferProcessor. + * Defaults are exposure 300us, 8x digital gain, the rest is all-zero. Format is ::IrsImageTransferProcessorFormat_320x240. + */ +void irsGetDefaultImageTransferProcessorConfig(IrsImageTransferProcessorConfig *config); + +/** + * Gets the default configuration for ImageTransferProcessorEx. + * Defaults are exposure 300us, 8x digital gain, the rest is all-zero. OrigFormat/TrimmingFormat are ::IrsImageTransferProcessorFormat_320x240. + */ +void irsGetDefaultImageTransferProcessorExConfig(IrsImageTransferProcessorExConfig *config); + +/** + * Gets the default configuration for IrLedProcessor. + */ +NX_CONSTEXPR void irsGetIrLedProcessorDefaultConfig(IrsIrLedProcessorConfig *config) { + config->light_target = 0; +} diff --git a/src/libnx/wrapper/switch/services/irs.nim b/src/libnx/wrapper/switch/services/irs.nim new file mode 100644 index 0000000..032c046 --- /dev/null +++ b/src/libnx/wrapper/switch/services/irs.nim @@ -0,0 +1,699 @@ +## * +## @file irs.h +## @brief HID IR sensor (irs) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/hid + +const + IRS_MAX_CAMERAS* = 0x9 + +## / IrCameraStatus + +type + IrsIrCameraStatus* = enum + IrsIrCameraStatusAvailable = 0, ## /< Available + IrsIrCameraStatusUnsupported = 1, ## /< Unsupported + IrsIrCameraStatusUnconnected = 2 ## /< Unconnected + + +## / IrCameraInternalStatus + +type + IrsIrCameraInternalStatus* = enum + IrsIrCameraInternalStatusStopped = 0, ## /< Stopped + IrsIrCameraInternalStatusFirmwareUpdateNeeded = 1, ## /< FirmwareUpdateNeeded + IrsIrCameraInternalStatusUnknown2 = 2, ## /< Unknown + IrsIrCameraInternalStatusUnknown3 = 3, ## /< Unknown + IrsIrCameraInternalStatusUnknown4 = 4, ## /< Unknown + IrsIrCameraInternalStatusFirmwareVersionRequested = 5, ## /< FirmwareVersionRequested + IrsIrCameraInternalStatusFirmwareVersionIsInvalid = 6, ## /< FirmwareVersionIsInvalid + IrsIrCameraInternalStatusReady = 7, ## /< [4.0.0+] Ready + IrsIrCameraInternalStatusSetting = 8 ## /< [4.0.0+] Setting + + +## / IrSensorMode + +type + IrsIrSensorMode* = enum + IrsIrSensorModeNone = 0, ## /< None + IrsIrSensorModeMomentProcessor = 1, ## /< MomentProcessor + IrsIrSensorModeClusteringProcessor = 2, ## /< ClusteringProcessor + IrsIrSensorModeImageTransferProcessor = 3, ## /< ImageTransferProcessor + IrsIrSensorModePointingProcessor = 4, ## /< PointingProcessor + IrsIrSensorModeTeraPluginProcessor = 5, ## /< TeraPluginProcessor + IrsIrSensorModeIrLedProcessor = 6 ## /< IrLedProcessor (doesn't apply to IrsDeviceFormat::ir_sensor_mode) + + +## / ImageProcessorStatus + +type + IrsImageProcessorStatus* = enum + IrsImageProcessorStatusStopped = 0, ## /< Stopped + IrsImageProcessorStatusRunning = 1 ## /< Running + + +## / ImageTransferProcessorFormat. IR Sensor image resolution. + +type + IrsImageTransferProcessorFormat* = enum + IrsImageTransferProcessorFormat320x240 = 0, ## /< 320x240 + IrsImageTransferProcessorFormat160x120 = 1, ## /< 160x120 + IrsImageTransferProcessorFormat80x60 = 2, ## /< 80x60 + IrsImageTransferProcessorFormat40x30 = 3, ## /< [4.0.0+] 40x30 + IrsImageTransferProcessorFormat20x15 = 4 ## /< [4.0.0+] 20x15 + + +## / AdaptiveClusteringMode + +type + IrsAdaptiveClusteringMode* = enum + IrsAdaptiveClusteringModeStaticFov = 0, ## /< StaticFov + IrsAdaptiveClusteringModeDynamicFov = 1 ## /< DynamicFov + + +## / AdaptiveClusteringTargetDistance + +type + IrsAdaptiveClusteringTargetDistance* = enum + IrsAdaptiveClusteringTargetDistanceNear = 0, ## /< Near + IrsAdaptiveClusteringTargetDistanceMiddle = 1, ## /< Middle + IrsAdaptiveClusteringTargetDistanceFar = 2 ## /< Far + + +## / HandAnalysisMode + +type + IrsHandAnalysisMode* = enum + IrsHandAnalysisModeSilhouette = 1, ## /< Silhouette + IrsHandAnalysisModeImage = 2, ## /< Image + IrsHandAnalysisModeSilhouetteAndImage = 3, ## /< SilhouetteAndImage + IrsHandAnalysisModeSilhouetteOnly = 4 ## /< [4.0.0+] SilhouetteOnly + + +## / Internal validation callblack. + +type + IrsValidationCb* = proc (userdata: pointer; arg: pointer): bool {.cdecl.} + +## / IrCameraHandle + +type + IrsIrCameraHandle* {.bycopy.} = object + playerNumber*: U8 ## /< PlayerNumber + deviceType*: U8 ## /< DeviceType + reserved*: array[0x2, U8] ## /< Reserved + + +## / PackedMcuVersion + +type + IrsPackedMcuVersion* {.bycopy.} = object + majorVersion*: U16 ## /< MajorVersion + minorVersion*: U16 ## /< MinorVersion + + +## / PackedFunctionLevel + +type + IrsPackedFunctionLevel* {.bycopy.} = object + irSensorFunctionLevel*: U8 ## /< IrSensorFunctionLevel + reserved*: array[0x3, U8] ## /< Reserved + + +## / Rect + +type + IrsRect* {.bycopy.} = object + x*: S16 ## /< X + y*: S16 ## /< Y + width*: S16 ## /< Width + height*: S16 ## /< Height + + +## / IrsMomentProcessorConfig + +type + IrsMomentProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U32 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U32 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x7, U8] ## /< Reserved. + windowOfInterest*: IrsRect ## /< WindowOfInterest + preprocess*: U32 ## /< Preprocess + preprocessIntensityThreshold*: U32 ## /< PreprocessIntensityThreshold + + +## / PackedMomentProcessorConfig + +type + IrsPackedMomentProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U8 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U8 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x5, U8] ## /< Reserved. + windowOfInterest*: IrsRect ## /< WindowOfInterest + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + preprocess*: U8 ## /< Preprocess + preprocessIntensityThreshold*: U8 ## /< PreprocessIntensityThreshold + reserved2*: array[0x2, U8] ## /< Reserved. + + +## / ClusteringProcessorConfig + +type + IrsClusteringProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U32 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U32 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x7, U8] ## /< Reserved. + windowOfInterest*: IrsRect ## /< WindowOfInterest + objectPixelCountMin*: U32 ## /< ObjectPixelCountMin + objectPixelCountMax*: U32 ## /< ObjectPixelCountMax + objectIntensityMin*: U32 ## /< ObjectIntensityMin + isExternalLightFilterEnabled*: U8 ## /< IsExternalLightFilterEnabled + + +## / PackedClusteringProcessorConfig + +type + IrsPackedClusteringProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U8 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U8 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x5, U8] ## /< Reserved. + windowOfInterest*: IrsRect ## /< WindowOfInterest + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + objectPixelCountMin*: U32 ## /< ObjectPixelCountMin + objectPixelCountMax*: U32 ## /< ObjectPixelCountMax + objectIntensityMin*: U8 ## /< ObjectIntensityMin + isExternalLightFilterEnabled*: U8 ## /< IsExternalLightFilterEnabled + reserved2*: array[0x2, U8] ## /< Reserved. + + +## / ImageTransferProcessorConfig + +type + IrsImageTransferProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U32 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U32 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x7, U8] ## /< Reserved. + format*: U32 ## /< \ref IrsImageTransferProcessorFormat + + +## / ImageTransferProcessorExConfig + +type + IrsImageTransferProcessorExConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U32 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U32 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x7, U8] ## /< Reserved. + origFormat*: U32 ## /< OrigFormat \ref IrsImageTransferProcessorFormat + trimmingFormat*: U32 ## /< TrimmingFormat \ref IrsImageTransferProcessorFormat + trimmingStartX*: U16 ## /< TrimmingStartX + trimmingStartY*: U16 ## /< TrimmingStartY + isExternalLightFilterEnabled*: U8 ## /< IsExternalLightFilterEnabled + + +## / PackedImageTransferProcessorConfig + +type + IrsPackedImageTransferProcessorConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U8 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U8 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x5, U8] ## /< Reserved. + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + format*: U8 ## /< \ref IrsImageTransferProcessorFormat + reserved2*: array[0x3, U8] ## /< Reserved. + + +## / PackedImageTransferProcessorExConfig + +type + IrsPackedImageTransferProcessorExConfig* {.bycopy.} = object + exposureTime*: U64 ## /< IR Sensor exposure time in nanoseconds. + lightTarget*: U8 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + gain*: U8 ## /< IR sensor signal's digital gain. + isNegativeImageUsed*: U8 ## /< Inverts the colors of the captured image. 0: Normal image, 1: Negative image. + reserved*: array[0x5, U8] ## /< Reserved. + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + origFormat*: U8 ## /< OrigFormat \ref IrsImageTransferProcessorFormat + trimmingFormat*: U8 ## /< TrimmingFormat \ref IrsImageTransferProcessorFormat + trimmingStartX*: U16 ## /< TrimmingStartX + trimmingStartY*: U16 ## /< TrimmingStartY + isExternalLightFilterEnabled*: U8 ## /< IsExternalLightFilterEnabled + reserved2*: array[0x5, U8] ## /< Reserved. + + +## / ImageTransferProcessorState + +type + IrsImageTransferProcessorState* {.bycopy.} = object + samplingNumber*: U64 ## /< SamplingNumber + ambientNoiseLevel*: U32 ## /< AmbientNoiseLevel + reserved*: array[0x4, U8] ## /< Reserved + + +## / PackedPointingProcessorConfig + +type + IrsPackedPointingProcessorConfig* {.bycopy.} = object + windowOfInterest*: IrsRect ## /< WindowOfInterest + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + + +## / TeraPluginProcessorConfig + +type + IrsTeraPluginProcessorConfig* {.bycopy.} = object + mode*: U8 ## /< Mode + unkX1*: U8 ## /< [6.0.0+] Unknown + unkX2*: U8 ## /< [6.0.0+] Unknown + unkX3*: U8 ## /< [6.0.0+] Unknown + + +## / PackedTeraPluginProcessorConfig + +type + IrsPackedTeraPluginProcessorConfig* {.bycopy.} = object + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + mode*: U8 ## /< Mode + unkX5*: U8 ## /< [6.0.0+] This is set to 0x2 | (IrsTeraPluginProcessorConfig::unk_x1 << 7). + unkX6*: U8 ## /< [6.0.0+] IrsTeraPluginProcessorConfig::unk_x2 + unkX7*: U8 ## /< [6.0.0+] IrsTeraPluginProcessorConfig::unk_x3 + + +## / IrLedProcessorConfig + +type + IrsIrLedProcessorConfig* {.bycopy.} = object + lightTarget*: U32 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + + +## / PackedIrLedProcessorConfig + +type + IrsPackedIrLedProcessorConfig* {.bycopy.} = object + requiredMcuVersion*: IrsPackedMcuVersion ## /< RequiredMcuVersion + lightTarget*: U8 ## /< Controls the IR leds. 0: All leds, 1: Bright group, 2: Dim group, 3: None. + pad*: array[0x3, U8] ## /< Padding + + +## / AdaptiveClusteringProcessorConfig + +type + IrsAdaptiveClusteringProcessorConfig* {.bycopy.} = object + mode*: U32 ## /< \ref IrsAdaptiveClusteringMode + targetDistance*: U32 ## /< [6.0.0+] \ref IrsAdaptiveClusteringTargetDistance + + +## / HandAnalysisConfig + +type + IrsHandAnalysisConfig* {.bycopy.} = object + mode*: U32 ## /< \ref IrsHandAnalysisMode + + +## / MomentStatistic + +type + IrsMomentStatistic* {.bycopy.} = object + averageIntensity*: cfloat ## /< AverageIntensity + centroidX*: cfloat ## /< CentroidX + centroidY*: cfloat ## /< CentroidY + + +## / MomentProcessorState + +type + IrsMomentProcessorState* {.bycopy.} = object + samplingNumber*: S64 ## /< SamplingNumber + timestamp*: U64 ## /< TimeStamp + ambientNoiseLevel*: U32 ## /< AmbientNoiseLevel + reserved*: array[0x4, U8] ## /< Reserved + statistic*: array[0x30, IrsMomentStatistic] ## /< \ref IrsMomentStatistic + + +## / ClusteringData + +type + IrsClusteringData* {.bycopy.} = object + averageIntensity*: cfloat ## /< AverageIntensity + centroidX*: cfloat ## /< CentroidX + centroidY*: cfloat ## /< CentroidY + pixelCount*: U32 ## /< PixelCount + boundX*: U16 ## /< BoundX + boundY*: U16 ## /< BoundY + boundtWidth*: U16 ## /< BoundtWidth + boundHeight*: U16 ## /< BoundHeight + + +## / ClusteringProcessorState + +type + IrsClusteringProcessorState* {.bycopy.} = object + samplingNumber*: S64 ## /< SamplingNumber + timestamp*: U64 ## /< TimeStamp + objectCount*: U8 ## /< ObjectCount + reserved*: array[0x3, U8] ## /< Reserved + ambientNoiseLevel*: U32 ## /< AmbientNoiseLevel + data*: array[0x10, IrsClusteringData] ## /< \ref IrsClusteringData + + +## / PointingProcessorMarkerState + +type + INNER_C_STRUCT_irs_1* {.bycopy.} = object + pointingStatus*: U8 ## /< PointingStatus + reserved*: array[0x3, U8] ## /< Reserved + unkX4*: array[0x4, U8] ## /< Unknown + unkX8*: cfloat ## /< Unknown + positionX*: cfloat ## /< PositionX + positionY*: cfloat ## /< PositionY + unkX14*: cfloat ## /< Unknown + windowOfInterest*: IrsRect ## /< WindowOfInterest + + IrsPointingProcessorMarkerState* {.bycopy.} = object + samplingNumber*: S64 ## /< SamplingNumber + timestamp*: U64 ## /< TimeStamp + data*: array[3, INNER_C_STRUCT_irs_1] + + +## / PointingProcessorState + +type + IrsPointingProcessorState* {.bycopy.} = object + samplingNumber*: S64 ## /< SamplingNumber + timestamp*: U64 ## /< TimeStamp + pointingStatus*: U32 ## /< PointingStatus + positionX*: cfloat ## /< PositionX + positionY*: cfloat ## /< PositionY + reserved*: array[0x4, U8] ## /< Reserved + + +## / TeraPluginProcessorState + +type + IrsTeraPluginProcessorState* {.bycopy.} = object + samplingNumber*: S64 ## /< SamplingNumber + timestamp*: U64 ## /< TimeStamp + ambientNoiseLevel*: U32 ## /< AmbientNoiseLevel + pluginData*: array[0x12c, U8] ## /< PluginData + + +## / ProcessorState + +type + IrsProcessorState* {.bycopy.} = object + start*: S64 ## /< Start + count*: U32 ## /< Count + pad*: U32 ## /< Padding + data*: array[0xe10, U8] ## /< Contains an array of *ProcessorState, depending on IrsDeviceFormat::ir_sensor_mode. + + +## / DeviceFormat + +type + IrsDeviceFormat* {.bycopy.} = object + irCameraStatus*: U32 ## /< \ref IrsIrCameraStatus + irCameraInternalStatus*: U32 ## /< \ref IrsIrCameraInternalStatus + irSensorMode*: U32 ## /< \ref IrsIrSensorMode + pad*: U32 ## /< Padding + processorState*: IrsProcessorState ## /< \ref IrsProcessorState + + +## / AruidFormat + +type + IrsAruidFormat* {.bycopy.} = object + irSensorAruid*: U64 ## /< IrSensorAruid + irSensorAruidStatus*: U32 ## /< IrSensorAruidStatus + pad*: U32 ## /< Padding + + +## / StatusManager + +type + IrsStatusManager* {.bycopy.} = object + deviceFormat*: array[Irs_Max_Cameras, IrsDeviceFormat] + aruidFormat*: array[0x5, IrsAruidFormat] + +proc irsInitialize*(): Result {.cdecl, importc: "irsInitialize".} +## / Initialize irs. + +proc irsExit*() {.cdecl, importc: "irsExit".} +## / Exit irs. + +proc irsGetServiceSession*(): ptr Service {.cdecl, importc: "irsGetServiceSession".} +## / Gets the Service object for the actual irs service session. + +proc irsGetSharedmemAddr*(): pointer {.cdecl, importc: "irsGetSharedmemAddr".} +## / Gets the address of the SharedMemory (\ref IrsStatusManager). + +proc irsGetIrCameraHandle*(handle: ptr IrsIrCameraHandle; id: HidNpadIdType): Result {. + cdecl, importc: "irsGetIrCameraHandle".} +## / Gets the \ref IrsIrCameraHandle for the specified controller. + +proc irsGetIrCameraStatus*(handle: IrsIrCameraHandle; `out`: ptr IrsIrCameraStatus): Result {. + cdecl, importc: "irsGetIrCameraStatus".} +## / GetIrCameraStatus + +proc irsCheckFirmwareUpdateNecessity*(handle: IrsIrCameraHandle; `out`: ptr bool): Result {. + cdecl, importc: "irsCheckFirmwareUpdateNecessity".} +## / CheckFirmwareUpdateNecessity +## / When successful where the output flag is set, the user should use \ref hidLaShowControllerFirmwareUpdate. +## / Only available on [4.0.0+]. + +proc irsGetImageProcessorStatus*(handle: IrsIrCameraHandle; + `out`: ptr IrsImageProcessorStatus): Result {.cdecl, + importc: "irsGetImageProcessorStatus".} +## / GetImageProcessorStatus +## / Only available on [4.0.0+]. + +proc irsStopImageProcessor*(handle: IrsIrCameraHandle): Result {.cdecl, + importc: "irsStopImageProcessor".} +## / Stop the current Processor. +## / \ref irsExit calls this with all IrCameraHandles which were not already used with \ref irsStopImageProcessor. + +proc irsStopImageProcessorAsync*(handle: IrsIrCameraHandle): Result {.cdecl, + importc: "irsStopImageProcessorAsync".} +## / Stop the current Processor, async. +## / Only available on [4.0.0+]. + +proc irsRunMomentProcessor*(handle: IrsIrCameraHandle; + config: ptr IrsMomentProcessorConfig): Result {.cdecl, + importc: "irsRunMomentProcessor".} +## * +## @brief Run the MomentProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsGetMomentProcessorStates*(handle: IrsIrCameraHandle; + states: ptr IrsMomentProcessorState; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "irsGetMomentProcessorStates".} +## * +## @brief Gets the states for MomentProcessor or IrLedProcessor. +## @note The official GetIrLedProcessorState is essentially the same as this, except it uses hard-coded count=1 with output-array on stack, without returning that data. Hence we don't implement a seperate func for that. +## @param[in] handle \ref IrsIrCameraHandle +## @param[out] states Output array of \ref IrsMomentProcessorState. +## @param[in] count Size of the states array in entries. Must be 1-5. +## @param[out] total_out Total output entries. +## + +proc irsCalculateMomentRegionStatistic*(state: ptr IrsMomentProcessorState; + rect: IrsRect; regionX: S32; regionY: S32; + regionWidth: S32; regionHeight: S32): IrsMomentStatistic {. + cdecl, importc: "irsCalculateMomentRegionStatistic".} +## * +## @brief Calculates an \ref IrsMomentStatistic from the specified region in the input \ref IrsMomentProcessorState. +## @param[in] state \ref IrsMomentProcessorState +## @param[in] rect \ref IrsRect, containing the image width and height. +## @param[in] region_x Region x, must be 0-5 (clamped to this range otherwise). region_x = image_x/6. +## @param[in] region_y Region y, must be 0-7 (clamped to this range otherwise). region_y = image_y/8. +## @param[in] region_width Region width. region_x+region_width must be <=6 (clamped to this range otherwise). +## @param[in] region_height Region height. region_y+region_height must be <=8 (clamped to this range otherwise). +## + +proc irsRunClusteringProcessor*(handle: IrsIrCameraHandle; + config: ptr IrsClusteringProcessorConfig): Result {. + cdecl, importc: "irsRunClusteringProcessor".} +## * +## @brief Run the ClusteringProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsGetClusteringProcessorStates*(handle: IrsIrCameraHandle; + states: ptr IrsClusteringProcessorState; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "irsGetClusteringProcessorStates".} +## * +## @brief Gets the states for ClusteringProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[out] states Output array of \ref IrsClusteringProcessorState. +## @param[in] count Size of the states array in entries. Must be 1-5. +## @param[out] total_out Total output entries. +## + +proc irsRunImageTransferProcessor*(handle: IrsIrCameraHandle; + config: ptr IrsImageTransferProcessorConfig; + size: csize_t): Result {.cdecl, + importc: "irsRunImageTransferProcessor".} +## * +## @brief Run the ImageTransferProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## @param[in] size Work-buffer size, must be 0x1000-byte aligned. +## + +proc irsRunImageTransferExProcessor*(handle: IrsIrCameraHandle; config: ptr IrsImageTransferProcessorExConfig; + size: csize_t): Result {.cdecl, + importc: "irsRunImageTransferExProcessor".} +## * +## @brief Run the ImageTransferExProcessor. +## @note Only available on [4.0.0+]. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## @param[in] size Work-buffer size, must be 0x1000-byte aligned. +## + +proc irsGetImageTransferProcessorState*(handle: IrsIrCameraHandle; buffer: pointer; + size: csize_t; state: ptr IrsImageTransferProcessorState): Result {. + cdecl, importc: "irsGetImageTransferProcessorState".} +## / GetImageTransferProcessorState + +proc irsRunPointingProcessor*(handle: IrsIrCameraHandle): Result {.cdecl, + importc: "irsRunPointingProcessor".} +## * +## @brief Run the PointingProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## + +proc irsGetPointingProcessorMarkerStates*(handle: IrsIrCameraHandle; + states: ptr IrsPointingProcessorMarkerState; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "irsGetPointingProcessorMarkerStates".} +## * +## @brief Gets the states for PointingProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[out] states Output array of \ref IrsPointingProcessorMarkerState. +## @param[in] count Size of the states array in entries. Must be 1-6. +## @param[out] total_out Total output entries. +## + +proc irsGetPointingProcessorStates*(handle: IrsIrCameraHandle; + states: ptr IrsPointingProcessorState; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "irsGetPointingProcessorStates".} +## * +## @brief Gets the states for \ref IrsPointingProcessorState. +## @note This uses \ref irsGetPointingProcessorMarkerStates, then converts the output to \ref IrsPointingProcessorState. +## @param[in] handle \ref IrsIrCameraHandle +## @param[out] states Output array of \ref IrsPointingProcessorState. +## @param[in] count Size of the states array in entries. Must be 1-6. +## @param[out] total_out Total output entries. +## + +proc irsRunTeraPluginProcessor*(handle: IrsIrCameraHandle; + config: ptr IrsTeraPluginProcessorConfig): Result {. + cdecl, importc: "irsRunTeraPluginProcessor".} +## * +## @brief Run the TeraPluginProcessor. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsGetTeraPluginProcessorStates*(handle: IrsIrCameraHandle; + states: ptr IrsTeraPluginProcessorState; + count: S32; samplingNumber: S64; + prefixData: U32; prefixBitcount: U32; + totalOut: ptr S32): Result {.cdecl, + importc: "irsGetTeraPluginProcessorStates".} +## * +## @brief Gets the states for TeraPluginProcessor, filtered using the input params. +## @param[in] handle \ref IrsIrCameraHandle +## @param[out] states Output array of \ref IrsTeraPluginProcessorState. +## @param[in] count Size of the states array in entries. Must be 1-5. +## @param[in] sampling_number Minimum value for IrsTeraPluginProcessorState::sampling_number. +## @param[in] prefix_data Only used when prefix_bitcount is not 0. The first prefix_bitcount bits from prefix_data must match the first prefix_bitcount bits in IrsTeraPluginProcessorState::plugin_data. +## @param[in] prefix_bitcount Total bits for prefix_data. +## @param[out] total_out Total output entries. +## + +proc irsRunIrLedProcessor*(handle: IrsIrCameraHandle; + config: ptr IrsIrLedProcessorConfig): Result {.cdecl, + importc: "irsRunIrLedProcessor".} +## * +## @brief Run the IrLedProcessor. +## @note Only available on [4.0.0+]. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsRunAdaptiveClusteringProcessor*(handle: IrsIrCameraHandle; config: ptr IrsAdaptiveClusteringProcessorConfig): Result {. + cdecl, importc: "irsRunAdaptiveClusteringProcessor".} +## * +## @brief Run the AdaptiveClusteringProcessor. +## @note Only available on [5.0.0+]. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsRunHandAnalysis*(handle: IrsIrCameraHandle; + config: ptr IrsHandAnalysisConfig): Result {.cdecl, + importc: "irsRunHandAnalysis".} +## * +## @brief Run HandAnalysis. +## @param[in] handle \ref IrsIrCameraHandle +## @param[in] config Input config. +## + +proc irsGetMomentProcessorDefaultConfig*(config: ptr IrsMomentProcessorConfig) {. + cdecl, importc: "irsGetMomentProcessorDefaultConfig".} +## * +## Gets the default configuration for MomentProcessor. +## + +proc irsGetClusteringProcessorDefaultConfig*( + config: ptr IrsClusteringProcessorConfig) {.cdecl, + importc: "irsGetClusteringProcessorDefaultConfig".} +## * +## Gets the default configuration for ClusteringProcessor. +## + +proc irsGetDefaultImageTransferProcessorConfig*( + config: ptr IrsImageTransferProcessorConfig) {.cdecl, + importc: "irsGetDefaultImageTransferProcessorConfig".} +## * +## Gets the default configuration for ImageTransferProcessor. +## Defaults are exposure 300us, 8x digital gain, the rest is all-zero. Format is ::IrsImageTransferProcessorFormat_320x240. +## + +proc irsGetDefaultImageTransferProcessorExConfig*( + config: ptr IrsImageTransferProcessorExConfig) {.cdecl, + importc: "irsGetDefaultImageTransferProcessorExConfig".} +## * +## Gets the default configuration for ImageTransferProcessorEx. +## Defaults are exposure 300us, 8x digital gain, the rest is all-zero. OrigFormat/TrimmingFormat are ::IrsImageTransferProcessorFormat_320x240. +## + +proc irsGetIrLedProcessorDefaultConfig*(config: ptr IrsIrLedProcessorConfig) {. + inline, cdecl.} = + ## * + ## Gets the default configuration for IrLedProcessor. + ## + config.lightTarget = 0 diff --git a/src/libnx/wrapper/switch/services/lbl.h b/src/libnx/wrapper/switch/services/lbl.h new file mode 100644 index 0000000..03bfb54 --- /dev/null +++ b/src/libnx/wrapper/switch/services/lbl.h @@ -0,0 +1,90 @@ +/** + * @file lbl.h + * @brief LBL service IPC wrapper. + * @author SciresM, exelix + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + LblBacklightSwitchStatus_Disabled = 0, + LblBacklightSwitchStatus_Enabled = 1, + LblBacklightSwitchStatus_Enabling = 2, + LblBacklightSwitchStatus_Disabling = 3, +} LblBacklightSwitchStatus; + +/// Initialize lbl. +Result lblInitialize(void); + +/// Exit lbl. +void lblExit(void); + +/// Gets the Service object for the actual lbl service session. +Service* lblGetServiceSession(void); + +Result lblSaveCurrentSetting(void); +Result lblLoadCurrentSetting(void); + +/** + * @note The brightness goes from 0 to 1.0. + */ +Result lblSetCurrentBrightnessSetting(float brightness); +Result lblGetCurrentBrightnessSetting(float *out_value); + +Result lblApplyCurrentBrightnessSettingToBacklight(void); +Result lblGetBrightnessSettingAppliedToBacklight(float *out_value); + +Result lblSwitchBacklightOn(u64 fade_time); +Result lblSwitchBacklightOff(u64 fade_time); +Result lblGetBacklightSwitchStatus(LblBacklightSwitchStatus *out_value); + +Result lblEnableDimming(void); +Result lblDisableDimming(void); +Result lblIsDimmingEnabled(bool *out_value); + +Result lblEnableAutoBrightnessControl(void); +Result lblDisableAutoBrightnessControl(void); +Result lblIsAutoBrightnessControlEnabled(bool *out_value); + +Result lblSetAmbientLightSensorValue(float value); + +/** + * @note Used internally by \ref appletGetAmbientLightSensorValue and \ref appletGetCurrentIlluminanceEx. + */ +Result lblGetAmbientLightSensorValue(bool *over_limit, float *lux); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletIsIlluminanceAvailable. + */ +Result lblIsAmbientLightSensorAvailable(bool *out_value); + +/** + * @note Only available on [3.0.0+]. + */ +Result lblSetCurrentBrightnessSettingForVrMode(float brightness); + +/** + * @note Only available on [3.0.0+]. + */ +Result lblGetCurrentBrightnessSettingForVrMode(float *out_value); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletSetVrModeEnabled. + */ +Result lblEnableVrMode(void); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletSetVrModeEnabled. + */ +Result lblDisableVrMode(void); + +/** + * @note Only available on [3.0.0+]. + * @note Used internally by \ref appletIsVrModeEnabled. + */ +Result lblIsVrModeEnabled(bool *out_value); diff --git a/src/libnx/wrapper/switch/services/lbl.nim b/src/libnx/wrapper/switch/services/lbl.nim new file mode 100644 index 0000000..6525682 --- /dev/null +++ b/src/libnx/wrapper/switch/services/lbl.nim @@ -0,0 +1,101 @@ +## * +## @file lbl.h +## @brief LBL service IPC wrapper. +## @author SciresM, exelix +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + LblBacklightSwitchStatus* = enum + LblBacklightSwitchStatusDisabled = 0, LblBacklightSwitchStatusEnabled = 1, + LblBacklightSwitchStatusEnabling = 2, LblBacklightSwitchStatusDisabling = 3 + + +## / Initialize lbl. + +proc lblInitialize*(): Result {.cdecl, importc: "lblInitialize".} +## / Exit lbl. + +proc lblExit*() {.cdecl, importc: "lblExit".} +## / Gets the Service object for the actual lbl service session. + +proc lblGetServiceSession*(): ptr Service {.cdecl, importc: "lblGetServiceSession".} +proc lblSaveCurrentSetting*(): Result {.cdecl, importc: "lblSaveCurrentSetting".} +proc lblLoadCurrentSetting*(): Result {.cdecl, importc: "lblLoadCurrentSetting".} +## * +## @note The brightness goes from 0 to 1.0. +## + +proc lblSetCurrentBrightnessSetting*(brightness: cfloat): Result {.cdecl, + importc: "lblSetCurrentBrightnessSetting".} +proc lblGetCurrentBrightnessSetting*(outValue: ptr cfloat): Result {.cdecl, + importc: "lblGetCurrentBrightnessSetting".} +proc lblApplyCurrentBrightnessSettingToBacklight*(): Result {.cdecl, + importc: "lblApplyCurrentBrightnessSettingToBacklight".} +proc lblGetBrightnessSettingAppliedToBacklight*(outValue: ptr cfloat): Result {. + cdecl, importc: "lblGetBrightnessSettingAppliedToBacklight".} +proc lblSwitchBacklightOn*(fadeTime: U64): Result {.cdecl, + importc: "lblSwitchBacklightOn".} +proc lblSwitchBacklightOff*(fadeTime: U64): Result {.cdecl, + importc: "lblSwitchBacklightOff".} +proc lblGetBacklightSwitchStatus*(outValue: ptr LblBacklightSwitchStatus): Result {. + cdecl, importc: "lblGetBacklightSwitchStatus".} +proc lblEnableDimming*(): Result {.cdecl, importc: "lblEnableDimming".} +proc lblDisableDimming*(): Result {.cdecl, importc: "lblDisableDimming".} +proc lblIsDimmingEnabled*(outValue: ptr bool): Result {.cdecl, + importc: "lblIsDimmingEnabled".} +proc lblEnableAutoBrightnessControl*(): Result {.cdecl, + importc: "lblEnableAutoBrightnessControl".} +proc lblDisableAutoBrightnessControl*(): Result {.cdecl, + importc: "lblDisableAutoBrightnessControl".} +proc lblIsAutoBrightnessControlEnabled*(outValue: ptr bool): Result {.cdecl, + importc: "lblIsAutoBrightnessControlEnabled".} +proc lblSetAmbientLightSensorValue*(value: cfloat): Result {.cdecl, + importc: "lblSetAmbientLightSensorValue".} +## * +## @note Used internally by \ref appletGetAmbientLightSensorValue and \ref appletGetCurrentIlluminanceEx. +## + +proc lblGetAmbientLightSensorValue*(overLimit: ptr bool; lux: ptr cfloat): Result {. + cdecl, importc: "lblGetAmbientLightSensorValue".} +## * +## @note Only available on [3.0.0+]. +## @note Used internally by \ref appletIsIlluminanceAvailable. +## + +proc lblIsAmbientLightSensorAvailable*(outValue: ptr bool): Result {.cdecl, + importc: "lblIsAmbientLightSensorAvailable".} +## * +## @note Only available on [3.0.0+]. +## + +proc lblSetCurrentBrightnessSettingForVrMode*(brightness: cfloat): Result {.cdecl, + importc: "lblSetCurrentBrightnessSettingForVrMode".} +## * +## @note Only available on [3.0.0+]. +## + +proc lblGetCurrentBrightnessSettingForVrMode*(outValue: ptr cfloat): Result {.cdecl, + importc: "lblGetCurrentBrightnessSettingForVrMode".} +## * +## @note Only available on [3.0.0+]. +## @note Used internally by \ref appletSetVrModeEnabled. +## + +proc lblEnableVrMode*(): Result {.cdecl, importc: "lblEnableVrMode".} +## * +## @note Only available on [3.0.0+]. +## @note Used internally by \ref appletSetVrModeEnabled. +## + +proc lblDisableVrMode*(): Result {.cdecl, importc: "lblDisableVrMode".} +## * +## @note Only available on [3.0.0+]. +## @note Used internally by \ref appletIsVrModeEnabled. +## + +proc lblIsVrModeEnabled*(outValue: ptr bool): Result {.cdecl, + importc: "lblIsVrModeEnabled".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/ldn.h b/src/libnx/wrapper/switch/services/ldn.h new file mode 100644 index 0000000..1da556c --- /dev/null +++ b/src/libnx/wrapper/switch/services/ldn.h @@ -0,0 +1,466 @@ +/** + * @file ldn.h + * @brief LDN (local network communications) IPC wrapper. See also: https://switchbrew.org/wiki/LDN_services + * @author yellows8 + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef enum { + LdnServiceType_User = 0, ///< Initializes ldn:u. + LdnServiceType_System = 1, ///< Initializes ldn:s. +} LdnServiceType; + +/// State loaded by \ref ldnmGetStateForMonitor / \ref ldnGetState. +typedef enum { + LdnState_None = 0, ///< None + LdnState_Initialized = 1, ///< Initialized + LdnState_AccessPointOpened = 2, ///< AccessPointOpened (\ref ldnOpenAccessPoint) + LdnState_AccessPointCreated = 3, ///< AccessPointCreated (\ref ldnCreateNetwork / \ref ldnCreateNetworkPrivate) + LdnState_StationOpened = 4, ///< StationOpened (\ref ldnOpenStation) + LdnState_StationConnected = 5, ///< StationConnected (\ref ldnConnect / \ref ldnConnectPrivate) + LdnState_Error = 6, ///< Error +} LdnState; + +/// DisconnectReason loaded by \ref ldnGetDisconnectReason. +typedef enum { + LdnDisconnectReason_None = 0, ///< None + LdnDisconnectReason_User = 1, ///< User + LdnDisconnectReason_SystemRequest = 2, ///< SystemRequest + LdnDisconnectReason_DestroyedByAdmin = 3, ///< DestroyedByAdmin + LdnDisconnectReason_DestroyedBySystemRequest = 4, ///< DestroyedBySystemRequest + LdnDisconnectReason_Admin = 5, ///< Admin + LdnDisconnectReason_SignalLost = 6, ///< SignalLost +} LdnDisconnectReason; + +/// ScanFilterFlags +typedef enum { + LdnScanFilterFlags_LocalCommunicationId = BIT(0), ///< When set, enables using LdnScanFilter::local_communication_id. + LdnScanFilterFlags_NetworkId = BIT(1), ///< When set, enables using LdnScanFilter::network_id. + LdnScanFilterFlags_Unknown2 = BIT(2), ///< When set, enables using LdnScanFilter::unk_x20. + LdnScanFilterFlags_MacAddr = BIT(3), ///< When set, enables using LdnScanFilter::mac_addr. Only available with \ref ldnScanPrivate. + LdnScanFilterFlags_Ssid = BIT(4), ///< When set, enables using the LdnScanFilter::ssid. + LdnScanFilterFlags_UserData = BIT(5), ///< When set, enables using LdnScanFilter::userdata_filter. +} LdnScanFilterFlags; + +/// AcceptPolicy +typedef enum { + LdnAcceptPolicy_AllowAll = 0, ///< Allow all. + LdnAcceptPolicy_DenyAll = 1, ///< Deny all. + LdnAcceptPolicy_Blacklist = 2, ///< Blacklist, addresses in the list (\ref ldnAddAcceptFilterEntry) are not allowed. + LdnAcceptPolicy_Whitelist = 3, ///< Whitelist, only addresses in the list (\ref ldnAddAcceptFilterEntry) are allowed. +} LdnAcceptPolicy; + +/// OperationMode +typedef enum { + LdnOperationMode_Unknown0 = 0, ///< Unknown + LdnOperationMode_Unknown1 = 1, ///< Unknown +} LdnOperationMode; + +/// WirelessControllerRestriction +typedef enum { + LdnWirelessControllerRestriction_Unknown0 = 0, ///< Unknown + LdnWirelessControllerRestriction_Unknown1 = 1, ///< Unknown +} LdnWirelessControllerRestriction; + +/// 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 +} LdnIpv4Address; + +/// SubnetMask. This is essentially the same as struct in_addr - hence this can be used with standard sockets (byteswap required). +typedef struct { + u32 mask; ///< Mask +} LdnSubnetMask; + +/// MacAddress +typedef struct { + u8 addr[6]; ///< Address +} LdnMacAddress; + +/// Ssid +typedef struct { + u8 len; ///< Length excluding NUL-terminator, must be 0x1-0x20. + char str[0x21]; ///< SSID string including NUL-terminator, str[len_field] must be 0. The chars in this string must be be in the range of 0x20-0x7F, for when the Ssid is converted to a string (otherwise the byte written to the string will be 0). +} LdnSsid; + +/// NodeLatestUpdate +typedef struct { + u8 val; ///< The field in state is reset to zero by \ref ldnGetNetworkInfoLatestUpdate after loading it. + u8 reserved[0x7]; ///< Not initialized with \ref ldnGetNetworkInfoLatestUpdate. +} LdnNodeLatestUpdate; + +/// AddressEntry +typedef struct { + LdnIpv4Address ip_addr; ///< \ref LdnIpv4Address + LdnMacAddress mac_addr; ///< \ref LdnMacAddress + u8 pad[0x2]; ///< Padding +} LdnAddressEntry; + +/// NodeInfo +typedef struct { + LdnIpv4Address ip_addr; ///< \ref LdnIpv4Address + LdnMacAddress mac_addr; ///< \ref LdnMacAddress + s8 id; ///< ID / index + u8 is_connected; ///< IsConnected flag + char nickname[0x20]; ///< LdnUserConfig::nickname + u8 reserved_x2C[0x2]; ///< Reserved + s16 local_communication_version; ///< LocalCommunicationVersion + u8 reserved_x30[0x10]; ///< Reserved +} LdnNodeInfo; + +/// UserConfig. The input struct is copied to a tmp struct, which is then used with the cmd. +typedef struct { + char nickname[0x20]; ///< NUL-terminated string for the user nickname. + u8 reserved[0x10]; ///< Cleared to zero for the tmp struct. +} LdnUserConfig; + +/// NetworkInfo +typedef struct { + u64 local_communication_id; ///< LocalCommunicationId + u8 reserved_x8[0x2]; ///< Reserved + u16 userdata_filter; ///< Arbitrary user data which can be used for filtering with \ref LdnScanFilter. + u8 reserved_xC[0x4]; ///< Reserved + u8 network_id[0x10]; ///< LdnSecurityParameter::network_id. NetworkId which is used to generate/overwrite the ssid. With \ref ldnScan / \ref ldnScanPrivate, this is only done after filtering when unk_x4B is value 0x2. + LdnMacAddress mac_addr; ///< \ref LdnMacAddress + LdnSsid ssid; ///< \ref LdnSsid + s16 network_channel; ///< NetworkChannel + s8 link_level; ///< LinkLevel + u8 unk_x4B; ///< Unknown. Set to hard-coded value 0x2 with output structs, except with \ref ldnScan / \ref ldnScanPrivate which can also set value 0x1 in certain cases. + u8 pad_x4C[0x4]; ///< Padding + u8 sec_param_data[0x10]; ///< LdnSecurityParameter::data + u16 sec_type; ///< LdnSecurityConfig::type + u8 accept_policy; ///< \ref LdnAcceptPolicy + u8 unk_x63; ///< Only set with \ref ldnScan / \ref ldnScanPrivate, when unk_x4B is value 0x2. + u8 pad_x64[0x2]; ///< Padding + s8 participant_max; ///< Maximum participants, for nodes. + u8 participant_num; ///< ParticipantNum, number of set entries in nodes. If unk_x4B is not 0x2, ParticipantNum should be handled as if it's 0. + LdnNodeInfo nodes[8]; ///< Array of \ref LdnNodeInfo, starting with the AccessPoint node. + u8 reserved_x268[0x2]; ///< Reserved + u16 advertise_data_size; ///< AdvertiseData size (\ref ldnSetAdvertiseData) + u8 advertise_data[0x180]; ///< AdvertiseData (\ref ldnSetAdvertiseData) + u8 reserved_x3EC[0x8C]; ///< Reserved + u64 auth_id; ///< Random AuthenticationId. +} LdnNetworkInfo; + +/// ScanFilter. The input struct is copied to a tmp struct, which is then used with the cmd (\ref ldnScan and \ref ldnScanPrivate). +typedef struct { + s64 local_communication_id; ///< See ::LdnScanFilterFlags_LocalCommunicationId. When enabled, this will be overwritten if it's -1 (written data is from the user-process control.nacp, with value 0 used instead if loading fails). During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter field must match LdnNetworkInfo::local_communication_id. + u8 pad_x8[0x2]; ///< Padding + u16 userdata_filter; ///< See ::LdnScanFilterFlags_UserData. During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter field must match LdnNetworkInfo::userdata_filter. + u8 pad_xC[0x4]; ///< Padding + u8 network_id[0x10]; ///< See ::LdnScanFilterFlags_NetworkId. During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter data must match LdnNetworkInfo::network_id. + u32 unk_x20; ///< See ::LdnScanFilterFlags_Unknown2. When enabled, this must be <=0x3, and during filtering must match LdnNetworkInfo::unk_x4B. + LdnMacAddress mac_addr; ///< \ref LdnMacAddress (::LdnScanFilterFlags_MacAddr, during filtering if enabled this must match LdnNetworkInfo::mac_addr) + LdnSsid ssid; ///< \ref LdnSsid (::LdnScanFilterFlags_Ssid, during filtering if enabled this must match LdnNetworkInfo::ssid) + u8 reserved[0x10]; ///< Cleared to zero for the tmp struct. + u32 flags; ///< Bitmask for \ref LdnScanFilterFlags. Masked with value 0x37 for \ref ldnScan, with \ref ldnScanPrivate this is masked with 0x3F. +} LdnScanFilter; + +/// SecurityConfig +typedef struct { + u16 type; ///< Type, a default of value 0x1 can be used here. Overwritten by \ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnect, \ref ldnConnectPrivate. + u16 data_size; ///< Data size. Must be 0x10-0x40. + u8 data[0x40]; ///< Data, used with key derivation. +} LdnSecurityConfig; + +/// SecurityParameter. The struct used by \ref ldnCreateNetwork internally is randomly-generated. +typedef struct { + u8 data[0x10]; ///< Data, used with the same key derivation as \ref LdnSecurityConfig. + u8 network_id[0x10]; ///< LdnNetworkInfo::network_id +} LdnSecurityParameter; + +/// NetworkConfig. The input struct is copied to a tmp struct, which is then used with the cmd (\ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnectPrivate). +typedef struct { + s64 local_communication_id; ///< LdnNetworkInfo::local_communication_id. \ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnect, \ref ldnConnectPrivate: When -1, this is overwritten with the first LocalCommunicationId from the user-process control.nacp, if loading fails value 0 is written instead. Otherwise when not -1, if control.nacp loading is successful, this field must match one of the LocalCommunicationIds from there. + u8 reserved_x8[2]; ///< Cleared to zero for the tmp struct. + u16 userdata_filter; ///< LdnNetworkInfo::userdata_filter + u8 reserved_xC[4]; ///< Cleared to zero for the tmp struct. + s16 network_channel; ///< LdnNetworkInfo::network_channel. Channel, can be zero. Overwritten internally by \ref ldnCreateNetwork. + s8 participant_max; ///< LdnNetworkInfo::participant_max. \ref ldnCreateNetwork / \ref ldnCreateNetworkPrivate: Must be 0x1-0x8. + u8 reserved_x13; ///< Cleared to zero for the tmp struct. + s16 local_communication_version; ///< LdnNodeInfo::local_communication_version, for the first entry in LdnNetworkInfo::nodes. Must not be negative. + u8 reserved_x16[0xA]; ///< Cleared to zero for the tmp struct. +} LdnNetworkConfig; + +///@name ldn:m +///@{ + +/// Initialize ldn:m. +Result ldnmInitialize(void); + +/// Exit ldn:m. +void ldnmExit(void); + +/// Gets the Service object for IMonitorService. +Service* ldnmGetServiceSession_MonitorService(void); + +/** + * @brief GetStateForMonitor + * @param[out] out \ref LdnState + */ +Result ldnmGetStateForMonitor(LdnState *out); + +/** + * @brief GetNetworkInfoForMonitor + * @param[out] out \ref LdnNetworkInfo + */ +Result ldnmGetNetworkInfoForMonitor(LdnNetworkInfo *out); + +/** + * @brief GetIpv4AddressForMonitor + * @param[out] addr \ref LdnIpv4Address + * @param[out] mask \ref LdnSubnetMask + */ +Result ldnmGetIpv4AddressForMonitor(LdnIpv4Address *addr, LdnSubnetMask *mask); + +/** + * @brief GetSecurityParameterForMonitor + * @note Not exposed by official sw. + * @param[out] out \ref LdnSecurityParameter + */ +Result ldnmGetSecurityParameterForMonitor(LdnSecurityParameter *out); + +/** + * @brief GetNetworkConfigForMonitor + * @note Not exposed by official sw. + * @param[out] out \ref LdnNetworkConfig + */ +Result ldnmGetNetworkConfigForMonitor(LdnNetworkConfig *out); + +///@} + +///@name ldn +///@{ + +/// Initialize ldn. +Result ldnInitialize(LdnServiceType service_type); + +/// Exit ldn. +void ldnExit(void); + +/// Gets the Service object for IUserLocalCommunicationService/ISystemLocalCommunicationService. +Service* ldnGetServiceSession_LocalCommunicationService(void); + +/** + * @brief GetState + * @param[out] out \ref LdnState + */ +Result ldnGetState(LdnState *out); + +/** + * @brief GetNetworkInfo + * @param[out] out \ref LdnNetworkInfo + */ +Result ldnGetNetworkInfo(LdnNetworkInfo *out); + +/** + * @brief GetIpv4Address + * @param[out] addr \ref LdnIpv4Address + * @param[out] mask \ref LdnSubnetMask + */ +Result ldnGetIpv4Address(LdnIpv4Address *addr, LdnSubnetMask *mask); + +/** + * @brief GetDisconnectReason + * @param[out] out \ref LdnDisconnectReason + */ +Result ldnGetDisconnectReason(LdnDisconnectReason *out); + +/** + * @brief GetSecurityParameter + * @param[out] out \ref LdnSecurityParameter + */ +Result ldnGetSecurityParameter(LdnSecurityParameter *out); + +/** + * @brief GetNetworkConfig + * @param[out] out \ref LdnNetworkConfig + */ +Result ldnGetNetworkConfig(LdnNetworkConfig *out); + +/** + * @brief AttachStateChangeEvent + * @note The Event must be closed by the user once finished with it. + * @note This is signaled when the data returned by \ref ldnGetNetworkInfo / \ref ldnGetNetworkInfoLatestUpdate is updated. + * @param[out] out_event Output Event with autoclear=true. + */ +Result ldnAttachStateChangeEvent(Event* out_event); + +/** + * @brief GetNetworkInfoLatestUpdate + * @param[out] network_info \ref LdnNetworkInfo + * @param[out] nodes Output array of \ref LdnNodeLatestUpdate. + * @param[in] count Size of the nodes array in entries, must be 8. + */ +Result ldnGetNetworkInfoLatestUpdate(LdnNetworkInfo *network_info, LdnNodeLatestUpdate *nodes, s32 count); + +/** + * @brief Scan + * @note \ref LdnState must be ::LdnState_AccessPointCreated, ::LdnState_StationOpened, or ::LdnState_StationConnected. + * @note This is the same as \ref ldnScanPrivate (minus the masking for LdnScanFilter::flags), except this has the same channel-override functionality as \ref ldnCreateNetwork. + * @param[in] channel Channel, value 0 can be used for this. + * @param[in] filter \ref LdnScanFilter + * @param[out] network_info Output array of \ref LdnNetworkInfo. + * @param[in] count Size of the network_info array in entries. Must be at least 1, this is clamped to a maximum of 0x18 internally. + * @param[out] total_out Total output entries. + */ +Result ldnScan(s32 channel, const LdnScanFilter *filter, LdnNetworkInfo *network_info, s32 count, s32 *total_out); + +/** + * @brief ScanPrivate + * @note \ref LdnState must be ::LdnState_AccessPointCreated, ::LdnState_StationOpened, or ::LdnState_StationConnected. + * @note See \ref ldnScan. + * @param[in] channel Channel, value 0 can be used for this. + * @param[in] filter \ref LdnScanFilter + * @param[out] network_info Output array of \ref LdnNetworkInfo. + * @param[in] count Size of the network_info array in entries. Must be at least 1, this is clamped to a maximum of 0x18 internally. + * @param[out] total_out Total output entries. + */ +Result ldnScanPrivate(s32 channel, const LdnScanFilter *filter, LdnNetworkInfo *network_info, s32 count, s32 *total_out); + +/** + * @brief SetWirelessControllerRestriction + * @note Only available on [5.0.0+]. + * @note \ref LdnState must be ::LdnState_Initialized. + * @param[in] restriction \ref LdnWirelessControllerRestriction + */ +Result ldnSetWirelessControllerRestriction(LdnWirelessControllerRestriction restriction); + +/** + * @brief OpenAccessPoint + * @note \ref LdnState must be ::LdnState_Initialized, this eventually sets the State to ::LdnState_AccessPointOpened. + */ +Result ldnOpenAccessPoint(void); + +/** + * @brief CloseAccessPoint + * @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated, this eventually sets the State to ::LdnState_Initialized. + * @note Used automatically internally by \ref ldnExit if needed. + */ +Result ldnCloseAccessPoint(void); + +/** + * @brief CreateNetwork + * @note \ref LdnState must be ::LdnState_AccessPointOpened, this eventually sets the State to ::LdnState_AccessPointCreated. + * @param[in] sec_config \ref LdnSecurityConfig + * @param[in] user_config \ref LdnUserConfig + * @param[in] network_config \ref LdnNetworkConfig + */ +Result ldnCreateNetwork(const LdnSecurityConfig *sec_config, const LdnUserConfig *user_config, const LdnNetworkConfig *network_config); + +/** + * @brief CreateNetworkPrivate + * @note \ref LdnState must be ::LdnState_AccessPointOpened, this eventually sets the State to ::LdnState_AccessPointCreated. + * @note This is the same as \ref ldnCreateNetwork besides the additional user-specified params, and with this cmd LdnNetworkConfig::channel is not overwritten (unlike \ref ldnCreateNetwork). + * @param[in] sec_config \ref LdnSecurityConfig + * @param[in] sec_param \ref LdnSecurityParameter + * @param[in] user_config \ref LdnUserConfig + * @param[in] network_config \ref LdnNetworkConfig + * @param[in] addrs Input array of \ref LdnAddressEntry. This can be NULL. + * @param[in] count Size of the addrs array in entries. This must be <=8. This can be 0, in which case the network will be non-Private like \ref ldnCreateNetwork. + */ +Result ldnCreateNetworkPrivate(const LdnSecurityConfig *sec_config, const LdnSecurityParameter *sec_param, const LdnUserConfig *user_config, const LdnNetworkConfig *network_config, const LdnAddressEntry *addrs, s32 count); + +/** + * @brief DestroyNetwork + * @note \ref LdnState must be ::LdnState_AccessPointCreated, this eventually sets the State to ::LdnState_AccessPointOpened. + */ +Result ldnDestroyNetwork(void); + +/** + * @brief Reject + * @note \ref LdnState must be ::LdnState_AccessPointCreated. + * @param[in] addr \ref LdnIpv4Address + */ +Result ldnReject(LdnIpv4Address addr); + +/** + * @brief SetAdvertiseData + * @note An empty buffer (buffer=NULL/size=0) can be used to reset the AdvertiseData size in state to zero. + * @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. + * @param[in] buffer Input buffer containing arbitrary user data. + * @param[in] size Input buffer size, must be <=0x180. If this isn't enough space, you can for example also periodically use this cmd with different regions of your data with some sequence_number field (or use sockets while connected to the network). + */ +Result ldnSetAdvertiseData(const void* buffer, size_t size); + +/** + * @brief SetStationAcceptPolicy + * @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. + * @param[in] policy \ref LdnAcceptPolicy + */ +Result ldnSetStationAcceptPolicy(LdnAcceptPolicy policy); + +/** + * @brief AddAcceptFilterEntry + * @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. + * @note See \ref LdnAcceptPolicy. + * @param[in] addr \ref LdnMacAddress. If you want, you can also pass LdnNodeInfo::mac_addr for this. + */ +Result ldnAddAcceptFilterEntry(LdnMacAddress addr); + +/** + * @brief ClearAcceptFilter + * @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. + */ +Result ldnClearAcceptFilter(void); + +/** + * @brief OpenStation + * @note \ref LdnState must be ::LdnState_Initialized, this eventually sets the State to ::LdnState_StationOpened. + */ +Result ldnOpenStation(void); + +/** + * @brief CloseStation + * @note \ref LdnState must be ::LdnState_StationOpened or ::LdnState_StationConnected, this eventually sets the State to ::LdnState_Initialized. + * @note Used automatically internally by \ref ldnExit if needed. + */ +Result ldnCloseStation(void); + +/** + * @brief Connect + * @note \ref LdnState must be ::LdnState_StationOpened, this eventually sets the State to ::LdnState_StationConnected. + * @note This is identical to \ref ldnConnectPrivate besides the used params, the code overwriting LdnSecurityConfig::type also differs. + * @param[in] sec_config \ref LdnSecurityConfig + * @param[in] user_config \ref LdnUserConfig + * @param[in] version LocalCommunicationVersion, this must be 0x0-0x7FFF. + * @param[in] option ConnectOption bitmask, must be <=0x1. You can use value 0 for example here. + * @param[in] network_info \ref LdnNetworkInfo + */ +Result ldnConnect(const LdnSecurityConfig *sec_config, const LdnUserConfig *user_config, s32 version, u32 option, const LdnNetworkInfo *network_info); + +/** + * @brief ConnectPrivate + * @note \ref LdnState must be ::LdnState_StationOpened, this eventually sets the State to ::LdnState_StationConnected. + * @note See \ref ldnConnect. + * @param[in] sec_config \ref LdnSecurityConfig + * @param[in] sec_param \ref LdnSecurityParameter + * @param[in] user_config \ref LdnUserConfig + * @param[in] version LocalCommunicationVersion, this must be 0x0-0x7FFF. + * @param[in] option ConnectOption bitmask, must be <=0x1. You can use value 0 for example here. + * @param[in] network_config \ref LdnNetworkConfig + */ +Result ldnConnectPrivate(const LdnSecurityConfig *sec_config, const LdnSecurityParameter *sec_param, const LdnUserConfig *user_config, s32 version, u32 option, const LdnNetworkConfig *network_config); + +/** + * @brief Disconnect + * @note \ref LdnState must be ::LdnState_StationConnected, this eventually sets the State to ::LdnState_StationOpened. + */ +Result ldnDisconnect(void); + +/** + * @brief SetOperationMode + * @note Only available on [4.0.0+]. + * @note Only available with ::LdnServiceType_System. + * @note \ref LdnState must be ::LdnState_Initialized. + * @param[in] mode \ref LdnOperationMode + */ +Result ldnSetOperationMode(LdnOperationMode mode); + +///@} + diff --git a/src/libnx/wrapper/switch/services/ldn.nim b/src/libnx/wrapper/switch/services/ldn.nim new file mode 100644 index 0000000..de35894 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ldn.nim @@ -0,0 +1,540 @@ +## * +## @file ldn.h +## @brief LDN (local network communications) IPC wrapper. See also: https://switchbrew.org/wiki/LDN_services +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + LdnServiceType* = enum + LdnServiceTypeUser = 0, ## /< Initializes ldn:u. + LdnServiceTypeSystem = 1 ## /< Initializes ldn:s. + + +## / State loaded by \ref ldnmGetStateForMonitor / \ref ldnGetState. + +type + LdnState* = enum + LdnStateNone = 0, ## /< None + LdnStateInitialized = 1, ## /< Initialized + LdnStateAccessPointOpened = 2, ## /< AccessPointOpened (\ref ldnOpenAccessPoint) + LdnStateAccessPointCreated = 3, ## /< AccessPointCreated (\ref ldnCreateNetwork / \ref ldnCreateNetworkPrivate) + LdnStateStationOpened = 4, ## /< StationOpened (\ref ldnOpenStation) + LdnStateStationConnected = 5, ## /< StationConnected (\ref ldnConnect / \ref ldnConnectPrivate) + LdnStateError = 6 ## /< Error + + +## / DisconnectReason loaded by \ref ldnGetDisconnectReason. + +type + LdnDisconnectReason* = enum + LdnDisconnectReasonNone = 0, ## /< None + LdnDisconnectReasonUser = 1, ## /< User + LdnDisconnectReasonSystemRequest = 2, ## /< SystemRequest + LdnDisconnectReasonDestroyedByAdmin = 3, ## /< DestroyedByAdmin + LdnDisconnectReasonDestroyedBySystemRequest = 4, ## /< DestroyedBySystemRequest + LdnDisconnectReasonAdmin = 5, ## /< Admin + LdnDisconnectReasonSignalLost = 6 ## /< SignalLost + + +## / ScanFilterFlags + +type + LdnScanFilterFlags* = enum + LdnScanFilterFlagsLocalCommunicationId = bit(0), ## /< When set, enables using LdnScanFilter::local_communication_id. + LdnScanFilterFlagsNetworkId = bit(1), ## /< When set, enables using LdnScanFilter::network_id. + LdnScanFilterFlagsUnknown2 = bit(2), ## /< When set, enables using LdnScanFilter::unk_x20. + LdnScanFilterFlagsMacAddr = bit(3), ## /< When set, enables using LdnScanFilter::mac_addr. Only available with \ref ldnScanPrivate. + LdnScanFilterFlagsSsid = bit(4), ## /< When set, enables using the LdnScanFilter::ssid. + LdnScanFilterFlagsUserData = bit(5) ## /< When set, enables using LdnScanFilter::userdata_filter. + + +## / AcceptPolicy + +type + LdnAcceptPolicy* = enum + LdnAcceptPolicyAllowAll = 0, ## /< Allow all. + LdnAcceptPolicyDenyAll = 1, ## /< Deny all. + LdnAcceptPolicyBlacklist = 2, ## /< Blacklist, addresses in the list (\ref ldnAddAcceptFilterEntry) are not allowed. + LdnAcceptPolicyWhitelist = 3 ## /< Whitelist, only addresses in the list (\ref ldnAddAcceptFilterEntry) are allowed. + + +## / OperationMode + +type + LdnOperationMode* = enum + LdnOperationModeUnknown0 = 0, ## /< Unknown + LdnOperationModeUnknown1 = 1 ## /< Unknown + + +## / WirelessControllerRestriction + +type + LdnWirelessControllerRestriction* = enum + LdnWirelessControllerRestrictionUnknown0 = 0, ## /< Unknown + LdnWirelessControllerRestrictionUnknown1 = 1 ## /< Unknown + + +## / Ipv4Address. This is essentially the same as struct in_addr - hence this can be used with standard sockets (byteswap required). + +type + LdnIpv4Address* {.bycopy.} = object + `addr`*: U32 ## /< Address + + +## / SubnetMask. This is essentially the same as struct in_addr - hence this can be used with standard sockets (byteswap required). + +type + LdnSubnetMask* {.bycopy.} = object + mask*: U32 ## /< Mask + + +## / MacAddress + +type + LdnMacAddress* {.bycopy.} = object + `addr`*: array[6, U8] ## /< Address + + +## / Ssid + +type + LdnSsid* {.bycopy.} = object + len*: U8 ## /< Length excluding NUL-terminator, must be 0x1-0x20. + str*: array[0x21, char] ## /< SSID string including NUL-terminator, str[len_field] must be 0. The chars in this string must be be in the range of 0x20-0x7F, for when the Ssid is converted to a string (otherwise the byte written to the string will be 0). + + +## / NodeLatestUpdate + +type + LdnNodeLatestUpdate* {.bycopy.} = object + val*: U8 ## /< The field in state is reset to zero by \ref ldnGetNetworkInfoLatestUpdate after loading it. + reserved*: array[0x7, U8] ## /< Not initialized with \ref ldnGetNetworkInfoLatestUpdate. + + +## / AddressEntry + +type + LdnAddressEntry* {.bycopy.} = object + ipAddr*: LdnIpv4Address ## /< \ref LdnIpv4Address + macAddr*: LdnMacAddress ## /< \ref LdnMacAddress + pad*: array[0x2, U8] ## /< Padding + + +## / NodeInfo + +type + LdnNodeInfo* {.bycopy.} = object + ipAddr*: LdnIpv4Address ## /< \ref LdnIpv4Address + macAddr*: LdnMacAddress ## /< \ref LdnMacAddress + id*: S8 ## /< ID / index + isConnected*: U8 ## /< IsConnected flag + nickname*: array[0x20, char] ## /< LdnUserConfig::nickname + reservedX2C*: array[0x2, U8] ## /< Reserved + localCommunicationVersion*: S16 ## /< LocalCommunicationVersion + reservedX30*: array[0x10, U8] ## /< Reserved + + +## / UserConfig. The input struct is copied to a tmp struct, which is then used with the cmd. + +type + LdnUserConfig* {.bycopy.} = object + nickname*: array[0x20, char] ## /< NUL-terminated string for the user nickname. + reserved*: array[0x10, U8] ## /< Cleared to zero for the tmp struct. + + +## / NetworkInfo + +type + LdnNetworkInfo* {.bycopy.} = object + localCommunicationId*: U64 ## /< LocalCommunicationId + reservedX8*: array[0x2, U8] ## /< Reserved + userdataFilter*: U16 ## /< Arbitrary user data which can be used for filtering with \ref LdnScanFilter. + reservedXC*: array[0x4, U8] ## /< Reserved + networkId*: array[0x10, U8] ## /< LdnSecurityParameter::network_id. NetworkId which is used to generate/overwrite the ssid. With \ref ldnScan / \ref ldnScanPrivate, this is only done after filtering when unk_x4B is value 0x2. + macAddr*: LdnMacAddress ## /< \ref LdnMacAddress + ssid*: LdnSsid ## /< \ref LdnSsid + networkChannel*: S16 ## /< NetworkChannel + linkLevel*: S8 ## /< LinkLevel + unkX4B*: U8 ## /< Unknown. Set to hard-coded value 0x2 with output structs, except with \ref ldnScan / \ref ldnScanPrivate which can also set value 0x1 in certain cases. + padX4C*: array[0x4, U8] ## /< Padding + secParamData*: array[0x10, U8] ## /< LdnSecurityParameter::data + secType*: U16 ## /< LdnSecurityConfig::type + acceptPolicy*: U8 ## /< \ref LdnAcceptPolicy + unkX63*: U8 ## /< Only set with \ref ldnScan / \ref ldnScanPrivate, when unk_x4B is value 0x2. + padX64*: array[0x2, U8] ## /< Padding + participantMax*: S8 ## /< Maximum participants, for nodes. + participantNum*: U8 ## /< ParticipantNum, number of set entries in nodes. If unk_x4B is not 0x2, ParticipantNum should be handled as if it's 0. + nodes*: array[8, LdnNodeInfo] ## /< Array of \ref LdnNodeInfo, starting with the AccessPoint node. + reservedX268*: array[0x2, U8] ## /< Reserved + advertiseDataSize*: U16 ## /< AdvertiseData size (\ref ldnSetAdvertiseData) + advertiseData*: array[0x180, U8] ## /< AdvertiseData (\ref ldnSetAdvertiseData) + reservedX3EC*: array[0x8C, U8] ## /< Reserved + authId*: U64 ## /< Random AuthenticationId. + + +## / ScanFilter. The input struct is copied to a tmp struct, which is then used with the cmd (\ref ldnScan and \ref ldnScanPrivate). + +type + LdnScanFilter* {.bycopy.} = object + localCommunicationId*: S64 ## /< See ::LdnScanFilterFlags_LocalCommunicationId. When enabled, this will be overwritten if it's -1 (written data is from the user-process control.nacp, with value 0 used instead if loading fails). During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter field must match LdnNetworkInfo::local_communication_id. + padX8*: array[0x2, U8] ## /< Padding + userdataFilter*: U16 ## /< See ::LdnScanFilterFlags_UserData. During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter field must match LdnNetworkInfo::userdata_filter. + padXC*: array[0x4, U8] ## /< Padding + networkId*: array[0x10, U8] ## /< See ::LdnScanFilterFlags_NetworkId. During filtering if enabled, LdnNetworkInfo::unk_x4B must match 0x2, and this ScanFilter data must match LdnNetworkInfo::network_id. + unkX20*: U32 ## /< See ::LdnScanFilterFlags_Unknown2. When enabled, this must be <=0x3, and during filtering must match LdnNetworkInfo::unk_x4B. + macAddr*: LdnMacAddress ## /< \ref LdnMacAddress (::LdnScanFilterFlags_MacAddr, during filtering if enabled this must match LdnNetworkInfo::mac_addr) + ssid*: LdnSsid ## /< \ref LdnSsid (::LdnScanFilterFlags_Ssid, during filtering if enabled this must match LdnNetworkInfo::ssid) + reserved*: array[0x10, U8] ## /< Cleared to zero for the tmp struct. + flags*: U32 ## /< Bitmask for \ref LdnScanFilterFlags. Masked with value 0x37 for \ref ldnScan, with \ref ldnScanPrivate this is masked with 0x3F. + + +## / SecurityConfig + +type + LdnSecurityConfig* {.bycopy.} = object + `type`*: U16 ## /< Type, a default of value 0x1 can be used here. Overwritten by \ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnect, \ref ldnConnectPrivate. + dataSize*: U16 ## /< Data size. Must be 0x10-0x40. + data*: array[0x40, U8] ## /< Data, used with key derivation. + + +## / SecurityParameter. The struct used by \ref ldnCreateNetwork internally is randomly-generated. + +type + LdnSecurityParameter* {.bycopy.} = object + data*: array[0x10, U8] ## /< Data, used with the same key derivation as \ref LdnSecurityConfig. + networkId*: array[0x10, U8] ## /< LdnNetworkInfo::network_id + + +## / NetworkConfig. The input struct is copied to a tmp struct, which is then used with the cmd (\ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnectPrivate). + +type + LdnNetworkConfig* {.bycopy.} = object + localCommunicationId*: S64 ## /< LdnNetworkInfo::local_communication_id. \ref ldnCreateNetwork, \ref ldnCreateNetworkPrivate, \ref ldnConnect, \ref ldnConnectPrivate: When -1, this is overwritten with the first LocalCommunicationId from the user-process control.nacp, if loading fails value 0 is written instead. Otherwise when not -1, if control.nacp loading is successful, this field must match one of the LocalCommunicationIds from there. + reservedX8*: array[2, U8] ## /< Cleared to zero for the tmp struct. + userdataFilter*: U16 ## /< LdnNetworkInfo::userdata_filter + reservedXC*: array[4, U8] ## /< Cleared to zero for the tmp struct. + networkChannel*: S16 ## /< LdnNetworkInfo::network_channel. Channel, can be zero. Overwritten internally by \ref ldnCreateNetwork. + participantMax*: S8 ## /< LdnNetworkInfo::participant_max. \ref ldnCreateNetwork / \ref ldnCreateNetworkPrivate: Must be 0x1-0x8. + reservedX13*: U8 ## /< Cleared to zero for the tmp struct. + localCommunicationVersion*: S16 ## /< LdnNodeInfo::local_communication_version, for the first entry in LdnNetworkInfo::nodes. Must not be negative. + reservedX16*: array[0xA, U8] ## /< Cleared to zero for the tmp struct. + + +## /@name ldn:m +## /@{ +## / Initialize ldn:m. + +proc ldnmInitialize*(): Result {.cdecl, importc: "ldnmInitialize".} +## / Exit ldn:m. + +proc ldnmExit*() {.cdecl, importc: "ldnmExit".} +## / Gets the Service object for IMonitorService. + +proc ldnmGetServiceSessionMonitorService*(): ptr Service {.cdecl, + importc: "ldnmGetServiceSession_MonitorService".} +## * +## @brief GetStateForMonitor +## @param[out] out \ref LdnState +## + +proc ldnmGetStateForMonitor*(`out`: ptr LdnState): Result {.cdecl, + importc: "ldnmGetStateForMonitor".} +## * +## @brief GetNetworkInfoForMonitor +## @param[out] out \ref LdnNetworkInfo +## + +proc ldnmGetNetworkInfoForMonitor*(`out`: ptr LdnNetworkInfo): Result {.cdecl, + importc: "ldnmGetNetworkInfoForMonitor".} +## * +## @brief GetIpv4AddressForMonitor +## @param[out] addr \ref LdnIpv4Address +## @param[out] mask \ref LdnSubnetMask +## + +proc ldnmGetIpv4AddressForMonitor*(`addr`: ptr LdnIpv4Address; + mask: ptr LdnSubnetMask): Result {.cdecl, + importc: "ldnmGetIpv4AddressForMonitor".} +## * +## @brief GetSecurityParameterForMonitor +## @note Not exposed by official sw. +## @param[out] out \ref LdnSecurityParameter +## + +proc ldnmGetSecurityParameterForMonitor*(`out`: ptr LdnSecurityParameter): Result {. + cdecl, importc: "ldnmGetSecurityParameterForMonitor".} +## * +## @brief GetNetworkConfigForMonitor +## @note Not exposed by official sw. +## @param[out] out \ref LdnNetworkConfig +## + +proc ldnmGetNetworkConfigForMonitor*(`out`: ptr LdnNetworkConfig): Result {.cdecl, + importc: "ldnmGetNetworkConfigForMonitor".} +## /@} +## /@name ldn +## /@{ +## / Initialize ldn. + +proc ldnInitialize*(serviceType: LdnServiceType): Result {.cdecl, + importc: "ldnInitialize".} +## / Exit ldn. + +proc ldnExit*() {.cdecl, importc: "ldnExit".} +## / Gets the Service object for IUserLocalCommunicationService/ISystemLocalCommunicationService. + +proc ldnGetServiceSessionLocalCommunicationService*(): ptr Service {.cdecl, + importc: "ldnGetServiceSession_LocalCommunicationService".} +## * +## @brief GetState +## @param[out] out \ref LdnState +## + +proc ldnGetState*(`out`: ptr LdnState): Result {.cdecl, importc: "ldnGetState".} +## * +## @brief GetNetworkInfo +## @param[out] out \ref LdnNetworkInfo +## + +proc ldnGetNetworkInfo*(`out`: ptr LdnNetworkInfo): Result {.cdecl, + importc: "ldnGetNetworkInfo".} +## * +## @brief GetIpv4Address +## @param[out] addr \ref LdnIpv4Address +## @param[out] mask \ref LdnSubnetMask +## + +proc ldnGetIpv4Address*(`addr`: ptr LdnIpv4Address; mask: ptr LdnSubnetMask): Result {. + cdecl, importc: "ldnGetIpv4Address".} +## * +## @brief GetDisconnectReason +## @param[out] out \ref LdnDisconnectReason +## + +proc ldnGetDisconnectReason*(`out`: ptr LdnDisconnectReason): Result {.cdecl, + importc: "ldnGetDisconnectReason".} +## * +## @brief GetSecurityParameter +## @param[out] out \ref LdnSecurityParameter +## + +proc ldnGetSecurityParameter*(`out`: ptr LdnSecurityParameter): Result {.cdecl, + importc: "ldnGetSecurityParameter".} +## * +## @brief GetNetworkConfig +## @param[out] out \ref LdnNetworkConfig +## + +proc ldnGetNetworkConfig*(`out`: ptr LdnNetworkConfig): Result {.cdecl, + importc: "ldnGetNetworkConfig".} +## * +## @brief AttachStateChangeEvent +## @note The Event must be closed by the user once finished with it. +## @note This is signaled when the data returned by \ref ldnGetNetworkInfo / \ref ldnGetNetworkInfoLatestUpdate is updated. +## @param[out] out_event Output Event with autoclear=true. +## + +proc ldnAttachStateChangeEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "ldnAttachStateChangeEvent".} +## * +## @brief GetNetworkInfoLatestUpdate +## @param[out] network_info \ref LdnNetworkInfo +## @param[out] nodes Output array of \ref LdnNodeLatestUpdate. +## @param[in] count Size of the nodes array in entries, must be 8. +## + +proc ldnGetNetworkInfoLatestUpdate*(networkInfo: ptr LdnNetworkInfo; + nodes: ptr LdnNodeLatestUpdate; count: S32): Result {. + cdecl, importc: "ldnGetNetworkInfoLatestUpdate".} +## * +## @brief Scan +## @note \ref LdnState must be ::LdnState_AccessPointCreated, ::LdnState_StationOpened, or ::LdnState_StationConnected. +## @note This is the same as \ref ldnScanPrivate (minus the masking for LdnScanFilter::flags), except this has the same channel-override functionality as \ref ldnCreateNetwork. +## @param[in] channel Channel, value 0 can be used for this. +## @param[in] filter \ref LdnScanFilter +## @param[out] network_info Output array of \ref LdnNetworkInfo. +## @param[in] count Size of the network_info array in entries. Must be at least 1, this is clamped to a maximum of 0x18 internally. +## @param[out] total_out Total output entries. +## + +proc ldnScan*(channel: S32; filter: ptr LdnScanFilter; + networkInfo: ptr LdnNetworkInfo; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "ldnScan".} +## * +## @brief ScanPrivate +## @note \ref LdnState must be ::LdnState_AccessPointCreated, ::LdnState_StationOpened, or ::LdnState_StationConnected. +## @note See \ref ldnScan. +## @param[in] channel Channel, value 0 can be used for this. +## @param[in] filter \ref LdnScanFilter +## @param[out] network_info Output array of \ref LdnNetworkInfo. +## @param[in] count Size of the network_info array in entries. Must be at least 1, this is clamped to a maximum of 0x18 internally. +## @param[out] total_out Total output entries. +## + +proc ldnScanPrivate*(channel: S32; filter: ptr LdnScanFilter; + networkInfo: ptr LdnNetworkInfo; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "ldnScanPrivate".} +## * +## @brief SetWirelessControllerRestriction +## @note Only available on [5.0.0+]. +## @note \ref LdnState must be ::LdnState_Initialized. +## @param[in] restriction \ref LdnWirelessControllerRestriction +## + +proc ldnSetWirelessControllerRestriction*( + restriction: LdnWirelessControllerRestriction): Result {.cdecl, + importc: "ldnSetWirelessControllerRestriction".} +## * +## @brief OpenAccessPoint +## @note \ref LdnState must be ::LdnState_Initialized, this eventually sets the State to ::LdnState_AccessPointOpened. +## + +proc ldnOpenAccessPoint*(): Result {.cdecl, importc: "ldnOpenAccessPoint".} +## * +## @brief CloseAccessPoint +## @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated, this eventually sets the State to ::LdnState_Initialized. +## @note Used automatically internally by \ref ldnExit if needed. +## + +proc ldnCloseAccessPoint*(): Result {.cdecl, importc: "ldnCloseAccessPoint".} +## * +## @brief CreateNetwork +## @note \ref LdnState must be ::LdnState_AccessPointOpened, this eventually sets the State to ::LdnState_AccessPointCreated. +## @param[in] sec_config \ref LdnSecurityConfig +## @param[in] user_config \ref LdnUserConfig +## @param[in] network_config \ref LdnNetworkConfig +## + +proc ldnCreateNetwork*(secConfig: ptr LdnSecurityConfig; + userConfig: ptr LdnUserConfig; + networkConfig: ptr LdnNetworkConfig): Result {.cdecl, + importc: "ldnCreateNetwork".} +## * +## @brief CreateNetworkPrivate +## @note \ref LdnState must be ::LdnState_AccessPointOpened, this eventually sets the State to ::LdnState_AccessPointCreated. +## @note This is the same as \ref ldnCreateNetwork besides the additional user-specified params, and with this cmd LdnNetworkConfig::channel is not overwritten (unlike \ref ldnCreateNetwork). +## @param[in] sec_config \ref LdnSecurityConfig +## @param[in] sec_param \ref LdnSecurityParameter +## @param[in] user_config \ref LdnUserConfig +## @param[in] network_config \ref LdnNetworkConfig +## @param[in] addrs Input array of \ref LdnAddressEntry. This can be NULL. +## @param[in] count Size of the addrs array in entries. This must be <=8. This can be 0, in which case the network will be non-Private like \ref ldnCreateNetwork. +## + +proc ldnCreateNetworkPrivate*(secConfig: ptr LdnSecurityConfig; + secParam: ptr LdnSecurityParameter; + userConfig: ptr LdnUserConfig; + networkConfig: ptr LdnNetworkConfig; + addrs: ptr LdnAddressEntry; count: S32): Result {.cdecl, + importc: "ldnCreateNetworkPrivate".} +## * +## @brief DestroyNetwork +## @note \ref LdnState must be ::LdnState_AccessPointCreated, this eventually sets the State to ::LdnState_AccessPointOpened. +## + +proc ldnDestroyNetwork*(): Result {.cdecl, importc: "ldnDestroyNetwork".} +## * +## @brief Reject +## @note \ref LdnState must be ::LdnState_AccessPointCreated. +## @param[in] addr \ref LdnIpv4Address +## + +proc ldnReject*(`addr`: LdnIpv4Address): Result {.cdecl, importc: "ldnReject".} +## * +## @brief SetAdvertiseData +## @note An empty buffer (buffer=NULL/size=0) can be used to reset the AdvertiseData size in state to zero. +## @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. +## @param[in] buffer Input buffer containing arbitrary user data. +## @param[in] size Input buffer size, must be <=0x180. If this isn't enough space, you can for example also periodically use this cmd with different regions of your data with some sequence_number field (or use sockets while connected to the network). +## + +proc ldnSetAdvertiseData*(buffer: pointer; size: csize_t): Result {.cdecl, + importc: "ldnSetAdvertiseData".} +## * +## @brief SetStationAcceptPolicy +## @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. +## @param[in] policy \ref LdnAcceptPolicy +## + +proc ldnSetStationAcceptPolicy*(policy: LdnAcceptPolicy): Result {.cdecl, + importc: "ldnSetStationAcceptPolicy".} +## * +## @brief AddAcceptFilterEntry +## @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. +## @note See \ref LdnAcceptPolicy. +## @param[in] addr \ref LdnMacAddress. If you want, you can also pass LdnNodeInfo::mac_addr for this. +## + +proc ldnAddAcceptFilterEntry*(`addr`: LdnMacAddress): Result {.cdecl, + importc: "ldnAddAcceptFilterEntry".} +## * +## @brief ClearAcceptFilter +## @note \ref LdnState must be ::LdnState_AccessPointOpened or ::LdnState_AccessPointCreated. +## + +proc ldnClearAcceptFilter*(): Result {.cdecl, importc: "ldnClearAcceptFilter".} +## * +## @brief OpenStation +## @note \ref LdnState must be ::LdnState_Initialized, this eventually sets the State to ::LdnState_StationOpened. +## + +proc ldnOpenStation*(): Result {.cdecl, importc: "ldnOpenStation".} +## * +## @brief CloseStation +## @note \ref LdnState must be ::LdnState_StationOpened or ::LdnState_StationConnected, this eventually sets the State to ::LdnState_Initialized. +## @note Used automatically internally by \ref ldnExit if needed. +## + +proc ldnCloseStation*(): Result {.cdecl, importc: "ldnCloseStation".} +## * +## @brief Connect +## @note \ref LdnState must be ::LdnState_StationOpened, this eventually sets the State to ::LdnState_StationConnected. +## @note This is identical to \ref ldnConnectPrivate besides the used params, the code overwriting LdnSecurityConfig::type also differs. +## @param[in] sec_config \ref LdnSecurityConfig +## @param[in] user_config \ref LdnUserConfig +## @param[in] version LocalCommunicationVersion, this must be 0x0-0x7FFF. +## @param[in] option ConnectOption bitmask, must be <=0x1. You can use value 0 for example here. +## @param[in] network_info \ref LdnNetworkInfo +## + +proc ldnConnect*(secConfig: ptr LdnSecurityConfig; userConfig: ptr LdnUserConfig; + version: S32; option: U32; networkInfo: ptr LdnNetworkInfo): Result {. + cdecl, importc: "ldnConnect".} +## * +## @brief ConnectPrivate +## @note \ref LdnState must be ::LdnState_StationOpened, this eventually sets the State to ::LdnState_StationConnected. +## @note See \ref ldnConnect. +## @param[in] sec_config \ref LdnSecurityConfig +## @param[in] sec_param \ref LdnSecurityParameter +## @param[in] user_config \ref LdnUserConfig +## @param[in] version LocalCommunicationVersion, this must be 0x0-0x7FFF. +## @param[in] option ConnectOption bitmask, must be <=0x1. You can use value 0 for example here. +## @param[in] network_config \ref LdnNetworkConfig +## + +proc ldnConnectPrivate*(secConfig: ptr LdnSecurityConfig; + secParam: ptr LdnSecurityParameter; + userConfig: ptr LdnUserConfig; version: S32; option: U32; + networkConfig: ptr LdnNetworkConfig): Result {.cdecl, + importc: "ldnConnectPrivate".} +## * +## @brief Disconnect +## @note \ref LdnState must be ::LdnState_StationConnected, this eventually sets the State to ::LdnState_StationOpened. +## + +proc ldnDisconnect*(): Result {.cdecl, importc: "ldnDisconnect".} +## * +## @brief SetOperationMode +## @note Only available on [4.0.0+]. +## @note Only available with ::LdnServiceType_System. +## @note \ref LdnState must be ::LdnState_Initialized. +## @param[in] mode \ref LdnOperationMode +## + +proc ldnSetOperationMode*(mode: LdnOperationMode): Result {.cdecl, + importc: "ldnSetOperationMode".} +## /@} diff --git a/src/libnx/wrapper/switch/services/ldr.h b/src/libnx/wrapper/switch/services/ldr.h new file mode 100644 index 0000000..acc753f --- /dev/null +++ b/src/libnx/wrapper/switch/services/ldr.h @@ -0,0 +1,69 @@ +/** + * @file ldr.h + * @brief Loader (ldr*) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/ncm_types.h" + +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 ac_buffer[0x3E0]; +} LoaderProgramInfo; + +typedef struct { + u8 build_id[0x20]; + u64 base_address; + u64 size; +} LoaderModuleInfo; + +/// Initialize ldr:shel. +Result ldrShellInitialize(void); + +/// Exit ldr:shel. +void ldrShellExit(void); + +/// Gets the Service object for the actual ldr:shel service session. +Service* ldrShellGetServiceSession(void); + +/// Initialize ldr:dmnt. +Result ldrDmntInitialize(void); + +/// Exit ldr:dmnt. +void ldrDmntExit(void); + +/// Gets the Service object for the actual ldr:dmnt service session. +Service* ldrDmntGetServiceSession(void); + +/// Initialize ldr:pm. +Result ldrPmInitialize(void); + +/// Exit ldr:pm. +void ldrPmExit(void); + +/// Gets the Service object for the actual ldr:pm service session. +Service* ldrPmGetServiceSession(void); + +Result ldrShellSetProgramArguments(u64 program_id, const void *args, size_t args_size); +Result ldrShellFlushArguments(void); + +Result ldrDmntSetProgramArguments(u64 program_id, const void *args, size_t args_size); +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 ldrPmPinProgram(const NcmProgramLocation *loc, u64 *out_pin_id); +Result ldrPmUnpinProgram(u64 pin_id); +Result ldrPmSetEnabledProgramVerification(bool enabled); ///< [10.0.0+] diff --git a/src/libnx/wrapper/switch/services/ldr.nim b/src/libnx/wrapper/switch/services/ldr.nim new file mode 100644 index 0000000..2549d3b --- /dev/null +++ b/src/libnx/wrapper/switch/services/ldr.nim @@ -0,0 +1,71 @@ +## * +## @file ldr.h +## @brief Loader (ldr*) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/ncm_types + +type + LoaderProgramInfo* {.bycopy.} = object + mainThreadPriority*: U8 + defaultCpuId*: U8 + applicationType*: U16 + mainThreadStackSize*: U32 + programId*: U64 + acidSacSize*: U32 + aci0SacSize*: U32 + acidFacSize*: U32 + aci0FahSize*: U32 + acBuffer*: array[0x3E0, U8] + + LoaderModuleInfo* {.bycopy.} = object + buildId*: array[0x20, U8] + baseAddress*: U64 + size*: U64 + +proc ldrShellInitialize*(): Result {.cdecl, importc: "ldrShellInitialize".} +## / Initialize ldr:shel. +proc ldrShellExit*() {.cdecl, importc: "ldrShellExit".} +## / Exit ldr:shel. +proc ldrShellGetServiceSession*(): ptr Service {.cdecl, + importc: "ldrShellGetServiceSession".} +## / Gets the Service object for the actual ldr:shel service session. +proc ldrDmntInitialize*(): Result {.cdecl, importc: "ldrDmntInitialize".} +## / Initialize ldr:dmnt. +proc ldrDmntExit*() {.cdecl, importc: "ldrDmntExit".} +## / Exit ldr:dmnt. +proc ldrDmntGetServiceSession*(): ptr Service {.cdecl, + importc: "ldrDmntGetServiceSession".} +## / Gets the Service object for the actual ldr:dmnt service session. +proc ldrPmInitialize*(): Result {.cdecl, importc: "ldrPmInitialize".} +## / Initialize ldr:pm. +proc ldrPmExit*() {.cdecl, importc: "ldrPmExit".} +## / Exit ldr:pm. +proc ldrPmGetServiceSession*(): ptr Service {.cdecl, + importc: "ldrPmGetServiceSession".} +## / Gets the Service object for the actual ldr:pm service session. + +proc ldrShellSetProgramArguments*(programId: U64; args: pointer; argsSize: csize_t): Result {. + cdecl, importc: "ldrShellSetProgramArguments".} +proc ldrShellFlushArguments*(): Result {.cdecl, importc: "ldrShellFlushArguments".} +proc ldrDmntSetProgramArguments*(programId: U64; args: pointer; argsSize: csize_t): Result {. + cdecl, importc: "ldrDmntSetProgramArguments".} +proc ldrDmntFlushArguments*(): Result {.cdecl, importc: "ldrDmntFlushArguments".} +proc ldrDmntGetProcessModuleInfo*(pid: U64; outModuleInfos: ptr LoaderModuleInfo; + maxOutModules: csize_t; numOut: ptr S32): Result {. + cdecl, importc: "ldrDmntGetProcessModuleInfo".} +proc ldrPmCreateProcess*(pinId: U64; flags: U32; reslimitH: Handle; + outProcessH: ptr Handle): Result {.cdecl, + importc: "ldrPmCreateProcess".} +proc ldrPmGetProgramInfo*(loc: ptr NcmProgramLocation; + outProgramInfo: ptr LoaderProgramInfo): Result {.cdecl, + importc: "ldrPmGetProgramInfo".} +proc ldrPmPinProgram*(loc: ptr NcmProgramLocation; outPinId: ptr U64): Result {.cdecl, + importc: "ldrPmPinProgram".} +proc ldrPmUnpinProgram*(pinId: U64): Result {.cdecl, importc: "ldrPmUnpinProgram".} +proc ldrPmSetEnabledProgramVerification*(enabled: bool): Result {.cdecl, + importc: "ldrPmSetEnabledProgramVerification".} +## /< [10.0.0+] diff --git a/src/libnx/wrapper/switch/services/lp2p.h b/src/libnx/wrapper/switch/services/lp2p.h new file mode 100644 index 0000000..282b6b9 --- /dev/null +++ b/src/libnx/wrapper/switch/services/lp2p.h @@ -0,0 +1,339 @@ +/** + * @file lp2p.h + * @brief lp2p service IPC wrapper, for local-WLAN communications with accessories. See also: https://switchbrew.org/wiki/LDN_services + * @note Only available on [9.1.0+]. + * @author yellows8 + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef enum { + Lp2pServiceType_App = 0, ///< Initializes lp2p:app. + Lp2pServiceType_System = 1, ///< Initializes lp2p:sys. +} Lp2pServiceType; + +/// MacAddress +typedef struct { + u8 addr[6]; ///< Address +} Lp2pMacAddress; + +/// GroupId +typedef struct { + u8 id[0x6]; ///< BSSID +} Lp2pGroupId; + +/// GroupInfo +/// \ref lp2pScan only uses the following fields for the cmd input struct: supported_platform/priority, frequency/channel, and preshared_key_binary_size/preshared_key. +typedef struct { + u8 unk_x0[0x10]; ///< When zero, this is set to randomly-generated data. Used during key derivation. + u64 local_communication_id; ///< LocalCommunicationId. When zero, the value from the user-process control.nacp is loaded. This is later validated by \ref lp2pJoin / \ref lp2pCreateGroup the same way as LdnNetworkConfig::local_communication_id. Used during key derivation. + Lp2pGroupId group_id; ///< Should be all-zero for the input struct so that the default is used. + char service_name[0x21]; ///< ServiceName. NUL-terminated string for the SSID. These characters must be '-' or alphanumeric (lowercase/uppercase). '_' must not be used, unless you generate valid data for that. The data for '_' will be automatically generated if it's not present. + s8 flags_count; ///< Must be <=0x3F. + s8 flags[0x40]; ///< Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. + u8 supported_platform; ///< SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdFuji. + s8 member_count_max; ///< MemberCountMax. Must be <=0x8. If zero during group-creation, a default of value 1 is used for the value passed to a service-cmd. + u8 unk_x82; ///< Unknown + u8 unk_x83; ///< Unknown + u16 frequency; ///< Wifi frequency: 24 = 2.4GHz, 50 = 5GHz. + s16 channel; ///< Wifi channel number. 0 = use default, otherwise this must be one of the following depending on the frequency field. 24: 1, 6, 11. 50: 36, 40, 44, 48. + u8 network_mode; ///< NetworkMode + u8 performance_requirement; ///< PerformanceRequirement + u8 security_type; ///< Security type, used during key derivation. 0 = use defaults, 1 = plaintext, 2 = encrypted. [11.0.0+] 3: Standard WPA2-PSK. + s8 static_aes_key_index; ///< StaticAesKeyIndex. Used as the array-index for selecting the KeySource used with GenerateAesKek during key derivation. Should be 1-2, otherwise GenerateAesKek is skipped and zeros are used for the AccessKey instead. + u8 unk_x8C; ///< Unknown + u8 priority; ///< Priority. Must match one of the following, depending on the used service (doesn't apply to \ref lp2pJoin): 55 = SystemPriority (lp2p:sys), 90 = ApplicationPriority (lp2p:app and lp2p:sys). + u8 stealth_enabled; ///< StealthEnabled. Bool flag, controls whether the SSID is hidden. + u8 unk_x8F; ///< If zero, a default value of 0x20 is used. + u8 unk_x90[0x130]; ///< Unknown + u8 preshared_key_binary_size; ///< PresharedKeyBinarySize + u8 preshared_key[0x3F]; ///< PresharedKey. Used during key derivation. +} Lp2pGroupInfo; + +/// ScanResult +typedef struct { + Lp2pGroupInfo group_info; ///< \ref Lp2pGroupInfo + u8 unk_x200; ///< Unknown + u8 unk_x201[0x5]; ///< Unknown + u16 advertise_data_size; ///< Size of the following AdvertiseData. + u8 advertise_data[0x80]; ///< AdvertiseData, with the above size. This originates from \ref lp2pSetAdvertiseData. + u8 unk_x288[0x78]; ///< Unknown +} Lp2pScanResult; + +/// NodeInfo +typedef struct { + u8 ip_addr[0x20]; ///< struct sockaddr for the IP address. + u8 unk_x20[0x4]; ///< Unknown + Lp2pMacAddress mac_addr; ///< \ref Lp2pMacAddress + u8 unk_x2A[0x56]; ///< Unknown +} Lp2pNodeInfo; + +/// IpConfig. Only contains IPv4 addresses. +typedef struct { + u8 unk_x0[0x20]; ///< Always zeros. + u8 ip_addr[0x20]; ///< struct sockaddr for the IP address. + u8 subnet_mask[0x20]; ///< struct sockaddr for the subnet-mask. + u8 gateway[0x20]; ///< struct sockaddr for the gateway(?). + u8 unk_x80[0x80]; ///< Always zeros. +} Lp2pIpConfig; + +/// Initialize lp2p. +Result lp2pInitialize(Lp2pServiceType service_type); + +/// Exit lp2p. +void lp2pExit(void); + +/// Gets the Service object for INetworkService. +Service* lp2pGetServiceSession_INetworkService(void); + +/// Gets the Service object for INetworkServiceMonitor. +Service* lp2pGetServiceSession_INetworkServiceMonitor(void); + +/** + * @brief Creates a default \ref Lp2pGroupInfo for use with \ref lp2pCreateGroup / \ref lp2pJoin. + * @param info \ref Lp2pGroupInfo + */ +void lp2pCreateGroupInfo(Lp2pGroupInfo *info); + +/** + * @brief Creates a default \ref Lp2pGroupInfo for use with \ref lp2pScan. + * @param info \ref Lp2pGroupInfo + */ +void lp2pCreateGroupInfoScan(Lp2pGroupInfo *info); + +/** + * @brief Sets Lp2pGroupInfo::service_name. + * @param info \ref Lp2pGroupInfo + * @param[in] name ServiceName / SSID. + */ +void lp2pGroupInfoSetServiceName(Lp2pGroupInfo *info, const char *name); + +/** + * @brief Sets Lp2pGroupInfo::flags_count and Lp2pGroupInfo::flags. + * @note The default is count=1 flags[0]=1, which is used by \ref lp2pCreateGroupInfo. [11.0.0+] To use standard WPA2-PSK, you can use flags[0]=0. + * @param info \ref Lp2pGroupInfo + * @param[in] flags Lp2pGroupInfo::flags + * @param[in] count Lp2pGroupInfo::flags_count + */ +void lp2pGroupInfoSetFlags(Lp2pGroupInfo *info, s8 *flags, size_t count); + +/** + * @brief Sets Lp2pGroupInfo::member_count_max. + * @param info \ref Lp2pGroupInfo + * @param[in] count MemberCountMax + */ +NX_CONSTEXPR void lp2pGroupInfoSetMemberCountMax(Lp2pGroupInfo *info, size_t count) { + info->member_count_max = count; +} + +/** + * @brief Sets Lp2pGroupInfo::frequency and Lp2pGroupInfo::channel. + * @param info \ref Lp2pGroupInfo + * @param[in] frequency Lp2pGroupInfo::frequency + * @param[in] channel Lp2pGroupInfo::channel + */ +NX_CONSTEXPR void lp2pGroupInfoSetFrequencyChannel(Lp2pGroupInfo *info, u16 frequency, s16 channel) { + info->frequency = frequency; + info->channel = channel; +} + +/** + * @brief Sets Lp2pGroupInfo::stealth_enabled. + * @param info \ref Lp2pGroupInfo + * @param[in] flag Lp2pGroupInfo::stealth_enabled + */ +NX_CONSTEXPR void lp2pGroupInfoSetStealthEnabled(Lp2pGroupInfo *info, bool flag) { + info->stealth_enabled = flag!=0; +} + +/** + * @brief Sets the PresharedKey for the specified \ref Lp2pGroupInfo. + * @note Using this is required before using the \ref Lp2pGroupInfo as input for any cmds, so that Lp2pGroupInfo::preshared_key_binary_size gets initialized. + * @note If standard WPA2-PSK is being used, use \ref lp2pGroupInfoSetPassphrase instead. + * @param info \ref Lp2pGroupInfo + * @param[in] key Data for the PresharedKey. + * @param[in] size Size to copy into the PresharedKey, max is 0x20. + */ +void lp2pGroupInfoSetPresharedKey(Lp2pGroupInfo *info, const void* key, size_t size); + +/** + * @brief Sets the passphrase, for when standard WPA2-PSK is being used. + * @note Configure standard WPA2-PSK usage via \ref lp2pGroupInfoSetFlags / Lp2pGroupInfo::security_type. + * @note Only available on [11.0.0+]. + * @param info \ref Lp2pGroupInfo + * @param[in] passphrase Passphrase string, the required length is 0x8-0x3F. + */ +Result lp2pGroupInfoSetPassphrase(Lp2pGroupInfo *info, const char *passphrase); + +///@name INetworkService +///@{ + +/** + * @brief Scan + * @param[in] info \ref Lp2pGroupInfo + * @param[out] results Output array of \ref Lp2pScanResult. + * @param[in] count Size of the results array in entries. + * @param[out] total_out Total output entries. + */ +Result lp2pScan(const Lp2pGroupInfo *info, Lp2pScanResult *results, s32 count, s32 *total_out); + +/** + * @brief CreateGroup + * @note The role (\ref lp2pGetRole) must be 0. This eventually sets the role to value 1. + * @param[in] info \ref Lp2pGroupInfo + */ +Result lp2pCreateGroup(const Lp2pGroupInfo *info); + +/** + * @brief This destroys the previously created group from \ref lp2pCreateGroup. + * @note If no group was previously created (role from \ref lp2pGetRole is not 1), this just returns 0. + */ +Result lp2pDestroyGroup(void); + +/** + * @brief SetAdvertiseData + * @note The role (\ref lp2pGetRole) must be <=1. + * @note An empty buffer (buffer=NULL/size=0) can be used to reset the AdvertiseData size in state to zero. + * @param[out] buffer Input buffer containing arbitrary user data. + * @param[in] size Input buffer size, must be <=0x80. + */ +Result lp2pSetAdvertiseData(const void* buffer, size_t size); + +/** + * @brief This sends an Action frame to the specified \ref Lp2pGroupId, with the specified destination \ref Lp2pMacAddress. + * @note The role (\ref lp2pGetRole) must be non-zero. + * @note The error from \ref lp2pGetNetworkInterfaceLastError will be returned if it's set. + * @note [11.0.0+] Lp2pGroupInfo::security_type must be value 2 (default encryption), otherwise an error is returned. + * @param[in] buffer Input buffer containing arbitrary user data. + * @param[in] size Input buffer size, must be <=0x400. + * @param[in] addr \ref Lp2pMacAddress, this can be a broadcast address. This must be non-zero. + * @param[in] group_id \ref Lp2pGroupId + * @param[in] frequency Must be >=1. See Lp2pGroupInfo::frequency. + * @param[in] channel Must be >=1. See Lp2pGroupInfo::channel. + * @param[in] flags Only bit0 is used: clear = block until the data can be sent, set = return error when the data can't be sent. + */ +Result lp2pSendToOtherGroup(const void* buffer, size_t size, Lp2pMacAddress addr, Lp2pGroupId group_id, s16 frequency, s16 channel, u32 flags); + +/** + * @brief This receives an Action frame. + * @note The role (\ref lp2pGetRole) must be non-zero. + * @note When data is not available, the error from \ref lp2pGetNetworkInterfaceLastError will be returned if it's set. + * @param[out] buffer Output buffer containing arbitrary user data. + * @param[in] size Output buffer size. + * @param[in] flags Only bit0 is used: clear = block until data is available, set = return error when data is not available. + * @param[in] addr \ref Lp2pMacAddress + * @param[in] unk0 Unknown + * @param[in] unk1 Unknown + * @param[out] out_size This is the original size used for copying to the output buffer, before it's clamped to the output-buffer size. + * @param[out] unk2 Unknown + */ +Result lp2pRecvFromOtherGroup(void* buffer, size_t size, u32 flags, Lp2pMacAddress *addr, u16 *unk0, s32 *unk1, u64 *out_size, s32 *unk2); + +/** + * @brief AddAcceptableGroupId + * @param[in] group_id \ref Lp2pGroupId + */ +Result lp2pAddAcceptableGroupId(Lp2pGroupId group_id); + +/** + * @brief RemoveAcceptableGroupId + */ +Result lp2pRemoveAcceptableGroupId(void); + +///@name INetworkServiceMonitor +///@{ + +/** + * @brief AttachNetworkInterfaceStateChangeEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result lp2pAttachNetworkInterfaceStateChangeEvent(Event* out_event); + +/** + * @brief GetNetworkInterfaceLastError + */ +Result lp2pGetNetworkInterfaceLastError(void); + +/** + * @brief GetRole + * @param[out] out Output Role. + */ +Result lp2pGetRole(u8 *out); + +/** + * @brief GetAdvertiseData + * @note The role from \ref lp2pGetRole must be value 2. + * @param[out] buffer Output buffer data. + * @param[in] size Output buffer size. + * @param[out] transfer_size Size of the data copied into the buffer. + * @param[out] original_size Original size from state. + */ +Result lp2pGetAdvertiseData(void* buffer, size_t size, u16 *transfer_size, u16 *original_size); + +/** + * @brief GetAdvertiseData2 + * @note This is identical to \ref lp2pGetAdvertiseData except this doesn't run the role validation. + * @param[out] buffer Output buffer data. + * @param[in] size Output buffer size. + * @param[out] transfer_size Size of the data copied into the buffer. + * @param[out] original_size Original size from state. + */ +Result lp2pGetAdvertiseData2(void* buffer, size_t size, u16 *transfer_size, u16 *original_size); + +/** + * @brief GetGroupInfo + * @note The role from \ref lp2pGetRole must be non-zero. + * @param[out] out \ref Lp2pGroupInfo + */ +Result lp2pGetGroupInfo(Lp2pGroupInfo *out); + +/** + * @brief This runs the same code as \ref lp2pCreateGroup to generate the \ref Lp2pGroupInfo for the input struct. + * @param[out] out \ref Lp2pGroupInfo + * @param[in] info \ref Lp2pGroupInfo + */ +Result lp2pJoin(Lp2pGroupInfo *out, const Lp2pGroupInfo *info); + +/** + * @brief GetGroupOwner + * @note The role from \ref lp2pGetRole must be non-zero. + * @param[out] out \ref Lp2pNodeInfo + */ +Result lp2pGetGroupOwner(Lp2pNodeInfo *out); + +/** + * @brief GetIpConfig + * @note The role from \ref lp2pGetRole must be non-zero. + * @param[out] out \ref Lp2pIpConfig + */ +Result lp2pGetIpConfig(Lp2pIpConfig *out); + +/** + * @brief Leave + * @param[out] out Output value. + */ +Result lp2pLeave(u32 *out); + +/** + * @brief AttachJoinEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result lp2pAttachJoinEvent(Event* out_event); + +/** + * @brief GetMembers + * @note The role from \ref lp2pGetRole must be value 1. + * @param[out] members Output array of \ref Lp2pNodeInfo. + * @param[in] count Size of the members array in entries. A maximum of 8 entries can be returned. + * @param[out] total_out Total output entries. + */ +Result lp2pGetMembers(Lp2pNodeInfo *members, s32 count, s32 *total_out); + +///@} + diff --git a/src/libnx/wrapper/switch/services/lp2p.nim b/src/libnx/wrapper/switch/services/lp2p.nim new file mode 100644 index 0000000..add6976 --- /dev/null +++ b/src/libnx/wrapper/switch/services/lp2p.nim @@ -0,0 +1,382 @@ +## * +## @file lp2p.h +## @brief lp2p service IPC wrapper, for local-WLAN communications with accessories. See also: https://switchbrew.org/wiki/LDN_services +## @note Only available on [9.1.0+]. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + Lp2pServiceType* = enum + Lp2pServiceTypeApp = 0, ## /< Initializes lp2p:app. + Lp2pServiceTypeSystem = 1 ## /< Initializes lp2p:sys. + + +## / MacAddress + +type + Lp2pMacAddress* {.bycopy.} = object + `addr`*: array[6, U8] ## /< Address + + +## / GroupId + +type + Lp2pGroupId* {.bycopy.} = object + id*: array[0x6, U8] ## /< BSSID + + +## / GroupInfo +## / \ref lp2pScan only uses the following fields for the cmd input struct: supported_platform/priority, frequency/channel, and preshared_key_binary_size/preshared_key. + +type + Lp2pGroupInfo* {.bycopy.} = object + unkX0*: array[0x10, U8] ## /< When zero, this is set to randomly-generated data. Used during key derivation. + localCommunicationId*: U64 ## /< LocalCommunicationId. When zero, the value from the user-process control.nacp is loaded. This is later validated by \ref lp2pJoin / \ref lp2pCreateGroup the same way as LdnNetworkConfig::local_communication_id. Used during key derivation. + groupId*: Lp2pGroupId ## /< Should be all-zero for the input struct so that the default is used. + serviceName*: array[0x21, char] ## /< ServiceName. NUL-terminated string for the SSID. These characters must be '-' or alphanumeric (lowercase/uppercase). '_' must not be used, unless you generate valid data for that. The data for '_' will be automatically generated if it's not present. + flagsCount*: S8 ## /< Must be <=0x3F. + flags*: array[0x40, S8] ## /< Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. + supportedPlatform*: U8 ## /< SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdFuji. + memberCountMax*: S8 ## /< MemberCountMax. Must be <=0x8. If zero during group-creation, a default of value 1 is used for the value passed to a service-cmd. + unkX82*: U8 ## /< Unknown + unkX83*: U8 ## /< Unknown + frequency*: U16 ## /< Wifi frequency: 24 = 2.4GHz, 50 = 5GHz. + channel*: S16 ## /< Wifi channel number. 0 = use default, otherwise this must be one of the following depending on the frequency field. 24: 1, 6, 11. 50: 36, 40, 44, 48. + networkMode*: U8 ## /< NetworkMode + performanceRequirement*: U8 ## /< PerformanceRequirement + securityType*: U8 ## /< Security type, used during key derivation. 0 = use defaults, 1 = plaintext, 2 = encrypted. [11.0.0+] 3: Standard WPA2-PSK. + staticAesKeyIndex*: S8 ## /< StaticAesKeyIndex. Used as the array-index for selecting the KeySource used with GenerateAesKek during key derivation. Should be 1-2, otherwise GenerateAesKek is skipped and zeros are used for the AccessKey instead. + unkX8C*: U8 ## /< Unknown + priority*: U8 ## /< Priority. Must match one of the following, depending on the used service (doesn't apply to \ref lp2pJoin): 55 = SystemPriority (lp2p:sys), 90 = ApplicationPriority (lp2p:app and lp2p:sys). + stealthEnabled*: U8 ## /< StealthEnabled. Bool flag, controls whether the SSID is hidden. + unkX8F*: U8 ## /< If zero, a default value of 0x20 is used. + unkX90*: array[0x130, U8] ## /< Unknown + presharedKeyBinarySize*: U8 ## /< PresharedKeyBinarySize + presharedKey*: array[0x3F, U8] ## /< PresharedKey. Used during key derivation. + + +## / ScanResult + +type + Lp2pScanResult* {.bycopy.} = object + groupInfo*: Lp2pGroupInfo ## /< \ref Lp2pGroupInfo + unkX200*: U8 ## /< Unknown + unkX201*: array[0x5, U8] ## /< Unknown + advertiseDataSize*: U16 ## /< Size of the following AdvertiseData. + advertiseData*: array[0x80, U8] ## /< AdvertiseData, with the above size. This originates from \ref lp2pSetAdvertiseData. + unkX288*: array[0x78, U8] ## /< Unknown + + +## / NodeInfo + +type + Lp2pNodeInfo* {.bycopy.} = object + ipAddr*: array[0x20, U8] ## /< struct sockaddr for the IP address. + unkX20*: array[0x4, U8] ## /< Unknown + macAddr*: Lp2pMacAddress ## /< \ref Lp2pMacAddress + unkX2A*: array[0x56, U8] ## /< Unknown + + +## / IpConfig. Only contains IPv4 addresses. + +type + Lp2pIpConfig* {.bycopy.} = object + unkX0*: array[0x20, U8] ## /< Always zeros. + ipAddr*: array[0x20, U8] ## /< struct sockaddr for the IP address. + subnetMask*: array[0x20, U8] ## /< struct sockaddr for the subnet-mask. + gateway*: array[0x20, U8] ## /< struct sockaddr for the gateway(?). + unkX80*: array[0x80, U8] ## /< Always zeros. + +proc lp2pInitialize*(serviceType: Lp2pServiceType): Result {.cdecl, + importc: "lp2pInitialize".} +## / Initialize lp2p. + +proc lp2pExit*() {.cdecl, importc: "lp2pExit".} +## / Exit lp2p. + +proc lp2pGetServiceSessionINetworkService*(): ptr Service {.cdecl, + importc: "lp2pGetServiceSession_INetworkService".} +## / Gets the Service object for INetworkService. + +proc lp2pGetServiceSessionINetworkServiceMonitor*(): ptr Service {.cdecl, + importc: "lp2pGetServiceSession_INetworkServiceMonitor".} +## / Gets the Service object for INetworkServiceMonitor. + +proc lp2pCreateGroupInfo*(info: ptr Lp2pGroupInfo) {.cdecl, + importc: "lp2pCreateGroupInfo".} +## * +## @brief Creates a default \ref Lp2pGroupInfo for use with \ref lp2pCreateGroup / \ref lp2pJoin. +## @param info \ref Lp2pGroupInfo +## + +proc lp2pCreateGroupInfoScan*(info: ptr Lp2pGroupInfo) {.cdecl, + importc: "lp2pCreateGroupInfoScan".} +## * +## @brief Creates a default \ref Lp2pGroupInfo for use with \ref lp2pScan. +## @param info \ref Lp2pGroupInfo +## + +proc lp2pGroupInfoSetServiceName*(info: ptr Lp2pGroupInfo; name: cstring) {.cdecl, + importc: "lp2pGroupInfoSetServiceName".} +## * +## @brief Sets Lp2pGroupInfo::service_name. +## @param info \ref Lp2pGroupInfo +## @param[in] name ServiceName / SSID. +## + +proc lp2pGroupInfoSetFlags*(info: ptr Lp2pGroupInfo; flags: ptr S8; count: csize_t) {. + cdecl, importc: "lp2pGroupInfoSetFlags".} +## * +## @brief Sets Lp2pGroupInfo::flags_count and Lp2pGroupInfo::flags. +## @note The default is count=1 flags[0]=1, which is used by \ref lp2pCreateGroupInfo. [11.0.0+] To use standard WPA2-PSK, you can use flags[0]=0. +## @param info \ref Lp2pGroupInfo +## @param[in] flags Lp2pGroupInfo::flags +## @param[in] count Lp2pGroupInfo::flags_count +## + +proc lp2pGroupInfoSetMemberCountMax*(info: ptr Lp2pGroupInfo; count: csize_t) {. + inline, cdecl.} = + ## * + ## @brief Sets Lp2pGroupInfo::member_count_max. + ## @param info \ref Lp2pGroupInfo + ## @param[in] count MemberCountMax + ## + + info.memberCountMax = count.int8 + +proc lp2pGroupInfoSetFrequencyChannel*(info: ptr Lp2pGroupInfo; frequency: U16; + channel: S16) {.inline, cdecl.} = + ## * + ## @brief Sets Lp2pGroupInfo::frequency and Lp2pGroupInfo::channel. + ## @param info \ref Lp2pGroupInfo + ## @param[in] frequency Lp2pGroupInfo::frequency + ## @param[in] channel Lp2pGroupInfo::channel + ## + + info.frequency = frequency + info.channel = channel + +proc lp2pGroupInfoSetStealthEnabled*(info: ptr Lp2pGroupInfo; flag: bool) {.inline, + cdecl.} = + ## * + ## @brief Sets Lp2pGroupInfo::stealth_enabled. + ## @param info \ref Lp2pGroupInfo + ## @param[in] flag Lp2pGroupInfo::stealth_enabled + ## + + info.stealthEnabled = flag.U8 + +proc lp2pGroupInfoSetPresharedKey*(info: ptr Lp2pGroupInfo; key: pointer; + size: csize_t) {.cdecl, + importc: "lp2pGroupInfoSetPresharedKey".} +## * +## @brief Sets the PresharedKey for the specified \ref Lp2pGroupInfo. +## @note Using this is required before using the \ref Lp2pGroupInfo as input for any cmds, so that Lp2pGroupInfo::preshared_key_binary_size gets initialized. +## @note If standard WPA2-PSK is being used, use \ref lp2pGroupInfoSetPassphrase instead. +## @param info \ref Lp2pGroupInfo +## @param[in] key Data for the PresharedKey. +## @param[in] size Size to copy into the PresharedKey, max is 0x20. +## + +proc lp2pGroupInfoSetPassphrase*(info: ptr Lp2pGroupInfo; passphrase: cstring): Result {. + cdecl, importc: "lp2pGroupInfoSetPassphrase".} +## * +## @brief Sets the passphrase, for when standard WPA2-PSK is being used. +## @note Configure standard WPA2-PSK usage via \ref lp2pGroupInfoSetFlags / Lp2pGroupInfo::security_type. +## @note Only available on [11.0.0+]. +## @param info \ref Lp2pGroupInfo +## @param[in] passphrase Passphrase string, the required length is 0x8-0x3F. +## + +proc lp2pScan*(info: ptr Lp2pGroupInfo; results: ptr Lp2pScanResult; count: S32; + totalOut: ptr S32): Result {.cdecl, importc: "lp2pScan".} +## /@name INetworkService +## /@{ +## * +## @brief Scan +## @param[in] info \ref Lp2pGroupInfo +## @param[out] results Output array of \ref Lp2pScanResult. +## @param[in] count Size of the results array in entries. +## @param[out] total_out Total output entries. +## + +proc lp2pCreateGroup*(info: ptr Lp2pGroupInfo): Result {.cdecl, + importc: "lp2pCreateGroup".} +## * +## @brief CreateGroup +## @note The role (\ref lp2pGetRole) must be 0. This eventually sets the role to value 1. +## @param[in] info \ref Lp2pGroupInfo +## + +proc lp2pDestroyGroup*(): Result {.cdecl, importc: "lp2pDestroyGroup".} +## * +## @brief This destroys the previously created group from \ref lp2pCreateGroup. +## @note If no group was previously created (role from \ref lp2pGetRole is not 1), this just returns 0. +## + +proc lp2pSetAdvertiseData*(buffer: pointer; size: csize_t): Result {.cdecl, + importc: "lp2pSetAdvertiseData".} +## * +## @brief SetAdvertiseData +## @note The role (\ref lp2pGetRole) must be <=1. +## @note An empty buffer (buffer=NULL/size=0) can be used to reset the AdvertiseData size in state to zero. +## @param[out] buffer Input buffer containing arbitrary user data. +## @param[in] size Input buffer size, must be <=0x80. +## + +proc lp2pSendToOtherGroup*(buffer: pointer; size: csize_t; `addr`: Lp2pMacAddress; + groupId: Lp2pGroupId; frequency: S16; channel: S16; + flags: U32): Result {.cdecl, + importc: "lp2pSendToOtherGroup".} +## * +## @brief This sends an Action frame to the specified \ref Lp2pGroupId, with the specified destination \ref Lp2pMacAddress. +## @note The role (\ref lp2pGetRole) must be non-zero. +## @note The error from \ref lp2pGetNetworkInterfaceLastError will be returned if it's set. +## @note [11.0.0+] Lp2pGroupInfo::security_type must be value 2 (default encryption), otherwise an error is returned. +## @param[in] buffer Input buffer containing arbitrary user data. +## @param[in] size Input buffer size, must be <=0x400. +## @param[in] addr \ref Lp2pMacAddress, this can be a broadcast address. This must be non-zero. +## @param[in] group_id \ref Lp2pGroupId +## @param[in] frequency Must be >=1. See Lp2pGroupInfo::frequency. +## @param[in] channel Must be >=1. See Lp2pGroupInfo::channel. +## @param[in] flags Only bit0 is used: clear = block until the data can be sent, set = return error when the data can't be sent. +## + +proc lp2pRecvFromOtherGroup*(buffer: pointer; size: csize_t; flags: U32; + `addr`: ptr Lp2pMacAddress; unk0: ptr U16; unk1: ptr S32; + outSize: ptr U64; unk2: ptr S32): Result {.cdecl, + importc: "lp2pRecvFromOtherGroup".} +## * +## @brief This receives an Action frame. +## @note The role (\ref lp2pGetRole) must be non-zero. +## @note When data is not available, the error from \ref lp2pGetNetworkInterfaceLastError will be returned if it's set. +## @param[out] buffer Output buffer containing arbitrary user data. +## @param[in] size Output buffer size. +## @param[in] flags Only bit0 is used: clear = block until data is available, set = return error when data is not available. +## @param[in] addr \ref Lp2pMacAddress +## @param[in] unk0 Unknown +## @param[in] unk1 Unknown +## @param[out] out_size This is the original size used for copying to the output buffer, before it's clamped to the output-buffer size. +## @param[out] unk2 Unknown +## + +proc lp2pAddAcceptableGroupId*(groupId: Lp2pGroupId): Result {.cdecl, + importc: "lp2pAddAcceptableGroupId".} +## * +## @brief AddAcceptableGroupId +## @param[in] group_id \ref Lp2pGroupId +## + +proc lp2pRemoveAcceptableGroupId*(): Result {.cdecl, + importc: "lp2pRemoveAcceptableGroupId".} +## * +## @brief RemoveAcceptableGroupId +## + +proc lp2pAttachNetworkInterfaceStateChangeEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "lp2pAttachNetworkInterfaceStateChangeEvent".} +## /@name INetworkServiceMonitor +## /@{ +## * +## @brief AttachNetworkInterfaceStateChangeEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc lp2pGetNetworkInterfaceLastError*(): Result {.cdecl, + importc: "lp2pGetNetworkInterfaceLastError".} +## * +## @brief GetNetworkInterfaceLastError +## + +proc lp2pGetRole*(`out`: ptr U8): Result {.cdecl, importc: "lp2pGetRole".} +## * +## @brief GetRole +## @param[out] out Output Role. +## + +proc lp2pGetAdvertiseData*(buffer: pointer; size: csize_t; transferSize: ptr U16; + originalSize: ptr U16): Result {.cdecl, + importc: "lp2pGetAdvertiseData".} +## * +## @brief GetAdvertiseData +## @note The role from \ref lp2pGetRole must be value 2. +## @param[out] buffer Output buffer data. +## @param[in] size Output buffer size. +## @param[out] transfer_size Size of the data copied into the buffer. +## @param[out] original_size Original size from state. +## + +proc lp2pGetAdvertiseData2*(buffer: pointer; size: csize_t; transferSize: ptr U16; + originalSize: ptr U16): Result {.cdecl, + importc: "lp2pGetAdvertiseData2".} +## * +## @brief GetAdvertiseData2 +## @note This is identical to \ref lp2pGetAdvertiseData except this doesn't run the role validation. +## @param[out] buffer Output buffer data. +## @param[in] size Output buffer size. +## @param[out] transfer_size Size of the data copied into the buffer. +## @param[out] original_size Original size from state. +## + +proc lp2pGetGroupInfo*(`out`: ptr Lp2pGroupInfo): Result {.cdecl, + importc: "lp2pGetGroupInfo".} +## * +## @brief GetGroupInfo +## @note The role from \ref lp2pGetRole must be non-zero. +## @param[out] out \ref Lp2pGroupInfo +## + +proc lp2pJoin*(`out`: ptr Lp2pGroupInfo; info: ptr Lp2pGroupInfo): Result {.cdecl, + importc: "lp2pJoin".} +## * +## @brief This runs the same code as \ref lp2pCreateGroup to generate the \ref Lp2pGroupInfo for the input struct. +## @param[out] out \ref Lp2pGroupInfo +## @param[in] info \ref Lp2pGroupInfo +## + +proc lp2pGetGroupOwner*(`out`: ptr Lp2pNodeInfo): Result {.cdecl, + importc: "lp2pGetGroupOwner".} +## * +## @brief GetGroupOwner +## @note The role from \ref lp2pGetRole must be non-zero. +## @param[out] out \ref Lp2pNodeInfo +## + +proc lp2pGetIpConfig*(`out`: ptr Lp2pIpConfig): Result {.cdecl, + importc: "lp2pGetIpConfig".} +## * +## @brief GetIpConfig +## @note The role from \ref lp2pGetRole must be non-zero. +## @param[out] out \ref Lp2pIpConfig +## + +proc lp2pLeave*(`out`: ptr U32): Result {.cdecl, importc: "lp2pLeave".} +## * +## @brief Leave +## @param[out] out Output value. +## + +proc lp2pAttachJoinEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "lp2pAttachJoinEvent".} +## * +## @brief AttachJoinEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc lp2pGetMembers*(members: ptr Lp2pNodeInfo; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "lp2pGetMembers".} +## * +## @brief GetMembers +## @note The role from \ref lp2pGetRole must be value 1. +## @param[out] members Output array of \ref Lp2pNodeInfo. +## @param[in] count Size of the members array in entries. A maximum of 8 entries can be returned. +## @param[out] total_out Total output entries. +## + +## /@} diff --git a/src/libnx/wrapper/switch/services/lr.h b/src/libnx/wrapper/switch/services/lr.h new file mode 100644 index 0000000..7dc35fd --- /dev/null +++ b/src/libnx/wrapper/switch/services/lr.h @@ -0,0 +1,50 @@ +/** + * @file lr.h + * @brief Location Resolver (lr) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/ncm_types.h" + +typedef struct { + Service s; +} LrLocationResolver; + +typedef struct { + Service s; +} LrRegisteredLocationResolver; + +/// Initialize lr. +Result lrInitialize(void); + +/// Exit lr. +void lrExit(void); + +/// Gets the Service object for the actual lr service session. +Service* lrGetServiceSession(void); + +Result lrOpenLocationResolver(NcmStorageId storage, LrLocationResolver* out); +Result lrOpenRegisteredLocationResolver(LrRegisteredLocationResolver* out); +// TODO: Other ILocationResolverManager commands + +// ILocationResolver +Result lrLrResolveProgramPath(LrLocationResolver* lr, u64 tid, char *out); +Result lrLrRedirectProgramPath(LrLocationResolver* lr, u64 tid, const char *path); +Result lrLrResolveApplicationControlPath(LrLocationResolver* lr, u64 tid, char *out); +Result lrLrResolveApplicationHtmlDocumentPath(LrLocationResolver* lr, u64 tid, char *out); +Result lrLrResolveDataPath(LrLocationResolver* lr, u64 tid, char *out); +Result lrLrRedirectApplicationControlPath(LrLocationResolver* lr, u64 tid, u64 tid2, const char *path); +Result lrLrRedirectApplicationHtmlDocumentPath(LrLocationResolver* lr, u64 tid, u64 tid2, const char *path); +Result lrLrResolveApplicationLegalInformationPath(LrLocationResolver* lr, u64 tid, char *out); +Result lrLrRedirectApplicationLegalInformationPath(LrLocationResolver* lr, u64 tid, u64 tid2, const char *path); +Result lrLrRefresh(LrLocationResolver* lr); + +/// Only available on [5.0.0+]. +Result lrLrEraseProgramRedirection(LrLocationResolver* lr, u64 tid); + +// IRegisteredLocationResolver +Result lrRegLrResolveProgramPath(LrRegisteredLocationResolver* reg, u64 tid, char *out); +// TODO: Other IRegisteredLocationResolver commands diff --git a/src/libnx/wrapper/switch/services/lr.nim b/src/libnx/wrapper/switch/services/lr.nim new file mode 100644 index 0000000..ab5ff23 --- /dev/null +++ b/src/libnx/wrapper/switch/services/lr.nim @@ -0,0 +1,70 @@ +## * +## @file lr.h +## @brief Location Resolver (lr) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/ncm_types + +type + LrLocationResolver* {.bycopy.} = object + s*: Service + + LrRegisteredLocationResolver* {.bycopy.} = object + s*: Service + + + +proc lrInitialize*(): Result {.cdecl, importc: "lrInitialize".} +## / Initialize lr. + +proc lrExit*() {.cdecl, importc: "lrExit".} +## / Exit lr. + +proc lrGetServiceSession*(): ptr Service {.cdecl, importc: "lrGetServiceSession".} +## / Gets the Service object for the actual lr service session. +proc lrOpenLocationResolver*(storage: NcmStorageId; `out`: ptr LrLocationResolver): Result {. + cdecl, importc: "lrOpenLocationResolver".} +proc lrOpenRegisteredLocationResolver*(`out`: ptr LrRegisteredLocationResolver): Result {. + cdecl, importc: "lrOpenRegisteredLocationResolver".} + +## TODO: Other ILocationResolverManager commands +## ILocationResolver + +proc lrLrResolveProgramPath*(lr: ptr LrLocationResolver; tid: U64; `out`: cstring): Result {. + cdecl, importc: "lrLrResolveProgramPath".} +proc lrLrRedirectProgramPath*(lr: ptr LrLocationResolver; tid: U64; path: cstring): Result {. + cdecl, importc: "lrLrRedirectProgramPath".} +proc lrLrResolveApplicationControlPath*(lr: ptr LrLocationResolver; tid: U64; + `out`: cstring): Result {.cdecl, + importc: "lrLrResolveApplicationControlPath".} +proc lrLrResolveApplicationHtmlDocumentPath*(lr: ptr LrLocationResolver; tid: U64; + `out`: cstring): Result {.cdecl, + importc: "lrLrResolveApplicationHtmlDocumentPath".} +proc lrLrResolveDataPath*(lr: ptr LrLocationResolver; tid: U64; `out`: cstring): Result {. + cdecl, importc: "lrLrResolveDataPath".} +proc lrLrRedirectApplicationControlPath*(lr: ptr LrLocationResolver; tid: U64; + tid2: U64; path: cstring): Result {.cdecl, + importc: "lrLrRedirectApplicationControlPath".} +proc lrLrRedirectApplicationHtmlDocumentPath*(lr: ptr LrLocationResolver; tid: U64; + tid2: U64; path: cstring): Result {.cdecl, importc: "lrLrRedirectApplicationHtmlDocumentPath".} +proc lrLrResolveApplicationLegalInformationPath*(lr: ptr LrLocationResolver; + tid: U64; `out`: cstring): Result {.cdecl, importc: "lrLrResolveApplicationLegalInformationPath".} +proc lrLrRedirectApplicationLegalInformationPath*(lr: ptr LrLocationResolver; + tid: U64; tid2: U64; path: cstring): Result {.cdecl, + importc: "lrLrRedirectApplicationLegalInformationPath".} +proc lrLrRefresh*(lr: ptr LrLocationResolver): Result {.cdecl, importc: "lrLrRefresh".} + +proc lrLrEraseProgramRedirection*(lr: ptr LrLocationResolver; tid: U64): Result {. + cdecl, importc: "lrLrEraseProgramRedirection".} +## / Only available on [5.0.0+]. + +## IRegisteredLocationResolver + +proc lrRegLrResolveProgramPath*(reg: ptr LrRegisteredLocationResolver; tid: U64; + `out`: cstring): Result {.cdecl, + importc: "lrRegLrResolveProgramPath".} + +## TODO: Other IRegisteredLocationResolver commands diff --git a/src/libnx/wrapper/switch/services/mii.h b/src/libnx/wrapper/switch/services/mii.h new file mode 100644 index 0000000..9a6d63d --- /dev/null +++ b/src/libnx/wrapper/switch/services/mii.h @@ -0,0 +1,176 @@ +/** + * @file mii.h + * @brief Mii services (mii:*) IPC wrapper. + * @author XorTroll + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + MiiServiceType_System = 0, ///< Initializes mii:e. + MiiServiceType_User = 1, ///< Initializes mii:u. +} MiiServiceType; + +/// Mii age. +typedef enum { + MiiAge_Young = 0, ///< Young + MiiAge_Normal = 1, ///< Normal + MiiAge_Old = 2, ///< Old + MiiAge_All = 3, ///< All of them +} MiiAge; + +/// Mii gender. +typedef enum { + MiiGender_Male = 0, ///< Male + MiiGender_Female = 1, ///< Female + MiiGender_All = 2, ///< Both of them +} MiiGender; + +/// Mii face color. +typedef enum { + MiiFaceColor_Black = 0, ///< Black + MiiFaceColor_White = 1, ///< White + MiiFaceColor_Asian = 2, ///< Asian + MiiFaceColor_All = 3, ///< All of them +} MiiFaceColor; + +// Mii source flag. +typedef enum { + MiiSourceFlag_Database = BIT(0), ///< Miis created by the user + MiiSourceFlag_Default = BIT(1), ///< Default console miis + MiiSourceFlag_All = MiiSourceFlag_Database | MiiSourceFlag_Default, ///< All of them +} MiiSourceFlag; + +// Mii special key code +typedef enum { + MiiSpecialKeyCode_Normal = 0, ///< Normal miis + MiiSpecialKeyCode_Special = 0xA523B78F, ///< Special miis +} MiiSpecialKeyCode; + +typedef struct { + Service s; +} MiiDatabase; + +// Mii create ID. +typedef struct { + Uuid uuid; +} MiiCreateId; + +// Mii data structure. +typedef struct { + MiiCreateId create_id; + u16 mii_name[10+1]; ///< utf-16be, null-terminated + u8 unk_x26; + u8 mii_color; + u8 mii_sex; + u8 mii_height; + u8 mii_width; + u8 unk_x2b[2]; + u8 mii_face_shape; + u8 mii_face_color; + u8 mii_wrinkles_style; + u8 mii_makeup_style; + u8 mii_hair_style; + u8 mii_hair_color; + u8 mii_has_hair_flipped; + u8 mii_eye_style; + u8 mii_eye_color; + u8 mii_eye_size; + u8 mii_eye_thickness; + u8 mii_eye_angle; + u8 mii_eye_pos_x; + u8 mii_eye_pos_y; + u8 mii_eyebrow_style; + u8 mii_eyebrow_color; + u8 mii_eyebrow_size; + u8 mii_eyebrow_thickness; + u8 mii_eyebrow_angle; + u8 mii_eyebrow_pos_x; + u8 mii_eyebrow_pos_y; + u8 mii_nose_style; + u8 mii_nose_size; + u8 mii_nose_pos; + u8 mii_mouth_style; + u8 mii_mouth_color; + u8 mii_mouth_size; + u8 mii_mouth_thickness; + u8 mii_mouth_pos; + u8 mii_facial_hair_color; + u8 mii_beard_style; + u8 mii_mustache_style; + u8 mii_mustache_size; + u8 mii_mustache_pos; + u8 mii_glasses_style; + u8 mii_glasses_color; + u8 mii_glasses_size; + u8 mii_glasses_pos; + u8 mii_has_mole; + u8 mii_mole_size; + u8 mii_mole_pos_x; + u8 mii_mole_pos_y; + u8 unk_x57; +} MiiCharInfo; + +/// Initialize mii. +Result miiInitialize(MiiServiceType service_type); + +/// Exit mii. +void miiExit(void); + +/// Gets the Service object for the actual mii service session. +Service* miiGetServiceSession(void); + +/** + * @brief Opens a mii database. + * @param[in] key_code Mii key code filter. + * @param[out] out Database. + */ +Result miiOpenDatabase(MiiDatabase *out, MiiSpecialKeyCode key_code); + +/** + * @brief Returns whether the mii database is updated. + * @param[in] db Database. + * @param[in] flag Source flag. + * @param[out] out_updated Whether the mii database is updated. + */ +Result miiDatabaseIsUpdated(MiiDatabase *db, bool *out_updated, MiiSourceFlag flag); + +/** + * @brief Returns whether the mii database is full. + * @param[in] db Database. + * @param[out] out_full Whether the mii database is full. + */ +Result miiDatabaseIsFull(MiiDatabase *db, bool *out_full); + +/** + * @brief Returns number of miis in the database with the specified source flag. + * @param[in] db Database. + * @param[in] flag Source flag. + * @param[out] out_count Out mii count. + */ +Result miiDatabaseGetCount(MiiDatabase *db, s32 *out_count, MiiSourceFlag flag); + +/** + * @brief Reads mii charinfo data from the specified source flag. + * @param[in] db Database. + * @param[in] flag Source flag. + * @param[out] out_infos Output mii charinfo array. + * @param[in] count Number of mii chainfos to read. + * @param[out] total_out Number of mii charinfos which were actually read. + */ +Result miiDatabaseGet1(MiiDatabase *db, MiiSourceFlag flag, MiiCharInfo *out_infos, s32 count, s32 *total_out); + +/** + * @brief Generates a random mii charinfo (doesn't register it in the console database). + * @param[in] db Database. + * @param[in] age Mii's age. + * @param[in] gender Mii's gender. + * @param[in] face_color Mii's face color. + * @param[out] out_info Out mii charinfo data. + */ +Result miiDatabaseBuildRandom(MiiDatabase *db, MiiAge age, MiiGender gender, MiiFaceColor face_color, MiiCharInfo *out_info); + +/// Closes a mii database. +void miiDatabaseClose(MiiDatabase *db); diff --git a/src/libnx/wrapper/switch/services/mii.nim b/src/libnx/wrapper/switch/services/mii.nim new file mode 100644 index 0000000..58f9c31 --- /dev/null +++ b/src/libnx/wrapper/switch/services/mii.nim @@ -0,0 +1,200 @@ +## * +## @file mii.h +## @brief Mii services (mii:*) IPC wrapper. +## @author XorTroll +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + MiiServiceType* = enum + MiiServiceTypeSystem = 0, ## /< Initializes mii:e. + MiiServiceTypeUser = 1 ## /< Initializes mii:u. + + +## / Mii age. + +type + MiiAge* = enum + MiiAgeYoung = 0, ## /< Young + MiiAgeNormal = 1, ## /< Normal + MiiAgeOld = 2, ## /< Old + MiiAgeAll = 3 ## /< All of them + + +## / Mii gender. + +type + MiiGender* = enum + MiiGenderMale = 0, ## /< Male + MiiGenderFemale = 1, ## /< Female + MiiGenderAll = 2 ## /< Both of them + + +## / Mii face color. + +type + MiiFaceColor* = enum + MiiFaceColorBlack = 0, ## /< Black + MiiFaceColorWhite = 1, ## /< White + MiiFaceColorAsian = 2, ## /< Asian + MiiFaceColorAll = 3 ## /< All of them + + +## Mii source flag. + +type + MiiSourceFlag* = enum + MiiSourceFlagDatabase = bit(0), ## /< Miis created by the user + MiiSourceFlagDefault = bit(1), ## /< Default console miis + MiiSourceFlagAll = MiiSourceFlagDatabase.cint or MiiSourceFlagDefault.cint ## /< All of them + + +## Mii special key code + +type + MiiSpecialKeyCode* = enum + MiiSpecialKeyCodeNormal = 0, ## /< Normal miis + MiiSpecialKeyCodeSpecial = 0xA523B78F ## /< Special miis + MiiDatabase* {.bycopy.} = object + s*: Service + + + +## Mii create ID. + +type + MiiCreateId* {.bycopy.} = object + uuid*: Uuid + + +## Mii data structure. + +type + MiiCharInfo* {.bycopy.} = object + createId*: MiiCreateId + miiName*: array[10 + 1, U16] ## /< utf-16be, null-terminated + unkX26*: U8 + miiColor*: U8 + miiSex*: U8 + miiHeight*: U8 + miiWidth*: U8 + unkX2b*: array[2, U8] + miiFaceShape*: U8 + miiFaceColor*: U8 + miiWrinklesStyle*: U8 + miiMakeupStyle*: U8 + miiHairStyle*: U8 + miiHairColor*: U8 + miiHasHairFlipped*: U8 + miiEyeStyle*: U8 + miiEyeColor*: U8 + miiEyeSize*: U8 + miiEyeThickness*: U8 + miiEyeAngle*: U8 + miiEyePosX*: U8 + miiEyePosY*: U8 + miiEyebrowStyle*: U8 + miiEyebrowColor*: U8 + miiEyebrowSize*: U8 + miiEyebrowThickness*: U8 + miiEyebrowAngle*: U8 + miiEyebrowPosX*: U8 + miiEyebrowPosY*: U8 + miiNoseStyle*: U8 + miiNoseSize*: U8 + miiNosePos*: U8 + miiMouthStyle*: U8 + miiMouthColor*: U8 + miiMouthSize*: U8 + miiMouthThickness*: U8 + miiMouthPos*: U8 + miiFacialHairColor*: U8 + miiBeardStyle*: U8 + miiMustacheStyle*: U8 + miiMustacheSize*: U8 + miiMustachePos*: U8 + miiGlassesStyle*: U8 + miiGlassesColor*: U8 + miiGlassesSize*: U8 + miiGlassesPos*: U8 + miiHasMole*: U8 + miiMoleSize*: U8 + miiMolePosX*: U8 + miiMolePosY*: U8 + unkX57*: U8 + +proc miiInitialize*(serviceType: MiiServiceType): Result {.cdecl, + importc: "miiInitialize".} +## / Initialize mii. + +proc miiExit*() {.cdecl, importc: "miiExit".} +## / Exit mii. + +proc miiGetServiceSession*(): ptr Service {.cdecl, importc: "miiGetServiceSession".} +## / Gets the Service object for the actual mii service session. + +proc miiOpenDatabase*(`out`: ptr MiiDatabase; keyCode: MiiSpecialKeyCode): Result {. + cdecl, importc: "miiOpenDatabase".} +## * +## @brief Opens a mii database. +## @param[in] key_code Mii key code filter. +## @param[out] out Database. +## + +proc miiDatabaseIsUpdated*(db: ptr MiiDatabase; outUpdated: ptr bool; + flag: MiiSourceFlag): Result {.cdecl, + importc: "miiDatabaseIsUpdated".} +## * +## @brief Returns whether the mii database is updated. +## @param[in] db Database. +## @param[in] flag Source flag. +## @param[out] out_updated Whether the mii database is updated. +## + +proc miiDatabaseIsFull*(db: ptr MiiDatabase; outFull: ptr bool): Result {.cdecl, + importc: "miiDatabaseIsFull".} +## * +## @brief Returns whether the mii database is full. +## @param[in] db Database. +## @param[out] out_full Whether the mii database is full. +## + +proc miiDatabaseGetCount*(db: ptr MiiDatabase; outCount: ptr S32; flag: MiiSourceFlag): Result {. + cdecl, importc: "miiDatabaseGetCount".} +## * +## @brief Returns number of miis in the database with the specified source flag. +## @param[in] db Database. +## @param[in] flag Source flag. +## @param[out] out_count Out mii count. +## + +proc miiDatabaseGet1*(db: ptr MiiDatabase; flag: MiiSourceFlag; + outInfos: ptr MiiCharInfo; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "miiDatabaseGet1".} +## * +## @brief Reads mii charinfo data from the specified source flag. +## @param[in] db Database. +## @param[in] flag Source flag. +## @param[out] out_infos Output mii charinfo array. +## @param[in] count Number of mii chainfos to read. +## @param[out] total_out Number of mii charinfos which were actually read. +## + +proc miiDatabaseBuildRandom*(db: ptr MiiDatabase; age: MiiAge; gender: MiiGender; + faceColor: MiiFaceColor; outInfo: ptr MiiCharInfo): Result {. + cdecl, importc: "miiDatabaseBuildRandom".} +## * +## @brief Generates a random mii charinfo (doesn't register it in the console database). +## @param[in] db Database. +## @param[in] age Mii's age. +## @param[in] gender Mii's gender. +## @param[in] face_color Mii's face color. +## @param[out] out_info Out mii charinfo data. +## + +proc miiDatabaseClose*(db: ptr MiiDatabase) {.cdecl, importc: "miiDatabaseClose".} +## / Closes a mii database. + diff --git a/src/libnx/wrapper/switch/services/miiimg.h b/src/libnx/wrapper/switch/services/miiimg.h new file mode 100644 index 0000000..f269a48 --- /dev/null +++ b/src/libnx/wrapper/switch/services/miiimg.h @@ -0,0 +1,71 @@ +/** + * @file miiimg.h + * @brief Mii image (miiimg) service IPC wrapper. + * @author XorTroll + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/mii.h" + +/// Image ID. +typedef struct { + Uuid uuid; +} MiiimgImageId; + +/// Image attribute. +typedef struct { + MiiimgImageId image_id; ///< Image ID. + MiiCreateId create_id; ///< Mii's create ID. + u32 unk; + u16 mii_name[10+1]; ///< utf-16be, null-terminated +} PACKED MiiimgImageAttribute; + +/// Initialize miiimg. +Result miiimgInitialize(void); + +/// Exit miiimg. +void miiimgExit(void); + +/// Gets the Service object for the actual miiimg service session. +Service* miiimgGetServiceSession(void); + +/** + * @brief Reloads the image database. + */ +Result miiimgReload(void); + +/** + * @brief Gets the number of mii images in the database. + * @param[out] out_count Mii image count. + */ +Result miiimgGetCount(s32 *out_count); + +/** + * @brief Gets whether the image database is empty. + * @param[out] out_empty Whether the database is empty. + */ +Result miiimgIsEmpty(bool *out_empty); + +/** + * @brief Gets whether the image database is full. + * @param[out] out_empty Whether the database is full. + */ +Result miiimgIsFull(bool *out_full); + +/** + * @brief Gets the image attribute for the specified image index. + * @param[in] index Image index. + * @param[out] out_attr Out image attribute. + */ +Result miiimgGetAttribute(s32 index, MiiimgImageAttribute *out_attr); + +/** + * @brief Loads the image data (raw RGBA8) for the specified image ID. + * @note Server doesn't seem to check the image buffer size, but 0x40000 is the optimal size. + * @param[in] id Input image ID. + * @param[out] out_image Out iamge buffer. + * @param[in] out_image_size Out image buffer size. + */ +Result miiimgLoadImage(MiiimgImageId id, void* out_image, size_t out_image_size); diff --git a/src/libnx/wrapper/switch/services/miiimg.nim b/src/libnx/wrapper/switch/services/miiimg.nim new file mode 100644 index 0000000..26afd44 --- /dev/null +++ b/src/libnx/wrapper/switch/services/miiimg.nim @@ -0,0 +1,78 @@ +## * +## @file miiimg.h +## @brief Mii image (miiimg) service IPC wrapper. +## @author XorTroll +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/mii + +## / Image ID. + +type + MiiimgImageId* {.bycopy.} = object + uuid*: Uuid + + +## / Image attribute. + +type + MiiimgImageAttribute* {.bycopy.} = object + imageId*: MiiimgImageId ## /< Image ID. + createId*: MiiCreateId ## /< Mii's create ID. + unk*: U32 + miiName*: array[10 + 1, U16] ## /< utf-16be, null-terminated + + +## / Initialize miiimg. + +proc miiimgInitialize*(): Result {.cdecl, importc: "miiimgInitialize".} +## / Exit miiimg. + +proc miiimgExit*() {.cdecl, importc: "miiimgExit".} +## / Gets the Service object for the actual miiimg service session. + +proc miiimgGetServiceSession*(): ptr Service {.cdecl, + importc: "miiimgGetServiceSession".} +## * +## @brief Reloads the image database. +## + +proc miiimgReload*(): Result {.cdecl, importc: "miiimgReload".} +## * +## @brief Gets the number of mii images in the database. +## @param[out] out_count Mii image count. +## + +proc miiimgGetCount*(outCount: ptr S32): Result {.cdecl, importc: "miiimgGetCount".} +## * +## @brief Gets whether the image database is empty. +## @param[out] out_empty Whether the database is empty. +## + +proc miiimgIsEmpty*(outEmpty: ptr bool): Result {.cdecl, importc: "miiimgIsEmpty".} +## * +## @brief Gets whether the image database is full. +## @param[out] out_empty Whether the database is full. +## + +proc miiimgIsFull*(outFull: ptr bool): Result {.cdecl, importc: "miiimgIsFull".} +## * +## @brief Gets the image attribute for the specified image index. +## @param[in] index Image index. +## @param[out] out_attr Out image attribute. +## + +proc miiimgGetAttribute*(index: S32; outAttr: ptr MiiimgImageAttribute): Result {. + cdecl, importc: "miiimgGetAttribute".} +## * +## @brief Loads the image data (raw RGBA8) for the specified image ID. +## @note Server doesn't seem to check the image buffer size, but 0x40000 is the optimal size. +## @param[in] id Input image ID. +## @param[out] out_image Out iamge buffer. +## @param[in] out_image_size Out image buffer size. +## + +proc miiimgLoadImage*(id: MiiimgImageId; outImage: pointer; outImageSize: csize_t): Result {. + cdecl, importc: "miiimgLoadImage".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/mm.h b/src/libnx/wrapper/switch/services/mm.h new file mode 100644 index 0000000..aa8eea8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/mm.h @@ -0,0 +1,31 @@ +/** + * @file mmu.h + * @brief Multimedia (mm) IPC wrapper. + * @author averne + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + MmuModuleId_Ram = 2, + MmuModuleId_Nvenc = 5, + MmuModuleId_Nvdec = 6, + MmuModuleId_Nvjpg = 7, +} MmuModuleId; + +typedef struct { + MmuModuleId module; + u32 id; +} MmuRequest; + +Result mmuInitialize(void); +void mmuExit(void); +Service* mmuGetServiceSession(void); + +Result mmuRequestInitialize(MmuRequest *request, MmuModuleId module, u32 unk, bool autoclear); ///< unk is ignored by official software +Result mmuRequestFinalize(const MmuRequest *request); +Result mmuRequestGet(const MmuRequest *request, u32 *out_freq_hz); +Result mmuRequestSetAndWait(const MmuRequest *request, u32 freq_hz, s32 timeout); diff --git a/src/libnx/wrapper/switch/services/mm.nim b/src/libnx/wrapper/switch/services/mm.nim new file mode 100644 index 0000000..c6c109c --- /dev/null +++ b/src/libnx/wrapper/switch/services/mm.nim @@ -0,0 +1,33 @@ +## * +## @file mmu.h +## @brief Multimedia (mm) IPC wrapper. +## @author averne +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + MmuModuleId* = enum + MmuModuleIdRam = 2, MmuModuleIdNvenc = 5, MmuModuleIdNvdec = 6, MmuModuleIdNvjpg = 7 + MmuRequest* {.bycopy.} = object + module*: MmuModuleId + id*: U32 + + + +proc mmuInitialize*(): Result {.cdecl, importc: "mmuInitialize".} +proc mmuExit*() {.cdecl, importc: "mmuExit".} +proc mmuGetServiceSession*(): ptr Service {.cdecl, importc: "mmuGetServiceSession".} +proc mmuRequestInitialize*(request: ptr MmuRequest; module: MmuModuleId; unk: U32; + autoclear: bool): Result {.cdecl, + importc: "mmuRequestInitialize".} +## /< unk is ignored by official software + +proc mmuRequestFinalize*(request: ptr MmuRequest): Result {.cdecl, + importc: "mmuRequestFinalize".} +proc mmuRequestGet*(request: ptr MmuRequest; outFreqHz: ptr U32): Result {.cdecl, + importc: "mmuRequestGet".} +proc mmuRequestSetAndWait*(request: ptr MmuRequest; freqHz: U32; timeout: S32): Result {. + cdecl, importc: "mmuRequestSetAndWait".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/ncm.h b/src/libnx/wrapper/switch/services/ncm.h new file mode 100644 index 0000000..4134670 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ncm.h @@ -0,0 +1,107 @@ +/** + * @file ncm.h + * @brief Content Manager (ncm) service IPC wrapper. + * @author Adubbz & zhuowei + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../services/ncm_types.h" +#include "../services/fs.h" +#include "../sf/service.h" + +/// ContentStorage +typedef struct { + Service s; ///< IContentStorage +} NcmContentStorage; + +/// ContentMetaDatabase +typedef struct { + Service s; ///< IContentMetaDatabase +} NcmContentMetaDatabase; + +/// RightsId +typedef struct { + FsRightsId rights_id; + u8 key_generation; ///< [3.0.0+] + u8 pad[7]; ///< [3.0.0+] +} NcmRightsId; + +/// Initialize ncm. +Result ncmInitialize(void); + +/// Exit ncm. +void ncmExit(void); + +/// Gets the Service object for the actual ncm service session. +Service* ncmGetServiceSession(void); + +Result ncmCreateContentStorage(NcmStorageId storage_id); +Result ncmCreateContentMetaDatabase(NcmStorageId storage_id); +Result ncmVerifyContentStorage(NcmStorageId storage_id); +Result ncmVerifyContentMetaDatabase(NcmStorageId storage_id); +Result ncmOpenContentStorage(NcmContentStorage* out_content_storage, NcmStorageId storage_id); +Result ncmOpenContentMetaDatabase(NcmContentMetaDatabase* out_content_meta_database, NcmStorageId storage_id); +Result ncmCloseContentStorageForcibly(NcmStorageId storage_id); ///< [1.0.0] +Result ncmCloseContentMetaDatabaseForcibly(NcmStorageId storage_id); ///< [1.0.0] +Result ncmCleanupContentMetaDatabase(NcmStorageId storage_id); +Result ncmActivateContentStorage(NcmStorageId storage_id); ///< [2.0.0+] +Result ncmInactivateContentStorage(NcmStorageId storage_id); ///< [2.0.0+] +Result ncmActivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+] +Result ncmInactivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+] +Result ncmInvalidateRightsIdCache(void); ///< [9.0.0+] + +void ncmContentStorageClose(NcmContentStorage* cs); +Result ncmContentStorageGeneratePlaceHolderId(NcmContentStorage* cs, NcmPlaceHolderId* out_id); +Result ncmContentStorageCreatePlaceHolder(NcmContentStorage* cs, const NcmContentId* content_id, const NcmPlaceHolderId* placeholder_id, s64 size); +Result ncmContentStorageDeletePlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id); +Result ncmContentStorageHasPlaceHolder(NcmContentStorage* cs, bool* out, const NcmPlaceHolderId* placeholder_id); +Result ncmContentStorageWritePlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, u64 offset, const void* data, size_t data_size); +Result ncmContentStorageRegister(NcmContentStorage* cs, const NcmContentId* content_id, const NcmPlaceHolderId* placeholder_id); +Result ncmContentStorageDelete(NcmContentStorage* cs, const NcmContentId* content_id); +Result ncmContentStorageHas(NcmContentStorage* cs, bool* out, const NcmContentId* content_id); +Result ncmContentStorageGetPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmContentId* content_id); +Result ncmContentStorageGetPlaceHolderPath(NcmContentStorage* cs, char* out_path, size_t out_size, const NcmPlaceHolderId* placeholder_id); +Result ncmContentStorageCleanupAllPlaceHolder(NcmContentStorage* cs); +Result ncmContentStorageListPlaceHolder(NcmContentStorage* cs, NcmPlaceHolderId* out_ids, s32 count, s32* out_count); +Result ncmContentStorageGetContentCount(NcmContentStorage* cs, s32* out_count); +Result ncmContentStorageListContentId(NcmContentStorage* cs, NcmContentId* out_ids, s32 count, s32* out_count, s32 start_offset); +Result ncmContentStorageGetSizeFromContentId(NcmContentStorage* cs, s64* out_size, const NcmContentId* content_id); +Result ncmContentStorageDisableForcibly(NcmContentStorage* cs); +Result ncmContentStorageRevertToPlaceHolder(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, const NcmContentId* old_content_id, const NcmContentId* new_content_id); ///< [2.0.0+] +Result ncmContentStorageSetPlaceHolderSize(NcmContentStorage* cs, const NcmPlaceHolderId* placeholder_id, s64 size); ///< [2.0.0+] +Result ncmContentStorageReadContentIdFile(NcmContentStorage* cs, void* out_data, size_t out_data_size, const NcmContentId* content_id, s64 offset); ///< [2.0.0+] +Result ncmContentStorageGetRightsIdFromPlaceHolderId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id); ///< [2.0.0+] +Result ncmContentStorageGetRightsIdFromContentId(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmContentId* content_id); ///< [2.0.0+] +Result ncmContentStorageWriteContentForDebug(NcmContentStorage* cs, const NcmContentId* content_id, s64 offset, const void* data, size_t data_size); ///< [2.0.0+] +Result ncmContentStorageGetFreeSpaceSize(NcmContentStorage* cs, s64* out_size); ///< [2.0.0+] +Result ncmContentStorageGetTotalSpaceSize(NcmContentStorage* cs, s64* out_size); ///< [2.0.0+] +Result ncmContentStorageFlushPlaceHolder(NcmContentStorage* cs); ///< [3.0.0+] +Result ncmContentStorageGetSizeFromPlaceHolderId(NcmContentStorage* cs, s64* out_size, const NcmPlaceHolderId* placeholder_id); ///< [4.0.0+] +Result ncmContentStorageRepairInvalidFileAttribute(NcmContentStorage* cs); ///< [4.0.0+] +Result ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache(NcmContentStorage* cs, NcmRightsId* out_rights_id, const NcmPlaceHolderId* placeholder_id, const NcmContentId* cache_content_id); ///< [8.0.0+] +Result ncmContentStorageRegisterPath(NcmContentStorage* cs, const NcmContentId* content_id, const char *path); ///< [13.0.0+] +Result ncmContentStorageClearRegisteredPath(NcmContentStorage* cs); ///< [13.0.0+] + +void ncmContentMetaDatabaseClose(NcmContentMetaDatabase* db); +Result ncmContentMetaDatabaseSet(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, const void* data, u64 data_size); +Result ncmContentMetaDatabaseGet(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, u64* out_size, void* out_data, u64 out_data_size); +Result ncmContentMetaDatabaseRemove(NcmContentMetaDatabase* db, const NcmContentMetaKey *key); +Result ncmContentMetaDatabaseGetContentIdByType(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type); +Result ncmContentMetaDatabaseListContentInfo(NcmContentMetaDatabase* db, s32* out_entries_written, NcmContentInfo* out_info, s32 count, const NcmContentMetaKey* key, s32 start_index); +Result ncmContentMetaDatabaseList(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type, u64 id, u64 id_min, u64 id_max, NcmContentInstallType install_type); +Result ncmContentMetaDatabaseGetLatestContentMetaKey(NcmContentMetaDatabase* db, NcmContentMetaKey* out_key, u64 id); +Result ncmContentMetaDatabaseListApplication(NcmContentMetaDatabase* db, s32* out_entries_total, s32* out_entries_written, NcmApplicationContentMetaKey* out_keys, s32 count, NcmContentMetaType meta_type); +Result ncmContentMetaDatabaseHas(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key); +Result ncmContentMetaDatabaseHasAll(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* keys, s32 count); +Result ncmContentMetaDatabaseGetSize(NcmContentMetaDatabase* db, u64* out_size, const NcmContentMetaKey* key); +Result ncmContentMetaDatabaseGetRequiredSystemVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key); +Result ncmContentMetaDatabaseGetPatchId(NcmContentMetaDatabase* db, u64* out_patch_id, const NcmContentMetaKey* key); +Result ncmContentMetaDatabaseDisableForcibly(NcmContentMetaDatabase* db); +Result ncmContentMetaDatabaseLookupOrphanContent(NcmContentMetaDatabase* db, bool* out_orphaned, const NcmContentId* content_ids, s32 count); +Result ncmContentMetaDatabaseCommit(NcmContentMetaDatabase* db); +Result ncmContentMetaDatabaseHasContent(NcmContentMetaDatabase* db, bool* out, const NcmContentMetaKey* key, const NcmContentId* content_id); +Result ncmContentMetaDatabaseListContentMetaInfo(NcmContentMetaDatabase* db, s32* out_entries_written, void* out_meta_info, s32 count, const NcmContentMetaKey* key, s32 start_index); +Result ncmContentMetaDatabaseGetAttributes(NcmContentMetaDatabase* db, const NcmContentMetaKey* key, u8* out); +Result ncmContentMetaDatabaseGetRequiredApplicationVersion(NcmContentMetaDatabase* db, u32* out_version, const NcmContentMetaKey* key); ///< [2.0.0+] +Result ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset(NcmContentMetaDatabase* db, NcmContentId* out_content_id, const NcmContentMetaKey* key, NcmContentType type, u8 id_offset); ///< [5.0.0+] diff --git a/src/libnx/wrapper/switch/services/ncm.nim b/src/libnx/wrapper/switch/services/ncm.nim new file mode 100644 index 0000000..efb6167 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ncm.nim @@ -0,0 +1,285 @@ +## * +## @file ncm.h +## @brief Content Manager (ncm) service IPC wrapper. +## @author Adubbz & zhuowei +## @copyright libnx Authors +## + +import + ../types, ../services/ncm_types, ../services/fs, ../sf/service + +## / ContentStorage + +type + NcmContentStorage* {.bycopy.} = object + s*: Service ## /< IContentStorage + + +## / ContentMetaDatabase + +type + NcmContentMetaDatabase* {.bycopy.} = object + s*: Service ## /< IContentMetaDatabase + + +## / RightsId + +type + NcmRightsId* {.bycopy.} = object + rightsId*: FsRightsId + keyGeneration*: U8 ## /< [3.0.0+] + pad*: array[7, U8] ## /< [3.0.0+] + + + +proc ncmInitialize*(): Result {.cdecl, importc: "ncmInitialize".} +## / Initialize ncm. + +proc ncmExit*() {.cdecl, importc: "ncmExit".} +## / Exit ncm. + +proc ncmGetServiceSession*(): ptr Service {.cdecl, importc: "ncmGetServiceSession".} +## / Gets the Service object for the actual ncm service session. + +proc ncmCreateContentStorage*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmCreateContentStorage".} +proc ncmCreateContentMetaDatabase*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmCreateContentMetaDatabase".} +proc ncmVerifyContentStorage*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmVerifyContentStorage".} +proc ncmVerifyContentMetaDatabase*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmVerifyContentMetaDatabase".} +proc ncmOpenContentStorage*(outContentStorage: ptr NcmContentStorage; + storageId: NcmStorageId): Result {.cdecl, + importc: "ncmOpenContentStorage".} +proc ncmOpenContentMetaDatabase*(outContentMetaDatabase: ptr NcmContentMetaDatabase; + storageId: NcmStorageId): Result {.cdecl, + importc: "ncmOpenContentMetaDatabase".} +proc ncmCloseContentStorageForcibly*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmCloseContentStorageForcibly".} +## /< [1.0.0] + +proc ncmCloseContentMetaDatabaseForcibly*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmCloseContentMetaDatabaseForcibly".} +## /< [1.0.0] + +proc ncmCleanupContentMetaDatabase*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmCleanupContentMetaDatabase".} +proc ncmActivateContentStorage*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmActivateContentStorage".} +## /< [2.0.0+] + +proc ncmInactivateContentStorage*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmInactivateContentStorage".} +## /< [2.0.0+] + +proc ncmActivateContentMetaDatabase*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmActivateContentMetaDatabase".} +## /< [2.0.0+] + +proc ncmInactivateContentMetaDatabase*(storageId: NcmStorageId): Result {.cdecl, + importc: "ncmInactivateContentMetaDatabase".} +## /< [2.0.0+] + +proc ncmInvalidateRightsIdCache*(): Result {.cdecl, + importc: "ncmInvalidateRightsIdCache".} +## /< [9.0.0+] + +proc ncmContentStorageClose*(cs: ptr NcmContentStorage) {.cdecl, + importc: "ncmContentStorageClose".} +proc ncmContentStorageGeneratePlaceHolderId*(cs: ptr NcmContentStorage; + outId: ptr NcmPlaceHolderId): Result {.cdecl, importc: "ncmContentStorageGeneratePlaceHolderId".} +proc ncmContentStorageCreatePlaceHolder*(cs: ptr NcmContentStorage; + contentId: ptr NcmContentId; + placeholderId: ptr NcmPlaceHolderId; + size: S64): Result {.cdecl, + importc: "ncmContentStorageCreatePlaceHolder".} +proc ncmContentStorageDeletePlaceHolder*(cs: ptr NcmContentStorage; + placeholderId: ptr NcmPlaceHolderId): Result {. + cdecl, importc: "ncmContentStorageDeletePlaceHolder".} +proc ncmContentStorageHasPlaceHolder*(cs: ptr NcmContentStorage; `out`: ptr bool; + placeholderId: ptr NcmPlaceHolderId): Result {. + cdecl, importc: "ncmContentStorageHasPlaceHolder".} +proc ncmContentStorageWritePlaceHolder*(cs: ptr NcmContentStorage; + placeholderId: ptr NcmPlaceHolderId; + offset: U64; data: pointer; dataSize: csize_t): Result {. + cdecl, importc: "ncmContentStorageWritePlaceHolder".} +proc ncmContentStorageRegister*(cs: ptr NcmContentStorage; + contentId: ptr NcmContentId; + placeholderId: ptr NcmPlaceHolderId): Result {.cdecl, + importc: "ncmContentStorageRegister".} +proc ncmContentStorageDelete*(cs: ptr NcmContentStorage; contentId: ptr NcmContentId): Result {. + cdecl, importc: "ncmContentStorageDelete".} +proc ncmContentStorageHas*(cs: ptr NcmContentStorage; `out`: ptr bool; + contentId: ptr NcmContentId): Result {.cdecl, + importc: "ncmContentStorageHas".} +proc ncmContentStorageGetPath*(cs: ptr NcmContentStorage; outPath: cstring; + outSize: csize_t; contentId: ptr NcmContentId): Result {. + cdecl, importc: "ncmContentStorageGetPath".} +proc ncmContentStorageGetPlaceHolderPath*(cs: ptr NcmContentStorage; + outPath: cstring; outSize: csize_t; placeholderId: ptr NcmPlaceHolderId): Result {. + cdecl, importc: "ncmContentStorageGetPlaceHolderPath".} +proc ncmContentStorageCleanupAllPlaceHolder*(cs: ptr NcmContentStorage): Result {. + cdecl, importc: "ncmContentStorageCleanupAllPlaceHolder".} +proc ncmContentStorageListPlaceHolder*(cs: ptr NcmContentStorage; + outIds: ptr NcmPlaceHolderId; count: S32; + outCount: ptr S32): Result {.cdecl, + importc: "ncmContentStorageListPlaceHolder".} +proc ncmContentStorageGetContentCount*(cs: ptr NcmContentStorage; outCount: ptr S32): Result {. + cdecl, importc: "ncmContentStorageGetContentCount".} +proc ncmContentStorageListContentId*(cs: ptr NcmContentStorage; + outIds: ptr NcmContentId; count: S32; + outCount: ptr S32; startOffset: S32): Result {. + cdecl, importc: "ncmContentStorageListContentId".} +proc ncmContentStorageGetSizeFromContentId*(cs: ptr NcmContentStorage; + outSize: ptr S64; contentId: ptr NcmContentId): Result {.cdecl, + importc: "ncmContentStorageGetSizeFromContentId".} +proc ncmContentStorageDisableForcibly*(cs: ptr NcmContentStorage): Result {.cdecl, + importc: "ncmContentStorageDisableForcibly".} +proc ncmContentStorageRevertToPlaceHolder*(cs: ptr NcmContentStorage; + placeholderId: ptr NcmPlaceHolderId; oldContentId: ptr NcmContentId; + newContentId: ptr NcmContentId): Result {.cdecl, + importc: "ncmContentStorageRevertToPlaceHolder".} +## /< [2.0.0+] + +proc ncmContentStorageSetPlaceHolderSize*(cs: ptr NcmContentStorage; + placeholderId: ptr NcmPlaceHolderId; size: S64): Result {.cdecl, + importc: "ncmContentStorageSetPlaceHolderSize".} +## /< [2.0.0+] + +proc ncmContentStorageReadContentIdFile*(cs: ptr NcmContentStorage; + outData: pointer; outDataSize: csize_t; + contentId: ptr NcmContentId; offset: S64): Result {. + cdecl, importc: "ncmContentStorageReadContentIdFile".} +## /< [2.0.0+] + +proc ncmContentStorageGetRightsIdFromPlaceHolderId*(cs: ptr NcmContentStorage; + outRightsId: ptr NcmRightsId; placeholderId: ptr NcmPlaceHolderId): Result {.cdecl, + importc: "ncmContentStorageGetRightsIdFromPlaceHolderId".} +## /< [2.0.0+] + +proc ncmContentStorageGetRightsIdFromContentId*(cs: ptr NcmContentStorage; + outRightsId: ptr NcmRightsId; contentId: ptr NcmContentId): Result {.cdecl, + importc: "ncmContentStorageGetRightsIdFromContentId".} +## /< [2.0.0+] + +proc ncmContentStorageWriteContentForDebug*(cs: ptr NcmContentStorage; + contentId: ptr NcmContentId; offset: S64; data: pointer; dataSize: csize_t): Result {. + cdecl, importc: "ncmContentStorageWriteContentForDebug".} +## /< [2.0.0+] + +proc ncmContentStorageGetFreeSpaceSize*(cs: ptr NcmContentStorage; outSize: ptr S64): Result {. + cdecl, importc: "ncmContentStorageGetFreeSpaceSize".} +## /< [2.0.0+] + +proc ncmContentStorageGetTotalSpaceSize*(cs: ptr NcmContentStorage; outSize: ptr S64): Result {. + cdecl, importc: "ncmContentStorageGetTotalSpaceSize".} +## /< [2.0.0+] + +proc ncmContentStorageFlushPlaceHolder*(cs: ptr NcmContentStorage): Result {.cdecl, + importc: "ncmContentStorageFlushPlaceHolder".} +## /< [3.0.0+] + +proc ncmContentStorageGetSizeFromPlaceHolderId*(cs: ptr NcmContentStorage; + outSize: ptr S64; placeholderId: ptr NcmPlaceHolderId): Result {.cdecl, + importc: "ncmContentStorageGetSizeFromPlaceHolderId".} +## /< [4.0.0+] + +proc ncmContentStorageRepairInvalidFileAttribute*(cs: ptr NcmContentStorage): Result {. + cdecl, importc: "ncmContentStorageRepairInvalidFileAttribute".} +## /< [4.0.0+] + +proc ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache*( + cs: ptr NcmContentStorage; outRightsId: ptr NcmRightsId; + placeholderId: ptr NcmPlaceHolderId; cacheContentId: ptr NcmContentId): Result {. + cdecl, importc: "ncmContentStorageGetRightsIdFromPlaceHolderIdWithCache".} +## /< [8.0.0+] + +proc ncmContentStorageRegisterPath*(cs: ptr NcmContentStorage; + contentId: ptr NcmContentId; path: cstring): Result {. + cdecl, importc: "ncmContentStorageRegisterPath".} +## /< [13.0.0+] + +proc ncmContentStorageClearRegisteredPath*(cs: ptr NcmContentStorage): Result {. + cdecl, importc: "ncmContentStorageClearRegisteredPath".} +## /< [13.0.0+] + +proc ncmContentMetaDatabaseClose*(db: ptr NcmContentMetaDatabase) {.cdecl, + importc: "ncmContentMetaDatabaseClose".} +proc ncmContentMetaDatabaseSet*(db: ptr NcmContentMetaDatabase; + key: ptr NcmContentMetaKey; data: pointer; + dataSize: U64): Result {.cdecl, + importc: "ncmContentMetaDatabaseSet".} +proc ncmContentMetaDatabaseGet*(db: ptr NcmContentMetaDatabase; + key: ptr NcmContentMetaKey; outSize: ptr U64; + outData: pointer; outDataSize: U64): Result {.cdecl, + importc: "ncmContentMetaDatabaseGet".} +proc ncmContentMetaDatabaseRemove*(db: ptr NcmContentMetaDatabase; + key: ptr NcmContentMetaKey): Result {.cdecl, + importc: "ncmContentMetaDatabaseRemove".} +proc ncmContentMetaDatabaseGetContentIdByType*(db: ptr NcmContentMetaDatabase; + outContentId: ptr NcmContentId; key: ptr NcmContentMetaKey; `type`: NcmContentType): Result {. + cdecl, importc: "ncmContentMetaDatabaseGetContentIdByType".} +proc ncmContentMetaDatabaseListContentInfo*(db: ptr NcmContentMetaDatabase; + outEntriesWritten: ptr S32; outInfo: ptr NcmContentInfo; count: S32; + key: ptr NcmContentMetaKey; startIndex: S32): Result {.cdecl, + importc: "ncmContentMetaDatabaseListContentInfo".} +proc ncmContentMetaDatabaseList*(db: ptr NcmContentMetaDatabase; + outEntriesTotal: ptr S32; + outEntriesWritten: ptr S32; + outKeys: ptr NcmContentMetaKey; count: S32; + metaType: NcmContentMetaType; id: U64; idMin: U64; + idMax: U64; installType: NcmContentInstallType): Result {. + cdecl, importc: "ncmContentMetaDatabaseList".} +proc ncmContentMetaDatabaseGetLatestContentMetaKey*( + db: ptr NcmContentMetaDatabase; outKey: ptr NcmContentMetaKey; id: U64): Result {. + cdecl, importc: "ncmContentMetaDatabaseGetLatestContentMetaKey".} +proc ncmContentMetaDatabaseListApplication*(db: ptr NcmContentMetaDatabase; + outEntriesTotal: ptr S32; outEntriesWritten: ptr S32; + outKeys: ptr NcmApplicationContentMetaKey; count: S32; + metaType: NcmContentMetaType): Result {.cdecl, + importc: "ncmContentMetaDatabaseListApplication".} +proc ncmContentMetaDatabaseHas*(db: ptr NcmContentMetaDatabase; `out`: ptr bool; + key: ptr NcmContentMetaKey): Result {.cdecl, + importc: "ncmContentMetaDatabaseHas".} +proc ncmContentMetaDatabaseHasAll*(db: ptr NcmContentMetaDatabase; `out`: ptr bool; + keys: ptr NcmContentMetaKey; count: S32): Result {. + cdecl, importc: "ncmContentMetaDatabaseHasAll".} +proc ncmContentMetaDatabaseGetSize*(db: ptr NcmContentMetaDatabase; + outSize: ptr U64; key: ptr NcmContentMetaKey): Result {. + cdecl, importc: "ncmContentMetaDatabaseGetSize".} +proc ncmContentMetaDatabaseGetRequiredSystemVersion*( + db: ptr NcmContentMetaDatabase; outVersion: ptr U32; key: ptr NcmContentMetaKey): Result {. + cdecl, importc: "ncmContentMetaDatabaseGetRequiredSystemVersion".} +proc ncmContentMetaDatabaseGetPatchId*(db: ptr NcmContentMetaDatabase; + outPatchId: ptr U64; + key: ptr NcmContentMetaKey): Result {.cdecl, + importc: "ncmContentMetaDatabaseGetPatchId".} +proc ncmContentMetaDatabaseDisableForcibly*(db: ptr NcmContentMetaDatabase): Result {. + cdecl, importc: "ncmContentMetaDatabaseDisableForcibly".} +proc ncmContentMetaDatabaseLookupOrphanContent*(db: ptr NcmContentMetaDatabase; + outOrphaned: ptr bool; contentIds: ptr NcmContentId; count: S32): Result {.cdecl, + importc: "ncmContentMetaDatabaseLookupOrphanContent".} +proc ncmContentMetaDatabaseCommit*(db: ptr NcmContentMetaDatabase): Result {.cdecl, + importc: "ncmContentMetaDatabaseCommit".} +proc ncmContentMetaDatabaseHasContent*(db: ptr NcmContentMetaDatabase; + `out`: ptr bool; key: ptr NcmContentMetaKey; + contentId: ptr NcmContentId): Result {.cdecl, + importc: "ncmContentMetaDatabaseHasContent".} +proc ncmContentMetaDatabaseListContentMetaInfo*(db: ptr NcmContentMetaDatabase; + outEntriesWritten: ptr S32; outMetaInfo: pointer; count: S32; + key: ptr NcmContentMetaKey; startIndex: S32): Result {.cdecl, + importc: "ncmContentMetaDatabaseListContentMetaInfo".} +proc ncmContentMetaDatabaseGetAttributes*(db: ptr NcmContentMetaDatabase; + key: ptr NcmContentMetaKey; `out`: ptr U8): Result {.cdecl, + importc: "ncmContentMetaDatabaseGetAttributes".} +proc ncmContentMetaDatabaseGetRequiredApplicationVersion*( + db: ptr NcmContentMetaDatabase; outVersion: ptr U32; key: ptr NcmContentMetaKey): Result {. + cdecl, importc: "ncmContentMetaDatabaseGetRequiredApplicationVersion".} +## /< [2.0.0+] + +proc ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset*( + db: ptr NcmContentMetaDatabase; outContentId: ptr NcmContentId; + key: ptr NcmContentMetaKey; `type`: NcmContentType; idOffset: U8): Result {.cdecl, + importc: "ncmContentMetaDatabaseGetContentIdByTypeAndIdOffset".} +## /< [5.0.0+] diff --git a/src/libnx/wrapper/switch/services/ncm_types.h b/src/libnx/wrapper/switch/services/ncm_types.h new file mode 100644 index 0000000..db12897 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ncm_types.h @@ -0,0 +1,150 @@ +/** + * @file ncm_types.h + * @brief Content Manager (ncm) service types (see ncm.h for the rest). + * @author Adubbz, zhuowei, and yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../crypto/sha256.h" + +/// StorageId +typedef enum { + NcmStorageId_None = 0, ///< None + NcmStorageId_Host = 1, ///< Host + NcmStorageId_GameCard = 2, ///< GameCard + NcmStorageId_BuiltInSystem = 3, ///< BuiltInSystem + NcmStorageId_BuiltInUser = 4, ///< BuiltInUser + NcmStorageId_SdCard = 5, ///< SdCard + NcmStorageId_Any = 6, ///< Any +} NcmStorageId; + +/// ContentType +typedef enum { + NcmContentType_Meta = 0, ///< Meta + NcmContentType_Program = 1, ///< Program + NcmContentType_Data = 2, ///< Data + NcmContentType_Control = 3, ///< Control + NcmContentType_HtmlDocument = 4, ///< HtmlDocument + NcmContentType_LegalInformation = 5, ///< LegalInformation + NcmContentType_DeltaFragment = 6, ///< DeltaFragment +} NcmContentType; + +/// ContentMetaType +typedef enum { + NcmContentMetaType_Unknown = 0x0, ///< Unknown + NcmContentMetaType_SystemProgram = 0x1, ///< SystemProgram + NcmContentMetaType_SystemData = 0x2, ///< SystemData + NcmContentMetaType_SystemUpdate = 0x3, ///< SystemUpdate + NcmContentMetaType_BootImagePackage = 0x4, ///< BootImagePackage + NcmContentMetaType_BootImagePackageSafe = 0x5, ///< BootImagePackageSafe + NcmContentMetaType_Application = 0x80, ///< Application + NcmContentMetaType_Patch = 0x81, ///< Patch + NcmContentMetaType_AddOnContent = 0x82, ///< AddOnContent + NcmContentMetaType_Delta = 0x83, ///< Delta +} NcmContentMetaType; + +/// ContentMetaAttribute +typedef enum { + NcmContentMetaAttribute_None = 0, ///< None + NcmContentMetaAttribute_IncludesExFatDriver = BIT(0), ///< IncludesExFatDriver + NcmContentMetaAttribute_Rebootless = BIT(1), ///< Rebootless +} NcmContentMetaAttribute; + +/// ContentInstallType +typedef enum { + NcmContentInstallType_Full = 0, ///< Full + NcmContentInstallType_FragmentOnly = 1, ///< FragmentOnly + NcmContentInstallType_Unknown = 7, ///< Unknown +} NcmContentInstallType; + +/// ContentId +typedef struct { + alignas(4) u8 c[0x10]; ///< Id +} NcmContentId; + +/// PlaceHolderId +typedef struct { + alignas(8) Uuid uuid; ///< UUID +} NcmPlaceHolderId; + +/// ContentMetaKey +typedef struct { + u64 id; ///< Id. + u32 version; ///< Version. + u8 type; ///< \ref NcmContentMetaType + u8 install_type; ///< \ref NcmContentInstallType + u8 padding[2]; ///< Padding. +} NcmContentMetaKey; + +/// ApplicationContentMetaKey +typedef struct { + NcmContentMetaKey key; ///< \ref NcmContentMetaKey + u64 application_id; ///< ApplicationId. +} NcmApplicationContentMetaKey; + +/// ContentInfo +typedef struct { + NcmContentId content_id; ///< \ref NcmContentId + u8 size[0x6]; ///< Content size. + u8 content_type; ///< \ref NcmContentType. + u8 id_offset; ///< Offset of this content. Unused by most applications. +} NcmContentInfo; + +/// PackagedContentInfo +typedef struct { + u8 hash[SHA256_HASH_SIZE]; + NcmContentInfo info; +} NcmPackagedContentInfo; + +/// ContentMetaInfo +typedef struct { + u64 id; ///< Id. + u32 version; ///< Version. + u8 type; ///< \ref NcmContentMetaType + u8 attr; ///< \ref NcmContentMetaAttribute + u8 padding[2]; ///< Padding. +} NcmContentMetaInfo; + +/// ContentMetaHeader +typedef struct { + u16 extended_header_size; ///< Size of optional struct that comes after this one. + u16 content_count; ///< Number of NcmContentInfos after the extra bytes. + u16 content_meta_count; ///< Number of NcmContentMetaInfos that come after the NcmContentInfos. + u8 attributes; ///< Usually None (0). + u8 storage_id; ///< Usually None (0). +} NcmContentMetaHeader; + +/// ApplicationMetaExtendedHeader +typedef struct { + u64 patch_id; ///< PatchId of this application's patch. + u32 required_system_version; ///< Firmware version required by this application. + u32 required_application_version; ///< [9.0.0+] Owner application version required by this application. Previously padding. +} NcmApplicationMetaExtendedHeader; + +/// PatchMetaExtendedHeader +typedef struct { + u64 application_id; ///< ApplicationId of this patch's corresponding application. + u32 required_system_version; ///< Firmware version required by this patch. + u32 extended_data_size; ///< Size of the extended data following the NcmContentInfos. + u8 reserved[0x8]; ///< Unused. +} NcmPatchMetaExtendedHeader; + +/// AddOnContentMetaExtendedHeader +typedef struct { + u64 application_id; ///< ApplicationId of this add-on-content's corresponding application. + u32 required_application_version; ///< Version of the application required by this add-on-content. + u32 padding; ///< Padding. +} NcmAddOnContentMetaExtendedHeader; + +/// SystemUpdateMetaExtendedHeader +typedef struct { + u32 extended_data_size; ///< Size of the extended data after NcmContentInfos and NcmContentMetaInfos. +} NcmSystemUpdateMetaExtendedHeader; + +/// ProgramLocation +typedef struct { + u64 program_id; ///< ProgramId + u8 storageID; ///< \ref NcmStorageId + u8 pad[7]; ///< Padding +} NcmProgramLocation; diff --git a/src/libnx/wrapper/switch/services/ncm_types.nim b/src/libnx/wrapper/switch/services/ncm_types.nim new file mode 100644 index 0000000..c571de2 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ncm_types.nim @@ -0,0 +1,186 @@ +## * +## @file ncm_types.h +## @brief Content Manager (ncm) service types (see ncm.h for the rest). +## @author Adubbz, zhuowei, and yellows8 +## @copyright libnx Authors +## + +import + ../types, ../crypto/sha256 + +## / StorageId + +type + NcmStorageId* = enum + NcmStorageIdNone = 0, ## /< None + NcmStorageIdHost = 1, ## /< Host + NcmStorageIdGameCard = 2, ## /< GameCard + NcmStorageIdBuiltInSystem = 3, ## /< BuiltInSystem + NcmStorageIdBuiltInUser = 4, ## /< BuiltInUser + NcmStorageIdSdCard = 5, ## /< SdCard + NcmStorageIdAny = 6 ## /< Any + + +## / ContentType + +type + NcmContentType* = enum + NcmContentTypeMeta = 0, ## /< Meta + NcmContentTypeProgram = 1, ## /< Program + NcmContentTypeData = 2, ## /< Data + NcmContentTypeControl = 3, ## /< Control + NcmContentTypeHtmlDocument = 4, ## /< HtmlDocument + NcmContentTypeLegalInformation = 5, ## /< LegalInformation + NcmContentTypeDeltaFragment = 6 ## /< DeltaFragment + + +## / ContentMetaType + +type + NcmContentMetaType* = enum + NcmContentMetaTypeUnknown = 0x0, ## /< Unknown + NcmContentMetaTypeSystemProgram = 0x1, ## /< SystemProgram + NcmContentMetaTypeSystemData = 0x2, ## /< SystemData + NcmContentMetaTypeSystemUpdate = 0x3, ## /< SystemUpdate + NcmContentMetaTypeBootImagePackage = 0x4, ## /< BootImagePackage + NcmContentMetaTypeBootImagePackageSafe = 0x5, ## /< BootImagePackageSafe + NcmContentMetaTypeApplication = 0x80, ## /< Application + NcmContentMetaTypePatch = 0x81, ## /< Patch + NcmContentMetaTypeAddOnContent = 0x82, ## /< AddOnContent + NcmContentMetaTypeDelta = 0x83 ## /< Delta + + +## / ContentMetaAttribute + +type + NcmContentMetaAttribute* = enum + NcmContentMetaAttributeNone = 0, ## /< None + NcmContentMetaAttributeIncludesExFatDriver = bit(0), ## /< IncludesExFatDriver + NcmContentMetaAttributeRebootless = bit(1) ## /< Rebootless + + +## / ContentInstallType + +type + NcmContentInstallType* = enum + NcmContentInstallTypeFull = 0, ## /< Full + NcmContentInstallTypeFragmentOnly = 1, ## /< FragmentOnly + NcmContentInstallTypeUnknown = 7 ## /< Unknown + + +## / ContentId + +type + NcmContentId* {.bycopy.} = object + c*: array[0x10, U8] ## /< Id + + +## / PlaceHolderId + +type + NcmPlaceHolderId* {.bycopy.} = object + uuid*: Uuid ## /< UUID + + +## / ContentMetaKey + +type + NcmContentMetaKey* {.bycopy.} = object + id*: U64 ## /< Id. + version*: U32 ## /< Version. + `type`*: U8 ## /< \ref NcmContentMetaType + installType*: U8 ## /< \ref NcmContentInstallType + padding*: array[2, U8] ## /< Padding. + + +## / ApplicationContentMetaKey + +type + NcmApplicationContentMetaKey* {.bycopy.} = object + key*: NcmContentMetaKey ## /< \ref NcmContentMetaKey + applicationId*: U64 ## /< ApplicationId. + + +## / ContentInfo + +type + NcmContentInfo* {.bycopy.} = object + contentId*: NcmContentId ## /< \ref NcmContentId + size*: array[0x6, U8] ## /< Content size. + contentType*: U8 ## /< \ref NcmContentType. + idOffset*: U8 ## /< Offset of this content. Unused by most applications. + + +## / PackagedContentInfo + +type + NcmPackagedContentInfo* {.bycopy.} = object + hash*: array[Sha256Hash_Size, U8] + info*: NcmContentInfo + + +## / ContentMetaInfo + +type + NcmContentMetaInfo* {.bycopy.} = object + id*: U64 ## /< Id. + version*: U32 ## /< Version. + `type`*: U8 ## /< \ref NcmContentMetaType + attr*: U8 ## /< \ref NcmContentMetaAttribute + padding*: array[2, U8] ## /< Padding. + + +## / ContentMetaHeader + +type + NcmContentMetaHeader* {.bycopy.} = object + extendedHeaderSize*: U16 ## /< Size of optional struct that comes after this one. + contentCount*: U16 ## /< Number of NcmContentInfos after the extra bytes. + contentMetaCount*: U16 ## /< Number of NcmContentMetaInfos that come after the NcmContentInfos. + attributes*: U8 ## /< Usually None (0). + storageId*: U8 ## /< Usually None (0). + + +## / ApplicationMetaExtendedHeader + +type + NcmApplicationMetaExtendedHeader* {.bycopy.} = object + patchId*: U64 ## /< PatchId of this application's patch. + requiredSystemVersion*: U32 ## /< Firmware version required by this application. + requiredApplicationVersion*: U32 ## /< [9.0.0+] Owner application version required by this application. Previously padding. + + +## / PatchMetaExtendedHeader + +type + NcmPatchMetaExtendedHeader* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId of this patch's corresponding application. + requiredSystemVersion*: U32 ## /< Firmware version required by this patch. + extendedDataSize*: U32 ## /< Size of the extended data following the NcmContentInfos. + reserved*: array[0x8, U8] ## /< Unused. + + +## / AddOnContentMetaExtendedHeader + +type + NcmAddOnContentMetaExtendedHeader* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId of this add-on-content's corresponding application. + requiredApplicationVersion*: U32 ## /< Version of the application required by this add-on-content. + padding*: U32 ## /< Padding. + + +## / SystemUpdateMetaExtendedHeader + +type + NcmSystemUpdateMetaExtendedHeader* {.bycopy.} = object + extendedDataSize*: U32 ## /< Size of the extended data after NcmContentInfos and NcmContentMetaInfos. + + +## / ProgramLocation + +type + NcmProgramLocation* {.bycopy.} = object + programId*: U64 ## /< ProgramId + storageID*: U8 ## /< \ref NcmStorageId + pad*: array[7, U8] ## /< Padding + diff --git a/src/libnx/wrapper/switch/services/news.h b/src/libnx/wrapper/switch/services/news.h new file mode 100644 index 0000000..33efd87 --- /dev/null +++ b/src/libnx/wrapper/switch/services/news.h @@ -0,0 +1,109 @@ +/** + * @file news.h + * @brief News service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ + +#pragma once + +#include "../kernel/event.h" +#include "../services/acc.h" +#include "../sf/service.h" +#include "../types.h" + +typedef enum { + NewsServiceType_Administrator = 0, ///< Initializes news:a + NewsServiceType_Configuration = 1, ///< Initializes news:c + NewsServiceType_Manager = 2, ///< Initializes news:m + NewsServiceType_Post = 3, ///< Initializes news:p + NewsServiceType_Viewer = 4, ///< Initializes news:v + + NewsServiceType_Count +} NewsServiceType; + +typedef struct { + char name[0x20]; +} NewsTopicName; + +typedef struct { + Service s; +} NewsNewlyArrivedEventHolder; + +typedef struct { + Service s; +} NewsDataService; + +typedef struct { + Service s; +} NewsDatabaseService; + +typedef struct { + Service s; +} NewsOverwriteEventHolder; + +typedef struct { + char news_id[0x18]; + char user_id[0x18]; + s64 received_at; + s32 read; + s32 newly; + s32 displayed; +} NewsRecordV1; + +typedef struct { + char news_id[0x18]; + char user_id[0x18]; + NewsTopicName topic_id; + s64 received_at; + s64 pad_0; + s32 decoration_type; + s32 read; + s32 newly; + s32 displayed; + s32 feedback; + s32 pad_1; + s32 extra_1; + s32 extra_2; +} NewsRecord; + +Result newsInitialize(NewsServiceType service_type); +void newsExit(void); + +Service *newsGetServiceSession(void); + +Result newsCreateNewlyArrivedEventHolder(NewsNewlyArrivedEventHolder *out); +Result newsCreateNewsDataService(NewsDataService *out); +Result newsCreateNewsDatabaseService(NewsDatabaseService *out); +Result newsCreateOverwriteEventHolder(NewsOverwriteEventHolder *out); ///< [2.0.0+] + +Result newsPostLocalNews(const void *news, size_t size); +Result newsSetPassphrase(u64 program_id, const char *passphrase); +Result newsGetSubscriptionStatus(const char *filter, u32 *status); +Result newsGetTopicList(u32 channel, u32 *out_count, NewsTopicName *out, u32 max_count); ///< [3.0.0+] +Result newsGetSavedataUsage(u64 *current, u64 *total); ///< [6.0.0+] +Result newsIsSystemUpdateRequired(bool *out); +Result newsGetDatabaseVersion(u32 *version); ///< [10.0.0+] +Result newsRequestImmediateReception(const char *filter); +Result newsSetSubscriptionStatus(const char *filter, u32 status); +Result newsClearStorage(void); +Result newsClearSubscriptionStatusAll(void); +Result newsGetNewsDatabaseDump(void *buffer, u64 size, u64 *out); + +void newsNewlyArrivedEventHolderClose(NewsNewlyArrivedEventHolder *srv); +Result newsNewlyArrivedEventHolderGet(NewsNewlyArrivedEventHolder *srv, Event *out); + +void newsDataClose(NewsDataService *srv); +Result newsDataOpen(NewsDataService *srv, const char *file_name); +Result newsDataOpenWithNewsRecordV1(NewsDataService *srv, NewsRecordV1 *record); +Result newsDataRead(NewsDataService *srv, u64 *bytes_read, u64 offset, void *out, size_t out_size); +Result newsDataGetSize(NewsDataService *srv, u64 *size); +Result newsDataOpenWithNewsRecord(NewsDataService *srv, NewsRecord *record); ///< [6.0.0+] + +void newsDatabaseClose(NewsDatabaseService *srv); +Result newsDatabaseGetListV1(NewsDatabaseService *srv, NewsRecordV1 *out, u32 max_count, const char *where, const char *order, u32 *count, u32 offset); +Result newsDatabaseCount(NewsDatabaseService *srv, const char *filter, u32 *count); +Result newsDatabaseGetList(NewsDatabaseService *srv, NewsRecord *out, u32 max_count, const char *where, const char *order, u32 *count, u32 offset); ///< [6.0.0+] + +void newsOverwriteEventHolderClose(NewsOverwriteEventHolder *srv); +Result newsOverwriteEventHolderGet(NewsOverwriteEventHolder *srv, Event *out); diff --git a/src/libnx/wrapper/switch/services/news.nim b/src/libnx/wrapper/switch/services/news.nim new file mode 100644 index 0000000..bdccd61 --- /dev/null +++ b/src/libnx/wrapper/switch/services/news.nim @@ -0,0 +1,140 @@ +## * +## @file news.h +## @brief News service IPC wrapper. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../kernel/event, ../sf/service, ../types + +type + NewsServiceType* = enum + NewsServiceTypeAdministrator = 0, ## /< Initializes news:a + NewsServiceTypeConfiguration = 1, ## /< Initializes news:c + NewsServiceTypeManager = 2, ## /< Initializes news:m + NewsServiceTypePost = 3, ## /< Initializes news:p + NewsServiceTypeViewer = 4, ## /< Initializes news:v + NewsServiceTypeCount + NewsTopicName* {.bycopy.} = object + name*: array[0x20, char] + + NewsNewlyArrivedEventHolder* {.bycopy.} = object + s*: Service + + NewsDataService* {.bycopy.} = object + s*: Service + + NewsDatabaseService* {.bycopy.} = object + s*: Service + + NewsOverwriteEventHolder* {.bycopy.} = object + s*: Service + + NewsRecordV1* {.bycopy.} = object + newsId*: array[0x18, char] + userId*: array[0x18, char] + receivedAt*: S64 + read*: S32 + newly*: S32 + displayed*: S32 + + NewsRecord* {.bycopy.} = object + newsId*: array[0x18, char] + userId*: array[0x18, char] + topicId*: NewsTopicName + receivedAt*: S64 + pad0*: S64 + decorationType*: S32 + read*: S32 + newly*: S32 + displayed*: S32 + feedback*: S32 + pad1*: S32 + extra1*: S32 + extra2*: S32 + + + +proc newsInitialize*(serviceType: NewsServiceType): Result {.cdecl, + importc: "newsInitialize".} +proc newsExit*() {.cdecl, importc: "newsExit".} +proc newsGetServiceSession*(): ptr Service {.cdecl, importc: "newsGetServiceSession".} +proc newsCreateNewlyArrivedEventHolder*(`out`: ptr NewsNewlyArrivedEventHolder): Result {. + cdecl, importc: "newsCreateNewlyArrivedEventHolder".} +proc newsCreateNewsDataService*(`out`: ptr NewsDataService): Result {.cdecl, + importc: "newsCreateNewsDataService".} +proc newsCreateNewsDatabaseService*(`out`: ptr NewsDatabaseService): Result {.cdecl, + importc: "newsCreateNewsDatabaseService".} +proc newsCreateOverwriteEventHolder*(`out`: ptr NewsOverwriteEventHolder): Result {. + cdecl, importc: "newsCreateOverwriteEventHolder".} +## /< [2.0.0+] + +proc newsPostLocalNews*(news: pointer; size: csize_t): Result {.cdecl, + importc: "newsPostLocalNews".} +proc newsSetPassphrase*(programId: U64; passphrase: cstring): Result {.cdecl, + importc: "newsSetPassphrase".} +proc newsGetSubscriptionStatus*(filter: cstring; status: ptr U32): Result {.cdecl, + importc: "newsGetSubscriptionStatus".} +proc newsGetTopicList*(channel: U32; outCount: ptr U32; `out`: ptr NewsTopicName; + maxCount: U32): Result {.cdecl, importc: "newsGetTopicList".} +## /< [3.0.0+] + +proc newsGetSavedataUsage*(current: ptr U64; total: ptr U64): Result {.cdecl, + importc: "newsGetSavedataUsage".} +## /< [6.0.0+] + +proc newsIsSystemUpdateRequired*(`out`: ptr bool): Result {.cdecl, + importc: "newsIsSystemUpdateRequired".} +proc newsGetDatabaseVersion*(version: ptr U32): Result {.cdecl, + importc: "newsGetDatabaseVersion".} +## /< [10.0.0+] + +proc newsRequestImmediateReception*(filter: cstring): Result {.cdecl, + importc: "newsRequestImmediateReception".} +proc newsSetSubscriptionStatus*(filter: cstring; status: U32): Result {.cdecl, + importc: "newsSetSubscriptionStatus".} +proc newsClearStorage*(): Result {.cdecl, importc: "newsClearStorage".} +proc newsClearSubscriptionStatusAll*(): Result {.cdecl, + importc: "newsClearSubscriptionStatusAll".} +proc newsGetNewsDatabaseDump*(buffer: pointer; size: U64; `out`: ptr U64): Result {. + cdecl, importc: "newsGetNewsDatabaseDump".} +proc newsNewlyArrivedEventHolderClose*(srv: ptr NewsNewlyArrivedEventHolder) {. + cdecl, importc: "newsNewlyArrivedEventHolderClose".} +proc newsNewlyArrivedEventHolderGet*(srv: ptr NewsNewlyArrivedEventHolder; + `out`: ptr Event): Result {.cdecl, + importc: "newsNewlyArrivedEventHolderGet".} +proc newsDataClose*(srv: ptr NewsDataService) {.cdecl, importc: "newsDataClose".} +proc newsDataOpen*(srv: ptr NewsDataService; fileName: cstring): Result {.cdecl, + importc: "newsDataOpen".} +proc newsDataOpenWithNewsRecordV1*(srv: ptr NewsDataService; + record: ptr NewsRecordV1): Result {.cdecl, + importc: "newsDataOpenWithNewsRecordV1".} +proc newsDataRead*(srv: ptr NewsDataService; bytesRead: ptr U64; offset: U64; + `out`: pointer; outSize: csize_t): Result {.cdecl, + importc: "newsDataRead".} +proc newsDataGetSize*(srv: ptr NewsDataService; size: ptr U64): Result {.cdecl, + importc: "newsDataGetSize".} +proc newsDataOpenWithNewsRecord*(srv: ptr NewsDataService; record: ptr NewsRecord): Result {. + cdecl, importc: "newsDataOpenWithNewsRecord".} +## /< [6.0.0+] + +proc newsDatabaseClose*(srv: ptr NewsDatabaseService) {.cdecl, + importc: "newsDatabaseClose".} +proc newsDatabaseGetListV1*(srv: ptr NewsDatabaseService; `out`: ptr NewsRecordV1; + maxCount: U32; where: cstring; order: cstring; + count: ptr U32; offset: U32): Result {.cdecl, + importc: "newsDatabaseGetListV1".} +proc newsDatabaseCount*(srv: ptr NewsDatabaseService; filter: cstring; count: ptr U32): Result {. + cdecl, importc: "newsDatabaseCount".} +proc newsDatabaseGetList*(srv: ptr NewsDatabaseService; `out`: ptr NewsRecord; + maxCount: U32; where: cstring; order: cstring; + count: ptr U32; offset: U32): Result {.cdecl, + importc: "newsDatabaseGetList".} +## /< [6.0.0+] + +proc newsOverwriteEventHolderClose*(srv: ptr NewsOverwriteEventHolder) {.cdecl, + importc: "newsOverwriteEventHolderClose".} +proc newsOverwriteEventHolderGet*(srv: ptr NewsOverwriteEventHolder; + `out`: ptr Event): Result {.cdecl, + importc: "newsOverwriteEventHolderGet".} diff --git a/src/libnx/wrapper/switch/services/nfc.h b/src/libnx/wrapper/switch/services/nfc.h new file mode 100644 index 0000000..9d20eb4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nfc.h @@ -0,0 +1,161 @@ +/** + * @file nfc.h + * @brief Nintendo Figurine (amiibo) Platform (nfp:user) service IPC wrapper. + * @author averne + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/mii.h" + +/// NfpServiceType +typedef enum { + NfpServiceType_User = 0, ///< Initializes nfp:user. + NfpServiceType_Debug = 1, ///< Initializes nfp:dbg. + NfpServiceType_System = 2, ///< Initializes nfp:sys. +} NfpServiceType; + +/// NfcServiceType +typedef enum { + NfcServiceType_User = 0, ///< Initializes nfc:user. + NfcServiceType_System = 1, ///< Initializes nfc:sys. +} NfcServiceType; + +typedef enum { + NfpState_NonInitialized = 0, + NfpState_Initialized = 1, +} NfpState; + +typedef enum { + NfpDeviceState_Initialized = 0, + NfpDeviceState_SearchingForTag = 1, + NfpDeviceState_TagFound = 2, + NfpDeviceState_TagRemoved = 3, + NfpDeviceState_TagMounted = 4, + NfpDeviceState_Unavailable = 5, + NfpDeviceState_Finalized = 6, +} NfpDeviceState; + +typedef enum { + NfpDeviceType_Amiibo = 0, +} NfpDeviceType; + +typedef enum { + NfpMountTarget_Rom = 1, + NfpMountTarget_Ram = 2, + NfpMountTarget_All = 3, +} NfpMountTarget; + +typedef struct { + u8 uuid[10]; + u8 uuid_length; + u8 reserved1[0x15]; + u32 protocol; + u32 tag_type; + u8 reserved2[0x30]; +} PACKED NfpTagInfo; + +typedef struct { + u16 last_write_year; + u8 last_write_month; + u8 last_write_day; + u16 write_counter; + u16 version; + u32 application_area_size; + u8 reserved[0x34]; +} PACKED NfpCommonInfo; + +typedef struct { + u8 amiibo_id[0x8]; + u8 reserved[0x38]; +} PACKED NfpModelInfo; + +typedef struct { + MiiCharInfo mii; + u16 first_write_year; + u8 first_write_month; + u8 first_write_day; + char amiibo_name[10+1]; ///< utf-8, null-terminated + u8 reserved[0x99]; +} PACKED NfpRegisterInfo; + +typedef struct { + u64 version; + u64 reserved[3]; +} NfcRequiredMcuVersionData; + +/// Nfc/Nfp DeviceHandle +typedef struct { + u8 handle[0x8]; ///< Handle. +} NfcDeviceHandle; + +/// Initialize nfp:*. +Result nfpInitialize(NfpServiceType service_type); + +/// Exit nfp:*. +void nfpExit(void); + +/// Initialize nfc:*. +Result nfcInitialize(NfcServiceType service_type); + +/// Exit nfc:*. +void nfcExit(void); + +/// Gets the Service object for the actual nfp:* service session. +Service* nfpGetServiceSession(void); + +/// Gets the Service object for the interface from nfp:*. +Service* nfpGetServiceSession_Interface(void); + +/// Gets the Service object for the actual nfc:* service session. +Service* nfcGetServiceSession(void); + +/// Gets the Service object for the interface from nfc:*. +Service* nfcGetServiceSession_Interface(void); + +Result nfpListDevices(s32 *total_out, NfcDeviceHandle *out, s32 count); +Result nfpStartDetection(const NfcDeviceHandle *handle); +Result nfpStopDetection(const NfcDeviceHandle *handle); +Result nfpMount(const NfcDeviceHandle *handle, NfpDeviceType device_type, NfpMountTarget mount_target); +Result nfpUnmount(const NfcDeviceHandle *handle); + +/// Not available with ::NfpServiceType_System. +Result nfpOpenApplicationArea(const NfcDeviceHandle *handle, u32 app_id); + +/// Not available with ::NfpServiceType_System. +Result nfpGetApplicationArea(const NfcDeviceHandle *handle, void* buf, size_t buf_size); + +/// Not available with ::NfpServiceType_System. +Result nfpSetApplicationArea(const NfcDeviceHandle *handle, const void* buf, size_t buf_size); +Result nfpFlush(const NfcDeviceHandle *handle); +Result nfpRestore(const NfcDeviceHandle *handle); + +/// Not available with ::NfpServiceType_System. +Result nfpCreateApplicationArea(const NfcDeviceHandle *handle, u32 app_id, const void* buf, size_t buf_size); + +Result nfpGetTagInfo(const NfcDeviceHandle *handle, NfpTagInfo *out); +Result nfpGetRegisterInfo(const NfcDeviceHandle *handle, NfpRegisterInfo *out); +Result nfpGetCommonInfo(const NfcDeviceHandle *handle, NfpCommonInfo *out); +Result nfpGetModelInfo(const NfcDeviceHandle *handle, NfpModelInfo *out); + +/// Returned event will have autoclear off. +Result nfpAttachActivateEvent(const NfcDeviceHandle *handle, Event *out_event); +/// Returned event will have autoclear off. +Result nfpAttachDeactivateEvent(const NfcDeviceHandle *handle, Event *out_event); + +Result nfpGetState(NfpState *out); +Result nfpGetDeviceState(const NfcDeviceHandle *handle, NfpDeviceState *out); +Result nfpGetNpadId(const NfcDeviceHandle *handle, u32 *out); + +/// Returned event will have autoclear on. +/// Only available with [3.0.0+]. +Result nfpAttachAvailabilityChangeEvent(Event *out_event); + +/// This uses nfc:*. +Result nfcIsNfcEnabled(bool *out); + +Result nfcSendCommandByPassThrough(const NfcDeviceHandle *handle, u64 timeout, const void* cmd_buf, size_t cmd_buf_size, void* reply_buf, size_t reply_buf_size, u64 *out_size); +Result nfcKeepPassThroughSession(const NfcDeviceHandle *handle); +Result nfcReleasePassThroughSession(const NfcDeviceHandle *handle); diff --git a/src/libnx/wrapper/switch/services/nfc.nim b/src/libnx/wrapper/switch/services/nfc.nim new file mode 100644 index 0000000..1627dac --- /dev/null +++ b/src/libnx/wrapper/switch/services/nfc.nim @@ -0,0 +1,170 @@ +## * +## @file nfc.h +## @brief Nintendo Figurine (amiibo) Platform (nfp:user) service IPC wrapper. +## @author averne +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/mii, ../kernel/event + +## / NfpServiceType + +type + NfpServiceType* = enum + NfpServiceTypeUser = 0, ## /< Initializes nfp:user. + NfpServiceTypeDebug = 1, ## /< Initializes nfp:dbg. + NfpServiceTypeSystem = 2 ## /< Initializes nfp:sys. + + +## / NfcServiceType + +type + NfcServiceType* = enum + NfcServiceTypeUser = 0, ## /< Initializes nfc:user. + NfcServiceTypeSystem = 1 ## /< Initializes nfc:sys. + NfpState* = enum + NfpStateNonInitialized = 0, NfpStateInitialized = 1 + NfpDeviceState* = enum + NfpDeviceStateInitialized = 0, NfpDeviceStateSearchingForTag = 1, + NfpDeviceStateTagFound = 2, NfpDeviceStateTagRemoved = 3, + NfpDeviceStateTagMounted = 4, NfpDeviceStateUnavailable = 5, + NfpDeviceStateFinalized = 6 + NfpDeviceType* = enum + NfpDeviceTypeAmiibo = 0 + NfpMountTarget* = enum + NfpMountTargetRom = 1, NfpMountTargetRam = 2, NfpMountTargetAll = 3 + NfpTagInfo* {.bycopy.} = object + uuid*: array[10, U8] + uuidLength*: U8 + reserved1*: array[0x15, U8] + protocol*: U32 + tagType*: U32 + reserved2*: array[0x30, U8] + + NfpCommonInfo* {.bycopy.} = object + lastWriteYear*: U16 + lastWriteMonth*: U8 + lastWriteDay*: U8 + writeCounter*: U16 + version*: U16 + applicationAreaSize*: U32 + reserved*: array[0x34, U8] + + NfpModelInfo* {.bycopy.} = object + amiiboId*: array[0x8, U8] + reserved*: array[0x38, U8] + + NfpRegisterInfo* {.bycopy.} = object + mii*: MiiCharInfo + firstWriteYear*: U16 + firstWriteMonth*: U8 + firstWriteDay*: U8 + amiiboName*: array[10 + 1, char] ## /< utf-8, null-terminated + reserved*: array[0x99, U8] + + NfcRequiredMcuVersionData* {.bycopy.} = object + version*: U64 + reserved*: array[3, U64] + + + + + + + +## / Nfc/Nfp DeviceHandle + +type + NfcDeviceHandle* {.bycopy.} = object + handle*: array[0x8, U8] ## /< Handle. + +proc nfpInitialize*(serviceType: NfpServiceType): Result {.cdecl, + importc: "nfpInitialize".} +## / Initialize nfp:*. +proc nfpExit*() {.cdecl, importc: "nfpExit".} +## / Exit nfp:*. +proc nfcInitialize*(serviceType: NfcServiceType): Result {.cdecl, + importc: "nfcInitialize".} +## / Initialize nfc:*. +proc nfcExit*() {.cdecl, importc: "nfcExit".} +## / Exit nfc:*. +proc nfpGetServiceSession*(): ptr Service {.cdecl, importc: "nfpGetServiceSession".} +## / Gets the Service object for the actual nfp:* service session. +proc nfpGetServiceSessionInterface*(): ptr Service {.cdecl, + importc: "nfpGetServiceSession_Interface".} +## / Gets the Service object for the interface from nfp:*. +proc nfcGetServiceSession*(): ptr Service {.cdecl, importc: "nfcGetServiceSession".} +## / Gets the Service object for the actual nfc:* service session. +proc nfcGetServiceSessionInterface*(): ptr Service {.cdecl, + importc: "nfcGetServiceSession_Interface".} +## / Gets the Service object for the interface from nfc:*. + +proc nfpListDevices*(totalOut: ptr S32; `out`: ptr NfcDeviceHandle; count: S32): Result {. + cdecl, importc: "nfpListDevices".} +proc nfpStartDetection*(handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfpStartDetection".} +proc nfpStopDetection*(handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfpStopDetection".} +proc nfpMount*(handle: ptr NfcDeviceHandle; deviceType: NfpDeviceType; + mountTarget: NfpMountTarget): Result {.cdecl, importc: "nfpMount".} +proc nfpUnmount*(handle: ptr NfcDeviceHandle): Result {.cdecl, importc: "nfpUnmount".} + +proc nfpOpenApplicationArea*(handle: ptr NfcDeviceHandle; appId: U32): Result {.cdecl, + importc: "nfpOpenApplicationArea".} +## / Not available with ::NfpServiceType_System. + +proc nfpGetApplicationArea*(handle: ptr NfcDeviceHandle; buf: pointer; + bufSize: csize_t): Result {.cdecl, + importc: "nfpGetApplicationArea".} +## / Not available with ::NfpServiceType_System. + +proc nfpSetApplicationArea*(handle: ptr NfcDeviceHandle; buf: pointer; + bufSize: csize_t): Result {.cdecl, + importc: "nfpSetApplicationArea".} +## / Not available with ::NfpServiceType_System. +proc nfpFlush*(handle: ptr NfcDeviceHandle): Result {.cdecl, importc: "nfpFlush".} +proc nfpRestore*(handle: ptr NfcDeviceHandle): Result {.cdecl, importc: "nfpRestore".} + +proc nfpCreateApplicationArea*(handle: ptr NfcDeviceHandle; appId: U32; buf: pointer; + bufSize: csize_t): Result {.cdecl, + importc: "nfpCreateApplicationArea".} +## / Not available with ::NfpServiceType_System. +proc nfpGetTagInfo*(handle: ptr NfcDeviceHandle; `out`: ptr NfpTagInfo): Result {.cdecl, + importc: "nfpGetTagInfo".} +proc nfpGetRegisterInfo*(handle: ptr NfcDeviceHandle; `out`: ptr NfpRegisterInfo): Result {. + cdecl, importc: "nfpGetRegisterInfo".} +proc nfpGetCommonInfo*(handle: ptr NfcDeviceHandle; `out`: ptr NfpCommonInfo): Result {. + cdecl, importc: "nfpGetCommonInfo".} +proc nfpGetModelInfo*(handle: ptr NfcDeviceHandle; `out`: ptr NfpModelInfo): Result {. + cdecl, importc: "nfpGetModelInfo".} + +proc nfpAttachActivateEvent*(handle: ptr NfcDeviceHandle; outEvent: ptr Event): Result {. + cdecl, importc: "nfpAttachActivateEvent".} +## / Returned event will have autoclear off. + +proc nfpAttachDeactivateEvent*(handle: ptr NfcDeviceHandle; outEvent: ptr Event): Result {. + cdecl, importc: "nfpAttachDeactivateEvent".} +## / Returned event will have autoclear off. +proc nfpGetState*(`out`: ptr NfpState): Result {.cdecl, importc: "nfpGetState".} +proc nfpGetDeviceState*(handle: ptr NfcDeviceHandle; `out`: ptr NfpDeviceState): Result {. + cdecl, importc: "nfpGetDeviceState".} +proc nfpGetNpadId*(handle: ptr NfcDeviceHandle; `out`: ptr U32): Result {.cdecl, + importc: "nfpGetNpadId".} + +proc nfpAttachAvailabilityChangeEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nfpAttachAvailabilityChangeEvent".} +## / Returned event will have autoclear on. +## / Only available with [3.0.0+]. + +proc nfcIsNfcEnabled*(`out`: ptr bool): Result {.cdecl, importc: "nfcIsNfcEnabled".} +## / This uses nfc:*. +proc nfcSendCommandByPassThrough*(handle: ptr NfcDeviceHandle; timeout: U64; + cmdBuf: pointer; cmdBufSize: csize_t; + replyBuf: pointer; replyBufSize: csize_t; + outSize: ptr U64): Result {.cdecl, + importc: "nfcSendCommandByPassThrough".} +proc nfcKeepPassThroughSession*(handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfcKeepPassThroughSession".} +proc nfcReleasePassThroughSession*(handle: ptr NfcDeviceHandle): Result {.cdecl, + importc: "nfcReleasePassThroughSession".} diff --git a/src/libnx/wrapper/switch/services/nifm.h b/src/libnx/wrapper/switch/services/nifm.h new file mode 100644 index 0000000..30a71e8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nifm.h @@ -0,0 +1,321 @@ +/** + * @file nifm.h + * @brief Network interface service IPC wrapper. + * @author shadowninja108, shibboleet, exelix, yellows8 + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef enum { + NifmServiceType_User = 0, ///< Initializes nifm:u. + NifmServiceType_System = 1, ///< Initializes nifm:s. + NifmServiceType_Admin = 2, ///< Initializes nifm:a. +} NifmServiceType; + +typedef enum { + NifmInternetConnectionType_WiFi = 1, ///< Wi-Fi connection is used. + NifmInternetConnectionType_Ethernet = 2, ///< Ethernet connection is used. +} NifmInternetConnectionType; + +typedef enum { + NifmInternetConnectionStatus_ConnectingUnknown1 = 0, ///< Unknown internet connection status 1. + NifmInternetConnectionStatus_ConnectingUnknown2 = 1, ///< Unknown internet connection status 2. + NifmInternetConnectionStatus_ConnectingUnknown3 = 2, ///< Unknown internet connection status 3 (conntest?). + NifmInternetConnectionStatus_ConnectingUnknown4 = 3, ///< Unknown internet connection status 4. + NifmInternetConnectionStatus_Connected = 4, ///< Internet is connected. +} NifmInternetConnectionStatus; + +typedef enum { + NifmRequestState_Invalid = 0, ///< Error. + NifmRequestState_Unknown1 = 1, ///< Not yet submitted or error. + NifmRequestState_OnHold = 2, ///< OnHold + NifmRequestState_Available = 3, ///< Available + NifmRequestState_Unknown4 = 4, ///< Unknown + NifmRequestState_Unknown5 = 5, ///< Unknown +} NifmRequestState; + +/// Request +typedef struct { + Service s; ///< IRequest + Event event_request_state; ///< First Event from cmd GetSystemEventReadableHandles, autoclear=true. Signaled when the RequestState changes. + Event event1; ///< Second Event from cmd GetSystemEventReadableHandles. + + NifmRequestState request_state; ///< \ref NifmRequestState from the GetRequestState cmd. + Result res; ///< Result from the GetResult cmd. +} NifmRequest; + +/// ClientId +typedef struct { + u32 id; ///< ClientId +} NifmClientId; + +/// IpV4Address +typedef struct { + u8 addr[4]; ///< IPv4 address, aka struct in_addr. +} NifmIpV4Address; + +/// IpAddressSetting +typedef struct { + u8 is_automatic; ///< Whether this setting is automatic. Ignored by \ref nifmGetCurrentIpConfigInfo. + + NifmIpV4Address current_addr; ///< Current address. + NifmIpV4Address subnet_mask; ///< Subnet Mask. + NifmIpV4Address gateway; ///< Gateway. +} NifmIpAddressSetting; + +/// DnsSetting +typedef struct { + u8 is_automatic; ///< Whether this setting is automatic. Ignored by \ref nifmGetCurrentIpConfigInfo. + + NifmIpV4Address primary_dns_server; ///< Primary DNS server. + NifmIpV4Address secondary_dns_server; ///< Secondary DNS server. +} NifmDnsSetting; + +/// ProxySetting +typedef struct { + u8 enabled; ///< Enables using the proxy when set. + u8 pad; ///< Padding + u16 port; ///< Port + char server[0x64]; ///< Server string, NUL-terminated. + u8 auto_auth_enabled; ///< Enables auto-authentication when set, which uses the following two strings. + char user[0x20]; ///< User string, NUL-terminated. + char password[0x20]; ///< Password string, NUL-terminated. + u8 pad2; ///< Padding +} NifmProxySetting; + +/// IpSettingData +typedef struct { + NifmIpAddressSetting ip_address_setting; ///< \ref NifmIpAddressSetting + NifmDnsSetting dns_setting; ///< \ref NifmDnsSetting + NifmProxySetting proxy_setting; ///< \ref NifmProxySetting + u16 mtu; ///< MTU +} NifmIpSettingData; + +/// WirelessSettingData +typedef struct { + u8 ssid_len; ///< NifmSfWirelessSettingData::ssid_len + char ssid[0x21]; ///< NifmSfWirelessSettingData::ssid + u8 unk_x22; ///< NifmSfWirelessSettingData::unk_x21 + u8 pad; ///< Padding + u32 unk_x24; ///< NifmSfWirelessSettingData::unk_x22 + u32 unk_x28; ///< NifmSfWirelessSettingData::unk_x23 + u8 passphrase[0x41]; ///< NifmSfWirelessSettingData::passphrase + u8 pad2[0x3]; ///< Padding +} NifmWirelessSettingData; + +/// SfWirelessSettingData +typedef struct { + u8 ssid_len; ///< SSID length. + char ssid[0x20]; ///< SSID string. + u8 unk_x21; ///< Unknown + u8 unk_x22; ///< Unknown + u8 unk_x23; ///< Unknown + u8 passphrase[0x41]; ///< Passphrase +} NifmSfWirelessSettingData; + +/// SfNetworkProfileData. Converted to/from \ref NifmNetworkProfileData. +typedef struct { + NifmIpSettingData ip_setting_data; ///< \ref NifmIpSettingData + Uuid uuid; ///< Uuid + char network_name[0x40]; ///< NUL-terminated Network Name string. + u8 unk_x112; ///< Unknown + u8 unk_x113; ///< Unknown + u8 unk_x114; ///< Unknown + u8 unk_x115; ///< Unknown + NifmSfWirelessSettingData wireless_setting_data; ///< \ref NifmSfWirelessSettingData + u8 pad; ///< Padding +} NifmSfNetworkProfileData; + +/// NetworkProfileData. Converted from/to \ref NifmSfNetworkProfileData. +typedef struct { + Uuid uuid; ///< NifmSfNetworkProfileData::uuid + char network_name[0x40]; ///< NifmSfNetworkProfileData::network_name + u32 unk_x50; ///< NifmSfNetworkProfileData::unk_x112 + u32 unk_x54; ///< NifmSfNetworkProfileData::unk_x113 + u8 unk_x58; ///< NifmSfNetworkProfileData::unk_x114 + u8 unk_x59; ///< NifmSfNetworkProfileData::unk_x115 + u8 pad[2]; ///< Padding + NifmWirelessSettingData wireless_setting_data; ///< \ref NifmWirelessSettingData + NifmIpSettingData ip_setting_data; ///< \ref NifmIpSettingData +} NifmNetworkProfileData; + +/// Initialize nifm. This is used automatically by gethostid(). +Result nifmInitialize(NifmServiceType service_type); + +/// Exit nifm. This is used automatically by gethostid(). +void nifmExit(void); + +/// Gets the Service object for the actual nifm:* service session. +Service* nifmGetServiceSession_StaticService(void); + +/// Gets the Service object for IGeneralService. +Service* nifmGetServiceSession_GeneralService(void); + +/** + * @brief GetClientId + */ +NifmClientId nifmGetClientId(void); + +/** + * @brief CreateRequest + * @param[out] r \ref NifmRequest + * @param[in] autoclear Event autoclear to use for NifmRequest::event1, a default of true can be used for this. + */ +Result nifmCreateRequest(NifmRequest* r, bool autoclear); + +/** + * @brief GetCurrentNetworkProfile + * @param[out] profile \ref NifmNetworkProfileData + */ +Result nifmGetCurrentNetworkProfile(NifmNetworkProfileData *profile); + +/** + * @brief GetNetworkProfile + * @param[in] uuid Uuid + * @param[out] profile \ref NifmNetworkProfileData + */ +Result nifmGetNetworkProfile(Uuid uuid, NifmNetworkProfileData *profile); + +/** + * @brief SetNetworkProfile + * @note Only available with ::NifmServiceType_Admin. + * @param[in] profile \ref NifmNetworkProfileData + * @param[out] uuid Uuid + */ +Result nifmSetNetworkProfile(const NifmNetworkProfileData *profile, Uuid *uuid); + +/** + * @brief GetCurrentIpAddress + * @param[out] out IPv4 address (struct in_addr). + */ +Result nifmGetCurrentIpAddress(u32* out); + +/** + * @brief GetCurrentIpConfigInfo + * @param[out] current_addr Same as \ref nifmGetCurrentIpAddress output. + * @param[out] subnet_mask Subnet Mask (struct in_addr). + * @param[out] gateway Gateway (struct in_addr). + * @param[out] primary_dns_server Primary DNS server IPv4 address (struct in_addr). + * @param[out] secondary_dns_server Secondary DNS server IPv4 address (struct in_addr). + */ +Result nifmGetCurrentIpConfigInfo(u32 *current_addr, u32 *subnet_mask, u32 *gateway, u32 *primary_dns_server, u32 *secondary_dns_server); + +/** + * @note Works only if called from nifm:a or nifm:s. + */ +Result nifmSetWirelessCommunicationEnabled(bool enable); + +Result nifmIsWirelessCommunicationEnabled(bool* out); + +/** + * @note Will fail with 0xd46ed if Internet is neither connecting or connected (airplane mode or no known network in reach). + * @param wifiStrength Strength of the Wi-Fi signal in number of bars from 0 to 3. + */ +Result nifmGetInternetConnectionStatus(NifmInternetConnectionType* connectionType, u32* wifiStrength, NifmInternetConnectionStatus* connectionStatus); + +Result nifmIsEthernetCommunicationEnabled(bool* out); + +/** + * @brief IsAnyInternetRequestAccepted + * @param[in] id \ref NifmClientId + */ +bool nifmIsAnyInternetRequestAccepted(NifmClientId id); + +Result nifmIsAnyForegroundRequestAccepted(bool* out); +Result nifmPutToSleep(void); +Result nifmWakeUp(void); + +/** + * @brief SetWowlDelayedWakeTime + * @note Only available with ::NifmServiceType_System or ::NifmServiceType_Admin. + * @note Only available on [9.0.0+]. + * @param[in] val Input value. + */ +Result nifmSetWowlDelayedWakeTime(s32 val); + +///@name IRequest +///@{ + +/** + * @brief Close a \ref NifmRequest. + * @param r \ref NifmRequest + */ +void nifmRequestClose(NifmRequest* r); + +/** + * @brief GetRequestState + * @param r \ref NifmRequest + * @param[out] out \ref NifmRequestState + */ +Result nifmGetRequestState(NifmRequest* r, NifmRequestState *out); + +/** + * @brief GetResult + * @param r \ref NifmRequest + */ +Result nifmGetResult(NifmRequest* r); + +/** + * @brief Cancel + * @param r \ref NifmRequest + */ +Result nifmRequestCancel(NifmRequest* r); + +/** + * @brief Submit + * @param r \ref NifmRequest + */ +Result nifmRequestSubmit(NifmRequest* r); + +/** + * @brief SubmitAndWait + * @param r \ref NifmRequest + */ +Result nifmRequestSubmitAndWait(NifmRequest* r); + +/** + * @brief GetAppletInfo + * @note This is used by \ref nifmLaHandleNetworkRequestResult. + * @param r \ref NifmRequest + * @param[in] theme_color ThemeColor + * @param[out] buffer Output buffer for storage data. + * @param[in] size Output buffer size. + * @param[out] applet_id \ref AppletId + * @param[out] mode \ref LibAppletMode + * @param[out] out_size Total data size written to the output buffer. + */ +Result nifmRequestGetAppletInfo(NifmRequest* r, u32 theme_color, void* buffer, size_t size, u32 *applet_id, u32 *mode, u32 *out_size); + +/** + * @brief SetKeptInSleep + * @note Only available on [3.0.0+]. + * @note ::NifmRequestState must be ::NifmRequestState_Unknown1. + * @param r \ref NifmRequest + * @param[in] flag Flag + */ +Result nifmRequestSetKeptInSleep(NifmRequest* r, bool flag); + +/** + * @brief RegisterSocketDescriptor. Only 1 socket can be registered at a time with a NifmRequest. Do not use directly, use \ref socketNifmRequestRegisterSocketDescriptor instead. + * @note Only available on [3.0.0+]. + * @note ::NifmRequestState must be ::NifmRequestState_Available. + * @param r \ref NifmRequest + * @param[in] sockfd Socket fd + */ +Result nifmRequestRegisterSocketDescriptor(NifmRequest* r, int sockfd); + +/** + * @brief UnregisterSocketDescriptor. Do not use directly, use \ref socketNifmRequestUnregisterSocketDescriptor instead. + * @note Only available on [3.0.0+]. + * @note ::NifmRequestState must be ::NifmRequestState_Available. + * @param r \ref NifmRequest + * @param[in] sockfd Socket fd, must match the fd previously registered with \ref nifmRequestRegisterSocketDescriptor. + */ +Result nifmRequestUnregisterSocketDescriptor(NifmRequest* r, int sockfd); + +///@} + diff --git a/src/libnx/wrapper/switch/services/nifm.nim b/src/libnx/wrapper/switch/services/nifm.nim new file mode 100644 index 0000000..3af73a0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nifm.nim @@ -0,0 +1,360 @@ +## * +## @file nifm.h +## @brief Network interface service IPC wrapper. +## @author shadowninja108, shibboleet, exelix, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + NifmServiceType* = enum + NifmServiceTypeUser = 0, ## /< Initializes nifm:u. + NifmServiceTypeSystem = 1, ## /< Initializes nifm:s. + NifmServiceTypeAdmin = 2 ## /< Initializes nifm:a. + NifmInternetConnectionType* = enum + NifmInternetConnectionTypeWiFi = 1, ## /< Wi-Fi connection is used. + NifmInternetConnectionTypeEthernet = 2 ## /< Ethernet connection is used. + NifmInternetConnectionStatus* = enum + NifmInternetConnectionStatusConnectingUnknown1 = 0, ## /< Unknown internet connection status 1. + NifmInternetConnectionStatusConnectingUnknown2 = 1, ## /< Unknown internet connection status 2. + NifmInternetConnectionStatusConnectingUnknown3 = 2, ## /< Unknown internet connection status 3 (conntest?). + NifmInternetConnectionStatusConnectingUnknown4 = 3, ## /< Unknown internet connection status 4. + NifmInternetConnectionStatusConnected = 4 ## /< Internet is connected. + NifmRequestState* = enum + NifmRequestStateInvalid = 0, ## /< Error. + NifmRequestStateUnknown1 = 1, ## /< Not yet submitted or error. + NifmRequestStateOnHold = 2, ## /< OnHold + NifmRequestStateAvailable = 3, ## /< Available + NifmRequestStateUnknown4 = 4, ## /< Unknown + NifmRequestStateUnknown5 = 5 ## /< Unknown + + + + + +## / Request + +type + NifmRequest* {.bycopy.} = object + s*: Service ## /< IRequest + eventRequestState*: Event ## /< First Event from cmd GetSystemEventReadableHandles, autoclear=true. Signaled when the RequestState changes. + event1*: Event ## /< Second Event from cmd GetSystemEventReadableHandles. + requestState*: NifmRequestState ## /< \ref NifmRequestState from the GetRequestState cmd. + res*: Result ## /< Result from the GetResult cmd. + + +## / ClientId + +type + NifmClientId* {.bycopy.} = object + id*: U32 ## /< ClientId + + +## / IpV4Address + +type + NifmIpV4Address* {.bycopy.} = object + `addr`*: array[4, U8] ## /< IPv4 address, aka struct in_addr. + + +## / IpAddressSetting + +type + NifmIpAddressSetting* {.bycopy.} = object + isAutomatic*: U8 ## /< Whether this setting is automatic. Ignored by \ref nifmGetCurrentIpConfigInfo. + currentAddr*: NifmIpV4Address ## /< Current address. + subnetMask*: NifmIpV4Address ## /< Subnet Mask. + gateway*: NifmIpV4Address ## /< Gateway. + + +## / DnsSetting + +type + NifmDnsSetting* {.bycopy.} = object + isAutomatic*: U8 ## /< Whether this setting is automatic. Ignored by \ref nifmGetCurrentIpConfigInfo. + primaryDnsServer*: NifmIpV4Address ## /< Primary DNS server. + secondaryDnsServer*: NifmIpV4Address ## /< Secondary DNS server. + + +## / ProxySetting + +type + NifmProxySetting* {.bycopy.} = object + enabled*: U8 ## /< Enables using the proxy when set. + pad*: U8 ## /< Padding + port*: U16 ## /< Port + server*: array[0x64, char] ## /< Server string, NUL-terminated. + autoAuthEnabled*: U8 ## /< Enables auto-authentication when set, which uses the following two strings. + user*: array[0x20, char] ## /< User string, NUL-terminated. + password*: array[0x20, char] ## /< Password string, NUL-terminated. + pad2*: U8 ## /< Padding + + +## / IpSettingData + +type + NifmIpSettingData* {.bycopy.} = object + ipAddressSetting*: NifmIpAddressSetting ## /< \ref NifmIpAddressSetting + dnsSetting*: NifmDnsSetting ## /< \ref NifmDnsSetting + proxySetting*: NifmProxySetting ## /< \ref NifmProxySetting + mtu*: U16 ## /< MTU + + +## / WirelessSettingData + +type + NifmWirelessSettingData* {.bycopy.} = object + ssidLen*: U8 ## /< NifmSfWirelessSettingData::ssid_len + ssid*: array[0x21, char] ## /< NifmSfWirelessSettingData::ssid + unkX22*: U8 ## /< NifmSfWirelessSettingData::unk_x21 + pad*: U8 ## /< Padding + unkX24*: U32 ## /< NifmSfWirelessSettingData::unk_x22 + unkX28*: U32 ## /< NifmSfWirelessSettingData::unk_x23 + passphrase*: array[0x41, U8] ## /< NifmSfWirelessSettingData::passphrase + pad2*: array[0x3, U8] ## /< Padding + + +## / SfWirelessSettingData + +type + NifmSfWirelessSettingData* {.bycopy.} = object + ssidLen*: U8 ## /< SSID length. + ssid*: array[0x20, char] ## /< SSID string. + unkX21*: U8 ## /< Unknown + unkX22*: U8 ## /< Unknown + unkX23*: U8 ## /< Unknown + passphrase*: array[0x41, U8] ## /< Passphrase + + +## / SfNetworkProfileData. Converted to/from \ref NifmNetworkProfileData. + +type + NifmSfNetworkProfileData* {.bycopy.} = object + ipSettingData*: NifmIpSettingData ## /< \ref NifmIpSettingData + uuid*: Uuid ## /< Uuid + networkName*: array[0x40, char] ## /< NUL-terminated Network Name string. + unkX112*: U8 ## /< Unknown + unkX113*: U8 ## /< Unknown + unkX114*: U8 ## /< Unknown + unkX115*: U8 ## /< Unknown + wirelessSettingData*: NifmSfWirelessSettingData ## /< \ref NifmSfWirelessSettingData + pad*: U8 ## /< Padding + + +## / NetworkProfileData. Converted from/to \ref NifmSfNetworkProfileData. + +type + NifmNetworkProfileData* {.bycopy.} = object + uuid*: Uuid ## /< NifmSfNetworkProfileData::uuid + networkName*: array[0x40, char] ## /< NifmSfNetworkProfileData::network_name + unkX50*: U32 ## /< NifmSfNetworkProfileData::unk_x112 + unkX54*: U32 ## /< NifmSfNetworkProfileData::unk_x113 + unkX58*: U8 ## /< NifmSfNetworkProfileData::unk_x114 + unkX59*: U8 ## /< NifmSfNetworkProfileData::unk_x115 + pad*: array[2, U8] ## /< Padding + wirelessSettingData*: NifmWirelessSettingData ## /< \ref NifmWirelessSettingData + ipSettingData*: NifmIpSettingData ## /< \ref NifmIpSettingData + + +## / Initialize nifm. This is used automatically by gethostid(). + +proc nifmInitialize*(serviceType: NifmServiceType): Result {.cdecl, + importc: "nifmInitialize".} +## / Exit nifm. This is used automatically by gethostid(). + +proc nifmExit*() {.cdecl, importc: "nifmExit".} +## / Gets the Service object for the actual nifm:* service session. + +proc nifmGetServiceSessionStaticService*(): ptr Service {.cdecl, + importc: "nifmGetServiceSession_StaticService".} +## / Gets the Service object for IGeneralService. + +proc nifmGetServiceSessionGeneralService*(): ptr Service {.cdecl, + importc: "nifmGetServiceSession_GeneralService".} +## * +## @brief GetClientId +## + +proc nifmGetClientId*(): NifmClientId {.cdecl, importc: "nifmGetClientId".} +## * +## @brief CreateRequest +## @param[out] r \ref NifmRequest +## @param[in] autoclear Event autoclear to use for NifmRequest::event1, a default of true can be used for this. +## + +proc nifmCreateRequest*(r: ptr NifmRequest; autoclear: bool): Result {.cdecl, + importc: "nifmCreateRequest".} +## * +## @brief GetCurrentNetworkProfile +## @param[out] profile \ref NifmNetworkProfileData +## + +proc nifmGetCurrentNetworkProfile*(profile: ptr NifmNetworkProfileData): Result {. + cdecl, importc: "nifmGetCurrentNetworkProfile".} +## * +## @brief GetNetworkProfile +## @param[in] uuid Uuid +## @param[out] profile \ref NifmNetworkProfileData +## + +proc nifmGetNetworkProfile*(uuid: Uuid; profile: ptr NifmNetworkProfileData): Result {. + cdecl, importc: "nifmGetNetworkProfile".} +## * +## @brief SetNetworkProfile +## @note Only available with ::NifmServiceType_Admin. +## @param[in] profile \ref NifmNetworkProfileData +## @param[out] uuid Uuid +## + +proc nifmSetNetworkProfile*(profile: ptr NifmNetworkProfileData; uuid: ptr Uuid): Result {. + cdecl, importc: "nifmSetNetworkProfile".} +## * +## @brief GetCurrentIpAddress +## @param[out] out IPv4 address (struct in_addr). +## + +proc nifmGetCurrentIpAddress*(`out`: ptr U32): Result {.cdecl, + importc: "nifmGetCurrentIpAddress".} +## * +## @brief GetCurrentIpConfigInfo +## @param[out] current_addr Same as \ref nifmGetCurrentIpAddress output. +## @param[out] subnet_mask Subnet Mask (struct in_addr). +## @param[out] gateway Gateway (struct in_addr). +## @param[out] primary_dns_server Primary DNS server IPv4 address (struct in_addr). +## @param[out] secondary_dns_server Secondary DNS server IPv4 address (struct in_addr). +## + +proc nifmGetCurrentIpConfigInfo*(currentAddr: ptr U32; subnetMask: ptr U32; + gateway: ptr U32; primaryDnsServer: ptr U32; + secondaryDnsServer: ptr U32): Result {.cdecl, + importc: "nifmGetCurrentIpConfigInfo".} +## * +## @note Works only if called from nifm:a or nifm:s. +## + +proc nifmSetWirelessCommunicationEnabled*(enable: bool): Result {.cdecl, + importc: "nifmSetWirelessCommunicationEnabled".} +proc nifmIsWirelessCommunicationEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "nifmIsWirelessCommunicationEnabled".} +## * +## @note Will fail with 0xd46ed if Internet is neither connecting or connected (airplane mode or no known network in reach). +## @param wifiStrength Strength of the Wi-Fi signal in number of bars from 0 to 3. +## + +proc nifmGetInternetConnectionStatus*(connectionType: ptr NifmInternetConnectionType; + wifiStrength: ptr U32; connectionStatus: ptr NifmInternetConnectionStatus): Result {. + cdecl, importc: "nifmGetInternetConnectionStatus".} +proc nifmIsEthernetCommunicationEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "nifmIsEthernetCommunicationEnabled".} +## * +## @brief IsAnyInternetRequestAccepted +## @param[in] id \ref NifmClientId +## + +proc nifmIsAnyInternetRequestAccepted*(id: NifmClientId): bool {.cdecl, + importc: "nifmIsAnyInternetRequestAccepted".} +proc nifmIsAnyForegroundRequestAccepted*(`out`: ptr bool): Result {.cdecl, + importc: "nifmIsAnyForegroundRequestAccepted".} +proc nifmPutToSleep*(): Result {.cdecl, importc: "nifmPutToSleep".} +proc nifmWakeUp*(): Result {.cdecl, importc: "nifmWakeUp".} +## * +## @brief SetWowlDelayedWakeTime +## @note Only available with ::NifmServiceType_System or ::NifmServiceType_Admin. +## @note Only available on [9.0.0+]. +## @param[in] val Input value. +## + +proc nifmSetWowlDelayedWakeTime*(val: S32): Result {.cdecl, + importc: "nifmSetWowlDelayedWakeTime".} +## /@name IRequest +## /@{ +## * +## @brief Close a \ref NifmRequest. +## @param r \ref NifmRequest +## + +proc nifmRequestClose*(r: ptr NifmRequest) {.cdecl, importc: "nifmRequestClose".} +## * +## @brief GetRequestState +## @param r \ref NifmRequest +## @param[out] out \ref NifmRequestState +## + +proc nifmGetRequestState*(r: ptr NifmRequest; `out`: ptr NifmRequestState): Result {. + cdecl, importc: "nifmGetRequestState".} +## * +## @brief GetResult +## @param r \ref NifmRequest +## + +proc nifmGetResult*(r: ptr NifmRequest): Result {.cdecl, importc: "nifmGetResult".} +## * +## @brief Cancel +## @param r \ref NifmRequest +## + +proc nifmRequestCancel*(r: ptr NifmRequest): Result {.cdecl, + importc: "nifmRequestCancel".} +## * +## @brief Submit +## @param r \ref NifmRequest +## + +proc nifmRequestSubmit*(r: ptr NifmRequest): Result {.cdecl, + importc: "nifmRequestSubmit".} +## * +## @brief SubmitAndWait +## @param r \ref NifmRequest +## + +proc nifmRequestSubmitAndWait*(r: ptr NifmRequest): Result {.cdecl, + importc: "nifmRequestSubmitAndWait".} +## * +## @brief GetAppletInfo +## @note This is used by \ref nifmLaHandleNetworkRequestResult. +## @param r \ref NifmRequest +## @param[in] theme_color ThemeColor +## @param[out] buffer Output buffer for storage data. +## @param[in] size Output buffer size. +## @param[out] applet_id \ref AppletId +## @param[out] mode \ref LibAppletMode +## @param[out] out_size Total data size written to the output buffer. +## + +proc nifmRequestGetAppletInfo*(r: ptr NifmRequest; themeColor: U32; buffer: pointer; + size: csize_t; appletId: ptr U32; mode: ptr U32; + outSize: ptr U32): Result {.cdecl, + importc: "nifmRequestGetAppletInfo".} +## * +## @brief SetKeptInSleep +## @note Only available on [3.0.0+]. +## @note ::NifmRequestState must be ::NifmRequestState_Unknown1. +## @param r \ref NifmRequest +## @param[in] flag Flag +## + +proc nifmRequestSetKeptInSleep*(r: ptr NifmRequest; flag: bool): Result {.cdecl, + importc: "nifmRequestSetKeptInSleep".} +## * +## @brief RegisterSocketDescriptor. Only 1 socket can be registered at a time with a NifmRequest. Do not use directly, use \ref socketNifmRequestRegisterSocketDescriptor instead. +## @note Only available on [3.0.0+]. +## @note ::NifmRequestState must be ::NifmRequestState_Available. +## @param r \ref NifmRequest +## @param[in] sockfd Socket fd +## + +proc nifmRequestRegisterSocketDescriptor*(r: ptr NifmRequest; sockfd: cint): Result {. + cdecl, importc: "nifmRequestRegisterSocketDescriptor".} +## * +## @brief UnregisterSocketDescriptor. Do not use directly, use \ref socketNifmRequestUnregisterSocketDescriptor instead. +## @note Only available on [3.0.0+]. +## @note ::NifmRequestState must be ::NifmRequestState_Available. +## @param r \ref NifmRequest +## @param[in] sockfd Socket fd, must match the fd previously registered with \ref nifmRequestRegisterSocketDescriptor. +## + +proc nifmRequestUnregisterSocketDescriptor*(r: ptr NifmRequest; sockfd: cint): Result {. + cdecl, importc: "nifmRequestUnregisterSocketDescriptor".} +## /@} diff --git a/src/libnx/wrapper/switch/services/nim.h b/src/libnx/wrapper/switch/services/nim.h new file mode 100644 index 0000000..615486a --- /dev/null +++ b/src/libnx/wrapper/switch/services/nim.h @@ -0,0 +1,26 @@ +/** + * @file nim.h + * @brief Network Install Manager (nim) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// SystemUpdateTaskId +typedef struct { + alignas(8) Uuid uuid; ///< UUID +} NimSystemUpdateTaskId; + +/// Initialize nim. +Result nimInitialize(void); + +/// Exit nim. +void nimExit(void); + +/// Gets the Service object for the actual nim service session. +Service* nimGetServiceSession(void); + +Result nimListSystemUpdateTask(s32 *out_count, NimSystemUpdateTaskId *out_task_ids, size_t max_task_ids); +Result nimDestroySystemUpdateTask(const NimSystemUpdateTaskId *task_id); diff --git a/src/libnx/wrapper/switch/services/nim.nim b/src/libnx/wrapper/switch/services/nim.nim new file mode 100644 index 0000000..edb7f36 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nim.nim @@ -0,0 +1,32 @@ +## * +## @file nim.h +## @brief Network Install Manager (nim) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / SystemUpdateTaskId + +type + NimSystemUpdateTaskId* {.bycopy.} = object + uuid*: Uuid ## /< UUID + + +## / Initialize nim. + +proc nimInitialize*(): Result {.cdecl, importc: "nimInitialize".} +## / Exit nim. + +proc nimExit*() {.cdecl, importc: "nimExit".} +## / Gets the Service object for the actual nim service session. + +proc nimGetServiceSession*(): ptr Service {.cdecl, importc: "nimGetServiceSession".} +proc nimListSystemUpdateTask*(outCount: ptr S32; + outTaskIds: ptr NimSystemUpdateTaskId; + maxTaskIds: csize_t): Result {.cdecl, + importc: "nimListSystemUpdateTask".} +proc nimDestroySystemUpdateTask*(taskId: ptr NimSystemUpdateTaskId): Result {.cdecl, + importc: "nimDestroySystemUpdateTask".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/notif.h b/src/libnx/wrapper/switch/services/notif.h new file mode 100644 index 0000000..210c600 --- /dev/null +++ b/src/libnx/wrapper/switch/services/notif.h @@ -0,0 +1,179 @@ +/** + * @file notif.h + * @brief Alarm notification (notif:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/applet.h" +#include "../services/acc.h" +#include "../sf/service.h" + +/// ServiceType for \ref notifInitialize. +typedef enum { + NotifServiceType_Application = 0, ///< Initializes notif:a, for Application. + NotifServiceType_System = 1, ///< Initializes notif:s, for System. +} NotifServiceType; + +/// Data extracted from NotifWeeklyScheduleAlarmSetting::settings. This uses local-time. +typedef struct { + s32 hour; ///< Hour. + s32 minute; ///< Minute. +} NotifAlarmTime; + +/// WeeklyScheduleAlarmSetting +typedef struct { + u8 unk_x0[0xa]; ///< Unknown. + s16 settings[7]; ///< Schedule settings for each day of the week, Sun-Sat. High byte is the hour, low byte is the minute. This uses local-time. +} NotifWeeklyScheduleAlarmSetting; + +/// AlarmSetting +typedef struct { + u16 alarm_setting_id; ///< AlarmSettingId + u8 kind; ///< Kind: 0 = WeeklySchedule. + u8 muted; ///< u8 bool flag for whether this AlarmSetting is muted (non-zero = AlarmSetting turned off, zero = on). + u8 pad[4]; ///< Padding. + AccountUid uid; ///< \ref AccountUid. User account associated with this AlarmSetting. Used for the preselected_user (\ref accountGetPreselectedUser) when launching the Application when the system was previously in sleep-mode, instead of launching the applet for selecting the user. + u64 application_id; ///< ApplicationId + u64 unk_x20; ///< Unknown. + NotifWeeklyScheduleAlarmSetting schedule; ///< \ref NotifWeeklyScheduleAlarmSetting +} NotifAlarmSetting; + +/// Maximum alarms that can be registered at the same time by the host Application. +#define NOTIF_MAX_ALARMS 8 + +/// Initialize notif. Only available on [9.0.0+]. +Result notifInitialize(NotifServiceType service_type); + +/// Exit notif. +void notifExit(void); + +/// Gets the Service object for the actual notif:* service session. +Service* notifGetServiceSession(void); + +/** + * @brief Creates a \ref NotifAlarmSetting. + * @note This clears the struct, with all schedule settings set the same as \ref notifAlarmSettingDisable. + * @param[out] alarm_setting \ref NotifAlarmSetting + */ +void notifAlarmSettingCreate(NotifAlarmSetting *alarm_setting); + +/** + * @brief Sets whether the \ref NotifAlarmSetting is muted. + * @note By default (\ref notifAlarmSettingCreate) this is false. + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] flag Whether the alarm is muted (true = Alarm turned off, false = on). + */ +NX_INLINE void notifAlarmSettingSetIsMuted(NotifAlarmSetting *alarm_setting, bool flag) { + alarm_setting->muted = flag!=0; +} + +/** + * @brief Sets the \ref AccountUid for the \ref NotifAlarmSetting, see NotifAlarmSetting::uid. + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] uid \ref AccountUid. If want to clear the uid after it was previously set, you can use an all-zero uid to reset to the default (\ref notifAlarmSettingCreate). + */ +NX_INLINE void notifAlarmSettingSetUid(NotifAlarmSetting *alarm_setting, AccountUid uid) { + alarm_setting->uid = uid; +} + +/** + * @brief Gets whether the schedule setting for the specified day_of_week is enabled, for the \ref NotifAlarmSetting. + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). + * @param[out] out Whether the setting is enabled. + */ +Result notifAlarmSettingIsEnabled(NotifAlarmSetting *alarm_setting, u32 day_of_week, bool *out); + +/** + * @brief Gets the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. + * @note Should not be used if the output from \ref notifAlarmSettingIsEnabled is false. + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). + * @param[out] out \ref NotifAlarmTime + */ +Result notifAlarmSettingGet(NotifAlarmSetting *alarm_setting, u32 day_of_week, NotifAlarmTime *out); + +/** + * @brief Enables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. This uses local-time. + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). + * @param[in] hour Hour. + * @param[in] minute Minute. + */ +Result notifAlarmSettingEnable(NotifAlarmSetting *alarm_setting, u32 day_of_week, s32 hour, s32 minute); + +/** + * @brief Disables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. + * @note Schedule settings are disabled by default (\ref notifAlarmSettingCreate). + * @param alarm_setting \ref NotifAlarmSetting + * @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). + */ +Result notifAlarmSettingDisable(NotifAlarmSetting *alarm_setting, u32 day_of_week); + +/** + * @brief Registers the specified AlarmSetting. + * @note See \ref NOTIF_MAX_ALARMS for the maximum alarms. + * @note When indicated by the output from \ref hidIsFirmwareUpdateNeededForNotification, this will use \ref hidLaShowControllerFirmwareUpdate. + * @param[out] alarm_setting_id AlarmSettingId + * @param[in] alarm_setting \ref NotifAlarmSetting + * @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL. + * @param[in] size Input buffer size, must be <=0x400. Optional, can be 0. + */ +Result notifRegisterAlarmSetting(u16 *alarm_setting_id, const NotifAlarmSetting *alarm_setting, const void* buffer, size_t size); + +/** + * @brief Updates the specified AlarmSetting. + * @param[in] alarm_setting \ref NotifAlarmSetting + * @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL. + * @param[in] size Input buffer size, must be <=0x400. Optional, can be 0. + */ +Result notifUpdateAlarmSetting(const NotifAlarmSetting *alarm_setting, const void* buffer, size_t size); + +/** + * @brief Gets a listing of AlarmSettings. + * @param[out] alarm_settings Output \ref NotifAlarmSetting array. + * @param[in] count Total entries in the alarm_settings array. + * @param[out] total_out Total output entries. + */ +Result notifListAlarmSettings(NotifAlarmSetting *alarm_settings, s32 count, s32 *total_out); + +/** + * @brief Loads the ApplicationParameter for the specified AlarmSetting. + * @param[in] alarm_setting_id AlarmSettingId + * @param[out] buffer Output buffer containing the ApplicationParameter. + * @param[in] size Output buffer size. + * @param[out] actual_size Actual output size. + */ +Result notifLoadApplicationParameter(u16 alarm_setting_id, void* buffer, size_t size, u32 *actual_size); + +/** + * @brief Deletes the specified AlarmSetting. + * @param[in] alarm_setting_id AlarmSettingId + */ +Result notifDeleteAlarmSetting(u16 alarm_setting_id); + +/** + * @brief Gets an Event which is signaled when data is available with \ref notifTryPopNotifiedApplicationParameter. + * @note This is a wrapper for \ref appletGetNotificationStorageChannelEvent, see that for the usage requirements. + * @note Some official apps don't use this. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +NX_INLINE Result notifGetNotificationSystemEvent(Event *out_event) { + return appletGetNotificationStorageChannelEvent(out_event); +} + +/** + * @brief Uses \ref appletTryPopFromNotificationStorageChannel then reads the data from there into the output params. + * @note This is a wrapper for \ref appletTryPopFromNotificationStorageChannel, see that for the usage requirements. + * @note The system will only push data for this when launching the Application when the Alarm was triggered, where the system was previously in sleep-mode. + * @note Some official apps don't use this. + * @param[out] buffer Output buffer. + * @param[out] size Output buffer size. + * @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL. + */ +Result notifTryPopNotifiedApplicationParameter(void* buffer, u64 size, u64 *out_size); + diff --git a/src/libnx/wrapper/switch/services/notif.nim b/src/libnx/wrapper/switch/services/notif.nim new file mode 100644 index 0000000..7b898ff --- /dev/null +++ b/src/libnx/wrapper/switch/services/notif.nim @@ -0,0 +1,209 @@ +## * +## @file notif.h +## @brief Alarm notification (notif:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/applet, ../services/acc, ../sf/service + +## / ServiceType for \ref notifInitialize. + +type + NotifServiceType* = enum + NotifServiceTypeApplication = 0, ## /< Initializes notif:a, for Application. + NotifServiceTypeSystem = 1 ## /< Initializes notif:s, for System. + + +## / Data extracted from NotifWeeklyScheduleAlarmSetting::settings. This uses local-time. + +type + NotifAlarmTime* {.bycopy.} = object + hour*: S32 ## /< Hour. + minute*: S32 ## /< Minute. + + +## / WeeklyScheduleAlarmSetting + +type + NotifWeeklyScheduleAlarmSetting* {.bycopy.} = object + unkX0*: array[0xa, U8] ## /< Unknown. + settings*: array[7, S16] ## /< Schedule settings for each day of the week, Sun-Sat. High byte is the hour, low byte is the minute. This uses local-time. + + +## / AlarmSetting + +type + NotifAlarmSetting* {.bycopy.} = object + alarmSettingId*: U16 ## /< AlarmSettingId + kind*: U8 ## /< Kind: 0 = WeeklySchedule. + muted*: U8 ## /< u8 bool flag for whether this AlarmSetting is muted (non-zero = AlarmSetting turned off, zero = on). + pad*: array[4, U8] ## /< Padding. + uid*: AccountUid ## /< \ref AccountUid. User account associated with this AlarmSetting. Used for the preselected_user (\ref accountGetPreselectedUser) when launching the Application when the system was previously in sleep-mode, instead of launching the applet for selecting the user. + applicationId*: U64 ## /< ApplicationId + unkX20*: U64 ## /< Unknown. + schedule*: NotifWeeklyScheduleAlarmSetting ## /< \ref NotifWeeklyScheduleAlarmSetting + + +## / Maximum alarms that can be registered at the same time by the host Application. + +const + NOTIF_MAX_ALARMS* = 8 +proc notifInitialize*(serviceType: NotifServiceType): Result {.cdecl, + importc: "notifInitialize".} +## / Initialize notif. Only available on [9.0.0+]. + +proc notifExit*() {.cdecl, importc: "notifExit".} +## / Exit notif. + +proc notifGetServiceSession*(): ptr Service {.cdecl, + importc: "notifGetServiceSession".} +## / Gets the Service object for the actual notif:* service session. + +proc notifAlarmSettingCreate*(alarmSetting: ptr NotifAlarmSetting) {.cdecl, + importc: "notifAlarmSettingCreate".} +## * +## @brief Creates a \ref NotifAlarmSetting. +## @note This clears the struct, with all schedule settings set the same as \ref notifAlarmSettingDisable. +## @param[out] alarm_setting \ref NotifAlarmSetting +## + +proc notifAlarmSettingSetIsMuted*(alarmSetting: ptr NotifAlarmSetting; flag: bool) {. + inline, cdecl.} = + ## * + ## @brief Sets whether the \ref NotifAlarmSetting is muted. + ## @note By default (\ref notifAlarmSettingCreate) this is false. + ## @param alarm_setting \ref NotifAlarmSetting + ## @param[in] flag Whether the alarm is muted (true = Alarm turned off, false = on). + ## + + alarmSetting.muted = flag.U8 + +proc notifAlarmSettingSetUid*(alarmSetting: ptr NotifAlarmSetting; uid: AccountUid) {. + inline, cdecl.} = + ## * + ## @brief Sets the \ref AccountUid for the \ref NotifAlarmSetting, see NotifAlarmSetting::uid. + ## @param alarm_setting \ref NotifAlarmSetting + ## @param[in] uid \ref AccountUid. If want to clear the uid after it was previously set, you can use an all-zero uid to reset to the default (\ref notifAlarmSettingCreate). + ## + + alarmSetting.uid = uid + +proc notifAlarmSettingIsEnabled*(alarmSetting: ptr NotifAlarmSetting; + dayOfWeek: U32; `out`: ptr bool): Result {.cdecl, + importc: "notifAlarmSettingIsEnabled".} +## * +## @brief Gets whether the schedule setting for the specified day_of_week is enabled, for the \ref NotifAlarmSetting. +## @param alarm_setting \ref NotifAlarmSetting +## @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). +## @param[out] out Whether the setting is enabled. +## + +proc notifAlarmSettingGet*(alarmSetting: ptr NotifAlarmSetting; dayOfWeek: U32; + `out`: ptr NotifAlarmTime): Result {.cdecl, + importc: "notifAlarmSettingGet".} +## * +## @brief Gets the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. +## @note Should not be used if the output from \ref notifAlarmSettingIsEnabled is false. +## @param alarm_setting \ref NotifAlarmSetting +## @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). +## @param[out] out \ref NotifAlarmTime +## + +proc notifAlarmSettingEnable*(alarmSetting: ptr NotifAlarmSetting; dayOfWeek: U32; + hour: S32; minute: S32): Result {.cdecl, + importc: "notifAlarmSettingEnable".} +## * +## @brief Enables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. This uses local-time. +## @param alarm_setting \ref NotifAlarmSetting +## @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). +## @param[in] hour Hour. +## @param[in] minute Minute. +## + +proc notifAlarmSettingDisable*(alarmSetting: ptr NotifAlarmSetting; dayOfWeek: U32): Result {. + cdecl, importc: "notifAlarmSettingDisable".} +## * +## @brief Disables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. +## @note Schedule settings are disabled by default (\ref notifAlarmSettingCreate). +## @param alarm_setting \ref NotifAlarmSetting +## @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat). +## + +proc notifRegisterAlarmSetting*(alarmSettingId: ptr U16; + alarmSetting: ptr NotifAlarmSetting; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "notifRegisterAlarmSetting".} +## * +## @brief Registers the specified AlarmSetting. +## @note See \ref NOTIF_MAX_ALARMS for the maximum alarms. +## @note When indicated by the output from \ref hidIsFirmwareUpdateNeededForNotification, this will use \ref hidLaShowControllerFirmwareUpdate. +## @param[out] alarm_setting_id AlarmSettingId +## @param[in] alarm_setting \ref NotifAlarmSetting +## @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL. +## @param[in] size Input buffer size, must be <=0x400. Optional, can be 0. +## + +proc notifUpdateAlarmSetting*(alarmSetting: ptr NotifAlarmSetting; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "notifUpdateAlarmSetting".} +## * +## @brief Updates the specified AlarmSetting. +## @param[in] alarm_setting \ref NotifAlarmSetting +## @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL. +## @param[in] size Input buffer size, must be <=0x400. Optional, can be 0. +## + +proc notifListAlarmSettings*(alarmSettings: ptr NotifAlarmSetting; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "notifListAlarmSettings".} +## * +## @brief Gets a listing of AlarmSettings. +## @param[out] alarm_settings Output \ref NotifAlarmSetting array. +## @param[in] count Total entries in the alarm_settings array. +## @param[out] total_out Total output entries. +## + +proc notifLoadApplicationParameter*(alarmSettingId: U16; buffer: pointer; + size: csize_t; actualSize: ptr U32): Result {. + cdecl, importc: "notifLoadApplicationParameter".} +## * +## @brief Loads the ApplicationParameter for the specified AlarmSetting. +## @param[in] alarm_setting_id AlarmSettingId +## @param[out] buffer Output buffer containing the ApplicationParameter. +## @param[in] size Output buffer size. +## @param[out] actual_size Actual output size. +## + +proc notifDeleteAlarmSetting*(alarmSettingId: U16): Result {.cdecl, + importc: "notifDeleteAlarmSetting".} +## * +## @brief Deletes the specified AlarmSetting. +## @param[in] alarm_setting_id AlarmSettingId +## + +proc notifGetNotificationSystemEvent*(outEvent: ptr Event): Result {.inline, cdecl.} = + ## * + ## @brief Gets an Event which is signaled when data is available with \ref notifTryPopNotifiedApplicationParameter. + ## @note This is a wrapper for \ref appletGetNotificationStorageChannelEvent, see that for the usage requirements. + ## @note Some official apps don't use this. + ## @note The Event must be closed by the user once finished with it. + ## @param[out] out_event Output Event with autoclear=false. + ## + + return appletGetNotificationStorageChannelEvent(outEvent) + +proc notifTryPopNotifiedApplicationParameter*(buffer: pointer; size: U64; + outSize: ptr U64): Result {.cdecl, + importc: "notifTryPopNotifiedApplicationParameter".} +## * +## @brief Uses \ref appletTryPopFromNotificationStorageChannel then reads the data from there into the output params. +## @note This is a wrapper for \ref appletTryPopFromNotificationStorageChannel, see that for the usage requirements. +## @note The system will only push data for this when launching the Application when the Alarm was triggered, where the system was previously in sleep-mode. +## @note Some official apps don't use this. +## @param[out] buffer Output buffer. +## @param[out] size Output buffer size. +## @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL. +## + diff --git a/src/libnx/wrapper/switch/services/ns.h b/src/libnx/wrapper/switch/services/ns.h new file mode 100644 index 0000000..9f6e7a3 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ns.h @@ -0,0 +1,1644 @@ +/** + * @file ns.h + * @brief NS services IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../nacp.h" +#include "../sf/service.h" +#include "../services/ncm_types.h" +#include "../services/async.h" +#include "../services/acc.h" +#include "../services/fs.h" +#include "../applets/error.h" +#include "../kernel/event.h" +#include "../kernel/tmem.h" + +/// ShellEvent +typedef enum { + NsShellEvent_None = 0, ///< None + NsShellEvent_Exit = 1, ///< Exit + NsShellEvent_Start = 2, ///< Start + NsShellEvent_Crash = 3, ///< Crash + NsShellEvent_Debug = 4, ///< Debug +} NsShellEvent; + +/// ApplicationControlSource +typedef enum { + NsApplicationControlSource_CacheOnly = 0, ///< Returns data from cache. + NsApplicationControlSource_Storage = 1, ///< Returns data from storage if not present in cache. + NsApplicationControlSource_StorageOnly = 2, ///< Returns data from storage without using cache. +} NsApplicationControlSource; + +/// BackgroundNetworkUpdateState +typedef enum { + NsBackgroundNetworkUpdateState_None = 0, ///< No sysupdate task exists. + NsBackgroundNetworkUpdateState_Downloading = 1, ///< Sysupdate download in progress. + NsBackgroundNetworkUpdateState_Ready = 2, ///< Sysupdate ready, pending install. +} NsBackgroundNetworkUpdateState; + +/// LatestSystemUpdate +typedef enum { + NsLatestSystemUpdate_Unknown0 = 0, ///< Unknown. + NsLatestSystemUpdate_Unknown1 = 1, ///< Unknown. + NsLatestSystemUpdate_Unknown2 = 2, ///< Unknown. +} NsLatestSystemUpdate; + +/// RequestServerStopper +typedef struct { + Service s; ///< IRequestServerStopper +} NsRequestServerStopper; + +/// ProgressMonitorForDeleteUserSaveDataAll +typedef struct { + Service s; ///< IProgressMonitorForDeleteUserSaveDataAll +} NsProgressMonitorForDeleteUserSaveDataAll; + +/// ProgressAsyncResult +typedef struct { + Service s; ///< IProgressAsyncResult + Event event; ///< Event with autoclear=false. +} NsProgressAsyncResult; + +/// SystemUpdateControl +typedef struct { + Service s; ///< ISystemUpdateControl + TransferMemory tmem; ///< TransferMemory for SetupCardUpdate/SetupCardUpdateViaSystemUpdater. +} NsSystemUpdateControl; + +/// ApplicationControlData +typedef struct { + NacpStruct nacp; ///< \ref NacpStruct + u8 icon[0x20000]; ///< JPEG +} NsApplicationControlData; + +/// ApplicationOccupiedSize +typedef struct { + u8 unk_x0[0x80]; ///< Unknown. +} NsApplicationOccupiedSize; + +/// NsApplicationContentMetaStatus +typedef struct { + u8 meta_type; ///< \ref NcmContentMetaType + u8 storageID; ///< \ref NcmStorageId + u8 unk_x02; ///< Unknown. + u8 padding; ///< Padding. + u32 version; ///< Application version. + u64 application_id; ///< ApplicationId. +} NsApplicationContentMetaStatus; + +/// ApplicationRecord +typedef struct { + u64 application_id; ///< ApplicationId. + u8 type; ///< Type. + u8 unk_x09; ///< Unknown. + u8 unk_x0a[6]; ///< Unknown. + u8 unk_x10; ///< Unknown. + u8 unk_x11[7]; ///< Unknown. +} NsApplicationRecord; + +/// ProgressForDeleteUserSaveDataAll +typedef struct { + u8 unk_x0[0x28]; ///< Unknown. +} NsProgressForDeleteUserSaveDataAll; + +/// ApplicationViewDeprecated. The below comments are for the \ref NsApplicationView to NsApplicationViewDeprecated conversion done by \ref nsGetApplicationViewDeprecated on newer system-versions. +typedef struct { + u64 application_id; ///< Same as NsApplicationView::application_id. + u8 unk_x8[0x4]; ///< Same as NsApplicationView::unk_x8. + u32 flags; ///< Same as NsApplicationView::flags. + u8 unk_x10[0x10]; ///< Same as NsApplicationView::unk_x10. + u32 unk_x20; ///< Same as NsApplicationView::unk_x20. + u16 unk_x24; ///< Same as NsApplicationView::unk_x24. + u8 unk_x26[0x2]; ///< Cleared to zero. + u8 unk_x28[0x10]; ///< Same as NsApplicationView::unk_x30. + u32 unk_x38; ///< Same as NsApplicationView::unk_x40. + u8 unk_x3c; ///< Same as NsApplicationView::unk_x44. + u8 unk_x3d[3]; ///< Cleared to zero. +} NsApplicationViewDeprecated; + +/// ApplicationView +typedef struct { + u64 application_id; ///< ApplicationId. + u8 unk_x8[0x4]; ///< Unknown. + u32 flags; ///< Flags. + u8 unk_x10[0x10]; ///< Unknown. + u32 unk_x20; ///< Unknown. + u16 unk_x24; ///< Unknown. + u8 unk_x26[0x2]; ///< Unknown. + u8 unk_x28[0x8]; ///< Unknown. + u8 unk_x30[0x10]; ///< Unknown. + u32 unk_x40; ///< Unknown. + u8 unk_x44; ///< Unknown. + u8 unk_x45[0xb]; ///< Unknown. +} NsApplicationView; + +/// NsPromotionInfo +typedef struct { + u64 start_timestamp; ///< POSIX timestamp for the promotion start. + u64 end_timestamp; ///< POSIX timestamp for the promotion end. + s64 remaining_time; ///< Remaining time until the promotion ends, in nanoseconds ({end_timestamp - current_time} converted to nanoseconds). + u8 unk_x18[0x4]; ///< Not set, left at zero. + u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear: remaining_time is set. + u8 pad[3]; ///< Padding. +} NsPromotionInfo; + +/// NsApplicationViewWithPromotionInfo +typedef struct { + NsApplicationView view; ///< \ref NsApplicationView + NsPromotionInfo promotion; ///< \ref NsPromotionInfo +} NsApplicationViewWithPromotionInfo; + +/// LaunchProperties +typedef struct { + u64 program_id; ///< program_id. + u32 version; ///< Program version. + u8 storageID; ///< \ref NcmStorageId + u8 index; ///< Index. + u8 is_application; ///< Whether this is an Application. +} NsLaunchProperties; + +/// ShellEventInfo +typedef struct { + NsShellEvent event; ///< \ref NsShellEvent + u64 process_id; ///< processID. +} NsShellEventInfo; + +/// SystemUpdateProgress. Commands which have this as output will return 0 with the output cleared, when no task is available. +typedef struct { + s64 current_size; ///< Current size. This value can be larger than total_size when the async operation is finishing. When total_size is <=0, this current_size field may contain a progress value for when the total_size is not yet determined. + s64 total_size; ///< Total size, this field is only valid when >0. +} NsSystemUpdateProgress; + +/// ReceiveApplicationProgress. Same as \ref NsSystemUpdateProgress, except cmds which return this will return actual errors on failure, instead of returning 0 with a cleared struct. +typedef NsSystemUpdateProgress NsReceiveApplicationProgress; + +/// SendApplicationProgress. Same as \ref NsSystemUpdateProgress, except cmds which return this will return actual errors on failure, instead of returning 0 with a cleared struct. +typedef NsSystemUpdateProgress NsSendApplicationProgress; + +/// EulaDataPath +typedef struct { + char path[0x100]; ///< Path. +} NsEulaDataPath; + +/// SystemDeliveryInfo +typedef struct { + struct { + u32 system_delivery_protocol_version; ///< Must match a system-setting. + u32 application_delivery_protocol_version; ///< Loaded from a system-setting. Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + u32 includes_exfat; ///< Whether ExFat is included. Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + u32 system_update_meta_version; ///< SystemUpdate meta version. + u64 system_update_meta_id; ///< SystemUpdate meta Id. + u8 unk_x18; ///< Copied into state by \ref nssuRequestSendSystemUpdate. + u8 unk_x19; ///< Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + u8 unk_x1a; ///< Unknown. + u8 unk_x1b[0xc5]; ///< Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + } data; ///< Data used with the below hmac. + u8 hmac[0x20]; ///< HMAC-SHA256 over the above data. +} NsSystemDeliveryInfo; + +/// ApplicationDeliveryInfo +typedef struct { + struct { + u8 unk_x0[0x10]; ///< Unknown. + u32 application_version; ///< Application version. + u32 unk_x14; ///< Unknown. + u32 required_system_version; ///< Required system version, see NsSystemDeliveryInfo::system_update_meta_version. + u32 unk_x1c; ///< Unknown. + u8 unk_x20[0xc0]; ///< Unknown. + } data; ///< Data used with the below hmac. + u8 hmac[0x20]; ///< HMAC-SHA256 over the above data. +} NsApplicationDeliveryInfo; + +/// NsApplicationRightsOnClient +typedef struct { + u64 application_id; ///< ApplicationId. + AccountUid uid; ///< \ref AccountUid + u8 flags_x18; ///< qlaunch uses bit0-bit4 and bit7 from here. + u8 flags_x19; ///< qlaunch uses bit0 from here. + u8 unk_x1a[0x6]; ///< Unknown. +} NsApplicationRightsOnClient; + +/// DownloadTaskStatus +typedef struct { + u8 unk_x0[0x20]; ///< Unknown. +} NsDownloadTaskStatus; + +/// Default size for \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater. This is the size used by qlaunch for SetupCardUpdate. +#define NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT 0x100000 + +///@name ns +///@{ + +/// Initialize ns services. Uses ns:am on pre-3.0.0, ns:am2 on [3.0.0+]. +Result nsInitialize(void); + +/// Exit ns services. +void nsExit(void); + +/// Gets the Service object for the actual ns:* service session. Only initialized on [3.0.0+], on pre-3.0.0 see \ref nsGetServiceSession_ApplicationManagerInterface. +Service* nsGetServiceSession_GetterInterface(void); + +/// Gets the Service object for IApplicationManagerInterface. Only initialized on pre-3.0.0, on [3.0.0+] use \ref nsGetApplicationManagerInterface. +Service* nsGetServiceSession_ApplicationManagerInterface(void); + +/// Gets the Service object for IDynamicRightsInterface via the cmd for that. +/// Only available on [6.0.0+]. +Result nsGetDynamicRightsInterface(Service* srv_out); + +/// Gets the Service object for IReadOnlyApplicationControlDataInterface via the cmd for that. +/// Only available on [5.1.0+]. +Result nsGetReadOnlyApplicationControlDataInterface(Service* srv_out); + +/// Gets the Service object for IReadOnlyApplicationRecordInterface via the cmd for that. +/// Only available on [5.0.0+]. +Result nsGetReadOnlyApplicationRecordInterface(Service* srv_out); + +/// Gets the Service object for IECommerceInterface via the cmd for that. +/// Only available on [4.0.0+]. +Result nsGetECommerceInterface(Service* srv_out); + +/// Gets the Service object for IApplicationVersionInterface via the cmd for that. +/// Only available on [4.0.0+]. +Result nsGetApplicationVersionInterface(Service* srv_out); + +/// Gets the Service object for IFactoryResetInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetFactoryResetInterface(Service* srv_out); + +/// Gets the Service object for IAccountProxyInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetAccountProxyInterface(Service* srv_out); + +/// Gets the Service object for IApplicationManagerInterface via the cmd for that. +/// Only available on [3.0.0+], on prior sysvers use \ref nsGetServiceSession_ApplicationManagerInterface. +Result nsGetApplicationManagerInterface(Service* srv_out); + +/// Gets the Service object for IDownloadTaskInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetDownloadTaskInterface(Service* srv_out); + +/// Gets the Service object for IContentManagementInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetContentManagementInterface(Service* srv_out); + +/// Gets the Service object for IDocumentInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetDocumentInterface(Service* srv_out); + +///@} + +///@name IReadOnlyApplicationControlDataInterface +///@{ + +/** + * @brief Gets the \ref NsApplicationControlData for the specified application. + * @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. + * @param[in] source Source, official sw uses ::NsApplicationControlSource_Storage. + * @param[in] application_id ApplicationId. + * @param[out] buffer \ref NsApplicationControlData + * @param[in] size Size of the buffer. + * @param[out] actual_size Actual output size. + */ +Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); + +/** + * @brief GetApplicationDesiredLanguage. Selects a \ref NacpLanguageEntry to use from the specified \ref NacpStruct. + * @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. + * @param[in] nacp \ref NacpStruct + * @param[out] langentry \ref NacpLanguageEntry + */ +Result nsGetApplicationDesiredLanguage(NacpStruct *nacp, NacpLanguageEntry **langentry); + +///@} + +///@name IECommerceInterface +///@{ + +/** + * @brief RequestLinkDevice + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] uid \ref AccountUid + */ +Result nsRequestLinkDevice(AsyncResult *a, AccountUid uid); + +/** + * @brief RequestSyncRights + * @note Only available on [6.0.0+]. + * @param[out] a \ref AsyncResult + */ +Result nsRequestSyncRights(AsyncResult *a); + +/** + * @brief RequestUnlinkDevice + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [6.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] uid \ref AccountUid + */ +Result nsRequestUnlinkDevice(AsyncResult *a, AccountUid uid); + +///@} + +///@name IFactoryResetInterface +///@{ + +/** + * @brief ResetToFactorySettings + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsResetToFactorySettings(void); + +/** + * @brief ResetToFactorySettingsWithoutUserSaveData + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsResetToFactorySettingsWithoutUserSaveData(void); + +/** + * @brief ResetToFactorySettingsForRefurbishment + * @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsResetToFactorySettingsForRefurbishment(void); + +/** + * @brief ResetToFactorySettingsWithPlatformRegion + * @note Only available on [9.1.0+]. + */ +Result nsResetToFactorySettingsWithPlatformRegion(void); + +/** + * @brief ResetToFactorySettingsWithPlatformRegionAuthentication + * @note Only available on [9.1.0+]. + */ +Result nsResetToFactorySettingsWithPlatformRegionAuthentication(void); + +///@} + +///@name IApplicationManagerInterface +///@{ + +/** + * @brief Gets an listing of \ref NsApplicationRecord. + * @param[out] records Output array of \ref NsApplicationRecord. + * @param[in] count Size of the records array in entries. + * @param[in] entry_offset Starting entry offset. + * @param[out] out_entrycount Total output entries. + */ +Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount); + +/** + * @brief GetApplicationRecordUpdateSystemEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=true. + */ +Result nsGetApplicationRecordUpdateSystemEvent(Event* out_event); + +/** + * @brief GetApplicationViewDeprecated + * @note On [3.0.0+] you should generally use \ref nsGetApplicationView instead. + * @param[out] out Output array of \ref NsApplicationViewDeprecated. + * @param[in] application_ids Input array of ApplicationIds. + * @param[in] count Size of the input/output arrays in entries. + */ +Result nsGetApplicationViewDeprecated(NsApplicationViewDeprecated *views, const u64 *application_ids, s32 count); + +/** + * @brief DeleteApplicationEntity + * @param[in] application_id ApplicationId. + */ +Result nsDeleteApplicationEntity(u64 application_id); + +/** + * @brief DeleteApplicationCompletely + * @param[in] application_id ApplicationId. + */ +Result nsDeleteApplicationCompletely(u64 application_id); + +/** + * @brief DeleteRedundantApplicationEntity + */ +Result nsDeleteRedundantApplicationEntity(void); + +/** + * @brief IsApplicationEntityMovable + * @param[in] application_id ApplicationId. + * @param[in] storage_id \ref NcmStorageId + * @param[out] out Output flag. + */ +Result nsIsApplicationEntityMovable(u64 application_id, NcmStorageId storage_id, bool *out); + +/** + * @brief MoveApplicationEntity + * @note Only available on [1.0.0-9.2.0]. + * @param[in] application_id ApplicationId. + * @param[in] storage_id \ref NcmStorageId + */ +Result nsMoveApplicationEntity(u64 application_id, NcmStorageId storage_id); + +/** + * @brief RequestApplicationUpdateInfo + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @param[out] a \ref AsyncValue. The data that can be read from this is u8 ApplicationUpdateInfo. qlaunch just checks whether this is 0. + * @param application_id ApplicationId. + */ +Result nsRequestApplicationUpdateInfo(AsyncValue *a, u64 application_id); + +/** + * @brief CancelApplicationDownload + * @param[in] application_id ApplicationId. + */ +Result nsCancelApplicationDownload(u64 application_id); + +/** + * @brief ResumeApplicationDownload + * @param[in] application_id ApplicationId. + */ +Result nsResumeApplicationDownload(u64 application_id); + +/** + * @brief CheckApplicationLaunchVersion + * @param[in] application_id ApplicationId. + */ +Result nsCheckApplicationLaunchVersion(u64 application_id); + +/** + * @brief CalculateApplicationApplyDeltaRequiredSize + * @param[in] application_id ApplicationId. + * @param[out] storage_id Output \ref NcmStorageId. + * @param[out] size Output size. + */ +Result nsCalculateApplicationDownloadRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size); + +/** + * @brief CleanupSdCard + */ +Result nsCleanupSdCard(void); + +/** + * @brief GetSdCardMountStatusChangedEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result nsGetSdCardMountStatusChangedEvent(Event* out_event); + +/** + * @brief GetGameCardUpdateDetectionEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result nsGetGameCardUpdateDetectionEvent(Event* out_event); + +/** + * @brief DisableApplicationAutoDelete + * @param[in] application_id ApplicationId. + */ +Result nsDisableApplicationAutoDelete(u64 application_id); + +/** + * @brief EnableApplicationAutoDelete + * @param[in] application_id ApplicationId. + */ +Result nsEnableApplicationAutoDelete(u64 application_id); + +/** + * @brief SetApplicationTerminateResult + * @param[in] application_id ApplicationId. + * @param[in] res Result. + */ +Result nsSetApplicationTerminateResult(u64 application_id, Result res); + +/** + * @brief ClearApplicationTerminateResult + * @param[in] application_id ApplicationId. + */ +Result nsClearApplicationTerminateResult(u64 application_id); + +/** + * @brief GetLastSdCardMountUnexpectedResult + */ +Result nsGetLastSdCardMountUnexpectedResult(void); + +/** + * @brief Opens a \ref NsRequestServerStopper. + * @note Only available on [2.0.0+]. + * @param[out] r \ref NsRequestServerStopper + */ +Result nsGetRequestServerStopper(NsRequestServerStopper *r); + +/** + * @brief CancelApplicationApplyDelta + * @note Only available on [3.0.0+]. + * @param[in] application_id ApplicationId. + */ +Result nsCancelApplicationApplyDelta(u64 application_id); + +/** + * @brief ResumeApplicationApplyDelta + * @note Only available on [3.0.0+]. + * @param[in] application_id ApplicationId. + */ +Result nsResumeApplicationApplyDelta(u64 application_id); + +/** + * @brief CalculateApplicationApplyDeltaRequiredSize + * @note Only available on [3.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] storage_id Output \ref NcmStorageId. + * @param[out] size Output size. + */ +Result nsCalculateApplicationApplyDeltaRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size); + +/** + * @brief ResumeAll + * @note Only available on [3.0.0+]. + */ +Result nsResumeAll(void); + +/** + * @brief Temporarily mounts the specified fs ContentStorage, then uses fs GetTotalSpaceSize/GetFreeSpaceSize with that mounted ContentStorage. + * @note Only available on [3.0.0+]. + * @param[in] storage_id \ref NcmStorageId, must be ::NcmStorageId_BuiltInUser or ::NcmStorageId_SdCard. + * @param[out] total_space_size Output from GetTotalSpaceSize. + * @param[out] free_space_size Output from GetFreeSpaceSize. + */ +Result nsGetStorageSize(NcmStorageId storage_id, s64 *total_space_size, s64 *free_space_size); + +/** + * @brief RequestUpdateApplication2 + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] application_id ApplicationId. + */ +Result nsRequestUpdateApplication2(AsyncResult *a, u64 application_id); + +/** + * @brief DeleteUserSaveDataAll + * @param[in] p \ref NsProgressMonitorForDeleteUserSaveDataAll + * @param[in] uid \ref AccountUid + */ +Result nsDeleteUserSaveDataAll(NsProgressMonitorForDeleteUserSaveDataAll *p, AccountUid uid); + +/** + * @brief DeleteUserSystemSaveData + * @param[in] uid \ref AccountUid + * @param[in] system_save_data_id SystemSaveDataId + */ +Result nsDeleteUserSystemSaveData(AccountUid uid, u64 system_save_data_id); + +/** + * @brief DeleteSaveData + * @note Only available on [6.0.0+]. + * @param[in] save_data_space_id \ref FsSaveDataSpaceId + * @param[in] save_data_id SaveDataId + */ +Result nsDeleteSaveData(FsSaveDataSpaceId save_data_space_id, u64 save_data_id); + +/** + * @brief UnregisterNetworkServiceAccount + * @param[in] uid \ref AccountUid + */ +Result nsUnregisterNetworkServiceAccount(AccountUid uid); + +/** + * @brief UnregisterNetworkServiceAccountWithUserSaveDataDeletion + * @note Only available on [6.0.0+]. + * @param[in] uid \ref AccountUid + */ +Result nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion(AccountUid uid); + +/** + * @brief RequestDownloadApplicationControlData + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @param[out] a \ref AsyncResult + * @param[in] application_id ApplicationId. + */ +Result nsRequestDownloadApplicationControlData(AsyncResult *a, u64 application_id); + +/** + * @brief ListApplicationTitle + * @note The data available with \ref asyncValueGet is a s32 for the offset within the buffer where the output data is located, \ref asyncValueGetSize returns the total byte-size of the data located here. The data located here is the \ref NacpLanguageEntry for each specified ApplicationId. + * @note Only available on [8.0.0+]. + * @param[out] a \ref AsyncValue + * @param[in] source Source, qlaunch uses ::NsApplicationControlSource_Storage. + * @param[in] application_ids Input array of ApplicationIds. + * @param[in] count Size of the application_ids array in entries. + * @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. + * @param[in] size 0x1000-byte aligned buffer size for TransferMemory. This must be at least: count*sizeof(\ref NacpLanguageEntry) + count*sizeof(u64) + count*sizeof(\ref NsApplicationControlData). + */ +Result nsListApplicationTitle(AsyncValue *a, NsApplicationControlSource source, const u64 *application_ids, s32 count, void* buffer, size_t size); + +/** + * @brief ListApplicationIcon + * @note The data available with \ref asyncValueGet is a s32 for the offset within the buffer where the output data is located, \ref asyncValueGetSize returns the total byte-size of the data located here. This data is: an u64 for total entries, an array of u64s for each icon size, then the icon JPEGs for the specified ApplicationIds. + * @note Only available on [8.0.0+]. + * @param[out] a \ref AsyncValue + * @param[in] source Source. + * @param[in] application_ids Input array of ApplicationIds. + * @param[in] count Size of the application_ids array in entries. + * @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. + * @param[in] size 0x1000-byte aligned buffer size for TransferMemory. This must be at least: 0x4 + count*sizeof(u64) + count*sizeof(\ref NsApplicationControlData::icon) + count*sizeof(u64) + sizeof(\ref NsApplicationControlData). + */ +Result nsListApplicationIcon(AsyncValue *a, NsApplicationControlSource source, const u64 *application_ids, s32 count, void* buffer, size_t size); + +/** + * @brief RequestCheckGameCardRegistration + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] application_id ApplicationId. + */ +Result nsRequestCheckGameCardRegistration(AsyncResult *a, u64 application_id); + +/** + * @brief RequestGameCardRegistrationGoldPoint + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncValue. The data that can be read from this is 4-bytes. + * @param[in] uid \ref AccountUid + * @param[in] application_id ApplicationId. + */ +Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 application_id); + +/** + * @brief RequestRegisterGameCard + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] uid \ref AccountUid + * @param[in] application_id ApplicationId. + * @param[in] inval Input value. + */ +Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application_id, s32 inval); + +/** + * @brief GetGameCardMountFailureEvent + * @note The Event must be closed by the user once finished with it. + * @note Only available on [3.0.0+]. + * @param[out] out_event Output Event with autoclear=false. + */ +Result nsGetGameCardMountFailureEvent(Event* out_event); + +/** + * @brief IsGameCardInserted + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result nsIsGameCardInserted(bool *out); + +/** + * @brief EnsureGameCardAccess + * @note Only available on [3.0.0+]. + */ +Result nsEnsureGameCardAccess(void); + +/** + * @brief GetLastGameCardMountFailureResult + * @note Only available on [3.0.0+]. + */ +Result nsGetLastGameCardMountFailureResult(void); + +/** + * @brief ListApplicationIdOnGameCard + * @note Only available on [5.0.0+]. + * @param[out] application_ids Output array of ApplicationIds. + * @param[in] count Size of the application_ids array in entries. + * @param[out] total_out Total output entries. + */ +Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total_out); + +/** + * @brief TouchApplication + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + */ +Result nsTouchApplication(u64 application_id); + +/** + * @brief IsApplicationUpdateRequested + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] flag Output flag, indicating whether out is valid. + * @param[out] out Output value. + */ +Result nsIsApplicationUpdateRequested(u64 application_id, bool *flag, u32 *out); + +/** + * @brief WithdrawApplicationUpdateRequest + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + */ +Result nsWithdrawApplicationUpdateRequest(u64 application_id); + +/** + * @brief RequestVerifyAddOnContentsRights + * @note Only available on [3.0.0-9.2.0]. + * @param[out] a \ref NsProgressAsyncResult + * @param[in] application_id ApplicationId. + */ +Result nsRequestVerifyAddOnContentsRights(NsProgressAsyncResult *a, u64 application_id); + +/** + * @brief RequestVerifyApplication + * @note On pre-5.0.0 this uses cmd RequestVerifyApplicationDeprecated, otherwise cmd RequestVerifyApplication is used. + * @param[out] a \ref NsProgressAsyncResult. The data available with \ref nsProgressAsyncResultGetProgress is basically the same as \ref NsSystemUpdateProgress. + * @param[in] application_id ApplicationId. + * @param[in] unk Unknown. A default value of 0x7 can be used (which is what qlaunch uses). Only used on [5.0.0+]. + * @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. + * @param[in] size 0x1000-byte aligned buffer size for TransferMemory. qlaunch uses size 0x100000. + */ +Result nsRequestVerifyApplication(NsProgressAsyncResult *a, u64 application_id, u32 unk, void* buffer, size_t size); + +/** + * @brief IsAnyApplicationEntityInstalled + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] out Output flag. + */ +Result nsIsAnyApplicationEntityInstalled(u64 application_id, bool *out); + +/** + * @brief CleanupUnavailableAddOnContents + * @note Only available on [6.0.0+]. + * @param[in] application_id ApplicationId. + * @param[in] uid \ref AccountUid + */ +Result nsCleanupUnavailableAddOnContents(u64 application_id, AccountUid uid); + +/** + * @brief FormatSdCard + * @note Only available on [2.0.0+]. + */ +Result nsFormatSdCard(void); + +/** + * @brief NeedsSystemUpdateToFormatSdCard + * @note Only available on [2.0.0+]. + * @param[out] out Output flag. + */ +Result nsNeedsSystemUpdateToFormatSdCard(bool *out); + +/** + * @brief GetLastSdCardFormatUnexpectedResult + * @note Only available on [2.0.0+]. + */ +Result nsGetLastSdCardFormatUnexpectedResult(void); + +/** + * @brief GetApplicationView + * @note Only available on [3.0.0+], on prior system-versions use \ref nsGetApplicationViewDeprecated instead. + * @param[out] out Output array of \ref NsApplicationView. + * @param[in] application_ids Input array of ApplicationIds. + * @param[in] count Size of the input/output arrays in entries. + */ +Result nsGetApplicationView(NsApplicationView *views, const u64 *application_ids, s32 count); + +/** + * @brief GetApplicationViewDownloadErrorContext + * @note Only available on [4.0.0+]. + * @param[in] application_id ApplicationId + * @param[out] context \ref ErrorContext + */ +Result nsGetApplicationViewDownloadErrorContext(u64 application_id, ErrorContext *context); + +/** + * @brief GetApplicationViewWithPromotionInfo + * @note Only available on [8.0.0+]. + * @param[out] out Output array of \ref NsApplicationViewWithPromotionInfo. + * @param[in] application_ids Input array of ApplicationIds. + * @param[in] count Size of the input/output arrays in entries. + */ +Result nsGetApplicationViewWithPromotionInfo(NsApplicationViewWithPromotionInfo *out, const u64 *application_ids, s32 count); + +/** + * @brief RequestDownloadApplicationPrepurchasedRights + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] application_id ApplicationId. + */ +Result nsRequestDownloadApplicationPrepurchasedRights(AsyncResult *a, u64 application_id); + +/** + * @brief Generates a \ref NsSystemDeliveryInfo using the currently installed SystemUpdate meta. + * @note Only available on [4.0.0+]. + * @param[out] info \ref NsSystemDeliveryInfo + */ +Result nsGetSystemDeliveryInfo(NsSystemDeliveryInfo *info); + +/** + * @brief SelectLatestSystemDeliveryInfo + * @note This selects the \ref NsSystemDeliveryInfo with the latest version from sys_list, using minimum versions determined from app_list/state and base_info. This also does various validation, etc. + * @note Only available on [4.0.0+]. + * @param[in] sys_list Input array of \ref NsSystemDeliveryInfo. + * @param[in] sys_count Size of the sys_list array in entries. + * @param[in] base_info \ref NsSystemDeliveryInfo + * @param[in] app_list Input array of \ref NsApplicationDeliveryInfo. This can be NULL. + * @param[in] app_count Size of the app_list array in entries. This can be 0. + * @param[out] index Output index for the selected entry in sys_list, -1 if none found. + */ +Result nsSelectLatestSystemDeliveryInfo(const NsSystemDeliveryInfo *sys_list, s32 sys_count, const NsSystemDeliveryInfo *base_info, const NsApplicationDeliveryInfo *app_list, s32 app_count, s32 *index); + +/** + * @brief VerifyDeliveryProtocolVersion + * @note Only available on [4.0.0+]. + * @param[in] info \ref NsSystemDeliveryInfo + */ +Result nsVerifyDeliveryProtocolVersion(const NsSystemDeliveryInfo *info); + +/** + * @brief Generates \ref NsApplicationDeliveryInfo for the specified ApplicationId. + * @note Only available on [4.0.0+]. + * @param[out] info Output array of \ref NsApplicationDeliveryInfo. + * @param[in] count Size of the array in entries. + * @param[in] application_id ApplicationId + * @param[in] attr ApplicationDeliveryAttributeTag bitmask. + * @param[out] total_out Total output entries. + */ +Result nsGetApplicationDeliveryInfo(NsApplicationDeliveryInfo *info, s32 count, u64 application_id, u32 attr, s32 *total_out); + +/** + * @brief HasAllContentsToDeliver + * @note Only available on [4.0.0+]. + * @param[in] info Input array of \ref NsApplicationDeliveryInfo. + * @param[in] count Size of the array in entries. Must be value 1. + * @param[out] out Output flag. + */ +Result nsHasAllContentsToDeliver(const NsApplicationDeliveryInfo* info, s32 count, bool *out); + +/** + * @brief Both \ref NsApplicationDeliveryInfo are validated, then the application_version in the first/second \ref NsApplicationDeliveryInfo are compared. + * @note Only available on [4.0.0+]. + * @param[in] info0 First input array of \ref NsApplicationDeliveryInfo. + * @param[in] count0 Size of the info0 array in entries. Must be value 1. + * @param[in] info1 Second input array of \ref NsApplicationDeliveryInfo. + * @param[in] count1 Size of the info1 array in entries. Must be value 1. + * @param[out] out Comparison result: -1 for less than, 0 for equal, and 1 for higher than. + */ +Result nsCompareApplicationDeliveryInfo(const NsApplicationDeliveryInfo *info0, s32 count0, const NsApplicationDeliveryInfo *info1, s32 count1, s32 *out); + +/** + * @brief CanDeliverApplication + * @note Only available on [4.0.0+]. + * @param[in] info0 First input array of \ref NsApplicationDeliveryInfo. + * @param[in] count0 Size of the info0 array in entries. Must be value <=1, when 0 this will return 0 with out set to 0. + * @param[in] info1 Second input array of \ref NsApplicationDeliveryInfo. + * @param[in] count1 Size of the info1 array in entries. Must be value 1. + * @param[out] out Output flag. + */ +Result nsCanDeliverApplication(const NsApplicationDeliveryInfo *info0, s32 count0, const NsApplicationDeliveryInfo *info1, s32 count1, bool *out); + +/** + * @brief ListContentMetaKeyToDeliverApplication + * @note Only available on [4.0.0+]. + * @param[out] meta Output array of \ref NcmContentMetaKey. + * @param[in] meta_count Size of the meta array in entries. Must be at least 1, only 1 entry will be returned. + * @param[in] meta_index Meta entry index. An output \ref NcmContentMetaKey will not be returned when this value is larger than 0. + * @param[in] info Input array of \ref NsApplicationDeliveryInfo. + * @param[in] info_count Size of the info array in entries. Must be value 1. + * @param[out] total_out Total output entries. + */ +Result nsListContentMetaKeyToDeliverApplication(NcmContentMetaKey *meta, s32 meta_count, s32 meta_index, const NsApplicationDeliveryInfo *info, s32 info_count, s32 *total_out); + +/** + * @brief After validation etc, this sets the output bool by comparing system-version fields in the \ref NsSystemDeliveryInfo / info-array and with a state field. + * @note Only available on [4.0.0+]. + * @param[in] info Input array of \ref NsApplicationDeliveryInfo. + * @param[in] count Size of the info array in entries. Must be value 1. + * @param[in] sys_info \ref NsSystemDeliveryInfo + * @param[out] out Output flag. + */ +Result nsNeedsSystemUpdateToDeliverApplication(const NsApplicationDeliveryInfo *info, s32 count, const NsSystemDeliveryInfo *sys_info, bool *out); + +/** + * @brief EstimateRequiredSize + * @note Only available on [4.0.0+]. + * @param[in] meta Input array of \ref NcmContentMetaKey. + * @param[in] count Size of the meta array in entries. When less than 1, this will return 0 with out set to 0. + * @param[out] out Output size. + */ +Result nsEstimateRequiredSize(const NcmContentMetaKey *meta, s32 count, s64 *out); + +/** + * @brief RequestReceiveApplication + * @note This is the Application version of \ref nssuControlRequestReceiveSystemUpdate, see the notes for that. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] addr Server IPv4 address. + * @param[in] port Socket port. qlaunch uses value 55556. + * @param[in] application_id ApplicationId + * @param[in] meta Input array of \ref NcmContentMetaKey. The ::NcmContentMetaType must match ::NcmContentMetaType_Patch. + * @param[in] count Size of the meta array in entries. + * @param[in] storage_id \ref NcmStorageId. qlaunch uses ::NcmStorageId_Any. + */ +Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count, NcmStorageId storage_id); + +/** + * @brief CommitReceiveApplication + * @note Only available on [4.0.0+]. + * @param[in] application_id ApplicationId + */ +Result nsCommitReceiveApplication(u64 application_id); + +/** + * @brief GetReceiveApplicationProgress + * @note Only available on [4.0.0+]. + * @param[in] application_id ApplicationId + * @param[out] out \ref NsReceiveApplicationProgress + */ +Result nsGetReceiveApplicationProgress(u64 application_id, NsReceiveApplicationProgress *out); + +/** + * @brief RequestSendApplication + * @note This is the Application version of \ref nssuRequestSendSystemUpdate, see the notes for that. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] addr Client IPv4 address. + * @param[in] port Socket port. qlaunch uses value 55556. + * @param[in] application_id ApplicationId + * @param[in] meta Input array of \ref NcmContentMetaKey. The ::NcmContentMetaType must match ::NcmContentMetaType_Patch. + * @param[in] count Size of the meta array in entries. + */ +Result nsRequestSendApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count); + +/** + * @brief GetSendApplicationProgress + * @note Only available on [4.0.0+]. + * @param[in] application_id ApplicationId + * @param[out] out \ref NsSendApplicationProgress + */ +Result nsGetSendApplicationProgress(u64 application_id, NsSendApplicationProgress *out); + +/** + * @brief Both \ref NsSystemDeliveryInfo are validated, then the system_update_meta_version in the first/second \ref NsSystemDeliveryInfo are compared. + * @note Only available on [4.0.0+]. + * @param[in] info0 First \ref NsSystemDeliveryInfo. + * @param[in] info1 Second \ref NsSystemDeliveryInfo. + * @param[out] out Comparison result: -1 for less than, 0 for equal, and 1 for higher than. + */ +Result nsCompareSystemDeliveryInfo(const NsSystemDeliveryInfo *info0, const NsSystemDeliveryInfo *info1, s32 *out); + +/** + * @brief ListNotCommittedContentMeta + * @note Only available on [4.0.0+]. + * @param[out] meta Output array of \ref NcmContentMetaKey. + * @param[in] count Size of the meta array in entries. + * @param[in] application_id ApplicationId + * @param[in] unk Unknown. + * @param[out] total_out Total output entries. + */ +Result nsListNotCommittedContentMeta(NcmContentMetaKey *meta, s32 count, u64 application_id, s32 unk, s32 *total_out); + +/** + * @brief This extracts data from the input array for hashing with SHA256, with validation being done when handling each entry. + * @note Only available on [5.0.0+]. + * @param[in] info Input array of \ref NsApplicationDeliveryInfo. + * @param[in] count Size of the array in entries. + * @param[out] out_hash Output 0x20-byte SHA256 hash. + */ +Result nsGetApplicationDeliveryInfoHash(const NsApplicationDeliveryInfo *info, s32 count, u8 *out_hash); + +/** + * @brief GetApplicationTerminateResult + * @note Only available on [6.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] res Output Result. + */ +Result nsGetApplicationTerminateResult(u64 application_id, Result *res); + +/** + * @brief GetApplicationRightsOnClient + * @note Only available on [6.0.0+]. + * @param[out] rights Output array of \ref NsApplicationRightsOnClient. + * @param[in] count Size of the rights array in entries. qlaunch uses value 3 for this. + * @param[in] application_id ApplicationId + * @param[in] uid \ref AccountUid, can optionally be all-zero. + * @param[in] flags Flags. Official sw hard-codes this to value 0x3. + * @param[out] total_out Total output entries. + */ +Result nsGetApplicationRightsOnClient(NsApplicationRightsOnClient *rights, s32 count, u64 application_id, AccountUid uid, u32 flags, s32 *total_out); + +/** + * @brief RequestNoDownloadRightsErrorResolution + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [9.0.0+]. + * @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution. + * @param application_id ApplicationId. + */ +Result nsRequestNoDownloadRightsErrorResolution(AsyncValue *a, u64 application_id); + +/** + * @brief RequestResolveNoDownloadRightsError + * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. + * @note Only available on [9.0.0+]. + * @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution. + * @param application_id ApplicationId. + */ +Result nsRequestResolveNoDownloadRightsError(AsyncValue *a, u64 application_id); + +/** + * @brief GetPromotionInfo + * @note Only available on [8.0.0+]. + * @param[out] promotion \ref NsPromotionInfo + * @param application_id ApplicationId. + * @param[in] uid \ref AccountUid + */ +Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, AccountUid uid); + +///@} + +///@name IDownloadTaskInterface +///@{ + +/** + * @brief ClearTaskStatusList + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsClearTaskStatusList(void); + +/** + * @brief RequestDownloadTaskList + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + */ +Result nsRequestDownloadTaskList(void); + +/** + * @brief RequestEnsureDownloadTask + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncResult + */ +Result nsRequestEnsureDownloadTask(AsyncResult *a); + +/** + * @brief ListDownloadTaskStatus + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] tasks Output array of \ref NsDownloadTaskStatus. + * @param[in] count Size of the tasks array in entries. A maximum of 0x100 tasks can be stored in state. + * @param[out] total_out Total output entries. + */ +Result nsListDownloadTaskStatus(NsDownloadTaskStatus* tasks, s32 count, s32 *total_out); + +/** + * @brief RequestDownloadTaskListData + * @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[out] a \ref AsyncValue + */ +Result nsRequestDownloadTaskListData(AsyncValue *a); + +/** + * @brief TryCommitCurrentApplicationDownloadTask + * @note Only available on [4.0.0+]. + */ +Result nsTryCommitCurrentApplicationDownloadTask(void); + +/** + * @brief EnableAutoCommit + * @note Only available on [4.0.0+]. + */ +Result nsEnableAutoCommit(void); + +/** + * @brief DisableAutoCommit + * @note Only available on [4.0.0+]. + */ +Result nsDisableAutoCommit(void); + +/** + * @brief TriggerDynamicCommitEvent + * @note Only available on [4.0.0+]. + */ +Result nsTriggerDynamicCommitEvent(void); + +///@} + +///@name IContentManagementInterface +///@{ + +/** + * @brief CalculateApplicationOccupiedSize + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] application_id ApplicationId. + * @param[out] out \ref NsApplicationOccupiedSize + */ +Result nsCalculateApplicationOccupiedSize(u64 application_id, NsApplicationOccupiedSize *out); + +/** + * @brief CheckSdCardMountStatus + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsCheckSdCardMountStatus(void); + +/** + * @brief Returns the total storage capacity (used + free) from content manager services. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. + * @param[out] size Pointer to output the total storage size to. + */ +Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size); + +/** + * @brief Returns the available storage capacity from content manager services. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. + * @param[out] size Pointer to output the free storage size to. + */ +Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size); + +/** + * @brief CountApplicationContentMeta + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] out Output count. + */ +Result nsCountApplicationContentMeta(u64 application_id, s32 *out); + +/** + * @brief Gets an listing of \ref NsApplicationContentMetaStatus. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[in] index Starting entry index. + * @param[out] list Output array of \ref NsApplicationContentMetaStatus. + * @param[in] count Size of the list array in entries. + * @param[out] out_entrycount Total output entries. + */ +Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount); + +/** + * @brief IsAnyApplicationRunning + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result nsIsAnyApplicationRunning(bool *out); + +///@} + +///@name IRequestServerStopper +///@{ + +/** + * @brief Close a \ref NsRequestServerStopper. + * @param r \ref NsRequestServerStopper + */ +void nsRequestServerStopperClose(NsRequestServerStopper *r); + +///@} + +///@name IProgressMonitorForDeleteUserSaveDataAll +///@{ + +/** + * @brief Close a \ref NsProgressMonitorForDeleteUserSaveDataAll. When initialized this will use \ref nsProgressMonitorForDeleteUserSaveDataAllIsFinished, throwing errors on failure / when the operation isn't finished (without closing the object). + * @note Cancelling the operation before it's finished is not supported by \ref NsProgressMonitorForDeleteUserSaveDataAll. + * @param p \ref NsProgressMonitorForDeleteUserSaveDataAll + */ +Result nsProgressMonitorForDeleteUserSaveDataAllClose(NsProgressMonitorForDeleteUserSaveDataAll *p); + +/** + * @brief GetSystemEvent + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result nsProgressMonitorForDeleteUserSaveDataAllGetSystemEvent(NsProgressMonitorForDeleteUserSaveDataAll *p, Event* out_event); + +/** + * @brief IsFinished + * @param p \ref NsProgressMonitorForDeleteUserSaveDataAll + * @param[out] out Whether the operation finished. + */ +Result nsProgressMonitorForDeleteUserSaveDataAllIsFinished(NsProgressMonitorForDeleteUserSaveDataAll *p, bool *out); + +/** + * @brief GetResult + * @param p \ref NsProgressMonitorForDeleteUserSaveDataAll + */ +Result nsProgressMonitorForDeleteUserSaveDataAllGetResult(NsProgressMonitorForDeleteUserSaveDataAll *p); + +/** + * @brief GetProgress + * @param p \ref NsProgressMonitorForDeleteUserSaveDataAll + * @param[out] progress Output \ref NsProgressForDeleteUserSaveDataAll. + */ +Result nsProgressMonitorForDeleteUserSaveDataAllGetProgress(NsProgressMonitorForDeleteUserSaveDataAll *p, NsProgressForDeleteUserSaveDataAll *progress); + +///@} + +///@name IProgressAsyncResult +///@{ + +/** + * @brief Close a \ref NsProgressAsyncResult. + * @note When the object is initialized, this uses \ref nsProgressAsyncResultCancel then \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. + * @param a \ref NsProgressAsyncResult + */ +void nsProgressAsyncResultClose(NsProgressAsyncResult *a); + +/** + * @brief Waits for the async operation to finish using the specified timeout. + * @param a \ref NsProgressAsyncResult + * @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. + */ +Result nsProgressAsyncResultWait(NsProgressAsyncResult *a, u64 timeout); + +/** + * @brief Gets the Result. + * @note Prior to using the cmd, this uses \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. + * @param a \ref NsProgressAsyncResult + */ +Result nsProgressAsyncResultGet(NsProgressAsyncResult *a); + +/** + * @brief Cancels the async operation. + * @note Used automatically by \ref nsProgressAsyncResultClose. + * @param a \ref NsProgressAsyncResult + */ +Result nsProgressAsyncResultCancel(NsProgressAsyncResult *a); + +/** + * @brief Gets the progress. + * @param a \ref NsProgressAsyncResult + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size. + */ +Result nsProgressAsyncResultGetProgress(NsProgressAsyncResult *a, void* buffer, size_t size); + +/** + * @brief GetDetailResult + * @param a \ref NsProgressAsyncResult + */ +Result nsProgressAsyncResultGetDetailResult(NsProgressAsyncResult *a); + +/** + * @brief Gets the \ref ErrorContext. + * @note Only available on [4.0.0+]. + * @param a \ref NsProgressAsyncResult + * @param[out] context \ref ErrorContext + */ +Result nsProgressAsyncResultGetErrorContext(NsProgressAsyncResult *a, ErrorContext *context); + +///@} + +///@name ns:vm +///@{ + +/// Initialize ns:vm. On pre-3.0.0 this must be used with \ref nsInitialize. +Result nsvmInitialize(void); + +/// Exit ns:vm. +void nsvmExit(void); + +/// Gets the Service object for ns:vm. This is only initialized on [3.0.0+]. +Service* nsvmGetServiceSession(void); + +Result nsvmNeedsUpdateVulnerability(bool *out); +Result nsvmGetSafeSystemVersion(NcmContentMetaKey *out); ///< [4.0.0+] + +///@} + +///@name ns:dev +///@{ + +/// Initialize ns:dev. +Result nsdevInitialize(void); + +/// Initialize ns:dev. +void nsdevExit(void); + +/// Gets the Service object for ns:dev. +Service* nsdevGetServiceSession(void); + +Result nsdevLaunchProgram(u64* out_pid, const NsLaunchProperties* properties, u32 flags); ///< [1.0.0-9.2.0] +Result nsdevTerminateProcess(u64 pid); +Result nsdevTerminateProgram(u64 tid); ///< [1.0.0-9.2.0] +Result nsdevGetShellEvent(Event* out_event); ///< Autoclear for nsdevShellEvent is always true. [1.0.0-9.2.0] +Result nsdevGetShellEventInfo(NsShellEventInfo* out); ///< [1.0.0-9.2.0] +Result nsdevTerminateApplication(void); +Result nsdevPrepareLaunchProgramFromHost(NsLaunchProperties* out, const char* path, size_t path_len); ///< [1.0.0-9.2.0] +Result nsdevLaunchApplicationForDevelop(u64* out_pid, u64 application_id, u32 flags); ///< [1.0.0-9.2.0] +Result nsdevLaunchApplicationFromHost(u64* out_pid, const char* path, size_t path_len, u32 flags); ///< [10.0.0+] +Result nsdevLaunchApplicationWithStorageIdForDevelop(u64* out_pid, u64 application_id, u32 flags, u8 app_storage_id, u8 patch_storage_id); +Result nsdevIsSystemMemoryResourceLimitBoosted(bool* out); ///< [6.0.0-8.1.0] +Result nsdevGetRunningApplicationProcessIdForDevelop(u64* out_pid); ///< [6.0.0+] +Result nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop(bool can_be_active); ///< [6.0.0+] + +///@} + +///@name ns:su +///@{ + +/// Initialize ns:su. +Result nssuInitialize(void); + +/// Exit ns:su. +void nssuExit(void); + +/// Gets the Service object for ns:su. +Service* nssuGetServiceSession(void); + +/** + * @brief Gets the \ref NsBackgroundNetworkUpdateState. + * @note Internally this uses nim commands ListSystemUpdateTask and GetSystemUpdateTaskInfo to determine the output state. + * @param[out] out \ref NsBackgroundNetworkUpdateState + */ +Result nssuGetBackgroundNetworkUpdateState(NsBackgroundNetworkUpdateState *out); + +/** + * @brief Opens a \ref NsSystemUpdateControl. + * @note Only 1 \ref NsSystemUpdateControl can be open at a time. + * @param[out] c \ref NsSystemUpdateControl + */ +Result nssuOpenSystemUpdateControl(NsSystemUpdateControl *c); + +/** + * @brief Uses nim ListSystemUpdateTask, then uses the task with DestroySystemUpdateTask if it exists. Then this runs ExFat handling, updates state, and sets the same state flag as \ref nssuRequestBackgroundNetworkUpdate. + * @note Only usable when a \ref NsSystemUpdateControl isn't open. + */ +Result nssuNotifyExFatDriverRequired(void); + +/** + * @brief ClearExFatDriverStatusForDebug + */ +Result nssuClearExFatDriverStatusForDebug(void); + +/** + * @brief RequestBackgroundNetworkUpdate + * @note Only usable when a \ref NsSystemUpdateControl isn't open. + */ +Result nssuRequestBackgroundNetworkUpdate(void); + +/** + * @brief This checks whether a sysupdate is needed with the input \ref NcmContentMetaKey using NCM commands, if not this will just return 0. Otherwise, this will then run code which is identical to \ref nssuRequestBackgroundNetworkUpdate. + * @note Only usable when a \ref NsSystemUpdateControl isn't open. + * @param[in] key \ref NcmContentMetaKey + */ +Result nssuNotifyBackgroundNetworkUpdate(const NcmContentMetaKey *key); + +/** + * @brief NotifyExFatDriverDownloadedForDebug + */ +Result nssuNotifyExFatDriverDownloadedForDebug(void); + +/** + * @brief Gets an Event which can be signaled by \ref nssuNotifySystemUpdateForContentDelivery. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result nssuGetSystemUpdateNotificationEventForContentDelivery(Event* out_event); + +/** + * @brief Signals the event returned by \ref nssuGetSystemUpdateNotificationEventForContentDelivery. + */ +Result nssuNotifySystemUpdateForContentDelivery(void); + +/** + * @brief This does shutdown preparation. + * @note This is used by am-sysmodule, so generally there's no need to use this. + * @note Only available on [3.0.0+]. + */ +Result nssuPrepareShutdown(void); + +/** + * @brief This uses nim ListSystemUpdateTask, then when a task is returned uses it with DestroySystemUpdateTask. + * @note Only available on [4.0.0+]. + */ +Result nssuDestroySystemUpdateTask(void); + +/** + * @brief RequestSendSystemUpdate + * @note The system will use the input addr/port with bind(), the input addr will eventually be validated with the addr from accept(). addr/port are little-endian. + * @note After the system accepts a connection etc, an error will be thrown if the system is Internet-connected. + * @note Only available on [4.0.0+]. + * @param[out] a \ref AsyncResult + * @param[in] addr Client IPv4 address. qlaunch uses a local-WLAN addr. + * @param[in] port Socket port. qlaunch uses value 55556. + * @param[in] info \ref NsSystemDeliveryInfo + */ +Result nssuRequestSendSystemUpdate(AsyncResult *a, u32 addr, u16 port, NsSystemDeliveryInfo *info); + +/** + * @brief GetSendSystemUpdateProgress + * @note Only available on [4.0.0+]. + * @param[out] out \ref NsSystemUpdateProgress + */ +Result nssuGetSendSystemUpdateProgress(NsSystemUpdateProgress *out); + +///@} + +///@name ISystemUpdateControl +///@{ + +/** + * @brief Close a \ref NsSystemUpdateControl. + * @param c \ref NsSystemUpdateControl + */ +void nssuControlClose(NsSystemUpdateControl *c); + +/** + * @brief Gets whether a network sysupdate was downloaded, with install pending. + * @param c \ref NsSystemUpdateControl + * @param[out] out Output flag. + */ +Result nssuControlHasDownloaded(NsSystemUpdateControl *c, bool* out); + +/** + * @brief RequestCheckLatestUpdate + * @param c \ref NsSystemUpdateControl + * @param[out] a \ref AsyncValue. The data that can be read from this is u8 \ref NsLatestSystemUpdate. + */ +Result nssuControlRequestCheckLatestUpdate(NsSystemUpdateControl *c, AsyncValue *a); + +/** + * @brief RequestDownloadLatestUpdate + * @param c \ref NsSystemUpdateControl + * @param[out] a \ref AsyncResult + */ +Result nssuControlRequestDownloadLatestUpdate(NsSystemUpdateControl *c, AsyncResult *a); + +/** + * @brief GetDownloadProgress + * @param c \ref NsSystemUpdateControl + * @param[out] out \ref NsSystemUpdateProgress + */ +Result nssuControlGetDownloadProgress(NsSystemUpdateControl *c, NsSystemUpdateProgress *out); + +/** + * @brief ApplyDownloadedUpdate + * @param c \ref NsSystemUpdateControl + */ +Result nssuControlApplyDownloadedUpdate(NsSystemUpdateControl *c); + +/** + * @brief RequestPrepareCardUpdate + * @param c \ref NsSystemUpdateControl + * @param[out] a \ref AsyncResult + */ +Result nssuControlRequestPrepareCardUpdate(NsSystemUpdateControl *c, AsyncResult *a); + +/** + * @brief GetPrepareCardUpdateProgress + * @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. + * @param c \ref NsSystemUpdateControl + * @param[out] out \ref NsSystemUpdateProgress + */ +Result nssuControlGetPrepareCardUpdateProgress(NsSystemUpdateControl *c, NsSystemUpdateProgress *out); + +/** + * @brief HasPreparedCardUpdate + * @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. + * @param c \ref NsSystemUpdateControl + * @param[out] out Output flag. + */ +Result nssuControlHasPreparedCardUpdate(NsSystemUpdateControl *c, bool* out); + +/** + * @brief ApplyCardUpdate + * @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. + * @param c \ref NsSystemUpdateControl + */ +Result nssuControlApplyCardUpdate(NsSystemUpdateControl *c); + +/** + * @brief Gets the filesize for the specified DownloadedEulaData. + * @note This mounts the Eula SystemData, then uses the file ":/". + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetDownloadedEulaDataSize(NsSystemUpdateControl *c, const char* path, u64 *filesize); + +/** + * @brief Gets the specified DownloadedEulaData. + * @note See the note for \ref nssuControlGetDownloadedEulaDataSize. + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] buffer Output buffer. + * @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetDownloadedEulaDataSize. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetDownloadedEulaData(NsSystemUpdateControl *c, const char* path, void* buffer, size_t size, u64 *filesize); + +/** + * @brief SetupCardUpdate + * @param c \ref NsSystemUpdateControl + * @param[in] buffer TransferMemory buffer, when NULL this is automatically allocated. + * @param[in] size TransferMemory buffer size, see \ref NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT. + */ +Result nssuControlSetupCardUpdate(NsSystemUpdateControl *c, void* buffer, size_t size); + +/** + * @brief Gets the filesize for the specified PreparedCardUpdateEulaData. + * @note See the note for \ref nssuControlGetDownloadedEulaDataSize. + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetPreparedCardUpdateEulaDataSize(NsSystemUpdateControl *c, const char* path, u64 *filesize); + +/** + * @brief Gets the specified PreparedCardUpdateEulaData. + * @note See the note for \ref nssuControlGetDownloadedEulaDataSize. + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] buffer Output buffer. + * @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetPreparedCardUpdateEulaDataSize. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetPreparedCardUpdateEulaData(NsSystemUpdateControl *c, const char* path, void* buffer, size_t size, u64 *filesize); + +/** + * @brief SetupCardUpdateViaSystemUpdater + * @note Same as \ref nssuControlSetupCardUpdate, except this doesn't run the code for fs cmds GetGameCardHandle/GetGameCardUpdatePartitionInfo, and uses fs OpenRegisteredUpdatePartition instead of OpenGameCardFileSystem. + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[in] buffer TransferMemory buffer, when NULL this is automatically allocated. + * @param[in] size TransferMemory buffer size, see \ref NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT. + */ +Result nssuControlSetupCardUpdateViaSystemUpdater(NsSystemUpdateControl *c, void* buffer, size_t size); + +/** + * @brief HasReceived + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[out] out Output flag. + */ +Result nssuControlHasReceived(NsSystemUpdateControl *c, bool* out); + +/** + * @brief RequestReceiveSystemUpdate + * @note The system will use the input addr/port with connect(). addr/port are little-endian. + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[out] a \ref AsyncResult + * @param[in] addr Server IPv4 address. qlaunch uses a local-WLAN addr, however this can be any addr. + * @param[in] port Socket port. qlaunch uses value 55556. + * @param[in] info \ref NsSystemDeliveryInfo + */ +Result nssuControlRequestReceiveSystemUpdate(NsSystemUpdateControl *c, AsyncResult *a, u32 addr, u16 port, NsSystemDeliveryInfo *info); + +/** + * @brief GetReceiveProgress + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[out] out \ref NsSystemUpdateProgress + */ +Result nssuControlGetReceiveProgress(NsSystemUpdateControl *c, NsSystemUpdateProgress *out); + +/** + * @brief ApplyReceivedUpdate + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + */ +Result nssuControlApplyReceivedUpdate(NsSystemUpdateControl *c); + +/** + * @brief Gets the filesize for the specified ReceivedEulaData. + * @note See the note for \ref nssuControlGetDownloadedEulaDataSize. + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetReceivedEulaDataSize(NsSystemUpdateControl *c, const char* path, u64 *filesize); + +/** + * @brief Gets the specified ReceivedEulaData. + * @note See the note for \ref nssuControlGetDownloadedEulaDataSize. + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[in] path EulaData path. + * @param[out] buffer Output buffer. + * @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetReceivedEulaDataSize. + * @param[out] filesize Output filesize. + */ +Result nssuControlGetReceivedEulaData(NsSystemUpdateControl *c, const char* path, void* buffer, size_t size, u64 *filesize); + +/** + * @brief Does setup for ReceiveSystemUpdate by using the same nim cmds as \ref nssuDestroySystemUpdateTask. + * @note qlaunch uses this before \ref nssuControlRequestReceiveSystemUpdate. + * @note Only available on [4.0.0+]. + * @param c \ref NsSystemUpdateControl + */ +Result nssuControlSetupToReceiveSystemUpdate(NsSystemUpdateControl *c); + +/** + * @brief RequestCheckLatestUpdateIncludesRebootlessUpdate + * @note Only available on [6.0.0+]. + * @param c \ref NsSystemUpdateControl + * @param[out] a \ref AsyncValue + */ +Result nssuControlRequestCheckLatestUpdateIncludesRebootlessUpdate(NsSystemUpdateControl *c, AsyncValue *a); + +///@} + diff --git a/src/libnx/wrapper/switch/services/ns.nim b/src/libnx/wrapper/switch/services/ns.nim new file mode 100644 index 0000000..d29291f --- /dev/null +++ b/src/libnx/wrapper/switch/services/ns.nim @@ -0,0 +1,1956 @@ +## * +## @file ns.h +## @brief NS services IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../nacp, ../sf/service, ../services/ncm_types, ../services/async, + ../services/acc, ../services/fs, ../applets/error, ../kernel/event, ../kernel/tmem + +## / ShellEvent + +type + NsShellEvent* = enum + NsShellEventNone = 0, ## /< None + NsShellEventExit = 1, ## /< Exit + NsShellEventStart = 2, ## /< Start + NsShellEventCrash = 3, ## /< Crash + NsShellEventDebug = 4 ## /< Debug + + +## / ApplicationControlSource + +type + NsApplicationControlSource* = enum + NsApplicationControlSourceCacheOnly = 0, ## /< Returns data from cache. + NsApplicationControlSourceStorage = 1, ## /< Returns data from storage if not present in cache. + NsApplicationControlSourceStorageOnly = 2 ## /< Returns data from storage without using cache. + + +## / BackgroundNetworkUpdateState + +type + NsBackgroundNetworkUpdateState* = enum + NsBackgroundNetworkUpdateStateNone = 0, ## /< No sysupdate task exists. + NsBackgroundNetworkUpdateStateDownloading = 1, ## /< Sysupdate download in progress. + NsBackgroundNetworkUpdateStateReady = 2 ## /< Sysupdate ready, pending install. + + +## / LatestSystemUpdate + +type + NsLatestSystemUpdate* = enum + NsLatestSystemUpdateUnknown0 = 0, ## /< Unknown. + NsLatestSystemUpdateUnknown1 = 1, ## /< Unknown. + NsLatestSystemUpdateUnknown2 = 2 ## /< Unknown. + + +## / RequestServerStopper + +type + NsRequestServerStopper* {.bycopy.} = object + s*: Service ## /< IRequestServerStopper + + +## / ProgressMonitorForDeleteUserSaveDataAll + +type + NsProgressMonitorForDeleteUserSaveDataAll* {.bycopy.} = object + s*: Service ## /< IProgressMonitorForDeleteUserSaveDataAll + + +## / ProgressAsyncResult + +type + NsProgressAsyncResult* {.bycopy.} = object + s*: Service ## /< IProgressAsyncResult + event*: Event ## /< Event with autoclear=false. + + +## / SystemUpdateControl + +type + NsSystemUpdateControl* {.bycopy.} = object + s*: Service ## /< ISystemUpdateControl + tmem*: TransferMemory ## /< TransferMemory for SetupCardUpdate/SetupCardUpdateViaSystemUpdater. + + +## / ApplicationControlData + +type + NsApplicationControlData* {.bycopy.} = object + nacp*: NacpStruct ## /< \ref NacpStruct + icon*: array[0x20000, U8] ## /< JPEG + + +## / ApplicationOccupiedSize + +type + NsApplicationOccupiedSize* {.bycopy.} = object + unkX0*: array[0x80, U8] ## /< Unknown. + + +## / NsApplicationContentMetaStatus + +type + NsApplicationContentMetaStatus* {.bycopy.} = object + metaType*: U8 ## /< \ref NcmContentMetaType + storageID*: U8 ## /< \ref NcmStorageId + unkX02*: U8 ## /< Unknown. + padding*: U8 ## /< Padding. + version*: U32 ## /< Application version. + applicationId*: U64 ## /< ApplicationId. + + +## / ApplicationRecord + +type + NsApplicationRecord* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + `type`*: U8 ## /< Type. + unkX09*: U8 ## /< Unknown. + unkX0a*: array[6, U8] ## /< Unknown. + unkX10*: U8 ## /< Unknown. + unkX11*: array[7, U8] ## /< Unknown. + + +## / ProgressForDeleteUserSaveDataAll + +type + NsProgressForDeleteUserSaveDataAll* {.bycopy.} = object + unkX0*: array[0x28, U8] ## /< Unknown. + + +## / ApplicationViewDeprecated. The below comments are for the \ref NsApplicationView to NsApplicationViewDeprecated conversion done by \ref nsGetApplicationViewDeprecated on newer system-versions. + +type + NsApplicationViewDeprecated* {.bycopy.} = object + applicationId*: U64 ## /< Same as NsApplicationView::application_id. + unkX8*: array[0x4, U8] ## /< Same as NsApplicationView::unk_x8. + flags*: U32 ## /< Same as NsApplicationView::flags. + unkX10*: array[0x10, U8] ## /< Same as NsApplicationView::unk_x10. + unkX20*: U32 ## /< Same as NsApplicationView::unk_x20. + unkX24*: U16 ## /< Same as NsApplicationView::unk_x24. + unkX26*: array[0x2, U8] ## /< Cleared to zero. + unkX28*: array[0x10, U8] ## /< Same as NsApplicationView::unk_x30. + unkX38*: U32 ## /< Same as NsApplicationView::unk_x40. + unkX3c*: U8 ## /< Same as NsApplicationView::unk_x44. + unkX3d*: array[3, U8] ## /< Cleared to zero. + + +## / ApplicationView + +type + NsApplicationView* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + unkX8*: array[0x4, U8] ## /< Unknown. + flags*: U32 ## /< Flags. + unkX10*: array[0x10, U8] ## /< Unknown. + unkX20*: U32 ## /< Unknown. + unkX24*: U16 ## /< Unknown. + unkX26*: array[0x2, U8] ## /< Unknown. + unkX28*: array[0x8, U8] ## /< Unknown. + unkX30*: array[0x10, U8] ## /< Unknown. + unkX40*: U32 ## /< Unknown. + unkX44*: U8 ## /< Unknown. + unkX45*: array[0xb, U8] ## /< Unknown. + + +## / NsPromotionInfo + +type + NsPromotionInfo* {.bycopy.} = object + startTimestamp*: U64 ## /< POSIX timestamp for the promotion start. + endTimestamp*: U64 ## /< POSIX timestamp for the promotion end. + remainingTime*: S64 ## /< Remaining time until the promotion ends, in nanoseconds ({end_timestamp - current_time} converted to nanoseconds). + unkX18*: array[0x4, U8] ## /< Not set, left at zero. + flags*: U8 ## /< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear: remaining_time is set. + pad*: array[3, U8] ## /< Padding. + + +## / NsApplicationViewWithPromotionInfo + +type + NsApplicationViewWithPromotionInfo* {.bycopy.} = object + view*: NsApplicationView ## /< \ref NsApplicationView + promotion*: NsPromotionInfo ## /< \ref NsPromotionInfo + + +## / LaunchProperties + +type + NsLaunchProperties* {.bycopy.} = object + programId*: U64 ## /< program_id. + version*: U32 ## /< Program version. + storageID*: U8 ## /< \ref NcmStorageId + index*: U8 ## /< Index. + isApplication*: U8 ## /< Whether this is an Application. + + +## / ShellEventInfo + +type + NsShellEventInfo* {.bycopy.} = object + event*: NsShellEvent ## /< \ref NsShellEvent + processId*: U64 ## /< processID. + + +## / SystemUpdateProgress. Commands which have this as output will return 0 with the output cleared, when no task is available. + +type + NsSystemUpdateProgress* {.bycopy.} = object + currentSize*: S64 ## /< Current size. This value can be larger than total_size when the async operation is finishing. When total_size is <=0, this current_size field may contain a progress value for when the total_size is not yet determined. + totalSize*: S64 ## /< Total size, this field is only valid when >0. + + +## / ReceiveApplicationProgress. Same as \ref NsSystemUpdateProgress, except cmds which return this will return actual errors on failure, instead of returning 0 with a cleared struct. + +type + NsReceiveApplicationProgress* = NsSystemUpdateProgress + +## / SendApplicationProgress. Same as \ref NsSystemUpdateProgress, except cmds which return this will return actual errors on failure, instead of returning 0 with a cleared struct. + +type + NsSendApplicationProgress* = NsSystemUpdateProgress + +## / EulaDataPath + +type + NsEulaDataPath* {.bycopy.} = object + path*: array[0x100, char] ## /< Path. + + +## / SystemDeliveryInfo + +type + INNER_C_STRUCT_ns_1* {.bycopy.} = object + systemDeliveryProtocolVersion*: U32 ## /< Must match a system-setting. + applicationDeliveryProtocolVersion*: U32 ## /< Loaded from a system-setting. Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + includesExfat*: U32 ## /< Whether ExFat is included. Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + systemUpdateMetaVersion*: U32 ## /< SystemUpdate meta version. + systemUpdateMetaId*: U64 ## /< SystemUpdate meta Id. + unkX18*: U8 ## /< Copied into state by \ref nssuRequestSendSystemUpdate. + unkX19*: U8 ## /< Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + unkX1a*: U8 ## /< Unknown. + unkX1b*: array[0xc5, U8] ## /< Unused by \ref nssuRequestSendSystemUpdate / \ref nssuControlRequestReceiveSystemUpdate, besides HMAC validation. + + NsSystemDeliveryInfo* {.bycopy.} = object + data*: INNER_C_STRUCT_ns_1 ## /< Data used with the below hmac. + hmac*: array[0x20, U8] ## /< HMAC-SHA256 over the above data. + + +## / ApplicationDeliveryInfo + +type + INNER_C_STRUCT_ns_3* {.bycopy.} = object + unkX0*: array[0x10, U8] ## /< Unknown. + applicationVersion*: U32 ## /< Application version. + unkX14*: U32 ## /< Unknown. + requiredSystemVersion*: U32 ## /< Required system version, see NsSystemDeliveryInfo::system_update_meta_version. + unkX1c*: U32 ## /< Unknown. + unkX20*: array[0xc0, U8] ## /< Unknown. + + NsApplicationDeliveryInfo* {.bycopy.} = object + data*: INNER_C_STRUCT_ns_3 ## /< Data used with the below hmac. + hmac*: array[0x20, U8] ## /< HMAC-SHA256 over the above data. + + +## / NsApplicationRightsOnClient + +type + NsApplicationRightsOnClient* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + uid*: AccountUid ## /< \ref AccountUid + flagsX18*: U8 ## /< qlaunch uses bit0-bit4 and bit7 from here. + flagsX19*: U8 ## /< qlaunch uses bit0 from here. + unkX1a*: array[0x6, U8] ## /< Unknown. + + +## / DownloadTaskStatus + +type + NsDownloadTaskStatus* {.bycopy.} = object + unkX0*: array[0x20, U8] ## /< Unknown. + + +## / Default size for \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater. This is the size used by qlaunch for SetupCardUpdate. + +const + NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT* = 0x100000 +proc nsInitialize*(): Result {.cdecl, importc: "nsInitialize".} +## /@name ns +## /@{ +## / Initialize ns services. Uses ns:am on pre-3.0.0, ns:am2 on [3.0.0+]. + +proc nsExit*() {.cdecl, importc: "nsExit".} +## / Exit ns services. + +proc nsGetServiceSessionGetterInterface*(): ptr Service {.cdecl, + importc: "nsGetServiceSession_GetterInterface".} +## / Gets the Service object for the actual ns:* service session. Only initialized on [3.0.0+], on pre-3.0.0 see \ref nsGetServiceSession_ApplicationManagerInterface. + +proc nsGetServiceSessionApplicationManagerInterface*(): ptr Service {.cdecl, + importc: "nsGetServiceSession_ApplicationManagerInterface".} +## / Gets the Service object for IApplicationManagerInterface. Only initialized on pre-3.0.0, on [3.0.0+] use \ref nsGetApplicationManagerInterface. + +proc nsGetDynamicRightsInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetDynamicRightsInterface".} +## / Gets the Service object for IDynamicRightsInterface via the cmd for that. +## / Only available on [6.0.0+]. + +proc nsGetReadOnlyApplicationControlDataInterface*(srvOut: ptr Service): Result {. + cdecl, importc: "nsGetReadOnlyApplicationControlDataInterface".} +## / Gets the Service object for IReadOnlyApplicationControlDataInterface via the cmd for that. +## / Only available on [5.1.0+]. + +proc nsGetReadOnlyApplicationRecordInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetReadOnlyApplicationRecordInterface".} +## / Gets the Service object for IReadOnlyApplicationRecordInterface via the cmd for that. +## / Only available on [5.0.0+]. + +proc nsGetECommerceInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetECommerceInterface".} +## / Gets the Service object for IECommerceInterface via the cmd for that. +## / Only available on [4.0.0+]. + +proc nsGetApplicationVersionInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetApplicationVersionInterface".} +## / Gets the Service object for IApplicationVersionInterface via the cmd for that. +## / Only available on [4.0.0+]. + +proc nsGetFactoryResetInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetFactoryResetInterface".} +## / Gets the Service object for IFactoryResetInterface via the cmd for that. +## / Only available on [3.0.0+]. + +proc nsGetAccountProxyInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetAccountProxyInterface".} +## / Gets the Service object for IAccountProxyInterface via the cmd for that. +## / Only available on [3.0.0+]. + +proc nsGetApplicationManagerInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetApplicationManagerInterface".} +## / Gets the Service object for IApplicationManagerInterface via the cmd for that. +## / Only available on [3.0.0+], on prior sysvers use \ref nsGetServiceSession_ApplicationManagerInterface. + +proc nsGetDownloadTaskInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetDownloadTaskInterface".} +## / Gets the Service object for IDownloadTaskInterface via the cmd for that. +## / Only available on [3.0.0+]. + +proc nsGetContentManagementInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetContentManagementInterface".} +## / Gets the Service object for IContentManagementInterface via the cmd for that. +## / Only available on [3.0.0+]. + +proc nsGetDocumentInterface*(srvOut: ptr Service): Result {.cdecl, + importc: "nsGetDocumentInterface".} +## / Gets the Service object for IDocumentInterface via the cmd for that. +## / Only available on [3.0.0+]. + +proc nsGetApplicationControlData*(source: NsApplicationControlSource; + applicationId: U64; + buffer: ptr NsApplicationControlData; + size: csize_t; actualSize: ptr U64): Result {.cdecl, + importc: "nsGetApplicationControlData".} +## /@} +## /@name IReadOnlyApplicationControlDataInterface +## /@{ +## * +## @brief Gets the \ref NsApplicationControlData for the specified application. +## @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. +## @param[in] source Source, official sw uses ::NsApplicationControlSource_Storage. +## @param[in] application_id ApplicationId. +## @param[out] buffer \ref NsApplicationControlData +## @param[in] size Size of the buffer. +## @param[out] actual_size Actual output size. +## + +proc nsGetApplicationDesiredLanguage*(nacp: ptr NacpStruct; + langentry: ptr ptr NacpLanguageEntry): Result {. + cdecl, importc: "nsGetApplicationDesiredLanguage".} +## * +## @brief GetApplicationDesiredLanguage. Selects a \ref NacpLanguageEntry to use from the specified \ref NacpStruct. +## @note Uses \ref nsGetReadOnlyApplicationControlDataInterface on [5.1.0+], otherwise IApplicationManagerInterface is used. +## @param[in] nacp \ref NacpStruct +## @param[out] langentry \ref NacpLanguageEntry +## + +proc nsRequestLinkDevice*(a: ptr AsyncResult; uid: AccountUid): Result {.cdecl, + importc: "nsRequestLinkDevice".} +## /@} +## /@name IECommerceInterface +## /@{ +## * +## @brief RequestLinkDevice +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] uid \ref AccountUid +## + +proc nsRequestSyncRights*(a: ptr AsyncResult): Result {.cdecl, + importc: "nsRequestSyncRights".} +## * +## @brief RequestSyncRights +## @note Only available on [6.0.0+]. +## @param[out] a \ref AsyncResult +## + +proc nsRequestUnlinkDevice*(a: ptr AsyncResult; uid: AccountUid): Result {.cdecl, + importc: "nsRequestUnlinkDevice".} +## * +## @brief RequestUnlinkDevice +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [6.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] uid \ref AccountUid +## + +proc nsResetToFactorySettings*(): Result {.cdecl, + importc: "nsResetToFactorySettings".} +## /@} +## /@name IFactoryResetInterface +## /@{ +## * +## @brief ResetToFactorySettings +## @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## + +proc nsResetToFactorySettingsWithoutUserSaveData*(): Result {.cdecl, + importc: "nsResetToFactorySettingsWithoutUserSaveData".} +## * +## @brief ResetToFactorySettingsWithoutUserSaveData +## @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## + +proc nsResetToFactorySettingsForRefurbishment*(): Result {.cdecl, + importc: "nsResetToFactorySettingsForRefurbishment".} +## * +## @brief ResetToFactorySettingsForRefurbishment +## @note Uses \ref nsGetFactoryResetInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## + +proc nsResetToFactorySettingsWithPlatformRegion*(): Result {.cdecl, + importc: "nsResetToFactorySettingsWithPlatformRegion".} +## * +## @brief ResetToFactorySettingsWithPlatformRegion +## @note Only available on [9.1.0+]. +## + +proc nsResetToFactorySettingsWithPlatformRegionAuthentication*(): Result {.cdecl, + importc: "nsResetToFactorySettingsWithPlatformRegionAuthentication".} +## * +## @brief ResetToFactorySettingsWithPlatformRegionAuthentication +## @note Only available on [9.1.0+]. +## + +proc nsListApplicationRecord*(records: ptr NsApplicationRecord; count: S32; + entryOffset: S32; outEntrycount: ptr S32): Result {. + cdecl, importc: "nsListApplicationRecord".} +## /@} +## /@name IApplicationManagerInterface +## /@{ +## * +## @brief Gets an listing of \ref NsApplicationRecord. +## @param[out] records Output array of \ref NsApplicationRecord. +## @param[in] count Size of the records array in entries. +## @param[in] entry_offset Starting entry offset. +## @param[out] out_entrycount Total output entries. +## + +proc nsGetApplicationRecordUpdateSystemEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nsGetApplicationRecordUpdateSystemEvent".} +## * +## @brief GetApplicationRecordUpdateSystemEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=true. +## + +proc nsGetApplicationViewDeprecated*(views: ptr NsApplicationViewDeprecated; + applicationIds: ptr U64; count: S32): Result {. + cdecl, importc: "nsGetApplicationViewDeprecated".} +## * +## @brief GetApplicationViewDeprecated +## @note On [3.0.0+] you should generally use \ref nsGetApplicationView instead. +## @param[out] out Output array of \ref NsApplicationViewDeprecated. +## @param[in] application_ids Input array of ApplicationIds. +## @param[in] count Size of the input/output arrays in entries. +## + +proc nsDeleteApplicationEntity*(applicationId: U64): Result {.cdecl, + importc: "nsDeleteApplicationEntity".} +## * +## @brief DeleteApplicationEntity +## @param[in] application_id ApplicationId. +## + +proc nsDeleteApplicationCompletely*(applicationId: U64): Result {.cdecl, + importc: "nsDeleteApplicationCompletely".} +## * +## @brief DeleteApplicationCompletely +## @param[in] application_id ApplicationId. +## + +proc nsDeleteRedundantApplicationEntity*(): Result {.cdecl, + importc: "nsDeleteRedundantApplicationEntity".} +## * +## @brief DeleteRedundantApplicationEntity +## + +proc nsIsApplicationEntityMovable*(applicationId: U64; storageId: NcmStorageId; + `out`: ptr bool): Result {.cdecl, + importc: "nsIsApplicationEntityMovable".} +## * +## @brief IsApplicationEntityMovable +## @param[in] application_id ApplicationId. +## @param[in] storage_id \ref NcmStorageId +## @param[out] out Output flag. +## + +proc nsMoveApplicationEntity*(applicationId: U64; storageId: NcmStorageId): Result {. + cdecl, importc: "nsMoveApplicationEntity".} +## * +## @brief MoveApplicationEntity +## @note Only available on [1.0.0-9.2.0]. +## @param[in] application_id ApplicationId. +## @param[in] storage_id \ref NcmStorageId +## + +proc nsRequestApplicationUpdateInfo*(a: ptr AsyncValue; applicationId: U64): Result {. + cdecl, importc: "nsRequestApplicationUpdateInfo".} +## * +## @brief RequestApplicationUpdateInfo +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @param[out] a \ref AsyncValue. The data that can be read from this is u8 ApplicationUpdateInfo. qlaunch just checks whether this is 0. +## @param application_id ApplicationId. +## + +proc nsCancelApplicationDownload*(applicationId: U64): Result {.cdecl, + importc: "nsCancelApplicationDownload".} +## * +## @brief CancelApplicationDownload +## @param[in] application_id ApplicationId. +## + +proc nsResumeApplicationDownload*(applicationId: U64): Result {.cdecl, + importc: "nsResumeApplicationDownload".} +## * +## @brief ResumeApplicationDownload +## @param[in] application_id ApplicationId. +## + +proc nsCheckApplicationLaunchVersion*(applicationId: U64): Result {.cdecl, + importc: "nsCheckApplicationLaunchVersion".} +## * +## @brief CheckApplicationLaunchVersion +## @param[in] application_id ApplicationId. +## + +proc nsCalculateApplicationDownloadRequiredSize*(applicationId: U64; + storageId: ptr NcmStorageId; size: ptr S64): Result {.cdecl, + importc: "nsCalculateApplicationDownloadRequiredSize".} +## * +## @brief CalculateApplicationApplyDeltaRequiredSize +## @param[in] application_id ApplicationId. +## @param[out] storage_id Output \ref NcmStorageId. +## @param[out] size Output size. +## + +proc nsCleanupSdCard*(): Result {.cdecl, importc: "nsCleanupSdCard".} +## * +## @brief CleanupSdCard +## + +proc nsGetSdCardMountStatusChangedEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nsGetSdCardMountStatusChangedEvent".} +## * +## @brief GetSdCardMountStatusChangedEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc nsGetGameCardUpdateDetectionEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nsGetGameCardUpdateDetectionEvent".} +## * +## @brief GetGameCardUpdateDetectionEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc nsDisableApplicationAutoDelete*(applicationId: U64): Result {.cdecl, + importc: "nsDisableApplicationAutoDelete".} +## * +## @brief DisableApplicationAutoDelete +## @param[in] application_id ApplicationId. +## + +proc nsEnableApplicationAutoDelete*(applicationId: U64): Result {.cdecl, + importc: "nsEnableApplicationAutoDelete".} +## * +## @brief EnableApplicationAutoDelete +## @param[in] application_id ApplicationId. +## + +proc nsSetApplicationTerminateResult*(applicationId: U64; res: Result): Result {. + cdecl, importc: "nsSetApplicationTerminateResult".} +## * +## @brief SetApplicationTerminateResult +## @param[in] application_id ApplicationId. +## @param[in] res Result. +## + +proc nsClearApplicationTerminateResult*(applicationId: U64): Result {.cdecl, + importc: "nsClearApplicationTerminateResult".} +## * +## @brief ClearApplicationTerminateResult +## @param[in] application_id ApplicationId. +## + +proc nsGetLastSdCardMountUnexpectedResult*(): Result {.cdecl, + importc: "nsGetLastSdCardMountUnexpectedResult".} +## * +## @brief GetLastSdCardMountUnexpectedResult +## + +proc nsGetRequestServerStopper*(r: ptr NsRequestServerStopper): Result {.cdecl, + importc: "nsGetRequestServerStopper".} +## * +## @brief Opens a \ref NsRequestServerStopper. +## @note Only available on [2.0.0+]. +## @param[out] r \ref NsRequestServerStopper +## + +proc nsCancelApplicationApplyDelta*(applicationId: U64): Result {.cdecl, + importc: "nsCancelApplicationApplyDelta".} +## * +## @brief CancelApplicationApplyDelta +## @note Only available on [3.0.0+]. +## @param[in] application_id ApplicationId. +## + +proc nsResumeApplicationApplyDelta*(applicationId: U64): Result {.cdecl, + importc: "nsResumeApplicationApplyDelta".} +## * +## @brief ResumeApplicationApplyDelta +## @note Only available on [3.0.0+]. +## @param[in] application_id ApplicationId. +## + +proc nsCalculateApplicationApplyDeltaRequiredSize*(applicationId: U64; + storageId: ptr NcmStorageId; size: ptr S64): Result {.cdecl, + importc: "nsCalculateApplicationApplyDeltaRequiredSize".} +## * +## @brief CalculateApplicationApplyDeltaRequiredSize +## @note Only available on [3.0.0+]. +## @param[in] application_id ApplicationId. +## @param[out] storage_id Output \ref NcmStorageId. +## @param[out] size Output size. +## + +proc nsResumeAll*(): Result {.cdecl, importc: "nsResumeAll".} +## * +## @brief ResumeAll +## @note Only available on [3.0.0+]. +## + +proc nsGetStorageSize*(storageId: NcmStorageId; totalSpaceSize: ptr S64; + freeSpaceSize: ptr S64): Result {.cdecl, + importc: "nsGetStorageSize".} +## * +## @brief Temporarily mounts the specified fs ContentStorage, then uses fs GetTotalSpaceSize/GetFreeSpaceSize with that mounted ContentStorage. +## @note Only available on [3.0.0+]. +## @param[in] storage_id \ref NcmStorageId, must be ::NcmStorageId_BuiltInUser or ::NcmStorageId_SdCard. +## @param[out] total_space_size Output from GetTotalSpaceSize. +## @param[out] free_space_size Output from GetFreeSpaceSize. +## + +proc nsRequestUpdateApplication2*(a: ptr AsyncResult; applicationId: U64): Result {. + cdecl, importc: "nsRequestUpdateApplication2".} +## * +## @brief RequestUpdateApplication2 +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] application_id ApplicationId. +## + +proc nsDeleteUserSaveDataAll*(p: ptr NsProgressMonitorForDeleteUserSaveDataAll; + uid: AccountUid): Result {.cdecl, + importc: "nsDeleteUserSaveDataAll".} +## * +## @brief DeleteUserSaveDataAll +## @param[in] p \ref NsProgressMonitorForDeleteUserSaveDataAll +## @param[in] uid \ref AccountUid +## + +proc nsDeleteUserSystemSaveData*(uid: AccountUid; systemSaveDataId: U64): Result {. + cdecl, importc: "nsDeleteUserSystemSaveData".} +## * +## @brief DeleteUserSystemSaveData +## @param[in] uid \ref AccountUid +## @param[in] system_save_data_id SystemSaveDataId +## + +proc nsDeleteSaveData*(saveDataSpaceId: FsSaveDataSpaceId; saveDataId: U64): Result {. + cdecl, importc: "nsDeleteSaveData".} +## * +## @brief DeleteSaveData +## @note Only available on [6.0.0+]. +## @param[in] save_data_space_id \ref FsSaveDataSpaceId +## @param[in] save_data_id SaveDataId +## + +proc nsUnregisterNetworkServiceAccount*(uid: AccountUid): Result {.cdecl, + importc: "nsUnregisterNetworkServiceAccount".} +## * +## @brief UnregisterNetworkServiceAccount +## @param[in] uid \ref AccountUid +## + +proc nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion*(uid: AccountUid): Result {. + cdecl, importc: "nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion".} +## * +## @brief UnregisterNetworkServiceAccountWithUserSaveDataDeletion +## @note Only available on [6.0.0+]. +## @param[in] uid \ref AccountUid +## + +proc nsRequestDownloadApplicationControlData*(a: ptr AsyncResult; applicationId: U64): Result {. + cdecl, importc: "nsRequestDownloadApplicationControlData".} +## * +## @brief RequestDownloadApplicationControlData +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @param[out] a \ref AsyncResult +## @param[in] application_id ApplicationId. +## + +proc nsListApplicationTitle*(a: ptr AsyncValue; source: NsApplicationControlSource; + applicationIds: ptr U64; count: S32; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "nsListApplicationTitle".} +## * +## @brief ListApplicationTitle +## @note The data available with \ref asyncValueGet is a s32 for the offset within the buffer where the output data is located, \ref asyncValueGetSize returns the total byte-size of the data located here. The data located here is the \ref NacpLanguageEntry for each specified ApplicationId. +## @note Only available on [8.0.0+]. +## @param[out] a \ref AsyncValue +## @param[in] source Source, qlaunch uses ::NsApplicationControlSource_Storage. +## @param[in] application_ids Input array of ApplicationIds. +## @param[in] count Size of the application_ids array in entries. +## @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. +## @param[in] size 0x1000-byte aligned buffer size for TransferMemory. This must be at least: count*sizeof(\ref NacpLanguageEntry) + count*sizeof(u64) + count*sizeof(\ref NsApplicationControlData). +## + +proc nsListApplicationIcon*(a: ptr AsyncValue; source: NsApplicationControlSource; + applicationIds: ptr U64; count: S32; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "nsListApplicationIcon".} +## * +## @brief ListApplicationIcon +## @note The data available with \ref asyncValueGet is a s32 for the offset within the buffer where the output data is located, \ref asyncValueGetSize returns the total byte-size of the data located here. This data is: an u64 for total entries, an array of u64s for each icon size, then the icon JPEGs for the specified ApplicationIds. +## @note Only available on [8.0.0+]. +## @param[out] a \ref AsyncValue +## @param[in] source Source. +## @param[in] application_ids Input array of ApplicationIds. +## @param[in] count Size of the application_ids array in entries. +## @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. +## @param[in] size 0x1000-byte aligned buffer size for TransferMemory. This must be at least: 0x4 + count*sizeof(u64) + count*sizeof(\ref NsApplicationControlData::icon) + count*sizeof(u64) + sizeof(\ref NsApplicationControlData). +## + +proc nsRequestCheckGameCardRegistration*(a: ptr AsyncResult; applicationId: U64): Result {. + cdecl, importc: "nsRequestCheckGameCardRegistration".} +## * +## @brief RequestCheckGameCardRegistration +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [2.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] application_id ApplicationId. +## + +proc nsRequestGameCardRegistrationGoldPoint*(a: ptr AsyncValue; uid: AccountUid; + applicationId: U64): Result {.cdecl, importc: "nsRequestGameCardRegistrationGoldPoint".} +## * +## @brief RequestGameCardRegistrationGoldPoint +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [2.0.0+]. +## @param[out] a \ref AsyncValue. The data that can be read from this is 4-bytes. +## @param[in] uid \ref AccountUid +## @param[in] application_id ApplicationId. +## + +proc nsRequestRegisterGameCard*(a: ptr AsyncResult; uid: AccountUid; + applicationId: U64; inval: S32): Result {.cdecl, + importc: "nsRequestRegisterGameCard".} +## * +## @brief RequestRegisterGameCard +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [2.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] uid \ref AccountUid +## @param[in] application_id ApplicationId. +## @param[in] inval Input value. +## + +proc nsGetGameCardMountFailureEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nsGetGameCardMountFailureEvent".} +## * +## @brief GetGameCardMountFailureEvent +## @note The Event must be closed by the user once finished with it. +## @note Only available on [3.0.0+]. +## @param[out] out_event Output Event with autoclear=false. +## + +proc nsIsGameCardInserted*(`out`: ptr bool): Result {.cdecl, + importc: "nsIsGameCardInserted".} +## * +## @brief IsGameCardInserted +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc nsEnsureGameCardAccess*(): Result {.cdecl, importc: "nsEnsureGameCardAccess".} +## * +## @brief EnsureGameCardAccess +## @note Only available on [3.0.0+]. +## + +proc nsGetLastGameCardMountFailureResult*(): Result {.cdecl, + importc: "nsGetLastGameCardMountFailureResult".} +## * +## @brief GetLastGameCardMountFailureResult +## @note Only available on [3.0.0+]. +## + +proc nsListApplicationIdOnGameCard*(applicationIds: ptr U64; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "nsListApplicationIdOnGameCard".} +## * +## @brief ListApplicationIdOnGameCard +## @note Only available on [5.0.0+]. +## @param[out] application_ids Output array of ApplicationIds. +## @param[in] count Size of the application_ids array in entries. +## @param[out] total_out Total output entries. +## + +proc nsTouchApplication*(applicationId: U64): Result {.cdecl, + importc: "nsTouchApplication".} +## * +## @brief TouchApplication +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## + +proc nsIsApplicationUpdateRequested*(applicationId: U64; flag: ptr bool; + `out`: ptr U32): Result {.cdecl, + importc: "nsIsApplicationUpdateRequested".} +## * +## @brief IsApplicationUpdateRequested +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## @param[out] flag Output flag, indicating whether out is valid. +## @param[out] out Output value. +## + +proc nsWithdrawApplicationUpdateRequest*(applicationId: U64): Result {.cdecl, + importc: "nsWithdrawApplicationUpdateRequest".} +## * +## @brief WithdrawApplicationUpdateRequest +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## + +proc nsRequestVerifyAddOnContentsRights*(a: ptr NsProgressAsyncResult; + applicationId: U64): Result {.cdecl, + importc: "nsRequestVerifyAddOnContentsRights".} +## * +## @brief RequestVerifyAddOnContentsRights +## @note Only available on [3.0.0-9.2.0]. +## @param[out] a \ref NsProgressAsyncResult +## @param[in] application_id ApplicationId. +## + +proc nsRequestVerifyApplication*(a: ptr NsProgressAsyncResult; applicationId: U64; + unk: U32; buffer: pointer; size: csize_t): Result {. + cdecl, importc: "nsRequestVerifyApplication".} +## * +## @brief RequestVerifyApplication +## @note On pre-5.0.0 this uses cmd RequestVerifyApplicationDeprecated, otherwise cmd RequestVerifyApplication is used. +## @param[out] a \ref NsProgressAsyncResult. The data available with \ref nsProgressAsyncResultGetProgress is basically the same as \ref NsSystemUpdateProgress. +## @param[in] application_id ApplicationId. +## @param[in] unk Unknown. A default value of 0x7 can be used (which is what qlaunch uses). Only used on [5.0.0+]. +## @param buffer 0x1000-byte aligned buffer for TransferMemory. This buffer must not be accessed until the async operation finishes. +## @param[in] size 0x1000-byte aligned buffer size for TransferMemory. qlaunch uses size 0x100000. +## + +proc nsIsAnyApplicationEntityInstalled*(applicationId: U64; `out`: ptr bool): Result {. + cdecl, importc: "nsIsAnyApplicationEntityInstalled".} +## * +## @brief IsAnyApplicationEntityInstalled +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## @param[out] out Output flag. +## + +proc nsCleanupUnavailableAddOnContents*(applicationId: U64; uid: AccountUid): Result {. + cdecl, importc: "nsCleanupUnavailableAddOnContents".} +## * +## @brief CleanupUnavailableAddOnContents +## @note Only available on [6.0.0+]. +## @param[in] application_id ApplicationId. +## @param[in] uid \ref AccountUid +## + +proc nsFormatSdCard*(): Result {.cdecl, importc: "nsFormatSdCard".} +## * +## @brief FormatSdCard +## @note Only available on [2.0.0+]. +## + +proc nsNeedsSystemUpdateToFormatSdCard*(`out`: ptr bool): Result {.cdecl, + importc: "nsNeedsSystemUpdateToFormatSdCard".} +## * +## @brief NeedsSystemUpdateToFormatSdCard +## @note Only available on [2.0.0+]. +## @param[out] out Output flag. +## + +proc nsGetLastSdCardFormatUnexpectedResult*(): Result {.cdecl, + importc: "nsGetLastSdCardFormatUnexpectedResult".} +## * +## @brief GetLastSdCardFormatUnexpectedResult +## @note Only available on [2.0.0+]. +## + +proc nsGetApplicationView*(views: ptr NsApplicationView; applicationIds: ptr U64; + count: S32): Result {.cdecl, + importc: "nsGetApplicationView".} +## * +## @brief GetApplicationView +## @note Only available on [3.0.0+], on prior system-versions use \ref nsGetApplicationViewDeprecated instead. +## @param[out] out Output array of \ref NsApplicationView. +## @param[in] application_ids Input array of ApplicationIds. +## @param[in] count Size of the input/output arrays in entries. +## + +proc nsGetApplicationViewDownloadErrorContext*(applicationId: U64; + context: ptr ErrorContext): Result {.cdecl, importc: "nsGetApplicationViewDownloadErrorContext".} +## * +## @brief GetApplicationViewDownloadErrorContext +## @note Only available on [4.0.0+]. +## @param[in] application_id ApplicationId +## @param[out] context \ref ErrorContext +## + +proc nsGetApplicationViewWithPromotionInfo*( + `out`: ptr NsApplicationViewWithPromotionInfo; applicationIds: ptr U64; count: S32): Result {. + cdecl, importc: "nsGetApplicationViewWithPromotionInfo".} +## * +## @brief GetApplicationViewWithPromotionInfo +## @note Only available on [8.0.0+]. +## @param[out] out Output array of \ref NsApplicationViewWithPromotionInfo. +## @param[in] application_ids Input array of ApplicationIds. +## @param[in] count Size of the input/output arrays in entries. +## + +proc nsRequestDownloadApplicationPrepurchasedRights*(a: ptr AsyncResult; + applicationId: U64): Result {.cdecl, importc: "nsRequestDownloadApplicationPrepurchasedRights".} +## * +## @brief RequestDownloadApplicationPrepurchasedRights +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] application_id ApplicationId. +## + +proc nsGetSystemDeliveryInfo*(info: ptr NsSystemDeliveryInfo): Result {.cdecl, + importc: "nsGetSystemDeliveryInfo".} +## * +## @brief Generates a \ref NsSystemDeliveryInfo using the currently installed SystemUpdate meta. +## @note Only available on [4.0.0+]. +## @param[out] info \ref NsSystemDeliveryInfo +## + +proc nsSelectLatestSystemDeliveryInfo*(sysList: ptr NsSystemDeliveryInfo; + sysCount: S32; + baseInfo: ptr NsSystemDeliveryInfo; + appList: ptr NsApplicationDeliveryInfo; + appCount: S32; index: ptr S32): Result {.cdecl, + importc: "nsSelectLatestSystemDeliveryInfo".} +## * +## @brief SelectLatestSystemDeliveryInfo +## @note This selects the \ref NsSystemDeliveryInfo with the latest version from sys_list, using minimum versions determined from app_list/state and base_info. This also does various validation, etc. +## @note Only available on [4.0.0+]. +## @param[in] sys_list Input array of \ref NsSystemDeliveryInfo. +## @param[in] sys_count Size of the sys_list array in entries. +## @param[in] base_info \ref NsSystemDeliveryInfo +## @param[in] app_list Input array of \ref NsApplicationDeliveryInfo. This can be NULL. +## @param[in] app_count Size of the app_list array in entries. This can be 0. +## @param[out] index Output index for the selected entry in sys_list, -1 if none found. +## + +proc nsVerifyDeliveryProtocolVersion*(info: ptr NsSystemDeliveryInfo): Result {. + cdecl, importc: "nsVerifyDeliveryProtocolVersion".} +## * +## @brief VerifyDeliveryProtocolVersion +## @note Only available on [4.0.0+]. +## @param[in] info \ref NsSystemDeliveryInfo +## + +proc nsGetApplicationDeliveryInfo*(info: ptr NsApplicationDeliveryInfo; count: S32; + applicationId: U64; attr: U32; totalOut: ptr S32): Result {. + cdecl, importc: "nsGetApplicationDeliveryInfo".} +## * +## @brief Generates \ref NsApplicationDeliveryInfo for the specified ApplicationId. +## @note Only available on [4.0.0+]. +## @param[out] info Output array of \ref NsApplicationDeliveryInfo. +## @param[in] count Size of the array in entries. +## @param[in] application_id ApplicationId +## @param[in] attr ApplicationDeliveryAttributeTag bitmask. +## @param[out] total_out Total output entries. +## + +proc nsHasAllContentsToDeliver*(info: ptr NsApplicationDeliveryInfo; count: S32; + `out`: ptr bool): Result {.cdecl, + importc: "nsHasAllContentsToDeliver".} +## * +## @brief HasAllContentsToDeliver +## @note Only available on [4.0.0+]. +## @param[in] info Input array of \ref NsApplicationDeliveryInfo. +## @param[in] count Size of the array in entries. Must be value 1. +## @param[out] out Output flag. +## + +proc nsCompareApplicationDeliveryInfo*(info0: ptr NsApplicationDeliveryInfo; + count0: S32; + info1: ptr NsApplicationDeliveryInfo; + count1: S32; `out`: ptr S32): Result {.cdecl, + importc: "nsCompareApplicationDeliveryInfo".} +## * +## @brief Both \ref NsApplicationDeliveryInfo are validated, then the application_version in the first/second \ref NsApplicationDeliveryInfo are compared. +## @note Only available on [4.0.0+]. +## @param[in] info0 First input array of \ref NsApplicationDeliveryInfo. +## @param[in] count0 Size of the info0 array in entries. Must be value 1. +## @param[in] info1 Second input array of \ref NsApplicationDeliveryInfo. +## @param[in] count1 Size of the info1 array in entries. Must be value 1. +## @param[out] out Comparison result: -1 for less than, 0 for equal, and 1 for higher than. +## + +proc nsCanDeliverApplication*(info0: ptr NsApplicationDeliveryInfo; count0: S32; + info1: ptr NsApplicationDeliveryInfo; count1: S32; + `out`: ptr bool): Result {.cdecl, + importc: "nsCanDeliverApplication".} +## * +## @brief CanDeliverApplication +## @note Only available on [4.0.0+]. +## @param[in] info0 First input array of \ref NsApplicationDeliveryInfo. +## @param[in] count0 Size of the info0 array in entries. Must be value <=1, when 0 this will return 0 with out set to 0. +## @param[in] info1 Second input array of \ref NsApplicationDeliveryInfo. +## @param[in] count1 Size of the info1 array in entries. Must be value 1. +## @param[out] out Output flag. +## + +proc nsListContentMetaKeyToDeliverApplication*(meta: ptr NcmContentMetaKey; + metaCount: S32; metaIndex: S32; info: ptr NsApplicationDeliveryInfo; + infoCount: S32; totalOut: ptr S32): Result {.cdecl, + importc: "nsListContentMetaKeyToDeliverApplication".} +## * +## @brief ListContentMetaKeyToDeliverApplication +## @note Only available on [4.0.0+]. +## @param[out] meta Output array of \ref NcmContentMetaKey. +## @param[in] meta_count Size of the meta array in entries. Must be at least 1, only 1 entry will be returned. +## @param[in] meta_index Meta entry index. An output \ref NcmContentMetaKey will not be returned when this value is larger than 0. +## @param[in] info Input array of \ref NsApplicationDeliveryInfo. +## @param[in] info_count Size of the info array in entries. Must be value 1. +## @param[out] total_out Total output entries. +## + +proc nsNeedsSystemUpdateToDeliverApplication*( + info: ptr NsApplicationDeliveryInfo; count: S32; + sysInfo: ptr NsSystemDeliveryInfo; `out`: ptr bool): Result {.cdecl, + importc: "nsNeedsSystemUpdateToDeliverApplication".} +## * +## @brief After validation etc, this sets the output bool by comparing system-version fields in the \ref NsSystemDeliveryInfo / info-array and with a state field. +## @note Only available on [4.0.0+]. +## @param[in] info Input array of \ref NsApplicationDeliveryInfo. +## @param[in] count Size of the info array in entries. Must be value 1. +## @param[in] sys_info \ref NsSystemDeliveryInfo +## @param[out] out Output flag. +## + +proc nsEstimateRequiredSize*(meta: ptr NcmContentMetaKey; count: S32; `out`: ptr S64): Result {. + cdecl, importc: "nsEstimateRequiredSize".} +## * +## @brief EstimateRequiredSize +## @note Only available on [4.0.0+]. +## @param[in] meta Input array of \ref NcmContentMetaKey. +## @param[in] count Size of the meta array in entries. When less than 1, this will return 0 with out set to 0. +## @param[out] out Output size. +## + +proc nsRequestReceiveApplication*(a: ptr AsyncResult; `addr`: U32; port: U16; + applicationId: U64; meta: ptr NcmContentMetaKey; + count: S32; storageId: NcmStorageId): Result {. + cdecl, importc: "nsRequestReceiveApplication".} +## * +## @brief RequestReceiveApplication +## @note This is the Application version of \ref nssuControlRequestReceiveSystemUpdate, see the notes for that. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] addr Server IPv4 address. +## @param[in] port Socket port. qlaunch uses value 55556. +## @param[in] application_id ApplicationId +## @param[in] meta Input array of \ref NcmContentMetaKey. The ::NcmContentMetaType must match ::NcmContentMetaType_Patch. +## @param[in] count Size of the meta array in entries. +## @param[in] storage_id \ref NcmStorageId. qlaunch uses ::NcmStorageId_Any. +## + +proc nsCommitReceiveApplication*(applicationId: U64): Result {.cdecl, + importc: "nsCommitReceiveApplication".} +## * +## @brief CommitReceiveApplication +## @note Only available on [4.0.0+]. +## @param[in] application_id ApplicationId +## + +proc nsGetReceiveApplicationProgress*(applicationId: U64; + `out`: ptr NsReceiveApplicationProgress): Result {. + cdecl, importc: "nsGetReceiveApplicationProgress".} +## * +## @brief GetReceiveApplicationProgress +## @note Only available on [4.0.0+]. +## @param[in] application_id ApplicationId +## @param[out] out \ref NsReceiveApplicationProgress +## + +proc nsRequestSendApplication*(a: ptr AsyncResult; `addr`: U32; port: U16; + applicationId: U64; meta: ptr NcmContentMetaKey; + count: S32): Result {.cdecl, + importc: "nsRequestSendApplication".} +## * +## @brief RequestSendApplication +## @note This is the Application version of \ref nssuRequestSendSystemUpdate, see the notes for that. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] addr Client IPv4 address. +## @param[in] port Socket port. qlaunch uses value 55556. +## @param[in] application_id ApplicationId +## @param[in] meta Input array of \ref NcmContentMetaKey. The ::NcmContentMetaType must match ::NcmContentMetaType_Patch. +## @param[in] count Size of the meta array in entries. +## + +proc nsGetSendApplicationProgress*(applicationId: U64; + `out`: ptr NsSendApplicationProgress): Result {. + cdecl, importc: "nsGetSendApplicationProgress".} +## * +## @brief GetSendApplicationProgress +## @note Only available on [4.0.0+]. +## @param[in] application_id ApplicationId +## @param[out] out \ref NsSendApplicationProgress +## + +proc nsCompareSystemDeliveryInfo*(info0: ptr NsSystemDeliveryInfo; + info1: ptr NsSystemDeliveryInfo; `out`: ptr S32): Result {. + cdecl, importc: "nsCompareSystemDeliveryInfo".} +## * +## @brief Both \ref NsSystemDeliveryInfo are validated, then the system_update_meta_version in the first/second \ref NsSystemDeliveryInfo are compared. +## @note Only available on [4.0.0+]. +## @param[in] info0 First \ref NsSystemDeliveryInfo. +## @param[in] info1 Second \ref NsSystemDeliveryInfo. +## @param[out] out Comparison result: -1 for less than, 0 for equal, and 1 for higher than. +## + +proc nsListNotCommittedContentMeta*(meta: ptr NcmContentMetaKey; count: S32; + applicationId: U64; unk: S32; totalOut: ptr S32): Result {. + cdecl, importc: "nsListNotCommittedContentMeta".} +## * +## @brief ListNotCommittedContentMeta +## @note Only available on [4.0.0+]. +## @param[out] meta Output array of \ref NcmContentMetaKey. +## @param[in] count Size of the meta array in entries. +## @param[in] application_id ApplicationId +## @param[in] unk Unknown. +## @param[out] total_out Total output entries. +## + +proc nsGetApplicationDeliveryInfoHash*(info: ptr NsApplicationDeliveryInfo; + count: S32; outHash: ptr U8): Result {.cdecl, + importc: "nsGetApplicationDeliveryInfoHash".} +## * +## @brief This extracts data from the input array for hashing with SHA256, with validation being done when handling each entry. +## @note Only available on [5.0.0+]. +## @param[in] info Input array of \ref NsApplicationDeliveryInfo. +## @param[in] count Size of the array in entries. +## @param[out] out_hash Output 0x20-byte SHA256 hash. +## + +proc nsGetApplicationTerminateResult*(applicationId: U64; res: ptr Result): Result {. + cdecl, importc: "nsGetApplicationTerminateResult".} +## * +## @brief GetApplicationTerminateResult +## @note Only available on [6.0.0+]. +## @param[in] application_id ApplicationId. +## @param[out] res Output Result. +## + +proc nsGetApplicationRightsOnClient*(rights: ptr NsApplicationRightsOnClient; + count: S32; applicationId: U64; uid: AccountUid; + flags: U32; totalOut: ptr S32): Result {.cdecl, + importc: "nsGetApplicationRightsOnClient".} +## * +## @brief GetApplicationRightsOnClient +## @note Only available on [6.0.0+]. +## @param[out] rights Output array of \ref NsApplicationRightsOnClient. +## @param[in] count Size of the rights array in entries. qlaunch uses value 3 for this. +## @param[in] application_id ApplicationId +## @param[in] uid \ref AccountUid, can optionally be all-zero. +## @param[in] flags Flags. Official sw hard-codes this to value 0x3. +## @param[out] total_out Total output entries. +## + +proc nsRequestNoDownloadRightsErrorResolution*(a: ptr AsyncValue; applicationId: U64): Result {. + cdecl, importc: "nsRequestNoDownloadRightsErrorResolution".} +## * +## @brief RequestNoDownloadRightsErrorResolution +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [9.0.0+]. +## @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution. +## @param application_id ApplicationId. +## + +proc nsRequestResolveNoDownloadRightsError*(a: ptr AsyncValue; applicationId: U64): Result {. + cdecl, importc: "nsRequestResolveNoDownloadRightsError".} +## * +## @brief RequestResolveNoDownloadRightsError +## @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false. +## @note Only available on [9.0.0+]. +## @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution. +## @param application_id ApplicationId. +## + +proc nsGetPromotionInfo*(promotion: ptr NsPromotionInfo; applicationId: U64; + uid: AccountUid): Result {.cdecl, + importc: "nsGetPromotionInfo".} +## * +## @brief GetPromotionInfo +## @note Only available on [8.0.0+]. +## @param[out] promotion \ref NsPromotionInfo +## @param application_id ApplicationId. +## @param[in] uid \ref AccountUid +## + +proc nsClearTaskStatusList*(): Result {.cdecl, importc: "nsClearTaskStatusList".} +## /@} +## /@name IDownloadTaskInterface +## /@{ +## * +## @brief ClearTaskStatusList +## @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## + +proc nsRequestDownloadTaskList*(): Result {.cdecl, + importc: "nsRequestDownloadTaskList".} +## * +## @brief RequestDownloadTaskList +## @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## + +proc nsRequestEnsureDownloadTask*(a: ptr AsyncResult): Result {.cdecl, + importc: "nsRequestEnsureDownloadTask".} +## * +## @brief RequestEnsureDownloadTask +## @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## @param[out] a \ref AsyncResult +## + +proc nsListDownloadTaskStatus*(tasks: ptr NsDownloadTaskStatus; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "nsListDownloadTaskStatus".} +## * +## @brief ListDownloadTaskStatus +## @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## @param[out] tasks Output array of \ref NsDownloadTaskStatus. +## @param[in] count Size of the tasks array in entries. A maximum of 0x100 tasks can be stored in state. +## @param[out] total_out Total output entries. +## + +proc nsRequestDownloadTaskListData*(a: ptr AsyncValue): Result {.cdecl, + importc: "nsRequestDownloadTaskListData".} +## * +## @brief RequestDownloadTaskListData +## @note Uses \ref nsGetDownloadTaskInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## @param[out] a \ref AsyncValue +## + +proc nsTryCommitCurrentApplicationDownloadTask*(): Result {.cdecl, + importc: "nsTryCommitCurrentApplicationDownloadTask".} +## * +## @brief TryCommitCurrentApplicationDownloadTask +## @note Only available on [4.0.0+]. +## + +proc nsEnableAutoCommit*(): Result {.cdecl, importc: "nsEnableAutoCommit".} +## * +## @brief EnableAutoCommit +## @note Only available on [4.0.0+]. +## + +proc nsDisableAutoCommit*(): Result {.cdecl, importc: "nsDisableAutoCommit".} +## * +## @brief DisableAutoCommit +## @note Only available on [4.0.0+]. +## + +proc nsTriggerDynamicCommitEvent*(): Result {.cdecl, + importc: "nsTriggerDynamicCommitEvent".} +## * +## @brief TriggerDynamicCommitEvent +## @note Only available on [4.0.0+]. +## + +proc nsCalculateApplicationOccupiedSize*(applicationId: U64; + `out`: ptr NsApplicationOccupiedSize): Result {. + cdecl, importc: "nsCalculateApplicationOccupiedSize".} +## /@} +## /@name IContentManagementInterface +## /@{ +## * +## @brief CalculateApplicationOccupiedSize +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @param[in] application_id ApplicationId. +## @param[out] out \ref NsApplicationOccupiedSize +## + +proc nsCheckSdCardMountStatus*(): Result {.cdecl, + importc: "nsCheckSdCardMountStatus".} +## * +## @brief CheckSdCardMountStatus +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## + +proc nsGetTotalSpaceSize*(storageId: NcmStorageId; size: ptr S64): Result {.cdecl, + importc: "nsGetTotalSpaceSize".} +## * +## @brief Returns the total storage capacity (used + free) from content manager services. +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. +## @param[out] size Pointer to output the total storage size to. +## + +proc nsGetFreeSpaceSize*(storageId: NcmStorageId; size: ptr S64): Result {.cdecl, + importc: "nsGetFreeSpaceSize".} +## * +## @brief Returns the available storage capacity from content manager services. +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. +## @param[out] size Pointer to output the free storage size to. +## + +proc nsCountApplicationContentMeta*(applicationId: U64; `out`: ptr S32): Result {. + cdecl, importc: "nsCountApplicationContentMeta".} +## * +## @brief CountApplicationContentMeta +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## @param[out] out Output count. +## + +proc nsListApplicationContentMetaStatus*(applicationId: U64; index: S32; list: ptr NsApplicationContentMetaStatus; + count: S32; outEntrycount: ptr S32): Result {. + cdecl, importc: "nsListApplicationContentMetaStatus".} +## * +## @brief Gets an listing of \ref NsApplicationContentMetaStatus. +## @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. +## @note Only available on [2.0.0+]. +## @param[in] application_id ApplicationId. +## @param[in] index Starting entry index. +## @param[out] list Output array of \ref NsApplicationContentMetaStatus. +## @param[in] count Size of the list array in entries. +## @param[out] out_entrycount Total output entries. +## + +proc nsIsAnyApplicationRunning*(`out`: ptr bool): Result {.cdecl, + importc: "nsIsAnyApplicationRunning".} +## * +## @brief IsAnyApplicationRunning +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc nsRequestServerStopperClose*(r: ptr NsRequestServerStopper) {.cdecl, + importc: "nsRequestServerStopperClose".} +## /@} +## /@name IRequestServerStopper +## /@{ +## * +## @brief Close a \ref NsRequestServerStopper. +## @param r \ref NsRequestServerStopper +## + +proc nsProgressMonitorForDeleteUserSaveDataAllClose*( + p: ptr NsProgressMonitorForDeleteUserSaveDataAll): Result {.cdecl, + importc: "nsProgressMonitorForDeleteUserSaveDataAllClose".} +## /@} +## /@name IProgressMonitorForDeleteUserSaveDataAll +## /@{ +## * +## @brief Close a \ref NsProgressMonitorForDeleteUserSaveDataAll. When initialized this will use \ref nsProgressMonitorForDeleteUserSaveDataAllIsFinished, throwing errors on failure / when the operation isn't finished (without closing the object). +## @note Cancelling the operation before it's finished is not supported by \ref NsProgressMonitorForDeleteUserSaveDataAll. +## @param p \ref NsProgressMonitorForDeleteUserSaveDataAll +## + +proc nsProgressMonitorForDeleteUserSaveDataAllGetSystemEvent*( + p: ptr NsProgressMonitorForDeleteUserSaveDataAll; outEvent: ptr Event): Result {. + cdecl, importc: "nsProgressMonitorForDeleteUserSaveDataAllGetSystemEvent".} +## * +## @brief GetSystemEvent +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc nsProgressMonitorForDeleteUserSaveDataAllIsFinished*( + p: ptr NsProgressMonitorForDeleteUserSaveDataAll; `out`: ptr bool): Result {.cdecl, + importc: "nsProgressMonitorForDeleteUserSaveDataAllIsFinished".} +## * +## @brief IsFinished +## @param p \ref NsProgressMonitorForDeleteUserSaveDataAll +## @param[out] out Whether the operation finished. +## + +proc nsProgressMonitorForDeleteUserSaveDataAllGetResult*( + p: ptr NsProgressMonitorForDeleteUserSaveDataAll): Result {.cdecl, + importc: "nsProgressMonitorForDeleteUserSaveDataAllGetResult".} +## * +## @brief GetResult +## @param p \ref NsProgressMonitorForDeleteUserSaveDataAll +## + +proc nsProgressMonitorForDeleteUserSaveDataAllGetProgress*( + p: ptr NsProgressMonitorForDeleteUserSaveDataAll; + progress: ptr NsProgressForDeleteUserSaveDataAll): Result {.cdecl, + importc: "nsProgressMonitorForDeleteUserSaveDataAllGetProgress".} +## * +## @brief GetProgress +## @param p \ref NsProgressMonitorForDeleteUserSaveDataAll +## @param[out] progress Output \ref NsProgressForDeleteUserSaveDataAll. +## + +proc nsProgressAsyncResultClose*(a: ptr NsProgressAsyncResult) {.cdecl, + importc: "nsProgressAsyncResultClose".} +## /@} +## /@name IProgressAsyncResult +## /@{ +## * +## @brief Close a \ref NsProgressAsyncResult. +## @note When the object is initialized, this uses \ref nsProgressAsyncResultCancel then \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. +## @param a \ref NsProgressAsyncResult +## + +proc nsProgressAsyncResultWait*(a: ptr NsProgressAsyncResult; timeout: U64): Result {. + cdecl, importc: "nsProgressAsyncResultWait".} +## * +## @brief Waits for the async operation to finish using the specified timeout. +## @param a \ref NsProgressAsyncResult +## @param[in] timeout Timeout in nanoseconds. UINT64_MAX for no timeout. +## + +proc nsProgressAsyncResultGet*(a: ptr NsProgressAsyncResult): Result {.cdecl, + importc: "nsProgressAsyncResultGet".} +## * +## @brief Gets the Result. +## @note Prior to using the cmd, this uses \ref nsProgressAsyncResultWait with timeout=UINT64_MAX. +## @param a \ref NsProgressAsyncResult +## + +proc nsProgressAsyncResultCancel*(a: ptr NsProgressAsyncResult): Result {.cdecl, + importc: "nsProgressAsyncResultCancel".} +## * +## @brief Cancels the async operation. +## @note Used automatically by \ref nsProgressAsyncResultClose. +## @param a \ref NsProgressAsyncResult +## + +proc nsProgressAsyncResultGetProgress*(a: ptr NsProgressAsyncResult; + buffer: pointer; size: csize_t): Result {. + cdecl, importc: "nsProgressAsyncResultGetProgress".} +## * +## @brief Gets the progress. +## @param a \ref NsProgressAsyncResult +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size. +## + +proc nsProgressAsyncResultGetDetailResult*(a: ptr NsProgressAsyncResult): Result {. + cdecl, importc: "nsProgressAsyncResultGetDetailResult".} +## * +## @brief GetDetailResult +## @param a \ref NsProgressAsyncResult +## + +proc nsProgressAsyncResultGetErrorContext*(a: ptr NsProgressAsyncResult; + context: ptr ErrorContext): Result {.cdecl, importc: "nsProgressAsyncResultGetErrorContext".} +## * +## @brief Gets the \ref ErrorContext. +## @note Only available on [4.0.0+]. +## @param a \ref NsProgressAsyncResult +## @param[out] context \ref ErrorContext +## + +proc nsvmInitialize*(): Result {.cdecl, importc: "nsvmInitialize".} +## /@} +## /@name ns:vm +## /@{ +## / Initialize ns:vm. On pre-3.0.0 this must be used with \ref nsInitialize. + +proc nsvmExit*() {.cdecl, importc: "nsvmExit".} +## / Exit ns:vm. + +proc nsvmGetServiceSession*(): ptr Service {.cdecl, importc: "nsvmGetServiceSession".} +## / Gets the Service object for ns:vm. This is only initialized on [3.0.0+]. + +proc nsvmNeedsUpdateVulnerability*(`out`: ptr bool): Result {.cdecl, + importc: "nsvmNeedsUpdateVulnerability".} +## + +proc nsvmGetSafeSystemVersion*(`out`: ptr NcmContentMetaKey): Result {.cdecl, + importc: "nsvmGetSafeSystemVersion".} +## + +proc nsdevInitialize*(): Result {.cdecl, importc: "nsdevInitialize".} +## /< [4.0.0+] +## /@} +## /@name ns:dev +## /@{ +## / Initialize ns:dev. + +proc nsdevExit*() {.cdecl, importc: "nsdevExit".} +## / Initialize ns:dev. + +proc nsdevGetServiceSession*(): ptr Service {.cdecl, + importc: "nsdevGetServiceSession".} +## / Gets the Service object for ns:dev. + +proc nsdevLaunchProgram*(outPid: ptr U64; properties: ptr NsLaunchProperties; + flags: U32): Result {.cdecl, importc: "nsdevLaunchProgram".} +## + +proc nsdevTerminateProcess*(pid: U64): Result {.cdecl, + importc: "nsdevTerminateProcess".} +## /< [1.0.0-9.2.0] + +proc nsdevTerminateProgram*(tid: U64): Result {.cdecl, + importc: "nsdevTerminateProgram".} +## + +proc nsdevGetShellEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "nsdevGetShellEvent".} +## /< [1.0.0-9.2.0] + +proc nsdevGetShellEventInfo*(`out`: ptr NsShellEventInfo): Result {.cdecl, + importc: "nsdevGetShellEventInfo".} +## /< Autoclear for nsdevShellEvent is always true. [1.0.0-9.2.0] + +proc nsdevTerminateApplication*(): Result {.cdecl, + importc: "nsdevTerminateApplication".} +## /< [1.0.0-9.2.0] + +proc nsdevPrepareLaunchProgramFromHost*(`out`: ptr NsLaunchProperties; + path: cstring; pathLen: csize_t): Result {. + cdecl, importc: "nsdevPrepareLaunchProgramFromHost".} +## + +proc nsdevLaunchApplicationForDevelop*(outPid: ptr U64; applicationId: U64; flags: U32): Result {. + cdecl, importc: "nsdevLaunchApplicationForDevelop".} +## /< [1.0.0-9.2.0] + +proc nsdevLaunchApplicationFromHost*(outPid: ptr U64; path: cstring; pathLen: csize_t; + flags: U32): Result {.cdecl, + importc: "nsdevLaunchApplicationFromHost".} +## /< [1.0.0-9.2.0] + +proc nsdevLaunchApplicationWithStorageIdForDevelop*(outPid: ptr U64; + applicationId: U64; flags: U32; appStorageId: U8; patchStorageId: U8): Result {. + cdecl, importc: "nsdevLaunchApplicationWithStorageIdForDevelop".} +## /< [10.0.0+] + +proc nsdevIsSystemMemoryResourceLimitBoosted*(`out`: ptr bool): Result {.cdecl, + importc: "nsdevIsSystemMemoryResourceLimitBoosted".} +## + +proc nsdevGetRunningApplicationProcessIdForDevelop*(outPid: ptr U64): Result {.cdecl, + importc: "nsdevGetRunningApplicationProcessIdForDevelop".} +## /< [6.0.0-8.1.0] + +proc nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop*( + canBeActive: bool): Result {.cdecl, importc: "nsdevSetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop".} +## /< [6.0.0+] + +proc nssuInitialize*(): Result {.cdecl, importc: "nssuInitialize".} +## /< [6.0.0+] +## /@} +## /@name ns:su +## /@{ +## / Initialize ns:su. + +proc nssuExit*() {.cdecl, importc: "nssuExit".} +## / Exit ns:su. + +proc nssuGetServiceSession*(): ptr Service {.cdecl, importc: "nssuGetServiceSession".} +## / Gets the Service object for ns:su. + +proc nssuGetBackgroundNetworkUpdateState*( + `out`: ptr NsBackgroundNetworkUpdateState): Result {.cdecl, + importc: "nssuGetBackgroundNetworkUpdateState".} +## * +## @brief Gets the \ref NsBackgroundNetworkUpdateState. +## @note Internally this uses nim commands ListSystemUpdateTask and GetSystemUpdateTaskInfo to determine the output state. +## @param[out] out \ref NsBackgroundNetworkUpdateState +## + +proc nssuOpenSystemUpdateControl*(c: ptr NsSystemUpdateControl): Result {.cdecl, + importc: "nssuOpenSystemUpdateControl".} +## * +## @brief Opens a \ref NsSystemUpdateControl. +## @note Only 1 \ref NsSystemUpdateControl can be open at a time. +## @param[out] c \ref NsSystemUpdateControl +## + +proc nssuNotifyExFatDriverRequired*(): Result {.cdecl, + importc: "nssuNotifyExFatDriverRequired".} +## * +## @brief Uses nim ListSystemUpdateTask, then uses the task with DestroySystemUpdateTask if it exists. Then this runs ExFat handling, updates state, and sets the same state flag as \ref nssuRequestBackgroundNetworkUpdate. +## @note Only usable when a \ref NsSystemUpdateControl isn't open. +## + +proc nssuClearExFatDriverStatusForDebug*(): Result {.cdecl, + importc: "nssuClearExFatDriverStatusForDebug".} +## * +## @brief ClearExFatDriverStatusForDebug +## + +proc nssuRequestBackgroundNetworkUpdate*(): Result {.cdecl, + importc: "nssuRequestBackgroundNetworkUpdate".} +## * +## @brief RequestBackgroundNetworkUpdate +## @note Only usable when a \ref NsSystemUpdateControl isn't open. +## + +proc nssuNotifyBackgroundNetworkUpdate*(key: ptr NcmContentMetaKey): Result {.cdecl, + importc: "nssuNotifyBackgroundNetworkUpdate".} +## * +## @brief This checks whether a sysupdate is needed with the input \ref NcmContentMetaKey using NCM commands, if not this will just return 0. Otherwise, this will then run code which is identical to \ref nssuRequestBackgroundNetworkUpdate. +## @note Only usable when a \ref NsSystemUpdateControl isn't open. +## @param[in] key \ref NcmContentMetaKey +## + +proc nssuNotifyExFatDriverDownloadedForDebug*(): Result {.cdecl, + importc: "nssuNotifyExFatDriverDownloadedForDebug".} +## * +## @brief NotifyExFatDriverDownloadedForDebug +## + +proc nssuGetSystemUpdateNotificationEventForContentDelivery*(outEvent: ptr Event): Result {. + cdecl, importc: "nssuGetSystemUpdateNotificationEventForContentDelivery".} +## * +## @brief Gets an Event which can be signaled by \ref nssuNotifySystemUpdateForContentDelivery. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc nssuNotifySystemUpdateForContentDelivery*(): Result {.cdecl, + importc: "nssuNotifySystemUpdateForContentDelivery".} +## * +## @brief Signals the event returned by \ref nssuGetSystemUpdateNotificationEventForContentDelivery. +## + +proc nssuPrepareShutdown*(): Result {.cdecl, importc: "nssuPrepareShutdown".} +## * +## @brief This does shutdown preparation. +## @note This is used by am-sysmodule, so generally there's no need to use this. +## @note Only available on [3.0.0+]. +## + +proc nssuDestroySystemUpdateTask*(): Result {.cdecl, + importc: "nssuDestroySystemUpdateTask".} +## * +## @brief This uses nim ListSystemUpdateTask, then when a task is returned uses it with DestroySystemUpdateTask. +## @note Only available on [4.0.0+]. +## + +proc nssuRequestSendSystemUpdate*(a: ptr AsyncResult; `addr`: U32; port: U16; + info: ptr NsSystemDeliveryInfo): Result {.cdecl, + importc: "nssuRequestSendSystemUpdate".} +## * +## @brief RequestSendSystemUpdate +## @note The system will use the input addr/port with bind(), the input addr will eventually be validated with the addr from accept(). addr/port are little-endian. +## @note After the system accepts a connection etc, an error will be thrown if the system is Internet-connected. +## @note Only available on [4.0.0+]. +## @param[out] a \ref AsyncResult +## @param[in] addr Client IPv4 address. qlaunch uses a local-WLAN addr. +## @param[in] port Socket port. qlaunch uses value 55556. +## @param[in] info \ref NsSystemDeliveryInfo +## + +proc nssuGetSendSystemUpdateProgress*(`out`: ptr NsSystemUpdateProgress): Result {. + cdecl, importc: "nssuGetSendSystemUpdateProgress".} +## * +## @brief GetSendSystemUpdateProgress +## @note Only available on [4.0.0+]. +## @param[out] out \ref NsSystemUpdateProgress +## + +proc nssuControlClose*(c: ptr NsSystemUpdateControl) {.cdecl, + importc: "nssuControlClose".} +## /@} +## /@name ISystemUpdateControl +## /@{ +## * +## @brief Close a \ref NsSystemUpdateControl. +## @param c \ref NsSystemUpdateControl +## + +proc nssuControlHasDownloaded*(c: ptr NsSystemUpdateControl; `out`: ptr bool): Result {. + cdecl, importc: "nssuControlHasDownloaded".} +## * +## @brief Gets whether a network sysupdate was downloaded, with install pending. +## @param c \ref NsSystemUpdateControl +## @param[out] out Output flag. +## + +proc nssuControlRequestCheckLatestUpdate*(c: ptr NsSystemUpdateControl; + a: ptr AsyncValue): Result {.cdecl, + importc: "nssuControlRequestCheckLatestUpdate".} +## * +## @brief RequestCheckLatestUpdate +## @param c \ref NsSystemUpdateControl +## @param[out] a \ref AsyncValue. The data that can be read from this is u8 \ref NsLatestSystemUpdate. +## + +proc nssuControlRequestDownloadLatestUpdate*(c: ptr NsSystemUpdateControl; + a: ptr AsyncResult): Result {.cdecl, + importc: "nssuControlRequestDownloadLatestUpdate".} +## * +## @brief RequestDownloadLatestUpdate +## @param c \ref NsSystemUpdateControl +## @param[out] a \ref AsyncResult +## + +proc nssuControlGetDownloadProgress*(c: ptr NsSystemUpdateControl; + `out`: ptr NsSystemUpdateProgress): Result {. + cdecl, importc: "nssuControlGetDownloadProgress".} +## * +## @brief GetDownloadProgress +## @param c \ref NsSystemUpdateControl +## @param[out] out \ref NsSystemUpdateProgress +## + +proc nssuControlApplyDownloadedUpdate*(c: ptr NsSystemUpdateControl): Result {.cdecl, + importc: "nssuControlApplyDownloadedUpdate".} +## * +## @brief ApplyDownloadedUpdate +## @param c \ref NsSystemUpdateControl +## + +proc nssuControlRequestPrepareCardUpdate*(c: ptr NsSystemUpdateControl; + a: ptr AsyncResult): Result {.cdecl, + importc: "nssuControlRequestPrepareCardUpdate".} +## * +## @brief RequestPrepareCardUpdate +## @param c \ref NsSystemUpdateControl +## @param[out] a \ref AsyncResult +## + +proc nssuControlGetPrepareCardUpdateProgress*(c: ptr NsSystemUpdateControl; + `out`: ptr NsSystemUpdateProgress): Result {.cdecl, + importc: "nssuControlGetPrepareCardUpdateProgress".} +## * +## @brief GetPrepareCardUpdateProgress +## @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. +## @param c \ref NsSystemUpdateControl +## @param[out] out \ref NsSystemUpdateProgress +## + +proc nssuControlHasPreparedCardUpdate*(c: ptr NsSystemUpdateControl; `out`: ptr bool): Result {. + cdecl, importc: "nssuControlHasPreparedCardUpdate".} +## * +## @brief HasPreparedCardUpdate +## @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. +## @param c \ref NsSystemUpdateControl +## @param[out] out Output flag. +## + +proc nssuControlApplyCardUpdate*(c: ptr NsSystemUpdateControl): Result {.cdecl, + importc: "nssuControlApplyCardUpdate".} +## * +## @brief ApplyCardUpdate +## @note \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater must have been used at some point prior to using this. +## @param c \ref NsSystemUpdateControl +## + +proc nssuControlGetDownloadedEulaDataSize*(c: ptr NsSystemUpdateControl; + path: cstring; filesize: ptr U64): Result {.cdecl, + importc: "nssuControlGetDownloadedEulaDataSize".} +## * +## @brief Gets the filesize for the specified DownloadedEulaData. +## @note This mounts the Eula SystemData, then uses the file ":/". +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] filesize Output filesize. +## + +proc nssuControlGetDownloadedEulaData*(c: ptr NsSystemUpdateControl; path: cstring; + buffer: pointer; size: csize_t; + filesize: ptr U64): Result {.cdecl, + importc: "nssuControlGetDownloadedEulaData".} +## * +## @brief Gets the specified DownloadedEulaData. +## @note See the note for \ref nssuControlGetDownloadedEulaDataSize. +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] buffer Output buffer. +## @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetDownloadedEulaDataSize. +## @param[out] filesize Output filesize. +## + +proc nssuControlSetupCardUpdate*(c: ptr NsSystemUpdateControl; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "nssuControlSetupCardUpdate".} +## * +## @brief SetupCardUpdate +## @param c \ref NsSystemUpdateControl +## @param[in] buffer TransferMemory buffer, when NULL this is automatically allocated. +## @param[in] size TransferMemory buffer size, see \ref NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT. +## + +proc nssuControlGetPreparedCardUpdateEulaDataSize*(c: ptr NsSystemUpdateControl; + path: cstring; filesize: ptr U64): Result {.cdecl, + importc: "nssuControlGetPreparedCardUpdateEulaDataSize".} +## * +## @brief Gets the filesize for the specified PreparedCardUpdateEulaData. +## @note See the note for \ref nssuControlGetDownloadedEulaDataSize. +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] filesize Output filesize. +## + +proc nssuControlGetPreparedCardUpdateEulaData*(c: ptr NsSystemUpdateControl; + path: cstring; buffer: pointer; size: csize_t; filesize: ptr U64): Result {.cdecl, + importc: "nssuControlGetPreparedCardUpdateEulaData".} +## * +## @brief Gets the specified PreparedCardUpdateEulaData. +## @note See the note for \ref nssuControlGetDownloadedEulaDataSize. +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] buffer Output buffer. +## @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetPreparedCardUpdateEulaDataSize. +## @param[out] filesize Output filesize. +## + +proc nssuControlSetupCardUpdateViaSystemUpdater*(c: ptr NsSystemUpdateControl; + buffer: pointer; size: csize_t): Result {.cdecl, + importc: "nssuControlSetupCardUpdateViaSystemUpdater".} +## * +## @brief SetupCardUpdateViaSystemUpdater +## @note Same as \ref nssuControlSetupCardUpdate, except this doesn't run the code for fs cmds GetGameCardHandle/GetGameCardUpdatePartitionInfo, and uses fs OpenRegisteredUpdatePartition instead of OpenGameCardFileSystem. +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[in] buffer TransferMemory buffer, when NULL this is automatically allocated. +## @param[in] size TransferMemory buffer size, see \ref NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT. +## + +proc nssuControlHasReceived*(c: ptr NsSystemUpdateControl; `out`: ptr bool): Result {. + cdecl, importc: "nssuControlHasReceived".} +## * +## @brief HasReceived +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[out] out Output flag. +## + +proc nssuControlRequestReceiveSystemUpdate*(c: ptr NsSystemUpdateControl; + a: ptr AsyncResult; `addr`: U32; port: U16; info: ptr NsSystemDeliveryInfo): Result {. + cdecl, importc: "nssuControlRequestReceiveSystemUpdate".} +## * +## @brief RequestReceiveSystemUpdate +## @note The system will use the input addr/port with connect(). addr/port are little-endian. +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[out] a \ref AsyncResult +## @param[in] addr Server IPv4 address. qlaunch uses a local-WLAN addr, however this can be any addr. +## @param[in] port Socket port. qlaunch uses value 55556. +## @param[in] info \ref NsSystemDeliveryInfo +## + +proc nssuControlGetReceiveProgress*(c: ptr NsSystemUpdateControl; + `out`: ptr NsSystemUpdateProgress): Result {. + cdecl, importc: "nssuControlGetReceiveProgress".} +## * +## @brief GetReceiveProgress +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[out] out \ref NsSystemUpdateProgress +## + +proc nssuControlApplyReceivedUpdate*(c: ptr NsSystemUpdateControl): Result {.cdecl, + importc: "nssuControlApplyReceivedUpdate".} +## * +## @brief ApplyReceivedUpdate +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## + +proc nssuControlGetReceivedEulaDataSize*(c: ptr NsSystemUpdateControl; + path: cstring; filesize: ptr U64): Result {. + cdecl, importc: "nssuControlGetReceivedEulaDataSize".} +## * +## @brief Gets the filesize for the specified ReceivedEulaData. +## @note See the note for \ref nssuControlGetDownloadedEulaDataSize. +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] filesize Output filesize. +## + +proc nssuControlGetReceivedEulaData*(c: ptr NsSystemUpdateControl; path: cstring; + buffer: pointer; size: csize_t; + filesize: ptr U64): Result {.cdecl, + importc: "nssuControlGetReceivedEulaData".} +## * +## @brief Gets the specified ReceivedEulaData. +## @note See the note for \ref nssuControlGetDownloadedEulaDataSize. +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[in] path EulaData path. +## @param[out] buffer Output buffer. +## @param[in] size Size of the output buffer, must be at least the output size from \ref nssuControlGetReceivedEulaDataSize. +## @param[out] filesize Output filesize. +## + +proc nssuControlSetupToReceiveSystemUpdate*(c: ptr NsSystemUpdateControl): Result {. + cdecl, importc: "nssuControlSetupToReceiveSystemUpdate".} +## * +## @brief Does setup for ReceiveSystemUpdate by using the same nim cmds as \ref nssuDestroySystemUpdateTask. +## @note qlaunch uses this before \ref nssuControlRequestReceiveSystemUpdate. +## @note Only available on [4.0.0+]. +## @param c \ref NsSystemUpdateControl +## + +proc nssuControlRequestCheckLatestUpdateIncludesRebootlessUpdate*( + c: ptr NsSystemUpdateControl; a: ptr AsyncValue): Result {.cdecl, + importc: "nssuControlRequestCheckLatestUpdateIncludesRebootlessUpdate".} +## * +## @brief RequestCheckLatestUpdateIncludesRebootlessUpdate +## @note Only available on [6.0.0+]. +## @param c \ref NsSystemUpdateControl +## @param[out] a \ref AsyncValue +## + +## /@} diff --git a/src/libnx/wrapper/switch/services/nv.h b/src/libnx/wrapper/switch/services/nv.h new file mode 100644 index 0000000..e391a39 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nv.h @@ -0,0 +1,40 @@ +/** + * @file nv.h + * @brief NVIDIA low level driver (nvdrv*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +/// Initialize nvdrv*. +Result nvInitialize(void); + +/// Exit nvdrv*. +void nvExit(void); + +/// Gets the Service object for the actual nvdrv* service session. +Service* nvGetServiceSession(void); + +typedef enum { + NvEventId_Gpu_SmException_BptIntReport=1, + NvEventId_Gpu_SmException_BptPauseReport=2, + NvEventId_Gpu_ErrorNotifier=3, + + NvEventId_CtrlGpu_ErrorEventHandle=1, + NvEventId_CtrlGpu_Unknown=2, +} NvEventId; + +#define NV_EVENT_ID_CTRL__SYNCPT(slot, syncpt) \ + ((1u<<28) | ((syncpt) << 16) | (slot)) + +Result nvOpen(u32 *fd, const char *devicepath); +Result nvIoctl(u32 fd, u32 request, void* argp); +Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf_size); ///< [3.0.0+] +Result nvIoctl3(u32 fd, u32 request, void* argp, void* outbuf, size_t outbuf_size); ///< [3.0.0+] +Result nvClose(u32 fd); +Result nvQueryEvent(u32 fd, u32 event_id, Event *event_out); + +Result nvConvertError(int rc); diff --git a/src/libnx/wrapper/switch/services/nv.nim b/src/libnx/wrapper/switch/services/nv.nim new file mode 100644 index 0000000..98f7b19 --- /dev/null +++ b/src/libnx/wrapper/switch/services/nv.nim @@ -0,0 +1,46 @@ +## * +## @file nv.h +## @brief NVIDIA low level driver (nvdrv*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + + +proc nvInitialize*(): Result {.cdecl, importc: "nvInitialize".} +## / Initialize nvdrv*. + +proc nvExit*() {.cdecl, importc: "nvExit".} +## / Exit nvdrv*. + +proc nvGetServiceSession*(): ptr Service {.cdecl, importc: "nvGetServiceSession".} +## / Gets the Service object for the actual nvdrv* service session. + +type + NvEventId* = enum + NvEventIdGpuSmExceptionBptIntReport = 1, + NvEventIdGpuSmExceptionBptPauseReport = 2, NvEventIdGpuErrorNotifier = 3 + +const + NvEventIdCtrlGpuErrorEventHandle* = NvEventIdGpuSmExceptionBptIntReport + NvEventIdCtrlGpuUnknown* = NvEventIdGpuSmExceptionBptPauseReport + +template nv_Event_Id_Ctrl_Syncpt*(slot, syncpt: untyped): untyped = + ((1'u shl 28) or ((syncpt) shl 16) or (slot)) + +proc nvOpen*(fd: ptr U32; devicepath: cstring): Result {.cdecl, importc: "nvOpen".} +proc nvIoctl*(fd: U32; request: U32; argp: pointer): Result {.cdecl, importc: "nvIoctl".} +proc nvIoctl2*(fd: U32; request: U32; argp: pointer; inbuf: pointer; inbufSize: csize_t): Result {. + cdecl, importc: "nvIoctl2".} +## /< [3.0.0+] + +proc nvIoctl3*(fd: U32; request: U32; argp: pointer; outbuf: pointer; outbufSize: csize_t): Result {. + cdecl, importc: "nvIoctl3".} +## /< [3.0.0+] + +proc nvClose*(fd: U32): Result {.cdecl, importc: "nvClose".} +proc nvQueryEvent*(fd: U32; eventId: U32; eventOut: ptr Event): Result {.cdecl, + importc: "nvQueryEvent".} +proc nvConvertError*(rc: cint): Result {.cdecl, importc: "nvConvertError".} diff --git a/src/libnx/wrapper/switch/services/pctl.h b/src/libnx/wrapper/switch/services/pctl.h new file mode 100644 index 0000000..1e3181d --- /dev/null +++ b/src/libnx/wrapper/switch/services/pctl.h @@ -0,0 +1,35 @@ +/** + * @file pctl.h + * @brief Parental Controls service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Initialize pctl. +Result pctlInitialize(void); + +/// Exit pctl. +void pctlExit(void); + +/// Gets the Service object for the actual pctl service session. +Service* pctlGetServiceSession(void); + +/// Gets the Service object for IParentalControlService. +Service* pctlGetServiceSession_Service(void); + +/// Confirm whether VrMode is allowed. Only available with [4.0.0+]. +Result pctlConfirmStereoVisionPermission(void); + +/// Gets whether Parental Controls are enabled. +Result pctlIsRestrictionEnabled(bool *flag); + +/// Reset the confirmation done by \ref pctlConfirmStereoVisionPermission. Only available with [5.0.0+]. +Result pctlResetConfirmedStereoVisionPermission(void); + +/// Gets whether VrMode is allowed. Only available with [5.0.0+]. +Result pctlIsStereoVisionPermitted(bool *flag); + diff --git a/src/libnx/wrapper/switch/services/pctl.nim b/src/libnx/wrapper/switch/services/pctl.nim new file mode 100644 index 0000000..d36aad2 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pctl.nim @@ -0,0 +1,39 @@ +## * +## @file pctl.h +## @brief Parental Controls service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Initialize pctl. + +proc pctlInitialize*(): Result {.cdecl, importc: "pctlInitialize".} +## / Exit pctl. + +proc pctlExit*() {.cdecl, importc: "pctlExit".} +## / Gets the Service object for the actual pctl service session. + +proc pctlGetServiceSession*(): ptr Service {.cdecl, importc: "pctlGetServiceSession".} +## / Gets the Service object for IParentalControlService. + +proc pctlGetServiceSessionService*(): ptr Service {.cdecl, + importc: "pctlGetServiceSession_Service".} +## / Confirm whether VrMode is allowed. Only available with [4.0.0+]. + +proc pctlConfirmStereoVisionPermission*(): Result {.cdecl, + importc: "pctlConfirmStereoVisionPermission".} +## / Gets whether Parental Controls are enabled. + +proc pctlIsRestrictionEnabled*(flag: ptr bool): Result {.cdecl, + importc: "pctlIsRestrictionEnabled".} +## / Reset the confirmation done by \ref pctlConfirmStereoVisionPermission. Only available with [5.0.0+]. + +proc pctlResetConfirmedStereoVisionPermission*(): Result {.cdecl, + importc: "pctlResetConfirmedStereoVisionPermission".} +## / Gets whether VrMode is allowed. Only available with [5.0.0+]. + +proc pctlIsStereoVisionPermitted*(flag: ptr bool): Result {.cdecl, + importc: "pctlIsStereoVisionPermitted".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/pcv.h b/src/libnx/wrapper/switch/services/pcv.h new file mode 100644 index 0000000..3887e9b --- /dev/null +++ b/src/libnx/wrapper/switch/services/pcv.h @@ -0,0 +1,212 @@ +/** + * @file pcv.h + * @brief PCV service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + PcvModule_CpuBus = 0, + PcvModule_GPU = 1, + PcvModule_I2S1 = 2, + PcvModule_I2S2 = 3, + PcvModule_I2S3 = 4, + PcvModule_PWM = 5, + PcvModule_I2C1 = 6, + PcvModule_I2C2 = 7, + PcvModule_I2C3 = 8, + PcvModule_I2C4 = 9, + PcvModule_I2C5 = 10, + PcvModule_I2C6 = 11, + PcvModule_SPI1 = 12, + PcvModule_SPI2 = 13, + PcvModule_SPI3 = 14, + PcvModule_SPI4 = 15, + PcvModule_DISP1 = 16, + PcvModule_DISP2 = 17, + PcvModule_ISP = 18, + PcvModule_VI = 19, + PcvModule_SDMMC1 = 20, + PcvModule_SDMMC2 = 21, + PcvModule_SDMMC3 = 22, + PcvModule_SDMMC4 = 23, + PcvModule_OWR = 24, + PcvModule_CSITE = 25, + PcvModule_TSEC = 26, + PcvModule_MSELECT = 27, + PcvModule_HDA2CODEC_2X = 28, + PcvModule_ACTMON = 29, + PcvModule_I2C_SLOW = 30, + PcvModule_SOR1 = 31, + PcvModule_SATA = 32, + PcvModule_HDA = 33, + PcvModule_XUSB_CORE_HOST = 34, + PcvModule_XUSB_FALCON = 35, + PcvModule_XUSB_FS = 36, + PcvModule_XUSB_CORE_DEV = 37, + PcvModule_XUSB_SS_HOSTDEV = 38, + PcvModule_UARTA = 39, + PcvModule_UARTB = 40, + PcvModule_UARTC = 41, + PcvModule_UARTD = 42, + PcvModule_HOST1X = 43, + PcvModule_ENTROPY = 44, + PcvModule_SOC_THERM = 45, + PcvModule_VIC = 46, + PcvModule_NVENC = 47, + PcvModule_NVJPG = 48, + PcvModule_NVDEC = 49, + PcvModule_QSPI = 50, + PcvModule_VI_I2C = 51, + PcvModule_TSECB = 52, + PcvModule_APE = 53, + PcvModule_ACLK = 54, + PcvModule_UARTAPE = 55, + PcvModule_EMC = 56, + PcvModule_PLLE0_0 = 57, + PcvModule_PLLE0_1 = 58, + PcvModule_DSI = 59, + PcvModule_MAUD = 60, + PcvModule_DPAUX1 = 61, + PcvModule_MIPI_CAL = 62, + PcvModule_UART_FST_MIPI_CAL = 63, + PcvModule_OSC = 64, + PcvModule_SCLK = 65, + PcvModule_SOR_SAFE = 66, + PcvModule_XUSB_SS = 67, + PcvModule_XUSB_HOST = 68, + PcvModule_XUSB_DEV = 69, + PcvModule_EXTPERIPH1 = 70, + PcvModule_AHUB = 71, + PcvModule_HDA2HDMICODEC = 72, + PcvModule_PLLP5 = 73, + PcvModule_USBD = 74, + PcvModule_USB2 = 75, + PcvModule_PCIE = 76, + PcvModule_AFI = 77, + PcvModule_PCIEXCLK = 78, + PcvModule_PEX_USB_UPHY = 79, + PcvModule_XUSB_PADCTL = 80, + PcvModule_APBDMA = 81, + PcvModule_USB2_TRK = 82, + PcvModule_PLLE0_2 = 83, + PcvModule_PLLE0_3 = 84, + PcvModule_CEC = 85, + PcvModule_EXTPERIPH2 = 86, + PcvModule_Count // Not a real module, used to know how many modules there are. +} PcvModule; + +/// Module id returned by [8.0.0+] pcv services +/// See also: https://switchbrew.org/wiki/PCV_services#Modules +typedef enum { + PcvModuleId_CpuBus = 0x40000001, + PcvModuleId_GPU = 0x40000002, + PcvModuleId_I2S1 = 0x40000003, + PcvModuleId_I2S2 = 0x40000004, + PcvModuleId_I2S3 = 0x40000005, + PcvModuleId_PWM = 0x40000006, + PcvModuleId_I2C1 = 0x02000001, + PcvModuleId_I2C2 = 0x02000002, + PcvModuleId_I2C3 = 0x02000003, + PcvModuleId_I2C4 = 0x02000004, + PcvModuleId_I2C5 = 0x02000005, + PcvModuleId_I2C6 = 0x02000006, + PcvModuleId_SPI1 = 0x07000000, + PcvModuleId_SPI2 = 0x07000001, + PcvModuleId_SPI3 = 0x07000002, + PcvModuleId_SPI4 = 0x07000003, + PcvModuleId_DISP1 = 0x40000011, + PcvModuleId_DISP2 = 0x40000012, + PcvModuleId_ISP = 0x40000013, + PcvModuleId_VI = 0x40000014, + PcvModuleId_SDMMC1 = 0x40000015, + PcvModuleId_SDMMC2 = 0x40000016, + PcvModuleId_SDMMC3 = 0x40000017, + PcvModuleId_SDMMC4 = 0x40000018, + PcvModuleId_OWR = 0x40000019, + PcvModuleId_CSITE = 0x4000001A, + PcvModuleId_TSEC = 0x4000001B, + PcvModuleId_MSELECT = 0x4000001C, + PcvModuleId_HDA2CODEC_2X = 0x4000001D, + PcvModuleId_ACTMON = 0x4000001E, + PcvModuleId_I2C_SLOW = 0x4000001F, + PcvModuleId_SOR1 = 0x40000020, + PcvModuleId_SATA = 0x40000021, + PcvModuleId_HDA = 0x40000022, + PcvModuleId_XUSB_CORE_HOST = 0x40000023, + PcvModuleId_XUSB_FALCON = 0x40000024, + PcvModuleId_XUSB_FS = 0x40000025, + PcvModuleId_XUSB_CORE_DEV = 0x40000026, + PcvModuleId_XUSB_SS_HOSTDEV = 0x40000027, + PcvModuleId_UARTA = 0x03000001, + PcvModuleId_UARTB = 0x35000405, + PcvModuleId_UARTC = 0x3500040F, + PcvModuleId_UARTD = 0x37000001, + PcvModuleId_HOST1X = 0x4000002C, + PcvModuleId_ENTROPY = 0x4000002D, + PcvModuleId_SOC_THERM = 0x4000002E, + PcvModuleId_VIC = 0x4000002F, + PcvModuleId_NVENC = 0x40000030, + PcvModuleId_NVJPG = 0x40000031, + PcvModuleId_NVDEC = 0x40000032, + PcvModuleId_QSPI = 0x40000033, + PcvModuleId_VI_I2C = 0x40000034, + PcvModuleId_TSECB = 0x40000035, + PcvModuleId_APE = 0x40000036, + PcvModuleId_ACLK = 0x40000037, + PcvModuleId_UARTAPE = 0x40000038, + PcvModuleId_EMC = 0x40000039, + PcvModuleId_PLLE0_0 = 0x4000003A, + PcvModuleId_PLLE0_1 = 0x4000003B, + PcvModuleId_DSI = 0x4000003C, + PcvModuleId_MAUD = 0x4000003D, + PcvModuleId_DPAUX1 = 0x4000003E, + PcvModuleId_MIPI_CAL = 0x4000003F, + PcvModuleId_UART_FST_MIPI_CAL = 0x40000040, + PcvModuleId_OSC = 0x40000041, + PcvModuleId_SCLK = 0x40000042, + PcvModuleId_SOR_SAFE = 0x40000043, + PcvModuleId_XUSB_SS = 0x40000044, + PcvModuleId_XUSB_HOST = 0x40000045, + PcvModuleId_XUSB_DEV = 0x40000046, + PcvModuleId_EXTPERIPH1 = 0x40000047, + PcvModuleId_AHUB = 0x40000048, + PcvModuleId_HDA2HDMICODEC = 0x40000049, + PcvModuleId_PLLP5 = 0x4000004A, + PcvModuleId_USBD = 0x4000004B, + PcvModuleId_USB2 = 0x4000004C, + PcvModuleId_PCIE = 0x4000004D, + PcvModuleId_AFI = 0x4000004E, + PcvModuleId_PCIEXCLK = 0x4000004F, + PcvModuleId_PEX_USB_UPHY = 0x40000050, + PcvModuleId_XUSB_PADCTL = 0x40000051, + PcvModuleId_APBDMA = 0x40000052, + PcvModuleId_USB2_TRK = 0x40000053, + PcvModuleId_PLLE0_2 = 0x40000054, + PcvModuleId_PLLE0_3 = 0x40000055, + PcvModuleId_CEC = 0x40000056, + PcvModuleId_EXTPERIPH2 = 0x40000057, +} PcvModuleId; + +/// Initialize pcv. +Result pcvInitialize(void); + +/// Exit pcv. +void pcvExit(void); + +/// Gets the Service object for the actual pcv service session. +Service* pcvGetServiceSession(void); + +Result pcvGetModuleId(PcvModuleId *module_id, PcvModule module); + +/// Only available on [1.0.0-7.0.1]. +Result pcvGetClockRate(PcvModule module, u32 *out_hz); +/// Only available on [1.0.0-7.0.1]. +Result pcvSetClockRate(PcvModule module, u32 hz); +/// Only available on [1.0.0-7.0.1]. +Result pcvSetVoltageEnabled(u32 power_domain, bool state); +/// Only available on [1.0.0-7.0.1]. +Result pcvGetVoltageEnabled(bool *isEnabled, u32 power_domain); diff --git a/src/libnx/wrapper/switch/services/pcv.nim b/src/libnx/wrapper/switch/services/pcv.nim new file mode 100644 index 0000000..2a4fa2c --- /dev/null +++ b/src/libnx/wrapper/switch/services/pcv.nim @@ -0,0 +1,117 @@ +## * +## @file pcv.h +## @brief PCV service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + PcvModule* = enum + PcvModuleCpuBus = 0, PcvModuleGPU = 1, PcvModuleI2S1 = 2, PcvModuleI2S2 = 3, + PcvModuleI2S3 = 4, PcvModulePWM = 5, PcvModuleI2C1 = 6, PcvModuleI2C2 = 7, + PcvModuleI2C3 = 8, PcvModuleI2C4 = 9, PcvModuleI2C5 = 10, PcvModuleI2C6 = 11, + PcvModuleSPI1 = 12, PcvModuleSPI2 = 13, PcvModuleSPI3 = 14, PcvModuleSPI4 = 15, + PcvModuleDISP1 = 16, PcvModuleDISP2 = 17, PcvModuleISP = 18, PcvModuleVI = 19, + PcvModuleSDMMC1 = 20, PcvModuleSDMMC2 = 21, PcvModuleSDMMC3 = 22, + PcvModuleSDMMC4 = 23, PcvModuleOWR = 24, PcvModuleCSITE = 25, PcvModuleTSEC = 26, + PcvModuleMSELECT = 27, PcvModuleHDA2CODEC_2X = 28, PcvModuleACTMON = 29, + PcvModuleI2C_SLOW = 30, PcvModuleSOR1 = 31, PcvModuleSATA = 32, PcvModuleHDA = 33, + PcvModuleXUSB_CORE_HOST = 34, PcvModuleXUSB_FALCON = 35, PcvModuleXUSB_FS = 36, + PcvModuleXUSB_CORE_DEV = 37, PcvModuleXUSB_SS_HOSTDEV = 38, PcvModuleUARTA = 39, + PcvModuleUARTB = 40, PcvModuleUARTC = 41, PcvModuleUARTD = 42, PcvModuleHOST1X = 43, + PcvModuleENTROPY = 44, PcvModuleSOC_THERM = 45, PcvModuleVIC = 46, + PcvModuleNVENC = 47, PcvModuleNVJPG = 48, PcvModuleNVDEC = 49, PcvModuleQSPI = 50, + PcvModuleVI_I2C = 51, PcvModuleTSECB = 52, PcvModuleAPE = 53, PcvModuleACLK = 54, + PcvModuleUARTAPE = 55, PcvModuleEMC = 56, PcvModulePLLE00 = 57, PcvModulePLLE01 = 58, + PcvModuleDSI = 59, PcvModuleMAUD = 60, PcvModuleDPAUX1 = 61, PcvModuleMIPI_CAL = 62, + PcvModuleUART_FST_MIPI_CAL = 63, PcvModuleOSC = 64, PcvModuleSCLK = 65, + PcvModuleSOR_SAFE = 66, PcvModuleXUSB_SS = 67, PcvModuleXUSB_HOST = 68, + PcvModuleXUSB_DEV = 69, PcvModuleEXTPERIPH1 = 70, PcvModuleAHUB = 71, + PcvModuleHDA2HDMICODEC = 72, PcvModulePLLP5 = 73, PcvModuleUSBD = 74, + PcvModuleUSB2 = 75, PcvModulePCIE = 76, PcvModuleAFI = 77, PcvModulePCIEXCLK = 78, + PcvModulePEX_USB_UPHY = 79, PcvModuleXUSB_PADCTL = 80, PcvModuleAPBDMA = 81, + PcvModuleUSB2TRK = 82, PcvModulePLLE02 = 83, PcvModulePLLE03 = 84, PcvModuleCEC = 85, + PcvModuleEXTPERIPH2 = 86, PcvModuleCount ## Not a real module, used to know how many modules there are. + + +## / Module id returned by [8.0.0+] pcv services +## / See also: https://switchbrew.org/wiki/PCV_services#Modules + +type + PcvModuleId* = enum + PcvModuleIdI2C1 = 0x02000001, PcvModuleIdI2C2 = 0x02000002, + PcvModuleIdI2C3 = 0x02000003, PcvModuleIdI2C4 = 0x02000004, + PcvModuleIdI2C5 = 0x02000005, PcvModuleIdI2C6 = 0x02000006, + PcvModuleIdUARTA = 0x03000001, PcvModuleIdSPI1 = 0x07000000, + PcvModuleIdSPI2 = 0x07000001, PcvModuleIdSPI3 = 0x07000002, + PcvModuleIdSPI4 = 0x07000003, PcvModuleIdUARTB = 0x35000405, + PcvModuleIdUARTC = 0x3500040F, PcvModuleIdUARTD = 0x37000001, + PcvModuleIdCpuBus = 0x40000001, PcvModuleIdGPU = 0x40000002, + PcvModuleIdI2S1 = 0x40000003, PcvModuleIdI2S2 = 0x40000004, + PcvModuleIdI2S3 = 0x40000005, PcvModuleIdPWM = 0x40000006, + PcvModuleIdDISP1 = 0x40000011, PcvModuleIdDISP2 = 0x40000012, + PcvModuleIdISP = 0x40000013, PcvModuleIdVI = 0x40000014, + PcvModuleIdSDMMC1 = 0x40000015, PcvModuleIdSDMMC2 = 0x40000016, + PcvModuleIdSDMMC3 = 0x40000017, PcvModuleIdSDMMC4 = 0x40000018, + PcvModuleIdOWR = 0x40000019, PcvModuleIdCSITE = 0x4000001A, + PcvModuleIdTSEC = 0x4000001B, PcvModuleIdMSELECT = 0x4000001C, + PcvModuleIdHDA2CODEC_2X = 0x4000001D, PcvModuleIdACTMON = 0x4000001E, + PcvModuleIdI2C_SLOW = 0x4000001F, PcvModuleIdSOR1 = 0x40000020, + PcvModuleIdSATA = 0x40000021, PcvModuleIdHDA = 0x40000022, + PcvModuleIdXUSB_CORE_HOST = 0x40000023, PcvModuleIdXUSB_FALCON = 0x40000024, + PcvModuleIdXUSB_FS = 0x40000025, PcvModuleIdXUSB_CORE_DEV = 0x40000026, + PcvModuleIdXUSB_SS_HOSTDEV = 0x40000027, PcvModuleIdHOST1X = 0x4000002C, + PcvModuleIdENTROPY = 0x4000002D, PcvModuleIdSOC_THERM = 0x4000002E, + PcvModuleIdVIC = 0x4000002F, PcvModuleIdNVENC = 0x40000030, + PcvModuleIdNVJPG = 0x40000031, PcvModuleIdNVDEC = 0x40000032, + PcvModuleIdQSPI = 0x40000033, PcvModuleIdVI_I2C = 0x40000034, + PcvModuleIdTSECB = 0x40000035, PcvModuleIdAPE = 0x40000036, + PcvModuleIdACLK = 0x40000037, PcvModuleIdUARTAPE = 0x40000038, + PcvModuleIdEMC = 0x40000039, PcvModuleIdPLLE00 = 0x4000003A, + PcvModuleIdPLLE01 = 0x4000003B, PcvModuleIdDSI = 0x4000003C, + PcvModuleIdMAUD = 0x4000003D, PcvModuleIdDPAUX1 = 0x4000003E, + PcvModuleIdMIPI_CAL = 0x4000003F, PcvModuleIdUART_FST_MIPI_CAL = 0x40000040, + PcvModuleIdOSC = 0x40000041, PcvModuleIdSCLK = 0x40000042, + PcvModuleIdSOR_SAFE = 0x40000043, PcvModuleIdXUSB_SS = 0x40000044, + PcvModuleIdXUSB_HOST = 0x40000045, PcvModuleIdXUSB_DEV = 0x40000046, + PcvModuleIdEXTPERIPH1 = 0x40000047, PcvModuleIdAHUB = 0x40000048, + PcvModuleIdHDA2HDMICODEC = 0x40000049, PcvModuleIdPLLP5 = 0x4000004A, + PcvModuleIdUSBD = 0x4000004B, PcvModuleIdUSB2 = 0x4000004C, + PcvModuleIdPCIE = 0x4000004D, PcvModuleIdAFI = 0x4000004E, + PcvModuleIdPCIEXCLK = 0x4000004F, PcvModuleIdPEX_USB_UPHY = 0x40000050, + PcvModuleIdXUSB_PADCTL = 0x40000051, PcvModuleIdAPBDMA = 0x40000052, + PcvModuleIdUSB2TRK = 0x40000053, PcvModuleIdPLLE02 = 0x40000054, + PcvModuleIdPLLE03 = 0x40000055, PcvModuleIdCEC = 0x40000056, + PcvModuleIdEXTPERIPH2 = 0x40000057 + + +## / Initialize pcv. + +proc pcvInitialize*(): Result {.cdecl, importc: "pcvInitialize".} +## / Exit pcv. + +proc pcvExit*() {.cdecl, importc: "pcvExit".} +## / Gets the Service object for the actual pcv service session. + +proc pcvGetServiceSession*(): ptr Service {.cdecl, importc: "pcvGetServiceSession".} +proc pcvGetModuleId*(moduleId: ptr PcvModuleId; module: PcvModule): Result {.cdecl, + importc: "pcvGetModuleId".} +## / Only available on [1.0.0-7.0.1]. + +proc pcvGetClockRate*(module: PcvModule; outHz: ptr U32): Result {.cdecl, + importc: "pcvGetClockRate".} +## / Only available on [1.0.0-7.0.1]. + +proc pcvSetClockRate*(module: PcvModule; hz: U32): Result {.cdecl, + importc: "pcvSetClockRate".} +## / Only available on [1.0.0-7.0.1]. + +proc pcvSetVoltageEnabled*(powerDomain: U32; state: bool): Result {.cdecl, + importc: "pcvSetVoltageEnabled".} +## / Only available on [1.0.0-7.0.1]. + +proc pcvGetVoltageEnabled*(isEnabled: ptr bool; powerDomain: U32): Result {.cdecl, + importc: "pcvGetVoltageEnabled".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/pdm.h b/src/libnx/wrapper/switch/services/pdm.h new file mode 100644 index 0000000..f49b38f --- /dev/null +++ b/src/libnx/wrapper/switch/services/pdm.h @@ -0,0 +1,282 @@ +/** + * @file pdm.h + * @brief PDM (pdm:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/acc.h" +#include "../kernel/event.h" + +/// PlayEventType +typedef enum { + PdmPlayEventType_Applet = 0, ///< Applet + PdmPlayEventType_Account = 1, ///< Account + PdmPlayEventType_PowerStateChange = 2, ///< PowerStateChange + PdmPlayEventType_OperationModeChange = 3, ///< OperationModeChange + PdmPlayEventType_Initialize = 4, ///< Initialize. Used for the very first PlayEvent entry in the log. +} PdmPlayEventType; + +/// AppletEventType +typedef enum { + PdmAppletEventType_Launch = 0, ///< "launch" + PdmAppletEventType_Exit = 1, ///< "exit" + PdmAppletEventType_InFocus = 2, ///< "in_focus" + PdmAppletEventType_OutOfFocus = 3, ///< "out_of_focus" + PdmAppletEventType_OutOfFocus4 = 4, ///< "out_of_focus" + PdmAppletEventType_Exit5 = 5, ///< "exit" + PdmAppletEventType_Exit6 = 6, ///< "exit" +} PdmAppletEventType; + +/// PlayLogPolicy +typedef enum { + PdmPlayLogPolicy_All = 0, ///< All pdm:qry commands which require ::PdmPlayEventType_Applet and AppletId = Application will only return the entry when PlayLogPolicy matches this value. + PdmPlayLogPolicy_LogOnly = 1, ///< The above commands will filter out the entry with this. + PdmPlayLogPolicy_None = 2, ///< The pdm:ntfy commands which handle ::PdmPlayEventType_Applet logging will immediately return 0 when the input param matches this value. + PdmPlayLogPolicy_Unknown3 = 3, ///< [10.0.0+] The cmds which require ::PdmPlayLogPolicy_All, now also allow value 3 if the cmd input flag is set. +} PdmPlayLogPolicy; + +/// AppletEvent. +/// Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00:00. +/// See \ref pdmPlayTimestampToPosix. +typedef struct { + u64 program_id; ///< ProgramId. + u32 entry_index; ///< Entry index. + u32 timestampUser; ///< See PdmPlayEvent::timestampUser, with the above timestamp format. + u32 timestampNetwork; ///< See PdmPlayEvent::timestampNetwork, with the above timestamp format. + u8 eventType; ///< \ref PdmAppletEventType + u8 pad[3]; ///< Padding. +} PdmAppletEvent; + +/// PlayStatistics +typedef struct { + u64 application_id; ///< ApplicationId. + + u32 first_entry_index; ///< Entry index for the first time the application was played. + u32 first_timestampUser; ///< See PdmAppletEvent::timestampUser. This is for the first time the application was played. + u32 first_timestampNetwork; ///< See PdmAppletEvent::timestampNetwork. This is for the first time the application was played. + + u32 last_entry_index; ///< Entry index for the last time the application was played. + u32 last_timestampUser; ///< See PdmAppletEvent::timestampUser. This is for the last time the application was played. + u32 last_timestampNetwork; ///< See PdmAppletEvent::timestampNetwork. This is for the last time the application was played. + + u32 playtimeMinutes; ///< Total play-time in minutes. + u32 totalLaunches; ///< Total times the application was launched. +} PdmPlayStatistics; + +/// LastPlayTime. +/// This contains data from the last time the application was played. +typedef struct { + u64 application_id; ///< ApplicationId. + u32 timestampUser; ///< See PdmAppletEvent::timestampUser. + u32 timestampNetwork; ///< See PdmAppletEvent::timestampNetwork. + u32 lastPlayedMinutes; ///< Total minutes since the application was last played. + u8 flag; ///< Flag indicating whether the above field is set. + u8 pad[3]; ///< Padding. +} PdmLastPlayTime; + +/// PlayEvent. +/// This is the raw entry struct directly read from FS, without any entry filtering. +typedef struct { + union { + struct { + u32 program_id[2]; ///< ProgramId. + + union { + struct { + u32 version; ///< Application version. + } application; ///< For AppletId == ::AppletId_application. + + struct { + u8 flag; ///< Set to 0x1 by pdm:ntfy cmd8, indicating that the below field is set to an input param. + u8 mode; ///< Input value from pdm:ntfy cmd8, see \ref LibAppletMode. + u8 pad[2]; ///< Padding. + } applet; ///< For AppletId != ::AppletId_application. + + u32 data; + } unk_x8; + + u8 appletId; ///< \ref AppletId + u8 storageId; ///< \ref NcmStorageId + u8 logPolicy; ///< \ref PdmPlayLogPolicy + u8 eventType; ///< \ref PdmAppletEventType + u8 unused[0xc]; ///< Unused. + } applet; + + struct { + u32 uid[4]; ///< userId. + u32 application_id[2]; ///< ApplicationId, see below. + u8 type; ///< 0-1 to be listed by \ref pdmqryQueryAccountEvent, or 2 to include the above ApplicationId. + } account; + + struct { + u8 value; ///< Input value from the pdm:ntfy command. + u8 unused[0x1b]; ///< Unused. + } powerStateChange; + + struct { + u8 value; ///< Input value from the pdm:ntfy command. + u8 unused[0x1b]; ///< Unused. + } operationModeChange; + + u8 data[0x1c]; + } eventData; ///< ProgramId/ApplicationId/userId stored within here have the u32 low/high swapped in each u64. + + u8 playEventType; ///< \ref PdmPlayEventType. Controls which struct in the above eventData is used. ::PdmPlayEventType_Initialize doesn't use eventData. + u8 pad[3]; ///< Padding. + + u64 timestampUser; ///< PosixTime timestamp from StandardUserSystemClock. + u64 timestampNetwork; ///< PosixTime timestamp from StandardNetworkSystemClock. + u64 timestampSteady; ///< Timestamp in seconds derived from StandardSteadyClock. +} PdmPlayEvent; + +/// AccountEvent +typedef struct { + AccountUid uid; ///< \ref AccountUid + u32 entry_index; ///< Entry index. + u8 pad[4]; ///< Padding. + u64 timestampUser; ///< See PdmPlayEvent::timestampUser. + u64 timestampNetwork; ///< See PdmPlayEvent::timestampNetwork. + u64 timestampSteady; ///< See PdmPlayEvent::timestampSteady. + u8 type; ///< See PdmPlayEvent::eventData::account::type. + u8 pad_x31[7]; ///< Padding. +} PdmAccountEvent; + +/// AccountPlayEvent. +/// This is the raw entry struct directly read from FS, without any entry filtering. This is separate from \ref PdmPlayEvent. +typedef struct { + u8 unk_x0[4]; ///< Unknown. + u32 application_id[2]; ///< ApplicationId, with the u32 low/high words swapped. + u8 unk_xc[0xc]; ///< Unknown. + u64 timestamp0; ///< POSIX timestamp. + u64 timestamp1; ///< POSIX timestamp. +} PdmAccountPlayEvent; + +/// ApplicationPlayStatistics +typedef struct { + u64 application_id; ///< ApplicationId. + u64 totalPlayTime; ///< Total play-time in nanoseconds. + u64 totalLaunches; ///< Total times the application was launched. +} PdmApplicationPlayStatistics; + +/// Initialize pdm:qry. +Result pdmqryInitialize(void); + +/// Exit pdm:qry. +void pdmqryExit(void); + +/// Gets the Service object for the actual pdm:qry service session. +Service* pdmqryGetServiceSession(void); + +/** + * @brief Gets a list of \ref PdmAppletEvent. + * @param[in] entry_index Start entry index. + * @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. + * @param[out] events Output \ref PdmAppletEvent array. + * @param[in] count Max entries in the output array. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryAppletEvent(s32 entry_index, bool flag, PdmAppletEvent *events, s32 count, s32 *total_out); + +/** + * @brief Gets \ref PdmPlayStatistics for the specified ApplicationId. + * @param[in] application_id ApplicationId + * @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. + * @param[out] stats \ref PdmPlayStatistics + */ +Result pdmqryQueryPlayStatisticsByApplicationId(u64 application_id, bool flag, PdmPlayStatistics *stats); + +/** + * @brief Gets \ref PdmPlayStatistics for the specified ApplicationId and account userId. + * @param[in] application_id ApplicationId + * @param[in] uid \ref AccountUid + * @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. + * @param[out] stats \ref PdmPlayStatistics + */ +Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 application_id, AccountUid uid, bool flag, PdmPlayStatistics *stats); + +/** + * @brief Gets \ref PdmLastPlayTime for the specified applications. + * @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. + * @param[out] playtimes Output \ref PdmLastPlayTime array. + * @param[in] application_ids Input ApplicationIds array. + * @param[in] count Total entries in the input/output arrays. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryLastPlayTime(bool flag, PdmLastPlayTime *playtimes, const u64 *application_ids, s32 count, s32 *total_out); + +/** + * @brief Gets a list of \ref PdmPlayEvent. + * @param[in] entry_index Start entry index. + * @param[out] events Output \ref PdmPlayEvent array. + * @param[in] count Max entries in the output array. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryPlayEvent(s32 entry_index, PdmPlayEvent *events, s32 count, s32 *total_out); + +/** + * @brief Gets range fields which can then be used with the other pdmqry funcs, except for \ref pdmqryQueryAccountPlayEvent. + * @param[out] total_entries Total entries. + * @param[out] start_entry_index Start entry index. + * @param[out] end_entry_index End entry index. + */ +Result pdmqryGetAvailablePlayEventRange(s32 *total_entries, s32 *start_entry_index, s32 *end_entry_index); + +/** + * @brief Gets a list of \ref PdmAccountEvent. + * @param[in] entry_index Start entry index. + * @param[out] events Output \ref PdmAccountEvent array. + * @param[in] count Max entries in the output array. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryAccountEvent(s32 entry_index, PdmAccountEvent *events, s32 count, s32 *total_out); + +/** + * @brief Gets a list of \ref PdmAccountPlayEvent. + * @note Only available with [4.0.0+]. + * @param[in] entry_index Start entry index. + * @param[in] uid \ref AccountUid + * @param[out] events Output \ref PdmAccountPlayEvent array. + * @param[in] count Max entries in the output array. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryAccountPlayEvent(s32 entry_index, AccountUid uid, PdmAccountPlayEvent *events, s32 count, s32 *total_out); + +/** + * @brief Gets range fields which can then be used with \ref pdmqryQueryAccountPlayEvent. + * @param[in] uid \ref AccountUid + * @param[out] total_entries Total entries. + * @param[out] start_entry_index Start entry index. + * @param[out] end_entry_index End entry index. + */ +Result pdmqryGetAvailableAccountPlayEventRange(AccountUid uid, s32 *total_entries, s32 *start_entry_index, s32 *end_entry_index); + +/** + * @brief Gets a list of applications played by the specified user. + * @note Only available with [6.0.0-14.1.2]. + * @param[in] uid \ref AccountUid + * @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. + * @param[out] application_ids Output ApplicationIds array. + * @param[in] count Max entries in the output array. + * @param[out] total_out Total output entries. + */ +Result pdmqryQueryRecentlyPlayedApplication(AccountUid uid, bool flag, u64 *application_ids, s32 count, s32 *total_out); + +/** + * @brief Gets an Event which is signaled when logging a new \ref PdmPlayEvent which would be available via \ref pdmqryQueryAccountEvent, where PdmPlayEvent::eventData::account::type is 0. + * @note Only available with [6.0.0-14.1.2]. + * @note The Event must be closed by the user once finished with it. + * @param[out] out_event Output Event with autoclear=false. + */ +Result pdmqryGetRecentlyPlayedApplicationUpdateEvent(Event* out_event); + +/** + * @brief Helper function which converts a Play timestamp from the Pdm*Event structs to POSIX. + * @param[in] timestamp Input timestamp. + */ +static inline u64 pdmPlayTimestampToPosix(u32 timestamp) { + return ((u64)timestamp) * 60 + 946598400; +} + diff --git a/src/libnx/wrapper/switch/services/pdm.nim b/src/libnx/wrapper/switch/services/pdm.nim new file mode 100644 index 0000000..a480bbb --- /dev/null +++ b/src/libnx/wrapper/switch/services/pdm.nim @@ -0,0 +1,317 @@ +## * +## @file pdm.h +## @brief PDM (pdm:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/acc, ../kernel/event + +## / PlayEventType + +type + PdmPlayEventType* = enum + PdmPlayEventTypeApplet = 0, ## /< Applet + PdmPlayEventTypeAccount = 1, ## /< Account + PdmPlayEventTypePowerStateChange = 2, ## /< PowerStateChange + PdmPlayEventTypeOperationModeChange = 3, ## /< OperationModeChange + PdmPlayEventTypeInitialize = 4 ## /< Initialize. Used for the very first PlayEvent entry in the log. + + +## / AppletEventType + +type + PdmAppletEventType* = enum + PdmAppletEventTypeLaunch = 0, ## /< "launch" + PdmAppletEventTypeExit = 1, ## /< "exit" + PdmAppletEventTypeInFocus = 2, ## /< "in_focus" + PdmAppletEventTypeOutOfFocus = 3, ## /< "out_of_focus" + PdmAppletEventTypeOutOfFocus4 = 4, ## /< "out_of_focus" + PdmAppletEventTypeExit5 = 5, ## /< "exit" + PdmAppletEventTypeExit6 = 6 ## /< "exit" + + +## / PlayLogPolicy + +type + PdmPlayLogPolicy* = enum + PdmPlayLogPolicyAll = 0, ## /< All pdm:qry commands which require ::PdmPlayEventType_Applet and AppletId = Application will only return the entry when PlayLogPolicy matches this value. + PdmPlayLogPolicyLogOnly = 1, ## /< The above commands will filter out the entry with this. + PdmPlayLogPolicyNone = 2, ## /< The pdm:ntfy commands which handle ::PdmPlayEventType_Applet logging will immediately return 0 when the input param matches this value. + PdmPlayLogPolicyUnknown3 = 3 ## /< [10.0.0+] The cmds which require ::PdmPlayLogPolicy_All, now also allow value 3 if the cmd input flag is set. + + +## / AppletEvent. +## / Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00:00. +## / See \ref pdmPlayTimestampToPosix. + +type + PdmAppletEvent* {.bycopy.} = object + programId*: U64 ## /< ProgramId. + entryIndex*: U32 ## /< Entry index. + timestampUser*: U32 ## /< See PdmPlayEvent::timestampUser, with the above timestamp format. + timestampNetwork*: U32 ## /< See PdmPlayEvent::timestampNetwork, with the above timestamp format. + eventType*: U8 ## /< \ref PdmAppletEventType + pad*: array[3, U8] ## /< Padding. + + +## / PlayStatistics + +type + PdmPlayStatistics* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + firstEntryIndex*: U32 ## /< Entry index for the first time the application was played. + firstTimestampUser*: U32 ## /< See PdmAppletEvent::timestampUser. This is for the first time the application was played. + firstTimestampNetwork*: U32 ## /< See PdmAppletEvent::timestampNetwork. This is for the first time the application was played. + lastEntryIndex*: U32 ## /< Entry index for the last time the application was played. + lastTimestampUser*: U32 ## /< See PdmAppletEvent::timestampUser. This is for the last time the application was played. + lastTimestampNetwork*: U32 ## /< See PdmAppletEvent::timestampNetwork. This is for the last time the application was played. + playtimeMinutes*: U32 ## /< Total play-time in minutes. + totalLaunches*: U32 ## /< Total times the application was launched. + + +## / LastPlayTime. +## / This contains data from the last time the application was played. + +type + PdmLastPlayTime* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + timestampUser*: U32 ## /< See PdmAppletEvent::timestampUser. + timestampNetwork*: U32 ## /< See PdmAppletEvent::timestampNetwork. + lastPlayedMinutes*: U32 ## /< Total minutes since the application was last played. + flag*: U8 ## /< Flag indicating whether the above field is set. + pad*: array[3, U8] ## /< Padding. + + +## / PlayEvent. +## / This is the raw entry struct directly read from FS, without any entry filtering. + +type + INNER_C_STRUCT_pdm_11* {.bycopy.} = object + version*: U32 ## /< Application version. + + INNER_C_STRUCT_pdm_12* {.bycopy.} = object + flag*: U8 ## /< Set to 0x1 by pdm:ntfy cmd8, indicating that the below field is set to an input param. + mode*: U8 ## /< Input value from pdm:ntfy cmd8, see \ref LibAppletMode. + pad*: array[2, U8] ## /< Padding. + + INNER_C_UNION_pdm_10* {.bycopy, union.} = object + application*: INNER_C_STRUCT_pdm_11 ## /< For AppletId == ::AppletId_application. + applet*: INNER_C_STRUCT_pdm_12 ## /< For AppletId != ::AppletId_application. + data*: U32 + + INNER_C_STRUCT_pdm_9* {.bycopy.} = object + programId*: array[2, U32] ## /< ProgramId. + unkX8*: INNER_C_UNION_pdm_10 + appletId*: U8 ## /< \ref AppletId + storageId*: U8 ## /< \ref NcmStorageId + logPolicy*: U8 ## /< \ref PdmPlayLogPolicy + eventType*: U8 ## /< \ref PdmAppletEventType + unused*: array[0xc, U8] ## /< Unused. + + INNER_C_STRUCT_pdm_13* {.bycopy.} = object + uid*: array[4, U32] ## /< userId. + applicationId*: array[2, U32] ## /< ApplicationId, see below. + `type`*: U8 ## /< 0-1 to be listed by \ref pdmqryQueryAccountEvent, or 2 to include the above ApplicationId. + + INNER_C_STRUCT_pdm_14* {.bycopy.} = object + value*: U8 ## /< Input value from the pdm:ntfy command. + unused*: array[0x1b, U8] ## /< Unused. + + INNER_C_STRUCT_pdm_15* {.bycopy.} = object + value*: U8 ## /< Input value from the pdm:ntfy command. + unused*: array[0x1b, U8] ## /< Unused. + + INNER_C_UNION_pdm_8* {.bycopy, union.} = object + applet*: INNER_C_STRUCT_pdm_9 + account*: INNER_C_STRUCT_pdm_13 + powerStateChange*: INNER_C_STRUCT_pdm_14 + operationModeChange*: INNER_C_STRUCT_pdm_15 + data*: array[0x1c, U8] + + PdmPlayEvent* {.bycopy.} = object + eventData*: INNER_C_UNION_pdm_8 ## /< ProgramId/ApplicationId/userId stored within here have the u32 low/high swapped in each u64. + playEventType*: U8 ## /< \ref PdmPlayEventType. Controls which struct in the above eventData is used. ::PdmPlayEventType_Initialize doesn't use eventData. + pad*: array[3, U8] ## /< Padding. + timestampUser*: U64 ## /< PosixTime timestamp from StandardUserSystemClock. + timestampNetwork*: U64 ## /< PosixTime timestamp from StandardNetworkSystemClock. + timestampSteady*: U64 ## /< Timestamp in seconds derived from StandardSteadyClock. + + +## / AccountEvent + +type + PdmAccountEvent* {.bycopy.} = object + uid*: AccountUid ## /< \ref AccountUid + entryIndex*: U32 ## /< Entry index. + pad*: array[4, U8] ## /< Padding. + timestampUser*: U64 ## /< See PdmPlayEvent::timestampUser. + timestampNetwork*: U64 ## /< See PdmPlayEvent::timestampNetwork. + timestampSteady*: U64 ## /< See PdmPlayEvent::timestampSteady. + `type`*: U8 ## /< See PdmPlayEvent::eventData::account::type. + padX31*: array[7, U8] ## /< Padding. + + +## / AccountPlayEvent. +## / This is the raw entry struct directly read from FS, without any entry filtering. This is separate from \ref PdmPlayEvent. + +type + PdmAccountPlayEvent* {.bycopy.} = object + unkX0*: array[4, U8] ## /< Unknown. + applicationId*: array[2, U32] ## /< ApplicationId, with the u32 low/high words swapped. + unkXc*: array[0xc, U8] ## /< Unknown. + timestamp0*: U64 ## /< POSIX timestamp. + timestamp1*: U64 ## /< POSIX timestamp. + + +## / ApplicationPlayStatistics + +type + PdmApplicationPlayStatistics* {.bycopy.} = object + applicationId*: U64 ## /< ApplicationId. + totalPlayTime*: U64 ## /< Total play-time in nanoseconds. + totalLaunches*: U64 ## /< Total times the application was launched. + + +## / Initialize pdm:qry. + +proc pdmqryInitialize*(): Result {.cdecl, importc: "pdmqryInitialize".} +## / Exit pdm:qry. + +proc pdmqryExit*() {.cdecl, importc: "pdmqryExit".} +## / Gets the Service object for the actual pdm:qry service session. + +proc pdmqryGetServiceSession*(): ptr Service {.cdecl, + importc: "pdmqryGetServiceSession".} +## * +## @brief Gets a list of \ref PdmAppletEvent. +## @param[in] entry_index Start entry index. +## @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. +## @param[out] events Output \ref PdmAppletEvent array. +## @param[in] count Max entries in the output array. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryAppletEvent*(entryIndex: S32; flag: bool; events: ptr PdmAppletEvent; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "pdmqryQueryAppletEvent".} +## * +## @brief Gets \ref PdmPlayStatistics for the specified ApplicationId. +## @param[in] application_id ApplicationId +## @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. +## @param[out] stats \ref PdmPlayStatistics +## + +proc pdmqryQueryPlayStatisticsByApplicationId*(applicationId: U64; flag: bool; + stats: ptr PdmPlayStatistics): Result {.cdecl, importc: "pdmqryQueryPlayStatisticsByApplicationId".} +## * +## @brief Gets \ref PdmPlayStatistics for the specified ApplicationId and account userId. +## @param[in] application_id ApplicationId +## @param[in] uid \ref AccountUid +## @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. +## @param[out] stats \ref PdmPlayStatistics +## + +proc pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId*( + applicationId: U64; uid: AccountUid; flag: bool; stats: ptr PdmPlayStatistics): Result {. + cdecl, importc: "pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId".} +## * +## @brief Gets \ref PdmLastPlayTime for the specified applications. +## @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. +## @param[out] playtimes Output \ref PdmLastPlayTime array. +## @param[in] application_ids Input ApplicationIds array. +## @param[in] count Total entries in the input/output arrays. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryLastPlayTime*(flag: bool; playtimes: ptr PdmLastPlayTime; + applicationIds: ptr U64; count: S32; totalOut: ptr S32): Result {. + cdecl, importc: "pdmqryQueryLastPlayTime".} +## * +## @brief Gets a list of \ref PdmPlayEvent. +## @param[in] entry_index Start entry index. +## @param[out] events Output \ref PdmPlayEvent array. +## @param[in] count Max entries in the output array. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryPlayEvent*(entryIndex: S32; events: ptr PdmPlayEvent; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "pdmqryQueryPlayEvent".} +## * +## @brief Gets range fields which can then be used with the other pdmqry funcs, except for \ref pdmqryQueryAccountPlayEvent. +## @param[out] total_entries Total entries. +## @param[out] start_entry_index Start entry index. +## @param[out] end_entry_index End entry index. +## + +proc pdmqryGetAvailablePlayEventRange*(totalEntries: ptr S32; + startEntryIndex: ptr S32; + endEntryIndex: ptr S32): Result {.cdecl, + importc: "pdmqryGetAvailablePlayEventRange".} +## * +## @brief Gets a list of \ref PdmAccountEvent. +## @param[in] entry_index Start entry index. +## @param[out] events Output \ref PdmAccountEvent array. +## @param[in] count Max entries in the output array. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryAccountEvent*(entryIndex: S32; events: ptr PdmAccountEvent; + count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "pdmqryQueryAccountEvent".} +## * +## @brief Gets a list of \ref PdmAccountPlayEvent. +## @note Only available with [4.0.0+]. +## @param[in] entry_index Start entry index. +## @param[in] uid \ref AccountUid +## @param[out] events Output \ref PdmAccountPlayEvent array. +## @param[in] count Max entries in the output array. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryAccountPlayEvent*(entryIndex: S32; uid: AccountUid; + events: ptr PdmAccountPlayEvent; count: S32; + totalOut: ptr S32): Result {.cdecl, + importc: "pdmqryQueryAccountPlayEvent".} +## * +## @brief Gets range fields which can then be used with \ref pdmqryQueryAccountPlayEvent. +## @param[in] uid \ref AccountUid +## @param[out] total_entries Total entries. +## @param[out] start_entry_index Start entry index. +## @param[out] end_entry_index End entry index. +## + +proc pdmqryGetAvailableAccountPlayEventRange*(uid: AccountUid; + totalEntries: ptr S32; startEntryIndex: ptr S32; endEntryIndex: ptr S32): Result {. + cdecl, importc: "pdmqryGetAvailableAccountPlayEventRange".} +## * +## @brief Gets a list of applications played by the specified user. +## @note Only available with [6.0.0-14.1.2]. +## @param[in] uid \ref AccountUid +## @param[in] flag [10.0.0+] Whether to additionally allow using entries with ::PdmPlayLogPolicy_Unknown3. +## @param[out] application_ids Output ApplicationIds array. +## @param[in] count Max entries in the output array. +## @param[out] total_out Total output entries. +## + +proc pdmqryQueryRecentlyPlayedApplication*(uid: AccountUid; flag: bool; + applicationIds: ptr U64; count: S32; totalOut: ptr S32): Result {.cdecl, + importc: "pdmqryQueryRecentlyPlayedApplication".} +## * +## @brief Gets an Event which is signaled when logging a new \ref PdmPlayEvent which would be available via \ref pdmqryQueryAccountEvent, where PdmPlayEvent::eventData::account::type is 0. +## @note Only available with [6.0.0-14.1.2]. +## @note The Event must be closed by the user once finished with it. +## @param[out] out_event Output Event with autoclear=false. +## + +proc pdmqryGetRecentlyPlayedApplicationUpdateEvent*(outEvent: ptr Event): Result {. + cdecl, importc: "pdmqryGetRecentlyPlayedApplicationUpdateEvent".} +## * +## @brief Helper function which converts a Play timestamp from the Pdm*Event structs to POSIX. +## @param[in] timestamp Input timestamp. +## + +proc pdmPlayTimestampToPosix*(timestamp: U32): U64 {.inline, cdecl.} = + return (cast[U64](timestamp)) * 60 + 946598400 diff --git a/src/libnx/wrapper/switch/services/pgl.h b/src/libnx/wrapper/switch/services/pgl.h new file mode 100644 index 0000000..5b3a882 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pgl.h @@ -0,0 +1,69 @@ +/** + * @file pgl.h + * @brief PGL service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../sf/tipc.h" +#include "../services/ncm_types.h" +#include "../services/pm.h" + +/// LaunchFlag +typedef enum { + PglLaunchFlag_None = 0, + PglLaunchFlag_EnableDetailedCrashReport = BIT(0), + PglLaunchFlag_EnableCrashReportScreenShotForProduction = BIT(1), + PglLaunchFlag_EnableCrashReportScreenShotForDevelop = BIT(2), +} PglLaunchFlag; + +/// SnapShotDumpType +typedef enum { + PglSnapShotDumpType_None = 0, + PglSnapShotDumpType_Auto = 1, + PglSnapShotDumpType_Full = 2, +} PglSnapShotDumpType; + +typedef struct { + u64 id; ///< Program Id + u32 version; ///< Version + u8 content_type; ///< NcmContentType + u8 id_offset; ///< Id Offset + u8 reserved_0E[2]; ///< Padding +} PglContentMetaInfo; + +typedef union { + Service s; + TipcService t; +} PglEventObserver; + +/// Initialize pgl. +Result pglInitialize(void); + +/// Exit pgl. +void pglExit(void); + +/// Gets the Service object for the actual pgl service session. Requires < 12.0.0 +Service* pglGetServiceSessionCmif(void); + +/// Gets the TipcService object for the actual pgl service session. Requires 12.0.0+ +TipcService* pglGetServiceSessionTipc(void); + +Result pglLaunchProgram(u64 *out_pid, const NcmProgramLocation *loc, u32 pm_launch_flags, u8 pgl_launch_flags); +Result pglTerminateProcess(u64 pid); +Result pglLaunchProgramFromHost(u64 *out_pid, const char *content_path, u32 pm_launch_flags); +Result pglGetHostContentMetaInfo(PglContentMetaInfo *out, const char *content_path); +Result pglGetApplicationProcessId(u64 *out); +Result pglBoostSystemMemoryResourceLimit(u64 size); +Result pglIsProcessTracked(bool *out, u64 pid); +Result pglEnableApplicationCrashReport(bool en); +Result pglIsApplicationCrashReportEnabled(bool *out); +Result pglEnableApplicationAllThreadDumpOnCrash(bool en); +Result pglTriggerApplicationSnapShotDumper(PglSnapShotDumpType dump_type, const char *arg); +Result pglGetEventObserver(PglEventObserver *out); + +Result pglEventObserverGetProcessEvent(PglEventObserver *observer, Event *out); +Result pglEventObserverGetProcessEventInfo(PglEventObserver *observer, PmProcessEventInfo *out); +void pglEventObserverClose(PglEventObserver *observer); diff --git a/src/libnx/wrapper/switch/services/pgl.nim b/src/libnx/wrapper/switch/services/pgl.nim new file mode 100644 index 0000000..617478b --- /dev/null +++ b/src/libnx/wrapper/switch/services/pgl.nim @@ -0,0 +1,85 @@ +## * +## @file pgl.h +## @brief PGL service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../sf/tipc, ../services/ncm_types, ../services/pm, ../kernel/event + +## / LaunchFlag + +type + PglLaunchFlag* = enum + PglLaunchFlagNone = 0, PglLaunchFlagEnableDetailedCrashReport = bit(0), + PglLaunchFlagEnableCrashReportScreenShotForProduction = bit(1), + PglLaunchFlagEnableCrashReportScreenShotForDevelop = bit(2) + + +## / SnapShotDumpType + +type + PglSnapShotDumpType* = enum + PglSnapShotDumpTypeNone = 0, PglSnapShotDumpTypeAuto = 1, + PglSnapShotDumpTypeFull = 2 + PglContentMetaInfo* {.bycopy.} = object + id*: U64 ## /< Program Id + version*: U32 ## /< Version + contentType*: U8 ## /< NcmContentType + idOffset*: U8 ## /< Id Offset + reserved0E*: array[2, U8] ## /< Padding + + PglEventObserver* {.bycopy, union.} = object + s*: Service + t*: TipcService + + + + +proc pglInitialize*(): Result {.cdecl, importc: "pglInitialize".} +## / Initialize pgl. + +proc pglExit*() {.cdecl, importc: "pglExit".} +## / Exit pgl. + +proc pglGetServiceSessionCmif*(): ptr Service {.cdecl, + importc: "pglGetServiceSessionCmif".} +## / Gets the Service object for the actual pgl service session. Requires < 12.0.0 + +proc pglGetServiceSessionTipc*(): ptr TipcService {.cdecl, + importc: "pglGetServiceSessionTipc".} +## / Gets the TipcService object for the actual pgl service session. Requires 12.0.0+ +proc pglLaunchProgram*(outPid: ptr U64; loc: ptr NcmProgramLocation; + pmLaunchFlags: U32; pglLaunchFlags: U8): Result {.cdecl, + importc: "pglLaunchProgram".} +proc pglTerminateProcess*(pid: U64): Result {.cdecl, importc: "pglTerminateProcess".} +proc pglLaunchProgramFromHost*(outPid: ptr U64; contentPath: cstring; + pmLaunchFlags: U32): Result {.cdecl, + importc: "pglLaunchProgramFromHost".} +proc pglGetHostContentMetaInfo*(`out`: ptr PglContentMetaInfo; contentPath: cstring): Result {. + cdecl, importc: "pglGetHostContentMetaInfo".} +proc pglGetApplicationProcessId*(`out`: ptr U64): Result {.cdecl, + importc: "pglGetApplicationProcessId".} +proc pglBoostSystemMemoryResourceLimit*(size: U64): Result {.cdecl, + importc: "pglBoostSystemMemoryResourceLimit".} +proc pglIsProcessTracked*(`out`: ptr bool; pid: U64): Result {.cdecl, + importc: "pglIsProcessTracked".} +proc pglEnableApplicationCrashReport*(en: bool): Result {.cdecl, + importc: "pglEnableApplicationCrashReport".} +proc pglIsApplicationCrashReportEnabled*(`out`: ptr bool): Result {.cdecl, + importc: "pglIsApplicationCrashReportEnabled".} +proc pglEnableApplicationAllThreadDumpOnCrash*(en: bool): Result {.cdecl, + importc: "pglEnableApplicationAllThreadDumpOnCrash".} +proc pglTriggerApplicationSnapShotDumper*(dumpType: PglSnapShotDumpType; + arg: cstring): Result {.cdecl, importc: "pglTriggerApplicationSnapShotDumper".} +proc pglGetEventObserver*(`out`: ptr PglEventObserver): Result {.cdecl, + importc: "pglGetEventObserver".} +proc pglEventObserverGetProcessEvent*(observer: ptr PglEventObserver; + `out`: ptr Event): Result {.cdecl, + importc: "pglEventObserverGetProcessEvent".} +proc pglEventObserverGetProcessEventInfo*(observer: ptr PglEventObserver; + `out`: ptr PmProcessEventInfo): Result {.cdecl, + importc: "pglEventObserverGetProcessEventInfo".} +proc pglEventObserverClose*(observer: ptr PglEventObserver) {.cdecl, + importc: "pglEventObserverClose".} diff --git a/src/libnx/wrapper/switch/services/pl.h b/src/libnx/wrapper/switch/services/pl.h new file mode 100644 index 0000000..d1a29a8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pl.h @@ -0,0 +1,52 @@ +/** + * @file pl.h + * @brief pl:u service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +typedef enum { + PlServiceType_User = 0, ///< Initializes pl:u. + PlServiceType_System = 1, ///< Initializes pl:s. +} PlServiceType; + +/// SharedFontType +typedef enum { + PlSharedFontType_Standard = 0, ///< Japan, US and Europe + PlSharedFontType_ChineseSimplified = 1, ///< Chinese Simplified + PlSharedFontType_ExtChineseSimplified = 2, ///< Extended Chinese Simplified + PlSharedFontType_ChineseTraditional = 3, ///< Chinese Traditional + PlSharedFontType_KO = 4, ///< Korean (Hangul) + PlSharedFontType_NintendoExt = 5, ///< Nintendo Extended. This font only has the special Nintendo-specific characters, which aren't available with the other fonts. + PlSharedFontType_Total, ///< Total fonts supported by this enum. +} PlSharedFontType; + +/// FontData +typedef struct { + u32 type; ///< \ref PlSharedFontType + u32 offset; ///< Offset of the font in sharedmem. + u32 size; ///< Size of the font. + void* address; ///< Address of the actual font. +} PlFontData; + +/// Initialize pl. +Result plInitialize(PlServiceType service_type); + +/// Exit pl. +void plExit(void); + +/// Gets the Service object for the actual pl service session. +Service* plGetServiceSession(void); + +/// Gets the address of the SharedMemory. +void* plGetSharedmemAddr(void); + +///< Gets a specific shared-font via \ref PlSharedFontType. +Result plGetSharedFontByType(PlFontData* font, PlSharedFontType SharedFontType); + +///< Gets shared font(s). +Result plGetSharedFont(u64 LanguageCode, PlFontData* fonts, s32 max_fonts, s32* total_fonts); + diff --git a/src/libnx/wrapper/switch/services/pl.nim b/src/libnx/wrapper/switch/services/pl.nim new file mode 100644 index 0000000..d566322 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pl.nim @@ -0,0 +1,60 @@ +## * +## @file pl.h +## @brief pl:u service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +type + PlServiceType* = enum + PlServiceTypeUser = 0, ## /< Initializes pl:u. + PlServiceTypeSystem = 1 ## /< Initializes pl:s. + + +## / SharedFontType + +type + PlSharedFontType* = enum + PlSharedFontTypeStandard = 0, ## /< Japan, US and Europe + PlSharedFontTypeChineseSimplified = 1, ## /< Chinese Simplified + PlSharedFontTypeExtChineseSimplified = 2, ## /< Extended Chinese Simplified + PlSharedFontTypeChineseTraditional = 3, ## /< Chinese Traditional + PlSharedFontTypeKO = 4, ## /< Korean (Hangul) + PlSharedFontTypeNintendoExt = 5, ## /< Nintendo Extended. This font only has the special Nintendo-specific characters, which aren't available with the other fonts. + PlSharedFontTypeTotal ## /< Total fonts supported by this enum. + + +## / FontData + +type + PlFontData* {.bycopy.} = object + `type`*: U32 ## /< \ref PlSharedFontType + offset*: U32 ## /< Offset of the font in sharedmem. + size*: U32 ## /< Size of the font. + address*: pointer ## /< Address of the actual font. + + +## / Initialize pl. + +proc plInitialize*(serviceType: PlServiceType): Result {.cdecl, + importc: "plInitialize".} +## / Exit pl. + +proc plExit*() {.cdecl, importc: "plExit".} +## / Gets the Service object for the actual pl service session. + +proc plGetServiceSession*(): ptr Service {.cdecl, importc: "plGetServiceSession".} +## / Gets the address of the SharedMemory. + +proc plGetSharedmemAddr*(): pointer {.cdecl, importc: "plGetSharedmemAddr".} +## /< Gets a specific shared-font via \ref PlSharedFontType. + +proc plGetSharedFontByType*(font: ptr PlFontData; sharedFontType: PlSharedFontType): Result {. + cdecl, importc: "plGetSharedFontByType".} +## /< Gets shared font(s). + +proc plGetSharedFont*(languageCode: U64; fonts: ptr PlFontData; maxFonts: S32; + totalFonts: ptr S32): Result {.cdecl, importc: "plGetSharedFont".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/pm.h b/src/libnx/wrapper/switch/services/pm.h new file mode 100644 index 0000000..13e1fd1 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pm.h @@ -0,0 +1,140 @@ +/** + * @file pm.h + * @brief Process management (pm*) service IPC wrapper. + * @author plutoo + * @author yellows8 + * @author mdbell + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" +#include "../services/ncm_types.h" + +/// LaunchFlag +typedef enum { + PmLaunchFlag_None = 0, + + ///< PmLaunchFlag_* should be used on [5.0.0+]. + PmLaunchFlag_SignalOnExit = (1 << 0), + PmLaunchFlag_SignalOnStart = (1 << 1), + PmLaunchFlag_SignalOnCrash = (1 << 2), + PmLaunchFlag_SignalOnDebug = (1 << 3), + PmLaunchFlag_StartSuspended = (1 << 4), + PmLaunchFlag_DisableAslr = (1 << 5), + + ///< PmLaunchFlagOld_* should be used on [1.0.0-4.1.0]. + PmLaunchFlagOld_SignalOnExit = (1 << 0), + PmLaunchFlagOld_StartSuspended = (1 << 1), + PmLaunchFlagOld_SignalOnCrash = (1 << 2), + PmLaunchFlagOld_DisableAslr = (1 << 3), + PmLaunchFlagOld_SignalOnDebug = (1 << 4), + ///< PmLaunchFlagOld_SignalOnStart is only available on [2.0.0+]. + PmLaunchFlagOld_SignalOnStart = (1 << 5), +} PmLaunchFlag; + +/// ProcessEvent +typedef enum { + PmProcessEvent_None = 0, + PmProcessEvent_Exit = 1, + PmProcessEvent_Start = 2, + PmProcessEvent_Crash = 3, + PmProcessEvent_DebugStart = 4, + PmProcessEvent_DebugBreak = 5, +} PmProcessEvent; + +/// ProcessEventInfo +typedef struct { + PmProcessEvent event; + u64 process_id; +} PmProcessEventInfo; + +/// BootMode +typedef enum { + PmBootMode_Normal = 0, ///< Normal + PmBootMode_Maintenance = 1, ///< Maintenance + PmBootMode_SafeMode = 2, ///< SafeMode +} PmBootMode; + +/// ResourceLimitValues +typedef struct { + u64 physical_memory; + u32 thread_count; + u32 event_count; + u32 transfer_memory_count; + u32 session_count; +} PmResourceLimitValues; + +/// Initialize pm:dmnt. +Result pmdmntInitialize(void); + +/// Exit pm:dmnt. +void pmdmntExit(void); + +/// Gets the Service object for the actual pm:dmnt service session. +Service* pmdmntGetServiceSession(void); + +/// Initialize pm:info. +Result pminfoInitialize(void); + +/// Exit pm:info. +void pminfoExit(void); + +/// Gets the Service object for the actual pm:info service session. +Service* pminfoGetServiceSession(void); + +/// Initialize pm:shell. +Result pmshellInitialize(void); + +/// Exit pm:shell. +void pmshellExit(void); + +/// Gets the Service object for the actual pm:shell service session. +Service* pmshellGetServiceSession(void); + +/// Initialize pm:bm. +Result pmbmInitialize(void); + +/// Exit pm:bm. +void pmbmExit(void); + +/// Gets the Service object for the actual pm:bm service session. +Service* pmbmGetServiceSession(void); + +/** + * @brief Gets the \ref PmBootMode. + * @param[out] out \ref PmBootMode + */ +Result pmbmGetBootMode(PmBootMode *out); + +/** + * @brief Sets the \ref PmBootMode to ::PmBootMode_Maintenance. + */ +Result pmbmSetMaintenanceBoot(void); + +Result pmdmntGetJitDebugProcessIdList(u32* out_count, u64* out_pids, size_t max_pids); +Result pmdmntStartProcess(u64 pid); +Result pmdmntGetProcessId(u64* pid_out, u64 program_id); +Result pmdmntHookToCreateProcess(Event* out, u64 program_id); +Result pmdmntGetApplicationProcessId(u64* pid_out); +Result pmdmntHookToCreateApplicationProcess(Event* out); +Result pmdmntClearHook(u32 which); +Result pmdmntGetProgramId(u64* program_id_out, u64 pid); + +Result pminfoGetProgramId(u64* program_id_out, u64 pid); +Result pminfoGetAppletCurrentResourceLimitValues(PmResourceLimitValues* out); +Result pminfoGetAppletPeakResourceLimitValues(PmResourceLimitValues* out); + +Result pmshellLaunchProgram(u32 launch_flags, const NcmProgramLocation *location, u64 *pid); +Result pmshellTerminateProcess(u64 processID); +Result pmshellTerminateProgram(u64 program_id); +Result pmshellGetProcessEventHandle(Event* out); // Autoclear for pmshellProcessEvent is always true. +Result pmshellGetProcessEventInfo(PmProcessEventInfo* out); +Result pmshellCleanupProcess(u64 pid); +Result pmshellClearJitDebugOccured(u64 pid); +Result pmshellNotifyBootFinished(void); +Result pmshellGetApplicationProcessIdForShell(u64* pid_out); +Result pmshellBoostSystemMemoryResourceLimit(u64 boost_size); +Result pmshellBoostApplicationThreadResourceLimit(void); +Result pmshellBoostSystemThreadResourceLimit(void); diff --git a/src/libnx/wrapper/switch/services/pm.nim b/src/libnx/wrapper/switch/services/pm.nim new file mode 100644 index 0000000..5436dc8 --- /dev/null +++ b/src/libnx/wrapper/switch/services/pm.nim @@ -0,0 +1,155 @@ +## * +## @file pm.h +## @brief Process management (pm*) service IPC wrapper. +## @author plutoo +## @author yellows8 +## @author mdbell +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service, ../services/ncm_types + +## / LaunchFlag + +type + PmLaunchFlag* = enum + PmLaunchFlagNone = 0, ## /< PmLaunchFlag_* should be used on [5.0.0+]. + PmLaunchFlagSignalOnExit = (1 shl 0), + PmLaunchFlagSignalOnStart = (1 shl 1), + PmLaunchFlagSignalOnCrash = (1 shl 2), + PmLaunchFlagSignalOnDebug = (1 shl 3), + PmLaunchFlagStartSuspended = (1 shl 4), + PmLaunchFlagDisableAslr = (1 shl 5), ## /< PmLaunchFlagOld_* should be used on [1.0.0-4.1.0]. + + PmLaunchFlagOld* = enum + PmLaunchFlagOldSignalOnExit = (1 shl 0), + PmLaunchFlagOldStartSuspended = (1 shl 1), + PmLaunchFlagOldSignalOnCrash = (1 shl 2), + PmLaunchFlagOldDisableAslr = (1 shl 3), + PmLaunchFlagOldSignalOnDebug = (1 shl 4), ## /< PmLaunchFlagOld_SignalOnStart is only available on [2.0.0+]. + PmLaunchFlagOldSignalOnStart = (1 shl 5) + + +## / ProcessEvent + +type + PmProcessEvent* = enum + PmProcessEventNone = 0, PmProcessEventExit = 1, PmProcessEventStart = 2, + PmProcessEventCrash = 3, PmProcessEventDebugStart = 4, + PmProcessEventDebugBreak = 5 + + +## / ProcessEventInfo + +type + PmProcessEventInfo* {.bycopy.} = object + event*: PmProcessEvent + processId*: U64 + + +## / BootMode + +type + PmBootMode* = enum + PmBootModeNormal = 0, ## /< Normal + PmBootModeMaintenance = 1, ## /< Maintenance + PmBootModeSafeMode = 2 ## /< SafeMode + + +## / ResourceLimitValues + +type + PmResourceLimitValues* {.bycopy.} = object + physicalMemory*: U64 + threadCount*: U32 + eventCount*: U32 + transferMemoryCount*: U32 + sessionCount*: U32 + +proc pmdmntInitialize*(): Result {.cdecl, importc: "pmdmntInitialize".} +## / Initialize pm:dmnt. +proc pmdmntExit*() {.cdecl, importc: "pmdmntExit".} +## / Exit pm:dmnt. +proc pmdmntGetServiceSession*(): ptr Service {.cdecl, + importc: "pmdmntGetServiceSession".} +## / Gets the Service object for the actual pm:dmnt service session. +proc pminfoInitialize*(): Result {.cdecl, importc: "pminfoInitialize".} +## / Initialize pm:info. +proc pminfoExit*() {.cdecl, importc: "pminfoExit".} +## / Exit pm:info. +proc pminfoGetServiceSession*(): ptr Service {.cdecl, + importc: "pminfoGetServiceSession".} +## / Gets the Service object for the actual pm:info service session. +proc pmshellInitialize*(): Result {.cdecl, importc: "pmshellInitialize".} +## / Initialize pm:shell. +proc pmshellExit*() {.cdecl, importc: "pmshellExit".} +## / Exit pm:shell. +proc pmshellGetServiceSession*(): ptr Service {.cdecl, + importc: "pmshellGetServiceSession".} +## / Gets the Service object for the actual pm:shell service session. +proc pmbmInitialize*(): Result {.cdecl, importc: "pmbmInitialize".} +## / Initialize pm:bm. +proc pmbmExit*() {.cdecl, importc: "pmbmExit".} +## / Exit pm:bm. +proc pmbmGetServiceSession*(): ptr Service {.cdecl, importc: "pmbmGetServiceSession".} +## / Gets the Service object for the actual pm:bm service session. +proc pmbmGetBootMode*(`out`: ptr PmBootMode): Result {.cdecl, + importc: "pmbmGetBootMode".} +## * +## @brief Gets the \ref PmBootMode. +## @param[out] out \ref PmBootMode +## +proc pmbmSetMaintenanceBoot*(): Result {.cdecl, importc: "pmbmSetMaintenanceBoot".} +## * +## @brief Sets the \ref PmBootMode to ::PmBootMode_Maintenance. +## + +proc pmdmntGetJitDebugProcessIdList*(outCount: ptr U32; outPids: ptr U64; + maxPids: csize_t): Result {.cdecl, + importc: "pmdmntGetJitDebugProcessIdList".} +proc pmdmntStartProcess*(pid: U64): Result {.cdecl, importc: "pmdmntStartProcess".} +proc pmdmntGetProcessId*(pidOut: ptr U64; programId: U64): Result {.cdecl, + importc: "pmdmntGetProcessId".} +proc pmdmntHookToCreateProcess*(`out`: ptr Event; programId: U64): Result {.cdecl, + importc: "pmdmntHookToCreateProcess".} +proc pmdmntGetApplicationProcessId*(pidOut: ptr U64): Result {.cdecl, + importc: "pmdmntGetApplicationProcessId".} +proc pmdmntHookToCreateApplicationProcess*(`out`: ptr Event): Result {.cdecl, + importc: "pmdmntHookToCreateApplicationProcess".} +proc pmdmntClearHook*(which: U32): Result {.cdecl, importc: "pmdmntClearHook".} +proc pmdmntGetProgramId*(programIdOut: ptr U64; pid: U64): Result {.cdecl, + importc: "pmdmntGetProgramId".} +proc pminfoGetProgramId*(programIdOut: ptr U64; pid: U64): Result {.cdecl, + importc: "pminfoGetProgramId".} +proc pminfoGetAppletCurrentResourceLimitValues*(`out`: ptr PmResourceLimitValues): Result {. + cdecl, importc: "pminfoGetAppletCurrentResourceLimitValues".} +proc pminfoGetAppletPeakResourceLimitValues*(`out`: ptr PmResourceLimitValues): Result {. + cdecl, importc: "pminfoGetAppletPeakResourceLimitValues".} +proc pmshellLaunchProgram*(launchFlags: U32; location: ptr NcmProgramLocation; + pid: ptr U64): Result {.cdecl, + importc: "pmshellLaunchProgram".} +proc pmshellTerminateProcess*(processID: U64): Result {.cdecl, + importc: "pmshellTerminateProcess".} +proc pmshellTerminateProgram*(programId: U64): Result {.cdecl, + importc: "pmshellTerminateProgram".} +proc pmshellGetProcessEventHandle*(`out`: ptr Event): Result {.cdecl, + importc: "pmshellGetProcessEventHandle".} + +proc pmshellGetProcessEventInfo*(`out`: ptr PmProcessEventInfo): Result {.cdecl, + importc: "pmshellGetProcessEventInfo".} +## Autoclear for pmshellProcessEvent is always true. +proc pmshellCleanupProcess*(pid: U64): Result {.cdecl, + importc: "pmshellCleanupProcess".} +proc pmshellClearJitDebugOccured*(pid: U64): Result {.cdecl, + importc: "pmshellClearJitDebugOccured".} +proc pmshellNotifyBootFinished*(): Result {.cdecl, + importc: "pmshellNotifyBootFinished".} +proc pmshellGetApplicationProcessIdForShell*(pidOut: ptr U64): Result {.cdecl, + importc: "pmshellGetApplicationProcessIdForShell".} +proc pmshellBoostSystemMemoryResourceLimit*(boostSize: U64): Result {.cdecl, + importc: "pmshellBoostSystemMemoryResourceLimit".} +proc pmshellBoostApplicationThreadResourceLimit*(): Result {.cdecl, + importc: "pmshellBoostApplicationThreadResourceLimit".} +proc pmshellBoostSystemThreadResourceLimit*(): Result {.cdecl, + importc: "pmshellBoostSystemThreadResourceLimit".} diff --git a/src/libnx/wrapper/switch/services/psc.h b/src/libnx/wrapper/switch/services/psc.h new file mode 100644 index 0000000..98bdd2a --- /dev/null +++ b/src/libnx/wrapper/switch/services/psc.h @@ -0,0 +1,103 @@ +/** + * @file psc.h + * @brief PSC service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +typedef enum { + PscPmState_Awake = 0, ///< Everything is awake. + PscPmState_ReadyAwaken = 1, ///< Preparing to transition to awake. + PscPmState_ReadySleep = 2, ///< Preparing to transition to sleep. + PscPmState_ReadySleepCritical = 3, ///< Critical services are ready to sleep. + PscPmState_ReadyAwakenCritical = 4, ///< Critical services are ready to wake up. + PscPmState_ReadyShutdown = 5, ///< Preparing to transition to shutdown. +} PscPmState; + +typedef enum { + PscPmModuleId_Usb = 4, + PscPmModuleId_Ethernet = 5, + PscPmModuleId_Fgm = 6, + PscPmModuleId_PcvClock = 7, + PscPmModuleId_PcvVoltage = 8, + PscPmModuleId_Gpio = 9, + PscPmModuleId_Pinmux = 10, + PscPmModuleId_Uart = 11, + PscPmModuleId_I2c = 12, + PscPmModuleId_I2cPcv = 13, + PscPmModuleId_Spi = 14, + PscPmModuleId_Pwm = 15, + PscPmModuleId_Psm = 16, + PscPmModuleId_Tc = 17, + PscPmModuleId_Omm = 18, + PscPmModuleId_Pcie = 19, + PscPmModuleId_Lbl = 20, + PscPmModuleId_Display = 21, + + PscPmModuleId_Hid = 24, + PscPmModuleId_WlanSockets = 25, + + PscPmModuleId_Fs = 27, + PscPmModuleId_Audio = 28, + + PscPmModuleId_TmaHostIo = 30, + PscPmModuleId_Bluetooth = 31, + PscPmModuleId_Bpc = 32, + PscPmModuleId_Fan = 33, + PscPmModuleId_Pcm = 34, + PscPmModuleId_Nfc = 35, + PscPmModuleId_Apm = 36, + PscPmModuleId_Btm = 37, + PscPmModuleId_Nifm = 38, + PscPmModuleId_GpioLow = 39, + PscPmModuleId_Npns = 40, + PscPmModuleId_Lm = 41, + PscPmModuleId_Bcat = 42, + PscPmModuleId_Time = 43, + PscPmModuleId_Pctl = 44, + PscPmModuleId_Erpt = 45, + PscPmModuleId_Eupld = 46, + PscPmModuleId_Friends = 47, + PscPmModuleId_Bgtc = 48, + PscPmModuleId_Account = 49, + PscPmModuleId_Sasbus = 50, + PscPmModuleId_Ntc = 51, + PscPmModuleId_Idle = 52, + PscPmModuleId_Tcap = 53, + PscPmModuleId_PsmLow = 54, + PscPmModuleId_Ndd = 55, + PscPmModuleId_Olsc = 56, + + PscPmModuleId_Ns = 61, + + PscPmModuleId_Nvservices = 101, + + PscPmModuleId_Spsm = 127, +} PscPmModuleId; + +typedef struct { + Event event; + Service srv; + PscPmModuleId module_id; +} PscPmModule; + +/// Initialize psc:m. +Result pscmInitialize(void); + +/// Exit psc:m. +void pscmExit(void); + +/// Gets the Service object for the actual psc:m service session. +Service* pscmGetServiceSession(void); + +Result pscmGetPmModule(PscPmModule *out, PscPmModuleId module_id, const u32 *dependencies, size_t dependency_count, bool autoclear); + +Result pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags); +Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state); +Result pscPmModuleFinalize(PscPmModule *module); + +void pscPmModuleClose(PscPmModule *module); diff --git a/src/libnx/wrapper/switch/services/psc.nim b/src/libnx/wrapper/switch/services/psc.nim new file mode 100644 index 0000000..1dfac3f --- /dev/null +++ b/src/libnx/wrapper/switch/services/psc.nim @@ -0,0 +1,65 @@ +## * +## @file psc.h +## @brief PSC service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +type + PscPmState* = enum + PscPmStateAwake = 0, ## /< Everything is awake. + PscPmStateReadyAwaken = 1, ## /< Preparing to transition to awake. + PscPmStateReadySleep = 2, ## /< Preparing to transition to sleep. + PscPmStateReadySleepCritical = 3, ## /< Critical services are ready to sleep. + PscPmStateReadyAwakenCritical = 4, ## /< Critical services are ready to wake up. + PscPmStateReadyShutdown = 5 ## /< Preparing to transition to shutdown. + PscPmModuleId* = enum + PscPmModuleIdUsb = 4, PscPmModuleIdEthernet = 5, PscPmModuleIdFgm = 6, + PscPmModuleIdPcvClock = 7, PscPmModuleIdPcvVoltage = 8, PscPmModuleIdGpio = 9, + PscPmModuleIdPinmux = 10, PscPmModuleIdUart = 11, PscPmModuleIdI2c = 12, + PscPmModuleIdI2cPcv = 13, PscPmModuleIdSpi = 14, PscPmModuleIdPwm = 15, + PscPmModuleIdPsm = 16, PscPmModuleIdTc = 17, PscPmModuleIdOmm = 18, + PscPmModuleIdPcie = 19, PscPmModuleIdLbl = 20, PscPmModuleIdDisplay = 21, + PscPmModuleIdHid = 24, PscPmModuleIdWlanSockets = 25, PscPmModuleIdFs = 27, + PscPmModuleIdAudio = 28, PscPmModuleIdTmaHostIo = 30, PscPmModuleIdBluetooth = 31, + PscPmModuleIdBpc = 32, PscPmModuleIdFan = 33, PscPmModuleIdPcm = 34, + PscPmModuleIdNfc = 35, PscPmModuleIdApm = 36, PscPmModuleIdBtm = 37, + PscPmModuleIdNifm = 38, PscPmModuleIdGpioLow = 39, PscPmModuleIdNpns = 40, + PscPmModuleIdLm = 41, PscPmModuleIdBcat = 42, PscPmModuleIdTime = 43, + PscPmModuleIdPctl = 44, PscPmModuleIdErpt = 45, PscPmModuleIdEupld = 46, + PscPmModuleIdFriends = 47, PscPmModuleIdBgtc = 48, PscPmModuleIdAccount = 49, + PscPmModuleIdSasbus = 50, PscPmModuleIdNtc = 51, PscPmModuleIdIdle = 52, + PscPmModuleIdTcap = 53, PscPmModuleIdPsmLow = 54, PscPmModuleIdNdd = 55, + PscPmModuleIdOlsc = 56, PscPmModuleIdNs = 61, PscPmModuleIdNvservices = 101, + PscPmModuleIdSpsm = 127 + PscPmModule* {.bycopy.} = object + event*: Event + srv*: Service + moduleId*: PscPmModuleId + + + + +## / Initialize psc:m. + +proc pscmInitialize*(): Result {.cdecl, importc: "pscmInitialize".} +## / Exit psc:m. + +proc pscmExit*() {.cdecl, importc: "pscmExit".} +## / Gets the Service object for the actual psc:m service session. + +proc pscmGetServiceSession*(): ptr Service {.cdecl, importc: "pscmGetServiceSession".} +proc pscmGetPmModule*(`out`: ptr PscPmModule; moduleId: PscPmModuleId; + dependencies: ptr U32; dependencyCount: csize_t; autoclear: bool): Result {. + cdecl, importc: "pscmGetPmModule".} +proc pscPmModuleGetRequest*(module: ptr PscPmModule; outState: ptr PscPmState; + outFlags: ptr U32): Result {.cdecl, + importc: "pscPmModuleGetRequest".} +proc pscPmModuleAcknowledge*(module: ptr PscPmModule; state: PscPmState): Result {. + cdecl, importc: "pscPmModuleAcknowledge".} +proc pscPmModuleFinalize*(module: ptr PscPmModule): Result {.cdecl, + importc: "pscPmModuleFinalize".} +proc pscPmModuleClose*(module: ptr PscPmModule) {.cdecl, importc: "pscPmModuleClose".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/psm.h b/src/libnx/wrapper/switch/services/psm.h new file mode 100644 index 0000000..fb379c0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/psm.h @@ -0,0 +1,63 @@ +/** + * @file psm.h + * @brief PSM service IPC wrapper. + * @author XorTroll, endrift, and yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../kernel/event.h" + +typedef enum { + PsmChargerType_Unconnected = 0, ///< No charger + PsmChargerType_EnoughPower = 1, ///< Full supported power + PsmChargerType_LowPower = 2, ///< Lower power supported USB-PD mode + PsmChargerType_NotSupported = 3, ///< No common supported USB-PD modes +} PsmChargerType; + +typedef enum { + PsmBatteryVoltageState_NeedsShutdown = 0, ///< Power state should transition to shutdown + PsmBatteryVoltageState_NeedsSleep = 1, ///< Power state should transition to sleep + PsmBatteryVoltageState_NoPerformanceBoost = 2, ///< Performance boost modes cannot be entered + PsmBatteryVoltageState_Normal = 3, ///< Everything is normal +} PsmBatteryVoltageState; + +/// IPsmSession +typedef struct { + Service s; + Event StateChangeEvent; ///< autoclear=false +} PsmSession; + +/// Initialize psm. +Result psmInitialize(void); + +/// Exit psm. +void psmExit(void); + +/// Gets the Service object for the actual psm service session. +Service* psmGetServiceSession(void); + +Result psmGetBatteryChargePercentage(u32 *out); +Result psmGetChargerType(PsmChargerType *out); +Result psmGetBatteryVoltageState(PsmBatteryVoltageState *out); +Result psmGetRawBatteryChargePercentage(double *out); +Result psmIsEnoughPowerSupplied(bool *out); +Result psmGetBatteryAgePercentage(double *out); + +/** + * @brief Wrapper func which opens a PsmSession and handles event setup. + * @note Uses the actual BindStateChangeEvent cmd internally. + * @note The event is not signalled on BatteryChargePercentage changes. + * @param[out] s PsmSession object. + * @param[in] ChargerType Passed to SetChargerTypeChangeEventEnabled. + * @param[in] PowerSupply Passed to SetPowerSupplyChangeEventEnabled. + * @param[in] BatteryVoltage Passed to SetBatteryVoltageStateChangeEventEnabled. + */ +Result psmBindStateChangeEvent(PsmSession* s, bool ChargerType, bool PowerSupply, bool BatteryVoltage); + +/// Wait on the Event setup by \ref psmBindStateChangeEvent. +Result psmWaitStateChangeEvent(PsmSession* s, u64 timeout); + +/// Cleanup version of \ref psmBindStateChangeEvent. Must be called by the user once the PsmSession is done being used. +Result psmUnbindStateChangeEvent(PsmSession* s); diff --git a/src/libnx/wrapper/switch/services/psm.nim b/src/libnx/wrapper/switch/services/psm.nim new file mode 100644 index 0000000..b9c172f --- /dev/null +++ b/src/libnx/wrapper/switch/services/psm.nim @@ -0,0 +1,74 @@ +## * +## @file psm.h +## @brief PSM service IPC wrapper. +## @author XorTroll, endrift, and yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../kernel/event + +type + PsmChargerType* = enum + PsmChargerTypeUnconnected = 0, ## /< No charger + PsmChargerTypeEnoughPower = 1, ## /< Full supported power + PsmChargerTypeLowPower = 2, ## /< Lower power supported USB-PD mode + PsmChargerTypeNotSupported = 3 ## /< No common supported USB-PD modes + PsmBatteryVoltageState* = enum + PsmBatteryVoltageStateNeedsShutdown = 0, ## /< Power state should transition to shutdown + PsmBatteryVoltageStateNeedsSleep = 1, ## /< Power state should transition to sleep + PsmBatteryVoltageStateNoPerformanceBoost = 2, ## /< Performance boost modes cannot be entered + PsmBatteryVoltageStateNormal = 3 ## /< Everything is normal + + + +## / IPsmSession + +type + PsmSession* {.bycopy.} = object + s*: Service + stateChangeEvent*: Event ## /< autoclear=false + + +## / Initialize psm. + +proc psmInitialize*(): Result {.cdecl, importc: "psmInitialize".} +## / Exit psm. + +proc psmExit*() {.cdecl, importc: "psmExit".} +## / Gets the Service object for the actual psm service session. + +proc psmGetServiceSession*(): ptr Service {.cdecl, importc: "psmGetServiceSession".} +proc psmGetBatteryChargePercentage*(`out`: ptr U32): Result {.cdecl, + importc: "psmGetBatteryChargePercentage".} +proc psmGetChargerType*(`out`: ptr PsmChargerType): Result {.cdecl, + importc: "psmGetChargerType".} +proc psmGetBatteryVoltageState*(`out`: ptr PsmBatteryVoltageState): Result {.cdecl, + importc: "psmGetBatteryVoltageState".} +proc psmGetRawBatteryChargePercentage*(`out`: ptr cdouble): Result {.cdecl, + importc: "psmGetRawBatteryChargePercentage".} +proc psmIsEnoughPowerSupplied*(`out`: ptr bool): Result {.cdecl, + importc: "psmIsEnoughPowerSupplied".} +proc psmGetBatteryAgePercentage*(`out`: ptr cdouble): Result {.cdecl, + importc: "psmGetBatteryAgePercentage".} +## * +## @brief Wrapper func which opens a PsmSession and handles event setup. +## @note Uses the actual BindStateChangeEvent cmd internally. +## @note The event is not signalled on BatteryChargePercentage changes. +## @param[out] s PsmSession object. +## @param[in] ChargerType Passed to SetChargerTypeChangeEventEnabled. +## @param[in] PowerSupply Passed to SetPowerSupplyChangeEventEnabled. +## @param[in] BatteryVoltage Passed to SetBatteryVoltageStateChangeEventEnabled. +## + +proc psmBindStateChangeEvent*(s: ptr PsmSession; chargerType: bool; powerSupply: bool; + batteryVoltage: bool): Result {.cdecl, + importc: "psmBindStateChangeEvent".} +## / Wait on the Event setup by \ref psmBindStateChangeEvent. + +proc psmWaitStateChangeEvent*(s: ptr PsmSession; timeout: U64): Result {.cdecl, + importc: "psmWaitStateChangeEvent".} +## / Cleanup version of \ref psmBindStateChangeEvent. Must be called by the user once the PsmSession is done being used. + +proc psmUnbindStateChangeEvent*(s: ptr PsmSession): Result {.cdecl, + importc: "psmUnbindStateChangeEvent".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/ro.h b/src/libnx/wrapper/switch/services/ro.h new file mode 100644 index 0000000..231c95a --- /dev/null +++ b/src/libnx/wrapper/switch/services/ro.h @@ -0,0 +1,51 @@ +/** + * @file ro.h + * @brief Relocatable Objects (ro) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/ldr.h" + +/// Initialize ldr:ro. +Result ldrRoInitialize(void); + +/// Exit ldr:ro. +void ldrRoExit(void); + +/// Gets the Service object for the actual ldr:ro service session. +Service* ldrRoGetServiceSession(void); + +/// Initialize ro:1. Only available with [7.0.0+]. +Result ro1Initialize(void); + +/// Exit ro:1. +void ro1Exit(void); + +/// Gets the Service object for the actual ro:1 service session. +Service* ro1GetServiceSession(void); + +/// Initialize ro:dmnt. Only available with [3.0.0+]. +Result roDmntInitialize(void); + +/// Exit ro:dmnt. +void roDmntExit(void); + +/// Gets the Service object for the actual ro:dmnt service session. +Service* roDmntGetServiceSession(void); + +Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); +Result ldrRoUnloadNro(u64 nro_address); +Result ldrRoLoadNrr(u64 nrr_address, u64 nrr_size); +Result ldrRoUnloadNrr(u64 nrr_address); +Result ldrRoLoadNrrEx(u64 nrr_address, u64 nrr_size); + +Result ro1LoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); +Result ro1UnloadNro(u64 nro_address); +Result ro1LoadNrr(u64 nrr_address, u64 nrr_size); +Result ro1UnloadNrr(u64 nrr_address); +Result ro1LoadNrrEx(u64 nrr_address, u64 nrr_size); + +Result roDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, s32 *num_out); diff --git a/src/libnx/wrapper/switch/services/ro.nim b/src/libnx/wrapper/switch/services/ro.nim new file mode 100644 index 0000000..e05b0d0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ro.nim @@ -0,0 +1,57 @@ +## * +## @file ro.h +## @brief Relocatable Objects (ro) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/ldr + +## / Initialize ldr:ro. + +proc ldrRoInitialize*(): Result {.cdecl, importc: "ldrRoInitialize".} +## / Exit ldr:ro. + +proc ldrRoExit*() {.cdecl, importc: "ldrRoExit".} +## / Gets the Service object for the actual ldr:ro service session. + +proc ldrRoGetServiceSession*(): ptr Service {.cdecl, + importc: "ldrRoGetServiceSession".} +## / Initialize ro:1. Only available with [7.0.0+]. + +proc ro1Initialize*(): Result {.cdecl, importc: "ro1Initialize".} +## / Exit ro:1. + +proc ro1Exit*() {.cdecl, importc: "ro1Exit".} +## / Gets the Service object for the actual ro:1 service session. + +proc ro1GetServiceSession*(): ptr Service {.cdecl, importc: "ro1GetServiceSession".} +## / Initialize ro:dmnt. Only available with [3.0.0+]. + +proc roDmntInitialize*(): Result {.cdecl, importc: "roDmntInitialize".} +## / Exit ro:dmnt. + +proc roDmntExit*() {.cdecl, importc: "roDmntExit".} +## / Gets the Service object for the actual ro:dmnt service session. + +proc roDmntGetServiceSession*(): ptr Service {.cdecl, + importc: "roDmntGetServiceSession".} +proc ldrRoLoadNro*(outAddress: ptr U64; nroAddress: U64; nroSize: U64; bssAddress: U64; + bssSize: U64): Result {.cdecl, importc: "ldrRoLoadNro".} +proc ldrRoUnloadNro*(nroAddress: U64): Result {.cdecl, importc: "ldrRoUnloadNro".} +proc ldrRoLoadNrr*(nrrAddress: U64; nrrSize: U64): Result {.cdecl, + importc: "ldrRoLoadNrr".} +proc ldrRoUnloadNrr*(nrrAddress: U64): Result {.cdecl, importc: "ldrRoUnloadNrr".} +proc ldrRoLoadNrrEx*(nrrAddress: U64; nrrSize: U64): Result {.cdecl, + importc: "ldrRoLoadNrrEx".} +proc ro1LoadNro*(outAddress: ptr U64; nroAddress: U64; nroSize: U64; bssAddress: U64; + bssSize: U64): Result {.cdecl, importc: "ro1LoadNro".} +proc ro1UnloadNro*(nroAddress: U64): Result {.cdecl, importc: "ro1UnloadNro".} +proc ro1LoadNrr*(nrrAddress: U64; nrrSize: U64): Result {.cdecl, importc: "ro1LoadNrr".} +proc ro1UnloadNrr*(nrrAddress: U64): Result {.cdecl, importc: "ro1UnloadNrr".} +proc ro1LoadNrrEx*(nrrAddress: U64; nrrSize: U64): Result {.cdecl, + importc: "ro1LoadNrrEx".} +proc roDmntGetProcessModuleInfo*(pid: U64; outModuleInfos: ptr LoaderModuleInfo; + maxOutModules: csize_t; numOut: ptr S32): Result {. + cdecl, importc: "roDmntGetProcessModuleInfo".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/set.h b/src/libnx/wrapper/switch/services/set.h new file mode 100644 index 0000000..031faba --- /dev/null +++ b/src/libnx/wrapper/switch/services/set.h @@ -0,0 +1,2611 @@ +/** + * @file set.h + * @brief Settings services IPC wrapper. + * @author plutoo + * @author yellows8 + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../services/time.h" +#include "../services/acc.h" +#include "../services/fs.h" +#include "../services/btdrv_types.h" +#include "../services/btm_types.h" +#include "../sf/service.h" + +#define SET_MAX_NAME_SIZE 0x48 + +typedef enum { + ColorSetId_Light = 0, + ColorSetId_Dark = 1, +} ColorSetId; + +/// Console Product Models +typedef enum { + SetSysProductModel_Invalid = 0, ///< Invalid Model + SetSysProductModel_Nx = 1, ///< Erista Model + SetSysProductModel_Copper = 2, ///< Erista "Simulation" Model + SetSysProductModel_Iowa = 3, ///< Mariko Model + SetSysProductModel_Hoag = 4, ///< Mariko Lite Model + SetSysProductModel_Calcio = 5, ///< Mariko "Simulation" Model + SetSysProductModel_Aula = 6, ///< Mariko Pro Model(?) +} SetSysProductModel; + +/// IDs for Language. +typedef enum +{ + SetLanguage_JA = 0, ///< Japanese + SetLanguage_ENUS = 1, ///< US English ("AmericanEnglish") + SetLanguage_FR = 2, ///< French + SetLanguage_DE = 3, ///< German + SetLanguage_IT = 4, ///< Italian + SetLanguage_ES = 5, ///< Spanish + SetLanguage_ZHCN = 6, ///< Simplified Chinese ("Chinese") + SetLanguage_KO = 7, ///< Korean + SetLanguage_NL = 8, ///< Dutch + SetLanguage_PT = 9, ///< Portuguese + SetLanguage_RU = 10, ///< Russian + SetLanguage_ZHTW = 11, ///< Traditional Chinese ("Taiwanese") + SetLanguage_ENGB = 12, ///< GB English ("BritishEnglish") + SetLanguage_FRCA = 13, ///< CA French ("CanadianFrench") + SetLanguage_ES419 = 14, ///< "LatinAmericanSpanish" + SetLanguage_ZHHANS = 15, ///< [4.0.0+] ChineseSimplified + SetLanguage_ZHHANT = 16, ///< [4.0.0+] ChineseTraditional + SetLanguage_PTBR = 17, ///< [10.1.0+] "BrazilianPortuguese" + SetLanguage_Total, ///< Total languages supported by this enum. +} SetLanguage; + +/// Region codes. +typedef enum { + SetRegion_JPN = 0, ///< Japan + SetRegion_USA = 1, ///< The Americas + SetRegion_EUR = 2, ///< Europe + SetRegion_AUS = 3, ///< Australia/New Zealand + SetRegion_HTK = 4, ///< Hong Kong/Taiwan/Korea + SetRegion_CHN = 5, ///< China +} SetRegion; + +/// ConnectionFlag +typedef enum { + SetSysConnectionFlag_ConnectAutomaticallyFlag = BIT(0), + SetSysConnectionFlag_Unknown = BIT(1), +} SetSysConnectionFlag; + +/// AccessPointSecurityType +typedef enum { + SetSysAccessPointSecurityType_None = 0, + SetSysAccessPointSecurityType_Shared = 1, + SetSysAccessPointSecurityType_Wpa = 2, + SetSysAccessPointSecurityType_Wpa2 = 3, +} SetSysAccessPointSecurityType; + +/// AccessPointSecurityStandard +typedef enum { + SetSysAccessPointSecurityStandard_None = 0, + SetSysAccessPointSecurityStandard_Wep = 1, + SetSysAccessPointSecurityStandard_Wpa = 2, +} SetSysAccessPointSecurityStandard; + +/// AutoSettings +typedef enum { + SetSysAutoSettings_AutoIp = BIT(0), + SetSysAutoSettings_AutoDns = BIT(1), +} SetSysAutoSettings; + +/// ProxyFlags +typedef enum { + SetSysProxyFlags_UseProxyFlag = BIT(0), + SetSysProxyFlags_ProxyAutoAuthenticateFlag = BIT(1), +} SetSysProxyFlags; + +/// UserSelectorFlag +typedef enum { + SetSysUserSelectorFlag_SkipsIfSingleUser = BIT(0), +} SetSysUserSelectorFlag; + +/// EulaVersionClockType +typedef enum { + SetSysEulaVersionClockType_NetworkSystemClock = 0, + SetSysEulaVersionClockType_SteadyClock = 1, +} SetSysEulaVersionClockType; + +/// NotificationVolume +typedef enum { + SetSysNotificationVolume_Mute = 0, + SetSysNotificationVolume_Low = 1, + SetSysNotificationVolume_High = 2, +} SetSysNotificationVolume; + +/// FriendPresenceOverlayPermission +typedef enum { + SetSysFriendPresenceOverlayPermission_NotConfirmed = 0, + SetSysFriendPresenceOverlayPermission_NoDisplay = 1, + SetSysFriendPresenceOverlayPermission_FavoriteFriends = 2, + SetSysFriendPresenceOverlayPermission_Friends = 3, +} SetSysFriendPresenceOverlayPermission; + +/// AudioDevice +typedef enum { + SetSysAudioDevice_Console = 0, + SetSysAudioDevice_Headphone = 1, + SetSysAudioDevice_Tv = 2, +} SetSysAudioDevice; + +/// PrimaryAlbumStorage +typedef enum { + SetSysPrimaryAlbumStorage_Nand = 0, + SetSysPrimaryAlbumStorage_SdCard = 1, +} SetSysPrimaryAlbumStorage; + +/// HandheldSleepPlan +typedef enum { + SetSysHandheldSleepPlan_1Min = 0, + SetSysHandheldSleepPlan_3Min = 1, + SetSysHandheldSleepPlan_5Min = 2, + SetSysHandheldSleepPlan_10Min = 3, + SetSysHandheldSleepPlan_30Min = 4, + SetSysHandheldSleepPlan_Never = 5, +} SetSysHandheldSleepPlan; + +/// ConsoleSleepPlan +typedef enum { + SetSysConsoleSleepPlan_1Hour = 0, + SetSysConsoleSleepPlan_2Hour = 1, + SetSysConsoleSleepPlan_3Hour = 2, + SetSysConsoleSleepPlan_6Hour = 3, + SetSysConsoleSleepPlan_12Hour = 4, + SetSysConsoleSleepPlan_Never = 5, +} SetSysConsoleSleepPlan; + +/// AudioOutputModeTarget +typedef enum { + SetSysAudioOutputModeTarget_Unknown0 = 0, + SetSysAudioOutputModeTarget_Unknown1 = 1, + SetSysAudioOutputModeTarget_Unknown2 = 2, + SetSysAudioOutputModeTarget_Unknown3 = 3, +} SetSysAudioOutputModeTarget; + +/// AudioOutputMode +typedef enum { + SetSysAudioOutputMode_Unknown1 = 1 ///< Default value. +} SetSysAudioOutputMode; + +/// ServiceDiscoveryControlSettings +typedef enum { + SetSysServiceDiscoveryControlSettings_IsChangeEnvironmentIdentifierDisabled = BIT(0), +} SetSysServiceDiscoveryControlSettings; + +/// ErrorReportSharePermission +typedef enum { + SetSysErrorReportSharePermission_NotConfirmed = 0, + SetSysErrorReportSharePermission_Granted = 1, + SetSysErrorReportSharePermission_Denied = 2, +} SetSysErrorReportSharePermission; + +/// KeyboardLayout +typedef enum { + SetKeyboardLayout_Japanese = 0, + SetKeyboardLayout_EnglishUs = 1, + SetKeyboardLayout_EnglishUsInternational = 2, + SetKeyboardLayout_EnglishUk = 3, + SetKeyboardLayout_French = 4, + SetKeyboardLayout_FrenchCa = 5, + SetKeyboardLayout_Spanish = 6, + SetKeyboardLayout_SpanishLatin = 7, + SetKeyboardLayout_German = 8, + SetKeyboardLayout_Italian = 9, + SetKeyboardLayout_Portuguese = 10, + SetKeyboardLayout_Russian = 11, + SetKeyboardLayout_Korean = 12, + SetKeyboardLayout_ChineseSimplified = 13, + SetKeyboardLayout_ChineseTraditional = 14, +} SetKeyboardLayout; + +/// ChineseTraditionalInputMethod +typedef enum { + SetChineseTraditionalInputMethod_Unknown1 = 1, + SetChineseTraditionalInputMethod_Unknown2 = 2, +} SetChineseTraditionalInputMethod; + +/// PtmCycleCountReliability +typedef enum { + PtmCycleCountReliability_Default = 0, + PtmCycleCountReliability_Unk = 1, +} SetSysPtmCycleCountReliability; + +/// PlatformRegion. Other values not listed here should be handled as "Unknown". +typedef enum { + SetSysPlatformRegion_Global = 1, + SetSysPlatformRegion_China = 2, +} SetSysPlatformRegion; + +/// TouchScreenMode, for "Touch-Screen Sensitivity". +typedef enum { + SetSysTouchScreenMode_Stylus = 0, ///< Stylus. + SetSysTouchScreenMode_Standard = 1, ///< Standard, the default. +} SetSysTouchScreenMode; + +/// BlockType +typedef enum { + SetSysBlockType_Audio = 1, + SetSysBlockType_Video = 2, + SetSysBlockType_VendorSpecific = 3, + SetSysBlockType_Speaker = 4, +} SetSysBlockType; + +/// ControllerType +typedef enum { + SetSysControllerType_JoyConR = 1, + SetSysControllerType_JoyConL = 2, + SetSysControllerType_ProCon = 3, +} SetSysControllerType; + +/// BatteryLot +typedef struct { + char lot[0x18]; ///< BatteryLot string. +} SetBatteryLot; + +/// NetworkSettings +typedef struct { + char name[0x40]; + Uuid uuid; + u32 connection_flags; ///< Bitmask with \ref SetSysConnectionFlag. + u32 wired_flag; + u32 connect_to_hidden_network; ///< Bitmask with UseStealthNetworkFlag. + char access_point_ssid[0x20]; + u32 access_point_ssid_len; + u32 access_point_security_type; ///< Bitmask with \ref SetSysAccessPointSecurityType. + u32 access_point_security_standard; ///< Bitmask with \ref SetSysAccessPointSecurityStandard. + char access_point_passphrase[0x40]; + u32 access_point_passphrase_len; + u32 auto_settings; ///< Bitmask with \ref SetSysAutoSettings. + u32 manual_ip_address; + u32 manual_subnet_mask; + u32 manual_gateway; + u32 primary_dns; + u32 secondary_dns; + u32 proxy_flags; ///< Bitmask with \ref SetSysProxyFlags. + char proxy_server[0x80]; + u16 proxy_port; + u16 padding1; + char proxy_autoauth_user[0x20]; + char proxy_autoauth_pass[0x20]; + u16 mtu; + u16 padding2; +} SetSysNetworkSettings; + +/// LcdBacklightBrightnessMapping +typedef struct { + float brightness_applied_to_backlight; + float ambient_light_sensor_value; + float unk_x8; +} SetSysLcdBacklightBrightnessMapping; + +/// BacklightSettings +typedef struct { + u32 auto_brightness_flags; + float screen_brightness; + SetSysLcdBacklightBrightnessMapping brightness_mapping; + float unk_x14; + float unk_x18; + float unk_x1C; + float unk_x20; + float unk_x24; +} SetSysBacklightSettings; + +/// BacklightSettingsEx +typedef struct { + u32 auto_brightness_flags; + float screen_brightness; + float current_brightness_for_vr_mode; + SetSysLcdBacklightBrightnessMapping brightness_mapping; + float unk_x18; + float unk_x1C; + float unk_x20; + float unk_x24; + float unk_x28; +} SetSysBacklightSettingsEx; + +/// BluetoothDevicesSettings +typedef struct { + BtdrvAddress addr; ///< \ref BtdrvAddress + BtmBdName name; ///< BdName. Unused on 13.0.0+ + BtmClassOfDevice class_of_device; ///< ClassOfDevice + u8 link_key[0x10]; ///< LinkKey + u8 link_key_present; ///< LinkKeyPresent + u16 version; ///< Version + u32 trusted_services; ///< TrustedServices + u16 vid; ///< Vid + u16 pid; ///< Pid + u8 sub_class; ///< SubClass + u8 attribute_mask; ///< AttributeMask + u16 descriptor_length; ///< DescriptorLength + u8 descriptor[0x80]; ///< Descriptor + u8 key_type; ///< KeyType + 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+] + }; +} SetSysBluetoothDevicesSettings; + +/// Structure returned by \ref setsysGetFirmwareVersion. +typedef struct { + u8 major; + u8 minor; + u8 micro; + u8 padding1; + u8 revision_major; + u8 revision_minor; + u8 padding2; + u8 padding3; + char platform[0x20]; + char version_hash[0x40]; + char display_version[0x18]; + char display_title[0x80]; +} SetSysFirmwareVersion; + +/// Structure returned by \ref setsysGetFirmwareVersionDigest. +typedef struct { + char digest[0x40]; +} SetSysFirmwareVersionDigest; + +/// Structure returned by \ref setsysGetSerialNumber. +typedef struct { + char number[0x18]; +} SetSysSerialNumber; + +/// DeviceNickName +typedef struct { + char nickname[0x80]; +} SetSysDeviceNickName; + +/// UserSelectorSettings +typedef struct { + u32 flags; ///< Bitmask with \ref SetSysUserSelectorFlag. +} SetSysUserSelectorSettings; + +/// AccountSettings +typedef struct { + SetSysUserSelectorSettings settings; +} SetSysAccountSettings; + +typedef struct { + u32 unk_x0; ///< 0 for Console and Tv, 2 for Headphones. + u8 volume; ///< From 0-15. +} SetSysAudioVolume; + +/// EulaVersion +typedef struct { + u32 version; + s32 region_code; + s32 clock_type; ///< \ref SetSysEulaVersionClockType + u32 pad; + u64 network_clock_time; ///< POSIX timestamp. + TimeSteadyClockTimePoint steady_clock_time; ///< \ref TimeSteadyClockTimePoint +} SetSysEulaVersion; + +/// NotificationTime +typedef struct { + s32 hour; + s32 minute; +} SetSysNotificationTime; + +/// NotificationSettings +typedef struct { + u32 flags; ///< Bitmask with NotificationFlag. + s32 volume; ///< \ref SetSysNotificationVolume + SetSysNotificationTime start_time; ///< \ref SetSysNotificationTime + SetSysNotificationTime end_time; ///< \ref SetSysNotificationTime +} SetSysNotificationSettings; + +/// AccountNotificationSettings +typedef struct { + AccountUid uid; ///< \ref AccountUid + u32 flags; ///< Bitmask with AccountNotificationFlag. + s8 friend_presence_overlay_permission; ///< \ref SetSysFriendPresenceOverlayPermission + u8 pad[3]; ///< Padding. +} SetSysAccountNotificationSettings; + +/// TvSettings +typedef struct { + u32 flags; ///< Bitmask with TvFlag. + s32 tv_resolution; ///< \ref SetSysTvResolution + s32 hdmi_content_type; ///< \ref SetSysHdmiContentType + s32 rgb_range; ///< \ref SetSysRgbRange + s32 cmu_mode; ///< \ref SetSysCmuMode + u32 underscan; ///< Underscan. + float gamma; ///< Gamma. + float contrast; ///< Contrast. +} SetSysTvSettings; + +typedef struct { + u16 pixel_clock; ///< In 10 kHz units. + u8 horizontal_active_pixels_lsb; + u8 horizontal_blanking_pixels_lsb; + u8 horizontal_blanking_pixels_msb : 4; + u8 horizontal_active_pixels_msb : 4; + u8 vertical_active_lines_lsb; + u8 vertical_blanking_lines_lsb; + u8 vertical_blanking_lines_msb : 4; + 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_msb : 2; + u8 vertical_sync_offset_lines_msb : 2; + u8 horizontal_sync_pulse_width_pixels_msb : 2; + u8 horizontal_sync_offset_pixels_msb : 2; + u8 horizontal_image_size_mm_lsb; + u8 vertical_image_size_mm_lsb; + u8 vertical_image_size_mm_msb : 4; + u8 horizontal_image_size_mm_msb : 4; + u8 horizontal_border_pixels; + u8 vertical_border_lines; + u8 features_bitmap_0 : 1; + u8 features_bitmap_1 : 1; + u8 features_bitmap_2 : 1; + u8 features_bitmap_34 : 2; + u8 features_bitmap_56 : 2; + u8 interlaced : 1; +} SetSysModeLine; + +typedef struct { + struct { + u8 size : 5; + SetSysBlockType block_type : 3; + struct { + u8 svd_index : 7; + u8 native_flag : 1; + } svd[0xC]; + } PACKED video; + struct { + u8 size : 5; + SetSysBlockType block_type : 3; + u8 channel_count : 3; + u8 format_code : 4; + u8 padding1 : 1; + u8 sampling_rates_bitmap; + u8 bitrate; + } PACKED audio; + struct { + u8 size : 5; + SetSysBlockType block_type : 3; + u8 ieee_registration_id[3]; + u16 source_physical_address; + u8 mode_bitmap; + u8 max_tmds_frequency; + u8 latency_bitmap; + } PACKED vendor_specific; + u8 padding[2]; +} SetSysDataBlock; + +/// Edid +typedef struct { + u8 pattern[8]; ///< Fixed pattern 00 FF FF FF FF FF FF 00. + u16 pnp_id; ///< Big-endian set of 3 5-bit values representing letters, 1 = A .. 26 = Z. + u16 product_code; + u32 serial_number; + u8 manufacture_week; + u8 manufacture_year; + u8 edid_version; + u8 edid_revision; + u8 video_input_parameters_bitmap; + u8 display_width; + u8 display_height; + u8 display_gamma; + u8 supported_features_bitmap; + struct { + u8 green_y_lsb : 2; + u8 green_x_lsb : 2; + u8 red_y_lsb : 2; + u8 red_x_lsb : 2; + u8 blue_lsb : 4; + u8 white_lsb : 4; + u8 red_x_msb; + u8 red_y_msb; + u8 green_x_msb; + u8 green_y_msb; + u8 blue_x_msb; + u8 blue_y_msb; + u8 white_x_msb; + u8 white_y_msb; + } chromaticity; + u8 timing_bitmap[3]; + struct { + u8 x_resolution; ///< Real value is (val + 31) * 8 pixels. + u8 vertical_frequency : 6; ///< Real value is val + 60 Hz. + u8 aspect_ratio : 2; ///< 0 = 16:10, 1 = 4:3, 2 = 5:4, 3 = 16:9. + } timing_info[8]; + SetSysModeLine timing_descriptor[2]; + struct { + u16 display_descriptor_zero; + u8 padding1; + u8 descriptor_type; + u8 padding2; + char name[0xD]; + } display_descriptor_name; + struct { + u16 display_descriptor_zero; + u8 padding1; + u8 descriptor_type; + u8 range_limit_offsets; + u8 vertical_field_rate_min; + u8 vertical_field_rate_max; + u8 horizontal_line_rate_min; + u8 horizontal_line_rate_max; + u8 pixel_clock_rate_max; ///< Rounded up to multiples of 10 MHz. + u8 extended_timing_info; + u8 padding[7]; + } display_descriptor_range_limits; + u8 extension_count; ///< Always 1. + u8 checksum; ///< Sum of all 128 bytes should equal 0 mod 256. + ///< Extended data. + u8 extension_tag; ///< Always 2 = CEA EDID timing extension. + u8 revision; + u8 dtd_start; + u8 native_dtd_count : 4; + u8 native_dtd_feature_bitmap : 4; + SetSysDataBlock data_block; + SetSysModeLine extended_timing_descriptor[5]; + u8 padding[5]; + u8 extended_checksum; ///< Sum of 128 extended bytes should equal 0 mod 256. +} SetSysEdid; + +/// DataDeletionSettings +typedef struct { + u32 flags; ///< Bitmask with DataDeletionFlag. + s32 use_count; ///< Use count. +} SetSysDataDeletionSettings; + +/// SleepSettings +typedef struct { + u32 flags; ///< Bitmask with SleepFlag. + s32 handheld_sleep_plan; ///< \ref SetSysHandheldSleepPlan + s32 console_sleep_plan; ///< \ref SetSysConsoleSleepPlan +} SetSysSleepSettings; + +/// InitialLaunchSettings +typedef struct { + u32 flags; ///< Bitmask with InitialLaunchFlag. + u32 pad; ///< Padding. + TimeSteadyClockTimePoint timestamp; ///< \ref TimeSteadyClockTimePoint timestamp. +} SetSysInitialLaunchSettings; + +/// PtmFuelGaugeParameter +typedef struct { + u16 rcomp0; + u16 tempc0; + u16 fullcap; + u16 fullcapnom; + u16 lavgempty; + u16 qresidual00; + u16 qresidual10; + u16 qresidual20; + u16 qresidual30; + u16 cycles; ///< Normally keeps the cycles reg. Unused and contains stack garbage. + u32 cycles_actual; ///< Keeps track of cycles. The fuel gauge cycles reg is reset if > 2.00 cycles and added here. +} SetSysPtmFuelGaugeParameter; + +/// Actually nn::util::Color4u8Type. +typedef struct { + u8 field[4]; +} SetSysColor4u8Type; + +/// NxControllerLegacySettings +typedef struct { + BtdrvAddress address; + u8 type; ///< \ref SetSysControllerType. + char serial[0x10]; + SetSysColor4u8Type body_color; + SetSysColor4u8Type button_color; + u8 unk_x1F[8]; + u8 unk_x27; + u8 interface_type; ///< Bitmask with \ref XcdInterfaceType. +} SetSysNxControllerLegacySettings; + +/// NxControllerSettings +typedef struct { + BtdrvAddress address; + u8 type; ///< \ref SetSysControllerType. + char serial[0x10]; + SetSysColor4u8Type body_color; + SetSysColor4u8Type button_color; + u8 unk_x1F[8]; + u8 unk_x27; + u8 interface_type; ///< Bitmask with \ref XcdInterfaceType. + u8 unk_x29[0x403]; ///< Unknown +} SetSysNxControllerSettings; + +/// ConsoleSixAxisSensorAccelerationBias +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; +} SetSysConsoleSixAxisSensorAccelerationBias; + +/// ConsoleSixAxisSensorAngularVelocityBias +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; +} SetSysConsoleSixAxisSensorAngularVelocityBias; + +/// ConsoleSixAxisSensorAccelerationGain +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; + float unk_xC; + float unk_x10; + float unk_x14; + float unk_x18; + float unk_x1C; + float unk_x20; +} SetSysConsoleSixAxisSensorAccelerationGain; + +/// ConsoleSixAxisSensorAngularVelocityGain +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; + float unk_xC; + float unk_x10; + float unk_x14; + float unk_x18; + float unk_x1C; + float unk_x20; +} SetSysConsoleSixAxisSensorAngularVelocityGain; + +/// AllowedSslHosts +typedef struct { + u8 hosts[0x100]; +} SetSysAllowedSslHosts; + +/// HostFsMountPoint +typedef struct { + char mount[0x100]; +} SetSysHostFsMountPoint; + +/// BlePairingSettings +typedef struct { + BtdrvAddress address; + u16 unk_x6; + u16 unk_x8; + u8 unk_xA; + u8 unk_xB; + u8 unk_xC; + u8 unk_xD; + u8 unk_xE; + u8 unk_xF; + u8 padding[0x70]; +} SetSysBlePairingSettings; + +/// ConsoleSixAxisSensorAngularVelocityTimeBias +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; +} SetSysConsoleSixAxisSensorAngularVelocityTimeBias; + +/// ConsoleSixAxisSensorAngularAcceleration +typedef struct { + float unk_x0; + float unk_x4; + float unk_x8; + float unk_xC; + float unk_x10; + float unk_x14; + float unk_x18; + float unk_x1C; + float unk_x20; +} SetSysConsoleSixAxisSensorAngularAcceleration; + +/// RebootlessSystemUpdateVersion. This is the content of the RebootlessSystemUpdateVersion SystemData, in the "/version" file. +typedef struct { + u32 version; + u8 reserved[0x1c]; + char display_version[0x20]; +} SetSysRebootlessSystemUpdateVersion; + +/// AccountOnlineStorageSettings +typedef struct { + AccountUid uid; ///< \ref AccountUid + u32 unk_x10; + u32 unk_x14; +} SetSysAccountOnlineStorageSettings; + +/// AnalogStickUserCalibration +typedef struct { + u16 unk_x0; + u16 unk_x2; + u16 unk_x4; + u16 unk_x6; + u16 unk_x8; + u16 unk_xA; + u16 unk_xC; + u16 unk_xE; +} SetSysAnalogStickUserCalibration; + +/// ThemeId +typedef struct { + u64 theme_id[0x10]; +} SetSysThemeId; + +/// ThemeSettings +typedef struct { + u64 theme_settings; +} SetSysThemeSettings; + +/// Output from \ref setsysGetHomeMenuScheme. This contains RGBA8 colors which correspond with the physical shell of the system. +typedef struct { + u32 main_color; ///< Main Color. + u32 back_color; ///< Back Color. + u32 sub_color; ///< Sub Color. + u32 bezel_color; ///< Bezel Color. + u32 extra_color; ///< Extra Color. +} SetSysHomeMenuScheme; + +/// ButtonConfigSettings +typedef struct { + u8 settings[0x5A8]; +} SetSysButtonConfigSettings; + +/// ButtonConfigRegisteredSettings +typedef struct { + u8 settings[0x5C8]; +} SetSysButtonConfigRegisteredSettings; + +typedef struct { + u8 offset[0x6]; +} SetCalAccelerometerOffset; + +typedef struct { + u8 scale[0x6]; +} SetCalAccelerometerScale; + +typedef struct { + u32 size; + u8 cert[0x70]; +} SetCalAmiiboEcdsaCertificate; + +typedef struct { + u32 size; + u8 cert[0x20]; +} SetCalAmiiboEcqvBlsCertificate; + +typedef struct { + u32 size; + u8 key[0x40]; + u32 generation; +} SetCalAmiiboEcqvBlsKey; + +typedef struct { + u32 size; + u8 cert[0x90]; +} SetCalAmiiboEcqvBlsRootCertificate; + +typedef struct { + u32 size; + u8 cert[0x14]; +} SetCalAmiiboEcqvCertificate; + +typedef struct { + u32 size; + u8 key[0x50]; + u32 generation; +} SetCalAmiiboKey; + +typedef struct { + u8 calibration[0x9]; +} SetCalAnalogStickFactoryCalibration; + +typedef struct { + u8 parameter[0x12]; +} SetCalAnalogStickModelParameter; + +typedef struct { + u8 bd_addr[0x6]; +} SetCalBdAddress; + +typedef struct { + u8 cfg[0x1E]; +} SetCalConfigurationId1; + +typedef struct { + u8 offset[0x6]; +} SetCalConsoleSixAxisSensorHorizontalOffset; + +typedef struct { + char code[0x3]; ///< Country code. +} SetCalCountryCode; + +typedef struct { + u8 cert[0x180]; +} SetCalEccB233DeviceCertificate; + +typedef struct { + u32 size; + u8 key[0x50]; + u32 generation; +} SetCalEccB233DeviceKey; + +typedef struct { + u8 cert[0x400]; +} SetCalGameCardCertificate; + +typedef struct { + u32 size; ///< Size of the entire key. + u8 key[0x130]; + u32 generation; +} SetCalGameCardKey; + +typedef struct { + u8 offset[0x6]; +} SetCalGyroscopeOffset; + +typedef struct { + u8 scale[0x6]; +} SetCalGyroscopeScale; + +typedef struct { + u8 addr[0x6]; ///< Mac address. +} SetCalMacAddress; + +typedef struct { + u8 cert[0x240]; +} SetCalRsa2048DeviceCertificate; + +typedef struct { + u32 size; ///< Size of the entire key. + u8 key[0x240]; + u32 generation; +} SetCalRsa2048DeviceKey; + +typedef SetSysSerialNumber SetCalSerialNumber; + +typedef struct { + u8 parameter[0x5A]; +} SetCalSpeakerParameter; + +typedef struct { + u32 size; ///< Size of the certificate data. + u8 cert[0x800]; +} SetCalSslCertificate; + +typedef struct { + u32 size; ///< Size of the entire key. + u8 key[0x130]; + u32 generation; +} SetCalSslKey; + +typedef struct { + u32 code; ///< Region code. +} SetCalRegionCode; + +/// Initialize set. +Result setInitialize(void); + +/// Exit set. +void setExit(void); + +/// Gets the Service object for the actual set service session. +Service* setGetServiceSession(void); + +/// Converts LanguageCode to \ref SetLanguage. +Result setMakeLanguage(u64 LanguageCode, SetLanguage *Language); + +/// Converts \ref SetLanguage to LanguageCode. +Result setMakeLanguageCode(SetLanguage Language, u64 *LanguageCode); + +/// Gets the current system LanguageCode. +/// Normally this should be used instead of \ref setGetLanguageCode. +/// LanguageCode is a string, see here: https://switchbrew.org/wiki/Settings_services#LanguageCode +Result setGetSystemLanguage(u64 *LanguageCode); + +/// Gets the current LanguageCode, \ref setGetSystemLanguage should be used instead normally. +Result setGetLanguageCode(u64 *LanguageCode); + +/// Gets available LanguageCodes. +/// On system-version <4.0.0, max_entries is set to the output from \ref setGetAvailableLanguageCodeCount if max_entries is larger than that. +Result setGetAvailableLanguageCodes(s32 *total_entries, u64 *LanguageCodes, size_t max_entries); + +/// Gets total available LanguageCodes. +/// Output total is overridden with value 0 if the total is <0. +Result setGetAvailableLanguageCodeCount(s32 *total); + +/// Gets the RegionCode. +Result setGetRegionCode(SetRegion *out); + +/** + * @brief GetQuestFlag + * @note Only available on [5.0.0+]. + * @param[out] out Output flag. + */ +Result setGetQuestFlag(bool *out); + +/** + * @brief Gets the system's nickname. + * @note Only available on [10.1.0+]. + * @param[out] nickname \ref SetSysDeviceNickName + */ +Result setGetDeviceNickname(SetSysDeviceNickName *nickname); + +/// Initialize setsys. +Result setsysInitialize(void); + +/// Exit setsys. +void setsysExit(void); + +/// Gets the Service object for the actual setsys service session. +Service* setsysGetServiceSession(void); + +/** + * @brief SetLanguageCode + * @param[in] LanguageCode LanguageCode. + */ +Result setsysSetLanguageCode(u64 LanguageCode); + +/** + * @brief SetNetworkSettings + * @param[in] settings Input array of \ref SetSysNetworkSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetNetworkSettings(const SetSysNetworkSettings *settings, s32 count); + +/** + * @brief GetNetworkSettings + * @param[out] total_out Total output entries. + * @param[out] versions Output array of \ref SetSysNetworkSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetNetworkSettings(s32 *total_out, SetSysNetworkSettings *settings, s32 count); + +/** + * @brief Gets the system firmware version. + * @param[out] out Firmware version to populate. + */ +Result setsysGetFirmwareVersion(SetSysFirmwareVersion *out); + +/** + * @brief GetFirmwareVersionDigest + * @param[out] out \ref SetSysFirmwareVersionDigest + */ +Result setsysGetFirmwareVersionDigest(SetSysFirmwareVersionDigest *out); + +/** + * @brief GetLockScreenFlag + * @param[out] out Output flag. + */ +Result setsysGetLockScreenFlag(bool *out); + +/** + * @brief SetLockScreenFlag + * @param[in] flag Input flag. + */ +Result setsysSetLockScreenFlag(bool flag); + +/** + * @brief GetBacklightSettings + * @param[out] out \ref SetSysBacklightSettings + */ +Result setsysGetBacklightSettings(SetSysBacklightSettings *out); + +/** + * @brief SetBacklightSettings + * @param[in] settings \ref SetSysBacklightSettings + */ +Result setsysSetBacklightSettings(const SetSysBacklightSettings *settings); + +/** + * @brief SetBluetoothDevicesSettings + * @param[in] settings Input array of \ref SetSysBluetoothDevicesSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetBluetoothDevicesSettings(const SetSysBluetoothDevicesSettings *settings, s32 count); + +/** + * @brief GetBluetoothDevicesSettings + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysBluetoothDevicesSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetBluetoothDevicesSettings(s32 *total_out, SetSysBluetoothDevicesSettings *settings, s32 count); + +/** + * @brief GetExternalSteadyClockSourceId + * @param[out] out \ref Uuid + */ +Result setsysGetExternalSteadyClockSourceId(Uuid *out); + +/** + * @brief SetExternalSteadyClockSourceId + * @param[in] uuid \ref Uuid + */ +Result setsysSetExternalSteadyClockSourceId(const Uuid *uuid); + +/** + * @brief GetUserSystemClockContext + * @param[out] out \ref TimeSystemClockContext + */ +Result setsysGetUserSystemClockContext(TimeSystemClockContext *out); + +/** + * @brief SetUserSystemClockContext + * @param[in] context \ref TimeSystemClockContext + */ +Result setsysSetUserSystemClockContext(const TimeSystemClockContext *context); + +/** + * @brief GetAccountSettings + * @param[out] out \ref SetSysAccountSettings + */ +Result setsysGetAccountSettings(SetSysAccountSettings *out); + +/** + * @brief SetAccountSettings + * @param[in] settings \ref SetSysAccountSettings + */ +Result setsysSetAccountSettings(SetSysAccountSettings settings); + +/** + * @brief GetAudioVolume + * @param[in] device \ref SetSysAudioDevice + * @param[out] out \ref SetSysAudioVolume + */ +Result setsysGetAudioVolume(SetSysAudioDevice device, SetSysAudioVolume *out); + +/** + * @brief SetAudioVolume + * @param[in] device \ref SetSysAudioDevice + * @param[in] volume \ref SetSysAudioVolume + */ +Result setsysSetAudioVolume(SetSysAudioDevice device, const SetSysAudioVolume *volume); + +/** + * @brief GetEulaVersions + * @param[out] total_out Total output entries. + * @param[out] versions Output array of \ref SetSysEulaVersion. + * @param[in] count Size of the versions array in entries. + */ +Result setsysGetEulaVersions(s32 *total_out, SetSysEulaVersion *versions, s32 count); + +/** + * @brief SetEulaVersions + * @param[in] versions Input array of \ref SetSysEulaVersion. + * @param[in] count Size of the versions array in entries. + */ +Result setsysSetEulaVersions(const SetSysEulaVersion *versions, s32 count); + +/// Gets the current system theme. +Result setsysGetColorSetId(ColorSetId *out); + +/// Sets the current system theme. +Result setsysSetColorSetId(ColorSetId id); + +/** + * @brief GetConsoleInformationUploadFlag + * @param[out] out Output flag. + */ +Result setsysGetConsoleInformationUploadFlag(bool *out); + +/** + * @brief SetConsoleInformationUploadFlag + * @param[in] flag Input flag. + */ +Result setsysSetConsoleInformationUploadFlag(bool flag); + +/** + * @brief GetAutomaticApplicationDownloadFlag + * @param[out] out Output flag. + */ +Result setsysGetAutomaticApplicationDownloadFlag(bool *out); + +/** + * @brief SetAutomaticApplicationDownloadFlag + * @param[in] flag Input flag. + */ +Result setsysSetAutomaticApplicationDownloadFlag(bool flag); + +/** + * @brief GetNotificationSettings + * @param[out] out \ref SetSysNotificationSettings + */ +Result setsysGetNotificationSettings(SetSysNotificationSettings *out); + +/** + * @brief SetNotificationSettings + * @param[in] settings \ref SetSysNotificationSettings + */ +Result setsysSetNotificationSettings(const SetSysNotificationSettings *settings); + +/** + * @brief GetAccountNotificationSettings + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysAccountNotificationSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetAccountNotificationSettings(s32 *total_out, SetSysAccountNotificationSettings *settings, s32 count); + +/** + * @brief SetAccountNotificationSettings + * @param[in] settings Input array of \ref SetSysAccountNotificationSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetAccountNotificationSettings(const SetSysAccountNotificationSettings *settings, s32 count); + +/** + * @brief GetVibrationMasterVolume + * @param[out] out Output volume. + */ +Result setsysGetVibrationMasterVolume(float *out); + +/** + * @brief SetVibrationMasterVolume + * @param[in] volume Input volume. + */ +Result setsysSetVibrationMasterVolume(float volume); + +/** + * @brief Gets the size of a settings item value. + * @param name Name string. + * @param item_key Item key string. + * @param size_out Pointer to output the size to. + */ +Result setsysGetSettingsItemValueSize(const char *name, const char *item_key, u64 *size_out); + +/** + * @brief Gets the value of a settings item. + * @param name Name string. + * @param item_key Item key string. + * @param value_out Pointer to output the value to. + * @param value_out_size Size of the value_out buffer. + * @param size_out Total size which was copied to value_out. + */ +Result setsysGetSettingsItemValue(const char *name, const char *item_key, void *value_out, size_t value_out_size, u64 *size_out); + +/** + * @brief GetTvSettings + * @param[out] out \ref SetSysTvSettings + */ +Result setsysGetTvSettings(SetSysTvSettings *out); + +/** + * @brief SetTvSettings + * @param[in] settings \ref SetSysTvSettings + */ +Result setsysSetTvSettings(const SetSysTvSettings *settings); + +/** + * @brief GetEdid + * @param[out] out \ref SetSysEdid + */ +Result setsysGetEdid(SetSysEdid *out); + +/** + * @brief SetEdid + * @param[in] edid \ref SetSysEdid + */ +Result setsysSetEdid(const SetSysEdid *edid); + +/** + * @brief GetAudioOutputMode + * @param[in] target \ref SetSysAudioOutputModeTarget + * @param[out] out \ref SetSysAudioOutputMode + */ +Result setsysGetAudioOutputMode(SetSysAudioOutputModeTarget target, SetSysAudioOutputMode *out); + +/** + * @brief SetAudioOutputMode + * @param[in] target \ref SetSysAudioOutputModeTarget + * @param[in] mode \ref SetSysAudioOutputMode + */ +Result setsysSetAudioOutputMode(SetSysAudioOutputModeTarget target, SetSysAudioOutputMode mode); + +/** + * @brief GetSpeakerAutoMuteFlag + * @param[out] out Output flag. + */ +Result setsysGetSpeakerAutoMuteFlag(bool *out); + +/** + * @brief SetSpeakerAutoMuteFlag + * @param[in] flag Input flag. + */ +Result setsysSetSpeakerAutoMuteFlag(bool flag); + +/** + * @brief GetQuestFlag + * @param[out] out Output flag. + */ +Result setsysGetQuestFlag(bool *out); + +/** + * @brief SetQuestFlag + * @param[in] flag Input flag. + */ +Result setsysSetQuestFlag(bool flag); + +/** + * @brief GetDataDeletionSettings + * @param[out] out \ref SetSysDataDeletionSettings + */ +Result setsysGetDataDeletionSettings(SetSysDataDeletionSettings *out); + +/** + * @brief SetDataDeletionSettings + * @param[in] settings \ref SetSysDataDeletionSettings + */ +Result setsysSetDataDeletionSettings(const SetSysDataDeletionSettings *settings); + +/** + * @brief GetInitialSystemAppletProgramId + * @param[out] out output ProgramId. + */ +Result setsysGetInitialSystemAppletProgramId(u64 *out); + +/** + * @brief GetOverlayDispProgramId + * @param[out] out output ProgramId. + */ +Result setsysGetOverlayDispProgramId(u64 *out); + +/** + * @brief GetDeviceTimeZoneLocationName + * @param[out] out \ref TimeLocationName + */ +Result setsysGetDeviceTimeZoneLocationName(TimeLocationName *out); + +/** + * @brief SetDeviceTimeZoneLocationName + * @param[in] name \ref TimeLocationName + */ +Result setsysSetDeviceTimeZoneLocationName(const TimeLocationName *name); + +/** + * @brief GetWirelessCertificationFileSize + * @param[out] out_size Output size. + */ +Result setsysGetWirelessCertificationFileSize(u64 *out_size); + +/** + * @brief GetWirelessCertificationFile + * @param[out] buffer Output buffer. + * @param[in] size Output buffer size. + * @param[out] out_size Output size. + */ +Result setsysGetWirelessCertificationFile(void* buffer, size_t size, u64 *out_size); + +/** + * @brief SetRegionCode + * @param[in] region \ref SetRegion + */ +Result setsysSetRegionCode(SetRegion region); + +/** + * @brief GetNetworkSystemClockContext + * @param[out] out \ref TimeSystemClockContext + */ +Result setsysGetNetworkSystemClockContext(TimeSystemClockContext *out); + +/** + * @brief SetNetworkSystemClockContext + * @param[in] context \ref TimeSystemClockContext + */ +Result setsysSetNetworkSystemClockContext(const TimeSystemClockContext *context); + +/** + * @brief IsUserSystemClockAutomaticCorrectionEnabled + * @param[out] out Output flag. + */ +Result setsysIsUserSystemClockAutomaticCorrectionEnabled(bool *out); + +/** + * @brief SetUserSystemClockAutomaticCorrectionEnabled + * @param[in] flag Input flag. + */ +Result setsysSetUserSystemClockAutomaticCorrectionEnabled(bool flag); + +/** + * @brief GetDebugModeFlag + * @param[out] out Output flag. + */ +Result setsysGetDebugModeFlag(bool *out); + +/** + * @brief GetPrimaryAlbumStorage + * @param[out] out \ref GetPrimaryAlbumStorage + */ +Result setsysGetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage *out); + +/** + * @brief SetPrimaryAlbumStorage + * @param[in] storage \ref SetSysPrimaryAlbumStorage + */ +Result setsysSetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage storage); + +/** + * @brief GetUsb30EnableFlag + * @param[out] out Output flag. + */ +Result setsysGetUsb30EnableFlag(bool *out); + +/** + * @brief SetUsb30EnableFlag + * @param[in] flag Input flag. + */ +Result setsysSetUsb30EnableFlag(bool flag); + +/** + * @brief Gets the \ref SetBatteryLot. + * @param[out] out \ref SetBatteryLot + */ +Result setsysGetBatteryLot(SetBatteryLot *out); + +/** + * @brief Gets the system's serial number. + * @param[out] out \ref SetSysSerialNumber + */ +Result setsysGetSerialNumber(SetSysSerialNumber *out); + +/** + * @brief GetNfcEnableFlag + * @param[out] out Output flag. + */ +Result setsysGetNfcEnableFlag(bool *out); + +/** + * @brief SetNfcEnableFlag + * @param[in] flag Input flag. + */ +Result setsysSetNfcEnableFlag(bool flag); + +/** + * @brief GetSleepSettings + * @param[out] out \ref SetSysSleepSettings + */ +Result setsysGetSleepSettings(SetSysSleepSettings *out); + +/** + * @brief SetSleepSettings + * @param[in] settings \ref SetSysSleepSettings + */ +Result setsysSetSleepSettings(const SetSysSleepSettings *settings); + +/** + * @brief GetWirelessLanEnableFlag + * @param[out] out Output flag. + */ +Result setsysGetWirelessLanEnableFlag(bool *out); + +/** + * @brief SetWirelessLanEnableFlag + * @param[in] flag Input flag. + */ +Result setsysSetWirelessLanEnableFlag(bool flag); + +/** + * @brief GetInitialLaunchSettings + * @param[out] out \ref SetSysInitialLaunchSettings + */ +Result setsysGetInitialLaunchSettings(SetSysInitialLaunchSettings *out); + +/** + * @brief SetInitialLaunchSettings + * @param[in] settings \ref SetSysInitialLaunchSettings + */ +Result setsysSetInitialLaunchSettings(const SetSysInitialLaunchSettings *settings); + +/** + * @brief Gets the system's nickname. + * @note Same as \ref setGetDeviceNickname, which official sw uses instead on [10.1.0+]. + * @param[out] nickname \ref SetSysDeviceNickName + */ +Result setsysGetDeviceNickname(SetSysDeviceNickName *nickname); + +/** + * @brief Sets the system's nickname. + * @param[in] nickname \ref SetSysDeviceNickName + */ +Result setsysSetDeviceNickname(const SetSysDeviceNickName *nickname); + +/** + * @brief GetProductModel + * @param[out] model Output SetSysProductModel. + */ +Result setsysGetProductModel(SetSysProductModel *model); + +/** + * @brief GetLdnChannel + * @param[out] out Output LdnChannel. + */ +Result setsysGetLdnChannel(s32 *out); + +/** + * @brief SetLdnChannel + * @param[in] channel Input LdnChannel. + */ +Result setsysSetLdnChannel(s32 channel); + +/** + * @brief Gets an event that settings will signal on flag change. + * @param out_event Event to bind. Output event will have autoclear=false. + */ +Result setsysAcquireTelemetryDirtyFlagEventHandle(Event *out_event); + +/** + * @brief Gets the settings flags that have changed. + * @param flags_0 Pointer to populate with first 64 flags. + * @param flags_1 Pointer to populate with second 64 flags. + */ +Result setsysGetTelemetryDirtyFlags(u64 *flags_0, u64 *flags_1); + +/** + * @brief GetPtmBatteryLot + * @param[out] out \ref SetBatteryLot + */ +Result setsysGetPtmBatteryLot(SetBatteryLot *out); + +/** + * @brief SetPtmBatteryLot + * @param[in] lot \ref SetBatteryLot + */ +Result setsysSetPtmBatteryLot(const SetBatteryLot *lot); + +/** + * @brief GetPtmFuelGaugeParameter + * @param[out] out \ref SetSysPtmFuelGaugeParameter + */ +Result setsysGetPtmFuelGaugeParameter(SetSysPtmFuelGaugeParameter *out); + +/** + * @brief SetPtmFuelGaugeParameter + * @param[in] parameter \ref SetSysPtmFuelGaugeParameter + */ +Result setsysSetPtmFuelGaugeParameter(const SetSysPtmFuelGaugeParameter *parameter); + +/** + * @brief GetBluetoothEnableFlag + * @param[out] out Output flag. + */ +Result setsysGetBluetoothEnableFlag(bool *out); + +/** + * @brief SetBluetoothEnableFlag + * @param[in] flag Input flag. + */ +Result setsysSetBluetoothEnableFlag(bool flag); + +/** + * @brief GetMiiAuthorId + * @param[out] out Output MiiAuthorId. + */ +Result setsysGetMiiAuthorId(Uuid *out); + +/** + * @brief SetShutdownRtcValue + * @param[in] value Input value. + */ +Result setsysSetShutdownRtcValue(u64 value); + +/** + * @brief GetShutdownRtcValue + * @param[out] out Output value. + */ +Result setsysGetShutdownRtcValue(u64 *out); + +/** + * @brief Gets an event that settings will signal on flag change. + * @param out_event Event to bind. Output event will have autoclear=false. + */ +Result setsysAcquireFatalDirtyFlagEventHandle(Event *out_event); + +/** + * @brief Gets the settings flags that have changed. + * @param flags_0 Pointer to populate with first 64 flags. + * @param flags_1 Pointer to populate with second 64 flags. + */ +Result setsysGetFatalDirtyFlags(u64 *flags_0, u64 *flags_1); + +/** + * @brief GetAutoUpdateEnableFlag + * @note Only available on [2.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetAutoUpdateEnableFlag(bool *out); + +/** + * @brief SetAutoUpdateEnableFlag + * @note Only available on [2.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetAutoUpdateEnableFlag(bool flag); + +/** + * @brief GetNxControllerSettings + * @note On [13.0.0+] \ref setsysGetNxControllerSettingsEx should be used instead. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysNxControllerLegacySettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetNxControllerSettings(s32 *total_out, SetSysNxControllerLegacySettings *settings, s32 count); + +/** + * @brief SetNxControllerSettings + * @note On [13.0.0+] \ref setsysSetNxControllerSettingsEx should be used instead. + * @param[in] settings Input array of \ref SetSysNxControllerLegacySettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetNxControllerSettings(const SetSysNxControllerLegacySettings *settings, s32 count); + +/** + * @brief GetBatteryPercentageFlag + * @note Only available on [2.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetBatteryPercentageFlag(bool *out); + +/** + * @brief SetBatteryPercentageFlag + * @note Only available on [2.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetBatteryPercentageFlag(bool flag); + +/** + * @brief GetExternalRtcResetFlag + * @note Only available on [2.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetExternalRtcResetFlag(bool *out); + +/** + * @brief SetExternalRtcResetFlag + * @note Only available on [2.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetExternalRtcResetFlag(bool flag); + +/** + * @brief GetUsbFullKeyEnableFlag + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetUsbFullKeyEnableFlag(bool *out); + +/** + * @brief SetUsbFullKeyEnableFlag + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetUsbFullKeyEnableFlag(bool flag); + +/** + * @brief SetExternalSteadyClockInternalOffset + * @note Only available on [3.0.0+]. + * @param[in] offset Input offset. + */ +Result setsysSetExternalSteadyClockInternalOffset(u64 offset); + +/** + * @brief GetExternalSteadyClockInternalOffset + * @note Only available on [3.0.0+]. + * @param[out] out Output offset. + */ +Result setsysGetExternalSteadyClockInternalOffset(u64 *out); + +/** + * @brief GetBacklightSettingsEx + * @note Only available on [3.0.0+]. + * @param[out] out \ref SetSysBacklightSettingsEx + */ +Result setsysGetBacklightSettingsEx(SetSysBacklightSettingsEx *out); + +/** + * @brief SetBacklightSettingsEx + * @note Only available on [3.0.0+]. + * @param[in] settings \ref SetSysBacklightSettingsEx + */ +Result setsysSetBacklightSettingsEx(const SetSysBacklightSettingsEx *settings); + +/** + * @brief GetHeadphoneVolumeWarningCount + * @note Only available on [3.0.0+]. + * @param[out] out Output count. + */ +Result setsysGetHeadphoneVolumeWarningCount(u32 *out); + +/** + * @brief SetHeadphoneVolumeWarningCount + * @note Only available on [3.0.0+]. + * @param[in] count Input count. + */ +Result setsysSetHeadphoneVolumeWarningCount(u32 count); + +/** + * @brief GetBluetoothAfhEnableFlag + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetBluetoothAfhEnableFlag(bool *out); + +/** + * @brief SetBluetoothAfhEnableFlag + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetBluetoothAfhEnableFlag(bool flag); + +/** + * @brief GetBluetoothBoostEnableFlag + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetBluetoothBoostEnableFlag(bool *out); + +/** + * @brief SetBluetoothBoostEnableFlag + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetBluetoothBoostEnableFlag(bool flag); + +/** + * @brief GetInRepairProcessEnableFlag + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetInRepairProcessEnableFlag(bool *out); + +/** + * @brief SetInRepairProcessEnableFlag + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetInRepairProcessEnableFlag(bool flag); + +/** + * @brief GetHeadphoneVolumeUpdateFlag + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetHeadphoneVolumeUpdateFlag(bool *out); + +/** + * @brief SetHeadphoneVolumeUpdateFlag + * @note Only available on [3.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetHeadphoneVolumeUpdateFlag(bool flag); + +/** + * @brief NeedsToUpdateHeadphoneVolume + * @note Only available on [3.0.0-14.1.2]. + * @param[out] a0 Output arg. + * @param[out] a1 Output arg. + * @param[out] a2 Output arg. + * @param[in] flag Input flag. + */ +Result setsysNeedsToUpdateHeadphoneVolume(u8 *a0, u8 *a1, u8 *a2, bool flag); + +/** + * @brief GetPushNotificationActivityModeOnSleep + * @note Only available on [3.0.0+]. + * @param[out] out Output mode. + */ +Result setsysGetPushNotificationActivityModeOnSleep(u32 *out); + +/** + * @brief SetPushNotificationActivityModeOnSleep + * @note Only available on [3.0.0+]. + * @param[in] mode Input mode. + */ +Result setsysSetPushNotificationActivityModeOnSleep(u32 mode); + +/** + * @brief GetServiceDiscoveryControlSettings + * @note Only available on [4.0.0+]. + * @param[out] out \ref ServiceDiscoveryControlSettings + */ +Result setsysGetServiceDiscoveryControlSettings(SetSysServiceDiscoveryControlSettings *out); + +/** + * @brief SetServiceDiscoveryControlSettings + * @note Only available on [4.0.0+]. + * @param[in] settings \ref ServiceDiscoveryControlSettings + */ +Result setsysSetServiceDiscoveryControlSettings(SetSysServiceDiscoveryControlSettings settings); + +/** + * @brief GetErrorReportSharePermission + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysErrorReportSharePermission + */ +Result setsysGetErrorReportSharePermission(SetSysErrorReportSharePermission *out); + +/** + * @brief SetErrorReportSharePermission + * @note Only available on [4.0.0+]. + * @param[in] permission \ref SetSysErrorReportSharePermission + */ +Result setsysSetErrorReportSharePermission(SetSysErrorReportSharePermission permission); + +/** + * @brief GetAppletLaunchFlags + * @note Only available on [4.0.0+]. + * @param[out] out Output AppletLaunchFlags bitmask. + */ +Result setsysGetAppletLaunchFlags(u32 *out); + +/** + * @brief SetAppletLaunchFlags + * @note Only available on [4.0.0+]. + * @param[in] flags Input AppletLaunchFlags bitmask. + */ +Result setsysSetAppletLaunchFlags(u32 flags); + +/** + * @brief GetConsoleSixAxisSensorAccelerationBias + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAccelerationBias + */ +Result setsysGetConsoleSixAxisSensorAccelerationBias(SetSysConsoleSixAxisSensorAccelerationBias *out); + +/** + * @brief SetConsoleSixAxisSensorAccelerationBias + * @note Only available on [4.0.0+]. + * @param[in] bias \ref SetSysConsoleSixAxisSensorAccelerationBias + */ +Result setsysSetConsoleSixAxisSensorAccelerationBias(const SetSysConsoleSixAxisSensorAccelerationBias *bias); + +/** + * @brief GetConsoleSixAxisSensorAngularVelocityBias + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityBias + */ +Result setsysGetConsoleSixAxisSensorAngularVelocityBias(SetSysConsoleSixAxisSensorAngularVelocityBias *out); + +/** + * @brief SetConsoleSixAxisSensorAngularVelocityBias + * @note Only available on [4.0.0+]. + * @param[in] bias \ref SetSysConsoleSixAxisSensorAngularVelocityBias + */ +Result setsysSetConsoleSixAxisSensorAngularVelocityBias(const SetSysConsoleSixAxisSensorAngularVelocityBias *bias); + +/** + * @brief GetConsoleSixAxisSensorAccelerationGain + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAccelerationGain + */ +Result setsysGetConsoleSixAxisSensorAccelerationGain(SetSysConsoleSixAxisSensorAccelerationGain *out); + +/** + * @brief SetConsoleSixAxisSensorAccelerationGain + * @note Only available on [4.0.0+]. + * @param[in] gain \ref SetSysConsoleSixAxisSensorAccelerationGain + */ +Result setsysSetConsoleSixAxisSensorAccelerationGain(const SetSysConsoleSixAxisSensorAccelerationGain *gain); + +/** + * @brief GetConsoleSixAxisSensorAngularVelocityGain + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityGain + */ +Result setsysGetConsoleSixAxisSensorAngularVelocityGain(SetSysConsoleSixAxisSensorAngularVelocityGain *out); + +/** + * @brief SetConsoleSixAxisSensorAngularVelocityGain + * @note Only available on [4.0.0+]. + * @param[in] gain \ref SetSysConsoleSixAxisSensorAngularVelocityGain + */ +Result setsysSetConsoleSixAxisSensorAngularVelocityGain(const SetSysConsoleSixAxisSensorAngularVelocityGain *gain); + +/** + * @brief GetKeyboardLayout + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetKeyboardLayout + */ +Result setsysGetKeyboardLayout(SetKeyboardLayout *out); + +/** + * @brief SetKeyboardLayout + * @note Only available on [4.0.0+]. + * @param[in] layout \ref SetKeyboardLayout + */ +Result setsysSetKeyboardLayout(SetKeyboardLayout layout); + +/** + * @brief GetWebInspectorFlag + * @note Only available on [4.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetWebInspectorFlag(bool *out); + +/** + * @brief GetAllowedSslHosts + * @note Only available on [4.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] out Output array of \ref SetSysAllowedSslHosts. + * @param[in] count Size of the hosts array in entries. + */ +Result setsysGetAllowedSslHosts(s32 *total_out, SetSysAllowedSslHosts *out, s32 count); + +/** + * @brief GetHostFsMountPoint + * @note Only available on [4.0.0+]. + * @param[out] out \ref SetSysHostFsMountPoint + */ +Result setsysGetHostFsMountPoint(SetSysHostFsMountPoint *out); + +/** + * @brief GetRequiresRunRepairTimeReviser + * @note Only available on [5.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetRequiresRunRepairTimeReviser(bool *out); + +/** + * @brief SetRequiresRunRepairTimeReviser + * @note Only available on [5.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetRequiresRunRepairTimeReviser(bool flag); + +/** + * @brief SetBlePairingSettings + * @note Only available on [5.0.0+]. + * @param[in] settings Input array of \ref SetSysBlePairingSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetBlePairingSettings(const SetSysBlePairingSettings *settings, s32 count); + +/** + * @brief GetBlePairingSettings + * @note Only available on [5.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysBlePairingSettings. + * @param[in] count Size of the hosts array in entries. + */ +Result setsysGetBlePairingSettings(s32 *total_out, SetSysBlePairingSettings *settings, s32 count); + +/** + * @brief GetConsoleSixAxisSensorAngularVelocityTimeBias + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityTimeBias + */ +Result setsysGetConsoleSixAxisSensorAngularVelocityTimeBias(SetSysConsoleSixAxisSensorAngularVelocityTimeBias *out); + +/** + * @brief SetConsoleSixAxisSensorAngularVelocityTimeBias + * @note Only available on [5.0.0+]. + * @param[in] bias \ref SetSysConsoleSixAxisSensorAngularVelocityTimeBias + */ +Result setsysSetConsoleSixAxisSensorAngularVelocityTimeBias(const SetSysConsoleSixAxisSensorAngularVelocityTimeBias *bias); + +/** + * @brief GetConsoleSixAxisSensorAngularAcceleration + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetSysConsoleSixAxisSensorAngularAcceleration + */ +Result setsysGetConsoleSixAxisSensorAngularAcceleration(SetSysConsoleSixAxisSensorAngularAcceleration *out); + +/** + * @brief SetConsoleSixAxisSensorAngularAcceleration + * @note Only available on [5.0.0+]. + * @param[in] acceleration \ref SetSysConsoleSixAxisSensorAngularAcceleration + */ +Result setsysSetConsoleSixAxisSensorAngularAcceleration(const SetSysConsoleSixAxisSensorAngularAcceleration *acceleration); + +/** + * @brief GetRebootlessSystemUpdateVersion + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetSysRebootlessSystemUpdateVersion + */ +Result setsysGetRebootlessSystemUpdateVersion(SetSysRebootlessSystemUpdateVersion *out); + +/** + * @brief GetDeviceTimeZoneLocationUpdatedTime + * @note Only available on [5.0.0+]. + * @param[out] out \ref TimeSteadyClockTimePoint + */ +Result setsysGetDeviceTimeZoneLocationUpdatedTime(TimeSteadyClockTimePoint *out); + +/** + * @brief SetDeviceTimeZoneLocationUpdatedTime + * @note Only available on [5.0.0+]. + * @param[in] time_point \ref TimeSteadyClockTimePoint + */ +Result setsysSetDeviceTimeZoneLocationUpdatedTime(const TimeSteadyClockTimePoint *time_point); + +/** + * @brief GetUserSystemClockAutomaticCorrectionUpdatedTime + * @note Only available on [6.0.0+]. + * @param[out] out \ref TimeSteadyClockTimePoint + */ +Result setsysGetUserSystemClockAutomaticCorrectionUpdatedTime(TimeSteadyClockTimePoint *out); + +/** + * @brief SetUserSystemClockAutomaticCorrectionUpdatedTime + * @note Only available on [6.0.0+]. + * @param[in] time_point \ref TimeSteadyClockTimePoint + */ +Result setsysSetUserSystemClockAutomaticCorrectionUpdatedTime(const TimeSteadyClockTimePoint *time_point); + +/** + * @brief GetAccountOnlineStorageSettings + * @note Only available on [6.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysAccountOnlineStorageSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetAccountOnlineStorageSettings(s32 *total_out, SetSysAccountOnlineStorageSettings *settings, s32 count); + +/** + * @brief SetAccountOnlineStorageSettings + * @note Only available on [6.0.0+]. + * @param[in] settings Input array of \ref SetSysAccountOnlineStorageSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetAccountOnlineStorageSettings(const SetSysAccountOnlineStorageSettings *settings, s32 count); + +/** + * @brief GetPctlReadyFlag + * @note Only available on [6.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetPctlReadyFlag(bool *out); + +/** + * @brief SetPctlReadyFlag + * @note Only available on [6.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetPctlReadyFlag(bool flag); + +/** + * @brief GetAnalogStickUserCalibrationL + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetSysAnalogStickUserCalibration + */ +Result setsysGetAnalogStickUserCalibrationL(SetSysAnalogStickUserCalibration *out); + +/** + * @brief SetAnalogStickUserCalibrationL + * @note Only available on [8.1.1+]. + * @param[in] calibration \ref SetSysAnalogStickUserCalibration + */ +Result setsysSetAnalogStickUserCalibrationL(const SetSysAnalogStickUserCalibration *calibration); + +/** + * @brief GetAnalogStickUserCalibrationR + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetSysAnalogStickUserCalibration + */ +Result setsysGetAnalogStickUserCalibrationR(SetSysAnalogStickUserCalibration *out); + +/** + * @brief SetAnalogStickUserCalibrationR + * @note Only available on [8.1.1+]. + * @param[in] calibration \ref SetSysAnalogStickUserCalibration + */ +Result setsysSetAnalogStickUserCalibrationR(const SetSysAnalogStickUserCalibration *calibration); + +/** + * @brief GetPtmBatteryVersion + * @note Only available on [6.0.0+]. + * @param[out] out Output version. + */ +Result setsysGetPtmBatteryVersion(u8 *out); + +/** + * @brief SetPtmBatteryVersion + * @note Only available on [6.0.0+]. + * @param[in] version Input version. + */ +Result setsysSetPtmBatteryVersion(u8 version); + +/** + * @brief GetUsb30HostEnableFlag + * @note Only available on [6.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetUsb30HostEnableFlag(bool *out); + +/** + * @brief SetUsb30HostEnableFlag + * @note Only available on [6.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetUsb30HostEnableFlag(bool flag); + +/** + * @brief GetUsb30DeviceEnableFlag + * @note Only available on [6.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetUsb30DeviceEnableFlag(bool *out); + +/** + * @brief SetUsb30DeviceEnableFlag + * @note Only available on [6.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetUsb30DeviceEnableFlag(bool flag); + +/** + * @brief GetThemeId + * @note Only available on [7.0.0+]. + * @param[in] type Input theme id type. + * @param[out] out \ref SetSysThemeId + */ +Result setsysGetThemeId(s32 type, SetSysThemeId *out); + +/** + * @brief SetThemeId + * @note Only available on [7.0.0+]. + * @param[in] type Input theme id type. + * @param[in] theme_id \ref SetSysThemeId + */ +Result setsysSetThemeId(s32 type, const SetSysThemeId *theme_id); + +/** + * @brief GetChineseTraditionalInputMethod + * @note Only available on [7.0.0+]. + * @param[out] out \ref SetChineseTraditionalInputMethod + */ +Result setsysGetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod *out); + +/** + * @brief SetChineseTraditionalInputMethod + * @note Only available on [7.0.0+]. + * @param[in] method \ref SetChineseTraditionalInputMethod + */ +Result setsysSetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod method); + +/** + * @brief GetPtmCycleCountReliability + * @note Only available on [7.0.0+]. + * @param[out] out \ref SetSysPtmCycleCountReliability + */ +Result setsysGetPtmCycleCountReliability(SetSysPtmCycleCountReliability *out); + +/** + * @brief SetPtmCycleCountReliability + * @note Only available on [7.0.0+]. + * @param[in] reliability \ref SetSysPtmCycleCountReliability + */ +Result setsysSetPtmCycleCountReliability(SetSysPtmCycleCountReliability reliability); + +/** + * @brief Gets the \ref SetSysHomeMenuScheme. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetSysHomeMenuScheme + */ +Result setsysGetHomeMenuScheme(SetSysHomeMenuScheme *out); + +/** + * @brief GetThemeSettings + * @note Only available on [7.0.0+]. + * @param[out] out \ref SetSysThemeSettings + */ +Result setsysGetThemeSettings(SetSysThemeSettings *out); + +/** + * @brief SetThemeSettings + * @note Only available on [7.0.0+]. + * @param[in] settings \ref SetSysThemeSettings + */ +Result setsysSetThemeSettings(const SetSysThemeSettings *settings); + +/** + * @brief GetThemeKey + * @note Only available on [7.0.0+]. + * @param[out] out \ref FsArchiveMacKey + */ +Result setsysGetThemeKey(FsArchiveMacKey *out); + +/** + * @brief SetThemeKey + * @note Only available on [7.0.0+]. + * @param[in] key \ref FsArchiveMacKey + */ +Result setsysSetThemeKey(const FsArchiveMacKey *key); + +/** + * @brief GetZoomFlag + * @note Only available on [8.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetZoomFlag(bool *out); + +/** + * @brief SetZoomFlag + * @note Only available on [8.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetZoomFlag(bool flag); + +/** + * @brief Returns Terra platform type flag. + * @note On [9.0.0+], this is a wrapper for \ref setsysGetPlatFormRegion() == 2. + * @note Only available on [8.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetT(bool *out); + +/** + * @brief Sets Terra platform type flag. + * @note On [9.0.0+], this is a wrapper for \ref setsysSetPlatFormRegion(1 + (IsT & 1)). + * @note Only available on [8.0.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetT(bool flag); + +/** + * @brief Gets the \ref SetSysPlatformRegion. + * @note This is used internally by \ref appletGetSettingsPlatformRegion. + * @note Only available on [9.0.0+]. + * @param[out] out \ref SetSysPlatformRegion + */ +Result setsysGetPlatformRegion(SetSysPlatformRegion *out); + +/** + * @brief Sets the \ref SetSysPlatformRegion. + * @note Only available on [9.0.0+]. + * @param[in] region \ref SetSysPlatformRegion + */ +Result setsysSetPlatformRegion(SetSysPlatformRegion region); + +/** + * @brief GetHomeMenuSchemeModel + * @note This will throw an error when loading the "settings_debug!{...}" system-setting which is used with this fails. + * @note Only available on [9.0.0+]. + * @param[out] out HomeMenuSchemeModel. + */ +Result setsysGetHomeMenuSchemeModel(u32 *out); + +/** + * @brief GetMemoryUsageRateFlag + * @note Only available on [9.0.0+]. + * @param[out] out Output flag. + */ +Result setsysGetMemoryUsageRateFlag(bool *out); + +/** + * @brief Gets the \ref SetSysTouchScreenMode. + * @note Only available on [9.0.0+]. + * @param[out] out \ref SetSysTouchScreenMode + */ +Result setsysGetTouchScreenMode(SetSysTouchScreenMode *out); + +/** + * @brief Sets the \ref SetSysTouchScreenMode. + * @note Only available on [9.0.0+]. + * @param[in] mode \ref SetSysTouchScreenMode + */ +Result setsysSetTouchScreenMode(SetSysTouchScreenMode mode); + +/** + * @brief GetButtonConfigSettingsFull + * @note Only available on [10.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetButtonConfigSettingsFull(s32 *total_out, SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief SetButtonConfigSettingsFull + * @note Only available on [10.0.0+]. + * @param[in] settings Input array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetButtonConfigSettingsFull(const SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief GetButtonConfigSettingsEmbedded + * @note Only available on [10.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetButtonConfigSettingsEmbedded(s32 *total_out, SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief SetButtonConfigSettingsEmbedded + * @note Only available on [10.0.0+]. + * @param[in] settings Input array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetButtonConfigSettingsEmbedded(const SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief GetButtonConfigSettingsLeft + * @note Only available on [10.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetButtonConfigSettingsLeft(s32 *total_out, SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief SetButtonConfigSettingsLeft + * @note Only available on [10.0.0+]. + * @param[in] settings Input array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetButtonConfigSettingsLeft(const SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief GetButtonConfigSettingsRight + * @note Only available on [10.0.0+]. + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetButtonConfigSettingsRight(s32 *total_out, SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief SetButtonConfigSettingsRight + * @note Only available on [10.0.0+]. + * @param[in] settings Input array of \ref SetSysButtonConfigSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetButtonConfigSettingsRight(const SetSysButtonConfigSettings *settings, s32 count); + +/** + * @brief GetButtonConfigRegisteredSettingsEmbedded + * @note Only available on [10.0.0+]. + * @param[out] settings \ref SetSysButtonConfigRegisteredSettings + */ +Result setsysGetButtonConfigRegisteredSettingsEmbedded(SetSysButtonConfigRegisteredSettings *settings); + +/** + * @brief SetButtonConfigRegisteredSettingsEmbedded + * @note Only available on [10.0.0+]. + * @param[in] settings \ref SetSysButtonConfigRegisteredSettings + */ +Result setsysSetButtonConfigRegisteredSettingsEmbedded(const SetSysButtonConfigRegisteredSettings *settings); + +/** + * @brief GetButtonConfigRegisteredSettings + * @note Only available on [10.0.0+]. + * @param[out] settings \ref SetSysButtonConfigRegisteredSettings + */ +Result setsysGetButtonConfigRegisteredSettings(s32 *total_out, SetSysButtonConfigRegisteredSettings *settings, s32 count); + +/** + * @brief SetButtonConfigRegisteredSettings + * @note Only available on [10.0.0+]. + * @param[in] settings \ref SetSysButtonConfigRegisteredSettings + */ +Result setsysSetButtonConfigRegisteredSettings(const SetSysButtonConfigRegisteredSettings *settings, s32 count); + +/** + * @brief GetFieldTestingFlag + * @note Only available on [10.1.0+]. + * @param[out] out Output flag. + */ +Result setsysGetFieldTestingFlag(bool *out); + +/** + * @brief SetFieldTestingFlag + * @note Only available on [10.1.0+]. + * @param[in] flag Input flag. + */ +Result setsysSetFieldTestingFlag(bool flag); + +/** + * @brief GetNxControllerSettingsEx + * @param[out] total_out Total output entries. + * @param[out] settings Output array of \ref SetSysNxControllerSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysGetNxControllerSettingsEx(s32 *total_out, SetSysNxControllerSettings *settings, s32 count); + +/** + * @brief SetNxControllerSettingsEx + * @param[in] settings Input array of \ref SetSysNxControllerSettings. + * @param[in] count Size of the settings array in entries. + */ +Result setsysSetNxControllerSettingsEx(const SetSysNxControllerSettings *settings, s32 count); + +/// Initialize setcal. +Result setcalInitialize(void); + +/// Exit setcal. +void setcalExit(void); + +/// Gets the Service object for the actual setcal service session. +Service* setcalGetServiceSession(void); + +/** + * @brief Gets the \ref SetCalBdAddress. + * @param[out] out \ref SetCalBdAddress + */ +Result setcalGetBdAddress(SetCalBdAddress *out); + +/** + * @brief Gets the \ref SetCalConfigurationId1. + * @param[out] out \ref SetCalConfigurationId1 + */ +Result setcalGetConfigurationId1(SetCalConfigurationId1 *out); + +/** + * @brief Gets the \ref SetCalAccelerometerOffset. + * @param[out] out \ref SetCalAccelerometerOffset + */ +Result setcalGetAccelerometerOffset(SetCalAccelerometerOffset *out); + +/** + * @brief Gets the \ref SetCalAccelerometerScale. + * @param[out] out \ref SetCalAccelerometerScale + */ +Result setcalGetAccelerometerScale(SetCalAccelerometerScale *out); + +/** + * @brief Gets the \ref SetCalGyroscopeOffset. + * @param[out] out \ref SetCalGyroscopeOffset + */ +Result setcalGetGyroscopeOffset(SetCalGyroscopeOffset *out); + +/** + * @brief Gets the \ref SetCalGyroscopeScale. + * @param[out] out \ref SetCalGyroscopeScale + */ +Result setcalGetGyroscopeScale(SetCalGyroscopeScale *out); + +/** + * @brief Gets the \ref SetCalMacAddress. + * @param[out] out \ref SetCalMacAddress + */ +Result setcalGetWirelessLanMacAddress(SetCalMacAddress *out); + +/** + * @brief GetWirelessLanCountryCodeCount + * @param[out] out_count Output count + */ +Result setcalGetWirelessLanCountryCodeCount(s32 *out_count); + +/** + * @brief GetWirelessLanCountryCodes + * @param[out] total_out Total output entries. + * @param[out] codes Output array of \ref SetCalCountryCode. + * @param[in] count Size of the versions array in entries. + */ +Result setcalGetWirelessLanCountryCodes(s32 *total_out, SetCalCountryCode *codes, s32 count); + +/** + * @brief Gets the \ref SetCalSerialNumber. + * @param[out] out \ref SetCalSerialNumber + */ +Result setcalGetSerialNumber(SetCalSerialNumber *out); + +/** + * @brief SetInitialSystemAppletProgramId + * @param[in] program_id input ProgramId. + */ +Result setcalSetInitialSystemAppletProgramId(u64 program_id); + +/** + * @brief SetOverlayDispProgramId + * @param[in] program_id input ProgramId. + */ +Result setcalSetOverlayDispProgramId(u64 program_id); + +/** + * @brief Gets the \ref SetBatteryLot. + * @param[out] out \ref SetBatteryLot + */ +Result setcalGetBatteryLot(SetBatteryLot *out); + +/** + * @brief Gets the \ref SetCalEccB233DeviceCertificate. + * @param[out] out \ref SetCalEccB233DeviceCertificate + */ +Result setcalGetEciDeviceCertificate(SetCalEccB233DeviceCertificate *out); + +/** + * @brief Gets the \ref SetCalRsa2048DeviceCertificate. + * @param[out] out \ref SetCalRsa2048DeviceCertificate + */ +Result setcalGetEticketDeviceCertificate(SetCalRsa2048DeviceCertificate *out); + +/** + * @brief Gets the \ref SetCalSslKey. + * @param[out] out \ref SetCalSslKey + */ +Result setcalGetSslKey(SetCalSslKey *out); + +/** + * @brief Gets the \ref SetCalSslCertificate. + * @param[out] out \ref SetCalSslCertificate + */ +Result setcalGetSslCertificate(SetCalSslCertificate *out); + +/** + * @brief Gets the \ref SetCalGameCardKey. + * @param[out] out \ref SetCalGameCardKey + */ +Result setcalGetGameCardKey(SetCalGameCardKey *out); + +/** + * @brief Gets the \ref SetCalGameCardCertificate. + * @param[out] out \ref SetCalGameCardCertificate + */ +Result setcalGetGameCardCertificate(SetCalGameCardCertificate *out); + +/** + * @brief Gets the \ref SetCalEccB233DeviceKey. + * @param[out] out \ref SetCalEccB233DeviceKey + */ +Result setcalGetEciDeviceKey(SetCalEccB233DeviceKey *out); + +/** + * @brief Gets the \ref SetCalRsa2048DeviceKey. + * @param[out] out \ref SetCalRsa2048DeviceKey + */ +Result setcalGetEticketDeviceKey(SetCalRsa2048DeviceKey *out); + +/** + * @brief Gets the \ref SetCalSpeakerParameter. + * @param[out] out \ref SetCalSpeakerParameter + */ +Result setcalGetSpeakerParameter(SetCalSpeakerParameter *out); + +/** + * @brief GetLcdVendorId + * @note Only available on [4.0.0+]. + * @param[out] out_vendor_id Output LcdVendorId. + */ +Result setcalGetLcdVendorId(u32 *out_vendor_id); + +/** + * @brief Gets the \ref SetCalRsa2048DeviceCertificate. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalRsa2048DeviceCertificate + */ +Result setcalGetEciDeviceCertificate2(SetCalRsa2048DeviceCertificate *out); + +/** + * @brief Gets the \ref SetCalRsa2048DeviceKey. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalRsa2048DeviceKey + */ +Result setcalGetEciDeviceKey2(SetCalRsa2048DeviceKey *out); + +/** + * @brief Gets the \ref SetCalAmiiboKey. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboKey + */ +Result setcalGetAmiiboKey(SetCalAmiiboKey *out); + +/** + * @brief Gets the \ref SetCalAmiiboEcqvCertificate. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboEcqvCertificate + */ +Result setcalGetAmiiboEcqvCertificate(SetCalAmiiboEcqvCertificate *out); + +/** + * @brief Gets the \ref SetCalAmiiboEcdsaCertificate. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboEcdsaCertificate + */ +Result setcalGetAmiiboEcdsaCertificate(SetCalAmiiboEcdsaCertificate *out); + +/** + * @brief Gets the \ref SetCalAmiiboEcqvBlsKey. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboEcqvBlsKey + */ +Result setcalGetAmiiboEcqvBlsKey(SetCalAmiiboEcqvBlsKey *out); + +/** + * @brief Gets the \ref SetCalAmiiboEcqvBlsCertificate. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboEcqvBlsCertificate + */ +Result setcalGetAmiiboEcqvBlsCertificate(SetCalAmiiboEcqvBlsCertificate *out); + +/** + * @brief Gets the \ref SetCalAmiiboEcqvBlsRootCertificate. + * @note Only available on [5.0.0+]. + * @param[out] out \ref SetCalAmiiboEcqvBlsRootCertificate + */ +Result setcalGetAmiiboEcqvBlsRootCertificate(SetCalAmiiboEcqvBlsRootCertificate *out); + +/** + * @brief GetUsbTypeCPowerSourceCircuitVersion + * @note Only available on [5.0.0+]. + * @param[out] out_version Output UsbTypeCPowerSourceCircuitVersion. + */ +Result setcalGetUsbTypeCPowerSourceCircuitVersion(u8 *out_version); + +/** + * @brief GetAnalogStickModuleTypeL + * @note Only available on [8.1.1+]. + * @param[out] out_version Output AnalogStickModuleType. + */ +Result setcalGetAnalogStickModuleTypeL(u8 *out_type); + +/** + * @brief Gets the \ref SetCalAnalogStickModelParameter. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetCalAnalogStickModelParameter + */ +Result setcalGetAnalogStickModelParameterL(SetCalAnalogStickModelParameter *out); + +/** + * @brief Gets the \ref SetCalAnalogStickFactoryCalibration. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetCalAnalogStickFactoryCalibration + */ +Result setcalGetAnalogStickFactoryCalibrationL(SetCalAnalogStickFactoryCalibration *out); + +/** + * @brief GetAnalogStickModuleTypeR + * @note Only available on [8.1.1+]. + * @param[out] out_version Output AnalogStickModuleType. + */ +Result setcalGetAnalogStickModuleTypeR(u8 *out_type); + +/** + * @brief Gets the \ref SetCalAnalogStickModelParameter. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetCalAnalogStickModelParameter + */ +Result setcalGetAnalogStickModelParameterR(SetCalAnalogStickModelParameter *out); + +/** + * @brief Gets the \ref SetCalAnalogStickFactoryCalibration. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetCalAnalogStickFactoryCalibration + */ +Result setcalGetAnalogStickFactoryCalibrationR(SetCalAnalogStickFactoryCalibration *out); + +/** + * @brief GetConsoleSixAxisSensorModuleType + * @note Only available on [8.1.1+]. + * @param[out] out_version Output ConsoleSixAxisSensorModuleType. + */ +Result setcalGetConsoleSixAxisSensorModuleType(u8 *out_type); + +/** + * @brief Gets the \ref SetCalConsoleSixAxisSensorHorizontalOffset. + * @note Only available on [8.1.1+]. + * @param[out] out \ref SetCalConsoleSixAxisSensorHorizontalOffset + */ +Result setcalGetConsoleSixAxisSensorHorizontalOffset(SetCalConsoleSixAxisSensorHorizontalOffset *out); + +/** + * @brief GetBatteryVersion + * @note Only available on [6.0.0+]. + * @param[out] out_version Output BatteryVersion. + */ +Result setcalGetBatteryVersion(u8 *out_version); + +/** + * @brief GetDeviceId + * @note Only available on [10.0.0+]. + * @param[out] out_type Output DeviceId. + */ +Result setcalGetDeviceId(u64 *out_device_id); + +/** + * @brief GetConsoleSixAxisSensorMountType + * @note Only available on [10.0.0+]. + * @param[out] out_type Output ConsoleSixAxisSensorMountType. + */ +Result setcalGetConsoleSixAxisSensorMountType(u8 *out_type); diff --git a/src/libnx/wrapper/switch/services/set.nim b/src/libnx/wrapper/switch/services/set.nim new file mode 100644 index 0000000..bebd481 --- /dev/null +++ b/src/libnx/wrapper/switch/services/set.nim @@ -0,0 +1,3013 @@ +## * +## @file set.h +## @brief Settings services IPC wrapper. +## @author plutoo +## @author yellows8 +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../services/time, ../services/acc, ../services/fs, + ../services/btdrv_types, ../services/btm_types, ../sf/service + +const + SET_MAX_NAME_SIZE* = 0x48 + +type + ColorSetId* = enum + ColorSetIdLight = 0, ColorSetIdDark = 1 + + +## / Console Product Models + +type + SetSysProductModel* = enum + SetSysProductModelInvalid = 0, ## /< Invalid Model + SetSysProductModelNx = 1, ## /< Erista Model + SetSysProductModelCopper = 2, ## /< Erista "Simulation" Model + SetSysProductModelIowa = 3, ## /< Mariko Model + SetSysProductModelHoag = 4, ## /< Mariko Lite Model + SetSysProductModelCalcio = 5, ## /< Mariko "Simulation" Model + SetSysProductModelAula = 6 ## /< Mariko Pro Model(?) + + +## / IDs for Language. + +type + SetLanguage* = enum + SetLanguageJA = 0, ## /< Japanese + SetLanguageENUS = 1, ## /< US English ("AmericanEnglish") + SetLanguageFR = 2, ## /< French + SetLanguageDE = 3, ## /< German + SetLanguageIT = 4, ## /< Italian + SetLanguageES = 5, ## /< Spanish + SetLanguageZHCN = 6, ## /< Simplified Chinese ("Chinese") + SetLanguageKO = 7, ## /< Korean + SetLanguageNL = 8, ## /< Dutch + SetLanguagePT = 9, ## /< Portuguese + SetLanguageRU = 10, ## /< Russian + SetLanguageZHTW = 11, ## /< Traditional Chinese ("Taiwanese") + SetLanguageENGB = 12, ## /< GB English ("BritishEnglish") + SetLanguageFRCA = 13, ## /< CA French ("CanadianFrench") + SetLanguageES419 = 14, ## /< "LatinAmericanSpanish" + SetLanguageZHHANS = 15, ## /< [4.0.0+] ChineseSimplified + SetLanguageZHHANT = 16, ## /< [4.0.0+] ChineseTraditional + SetLanguagePTBR = 17, ## /< [10.1.0+] "BrazilianPortuguese" + SetLanguageTotal ## /< Total languages supported by this enum. + + +## / Region codes. + +type + SetRegion* = enum + SetRegionJPN = 0, ## /< Japan + SetRegionUSA = 1, ## /< The Americas + SetRegionEUR = 2, ## /< Europe + SetRegionAUS = 3, ## /< Australia/New Zealand + SetRegionHTK = 4, ## /< Hong Kong/Taiwan/Korea + SetRegionCHN = 5 ## /< China + + +## / ConnectionFlag + +type + SetSysConnectionFlag* = enum + SetSysConnectionFlagConnectAutomaticallyFlag = bit(0), + SetSysConnectionFlagUnknown = bit(1) + + +## / AccessPointSecurityType + +type + SetSysAccessPointSecurityType* = enum + SetSysAccessPointSecurityTypeNone = 0, SetSysAccessPointSecurityTypeShared = 1, + SetSysAccessPointSecurityTypeWpa = 2, SetSysAccessPointSecurityTypeWpa2 = 3 + + +## / AccessPointSecurityStandard + +type + SetSysAccessPointSecurityStandard* = enum + SetSysAccessPointSecurityStandardNone = 0, + SetSysAccessPointSecurityStandardWep = 1, + SetSysAccessPointSecurityStandardWpa = 2 + + +## / AutoSettings + +type + SetSysAutoSettings* = enum + SetSysAutoSettingsAutoIp = bit(0), SetSysAutoSettingsAutoDns = bit(1) + + +## / ProxyFlags + +type + SetSysProxyFlags* = enum + SetSysProxyFlagsUseProxyFlag = bit(0), + SetSysProxyFlagsProxyAutoAuthenticateFlag = bit(1) + + +## / UserSelectorFlag + +type + SetSysUserSelectorFlag* = enum + SetSysUserSelectorFlagSkipsIfSingleUser = bit(0) + + +## / EulaVersionClockType + +type + SetSysEulaVersionClockType* = enum + SetSysEulaVersionClockTypeNetworkSystemClock = 0, + SetSysEulaVersionClockTypeSteadyClock = 1 + + +## / NotificationVolume + +type + SetSysNotificationVolume* = enum + SetSysNotificationVolumeMute = 0, SetSysNotificationVolumeLow = 1, + SetSysNotificationVolumeHigh = 2 + + +## / FriendPresenceOverlayPermission + +type + SetSysFriendPresenceOverlayPermission* = enum + SetSysFriendPresenceOverlayPermissionNotConfirmed = 0, + SetSysFriendPresenceOverlayPermissionNoDisplay = 1, + SetSysFriendPresenceOverlayPermissionFavoriteFriends = 2, + SetSysFriendPresenceOverlayPermissionFriends = 3 + + +## / AudioDevice + +type + SetSysAudioDevice* = enum + SetSysAudioDeviceConsole = 0, SetSysAudioDeviceHeadphone = 1, + SetSysAudioDeviceTv = 2 + + +## / PrimaryAlbumStorage + +type + SetSysPrimaryAlbumStorage* = enum + SetSysPrimaryAlbumStorageNand = 0, SetSysPrimaryAlbumStorageSdCard = 1 + + +## / HandheldSleepPlan + +type + SetSysHandheldSleepPlan* = enum + SetSysHandheldSleepPlan1Min = 0, SetSysHandheldSleepPlan3Min = 1, + SetSysHandheldSleepPlan5Min = 2, SetSysHandheldSleepPlan10Min = 3, + SetSysHandheldSleepPlan30Min = 4, SetSysHandheldSleepPlanNever = 5 + + +## / ConsoleSleepPlan + +type + SetSysConsoleSleepPlan* = enum + SetSysConsoleSleepPlan1Hour = 0, SetSysConsoleSleepPlan2Hour = 1, + SetSysConsoleSleepPlan3Hour = 2, SetSysConsoleSleepPlan6Hour = 3, + SetSysConsoleSleepPlan12Hour = 4, SetSysConsoleSleepPlanNever = 5 + + +## / AudioOutputModeTarget + +type + SetSysAudioOutputModeTarget* = enum + SetSysAudioOutputModeTargetUnknown0 = 0, + SetSysAudioOutputModeTargetUnknown1 = 1, + SetSysAudioOutputModeTargetUnknown2 = 2, + SetSysAudioOutputModeTargetUnknown3 = 3 + + +## / AudioOutputMode + +type + SetSysAudioOutputMode* = enum + SetSysAudioOutputModeUnknown1 = 1 ## /< Default value. + + +## / ServiceDiscoveryControlSettings + +type + SetSysServiceDiscoveryControlSettings* = enum + SetSysServiceDiscoveryControlSettingsIsChangeEnvironmentIdentifierDisabled = bit( + 0) + + +## / ErrorReportSharePermission + +type + SetSysErrorReportSharePermission* = enum + SetSysErrorReportSharePermissionNotConfirmed = 0, + SetSysErrorReportSharePermissionGranted = 1, + SetSysErrorReportSharePermissionDenied = 2 + + +## / KeyboardLayout + +type + SetKeyboardLayout* = enum + SetKeyboardLayoutJapanese = 0, SetKeyboardLayoutEnglishUs = 1, + SetKeyboardLayoutEnglishUsInternational = 2, SetKeyboardLayoutEnglishUk = 3, + SetKeyboardLayoutFrench = 4, SetKeyboardLayoutFrenchCa = 5, + SetKeyboardLayoutSpanish = 6, SetKeyboardLayoutSpanishLatin = 7, + SetKeyboardLayoutGerman = 8, SetKeyboardLayoutItalian = 9, + SetKeyboardLayoutPortuguese = 10, SetKeyboardLayoutRussian = 11, + SetKeyboardLayoutKorean = 12, SetKeyboardLayoutChineseSimplified = 13, + SetKeyboardLayoutChineseTraditional = 14 + + +## / ChineseTraditionalInputMethod + +type + SetChineseTraditionalInputMethod* = enum + SetChineseTraditionalInputMethodUnknown1 = 1, + SetChineseTraditionalInputMethodUnknown2 = 2 + + +## / PtmCycleCountReliability + +type + SetSysPtmCycleCountReliability* = enum + PtmCycleCountReliabilityDefault = 0, PtmCycleCountReliabilityUnk = 1 + + +## / PlatformRegion. Other values not listed here should be handled as "Unknown". + +type + SetSysPlatformRegion* = enum + SetSysPlatformRegionGlobal = 1, SetSysPlatformRegionChina = 2 + + +## / TouchScreenMode, for "Touch-Screen Sensitivity". + +type + SetSysTouchScreenMode* = enum + SetSysTouchScreenModeStylus = 0, ## /< Stylus. + SetSysTouchScreenModeStandard = 1 ## /< Standard, the default. + + +## / BlockType + +type + SetSysBlockType* = enum + SetSysBlockTypeAudio = 1, SetSysBlockTypeVideo = 2, + SetSysBlockTypeVendorSpecific = 3, SetSysBlockTypeSpeaker = 4 + + +## / ControllerType + +type + SetSysControllerType* = enum + SetSysControllerTypeJoyConR = 1, SetSysControllerTypeJoyConL = 2, + SetSysControllerTypeProCon = 3 + + +## / BatteryLot + +type + SetBatteryLot* {.bycopy.} = object + lot*: array[0x18, char] ## /< BatteryLot string. + + +## / NetworkSettings + +type + SetSysNetworkSettings* {.bycopy.} = object + name*: array[0x40, char] + uuid*: Uuid + connectionFlags*: U32 ## /< Bitmask with \ref SetSysConnectionFlag. + wiredFlag*: U32 + connectToHiddenNetwork*: U32 ## /< Bitmask with UseStealthNetworkFlag. + accessPointSsid*: array[0x20, char] + accessPointSsidLen*: U32 + accessPointSecurityType*: U32 ## /< Bitmask with \ref SetSysAccessPointSecurityType. + accessPointSecurityStandard*: U32 ## /< Bitmask with \ref SetSysAccessPointSecurityStandard. + accessPointPassphrase*: array[0x40, char] + accessPointPassphraseLen*: U32 + autoSettings*: U32 ## /< Bitmask with \ref SetSysAutoSettings. + manualIpAddress*: U32 + manualSubnetMask*: U32 + manualGateway*: U32 + primaryDns*: U32 + secondaryDns*: U32 + proxyFlags*: U32 ## /< Bitmask with \ref SetSysProxyFlags. + proxyServer*: array[0x80, char] + proxyPort*: U16 + padding1*: U16 + proxyAutoauthUser*: array[0x20, char] + proxyAutoauthPass*: array[0x20, char] + mtu*: U16 + padding2*: U16 + + +## / LcdBacklightBrightnessMapping + +type + SetSysLcdBacklightBrightnessMapping* {.bycopy.} = object + brightnessAppliedToBacklight*: cfloat + ambientLightSensorValue*: cfloat + unkX8*: cfloat + + +## / BacklightSettings + +type + SetSysBacklightSettings* {.bycopy.} = object + autoBrightnessFlags*: U32 + screenBrightness*: cfloat + brightnessMapping*: SetSysLcdBacklightBrightnessMapping + unkX14*: cfloat + unkX18*: cfloat + unkX1C*: cfloat + unkX20*: cfloat + unkX24*: cfloat + + +## / BacklightSettingsEx + +type + SetSysBacklightSettingsEx* {.bycopy.} = object + autoBrightnessFlags*: U32 + screenBrightness*: cfloat + currentBrightnessForVrMode*: cfloat + brightnessMapping*: SetSysLcdBacklightBrightnessMapping + unkX18*: cfloat + unkX1C*: cfloat + unkX20*: cfloat + unkX24*: cfloat + unkX28*: cfloat + + +## / BluetoothDevicesSettings + +type + INNER_C_STRUCT_set_5* {.bycopy.} = object + pad*: U8 ## /< Padding + name2*: array[0xF9, char] ## /< Name + + INNER_C_UNION_set_4* {.bycopy, union.} = object + reserved*: array[0x12B, U8] ## /< Reserved [1.0.0-12.1.0] + anoSet6*: INNER_C_STRUCT_set_5 + + SetSysBluetoothDevicesSettings* {.bycopy.} = object + `addr`*: BtdrvAddress ## /< \ref BtdrvAddress + name*: BtmBdName ## /< BdName. Unused on 13.0.0+ + classOfDevice*: BtmClassOfDevice ## /< ClassOfDevice + linkKey*: array[0x10, U8] ## /< LinkKey + linkKeyPresent*: U8 ## /< LinkKeyPresent + version*: U16 ## /< Version + trustedServices*: U32 ## /< TrustedServices + vid*: U16 ## /< Vid + pid*: U16 ## /< Pid + subClass*: U8 ## /< SubClass + attributeMask*: U8 ## /< AttributeMask + descriptorLength*: U16 ## /< DescriptorLength + descriptor*: array[0x80, U8] ## /< Descriptor + keyType*: U8 ## /< KeyType + deviceType*: U8 ## /< DeviceType + brrSize*: U16 ## /< BrrSize + brr*: array[0x9, U8] ## /< Brr + anoSet7*: INNER_C_UNION_set_4 + + +## / Structure returned by \ref setsysGetFirmwareVersion. + +type + SetSysFirmwareVersion* {.bycopy.} = object + major*: U8 + minor*: U8 + micro*: U8 + padding1*: U8 + revisionMajor*: U8 + revisionMinor*: U8 + padding2*: U8 + padding3*: U8 + platform*: array[0x20, char] + versionHash*: array[0x40, char] + displayVersion*: array[0x18, char] + displayTitle*: array[0x80, char] + + +## / Structure returned by \ref setsysGetFirmwareVersionDigest. + +type + SetSysFirmwareVersionDigest* {.bycopy.} = object + digest*: array[0x40, char] + + +## / Structure returned by \ref setsysGetSerialNumber. + +type + SetSysSerialNumber* {.bycopy.} = object + number*: array[0x18, char] + + +## / DeviceNickName + +type + SetSysDeviceNickName* {.bycopy.} = object + nickname*: array[0x80, char] + + +## / UserSelectorSettings + +type + SetSysUserSelectorSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with \ref SetSysUserSelectorFlag. + + +## / AccountSettings + +type + SetSysAccountSettings* {.bycopy.} = object + settings*: SetSysUserSelectorSettings + + SetSysAudioVolume* {.bycopy.} = object + unkX0*: U32 ## /< 0 for Console and Tv, 2 for Headphones. + volume*: U8 ## /< From 0-15. + + +## / EulaVersion + +type + SetSysEulaVersion* {.bycopy.} = object + version*: U32 + regionCode*: S32 + clockType*: S32 ## /< \ref SetSysEulaVersionClockType + pad*: U32 + networkClockTime*: U64 ## /< POSIX timestamp. + steadyClockTime*: TimeSteadyClockTimePoint ## /< \ref TimeSteadyClockTimePoint + + +## / NotificationTime + +type + SetSysNotificationTime* {.bycopy.} = object + hour*: S32 + minute*: S32 + + +## / NotificationSettings + +type + SetSysNotificationSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with NotificationFlag. + volume*: S32 ## /< \ref SetSysNotificationVolume + startTime*: SetSysNotificationTime ## /< \ref SetSysNotificationTime + endTime*: SetSysNotificationTime ## /< \ref SetSysNotificationTime + + +## / AccountNotificationSettings + +type + SetSysAccountNotificationSettings* {.bycopy.} = object + uid*: AccountUid ## /< \ref AccountUid + flags*: U32 ## /< Bitmask with AccountNotificationFlag. + friendPresenceOverlayPermission*: S8 ## /< \ref SetSysFriendPresenceOverlayPermission + pad*: array[3, U8] ## /< Padding. + + +## / TvSettings + +type + INNER_C_STRUCT_set_13* {.bycopy.} = object + svdIndex* {.bitsize: 7.}: U8 + nativeFlag* {.bitsize: 1.}: U8 + + INNER_C_STRUCT_set_12* {.bycopy.} = object + size* {.bitsize: 5.}: U8 + blockType* {.bitsize: 3.}: SetSysBlockType + svd*: array[0xC, INNER_C_STRUCT_set_13] + + INNER_C_STRUCT_set_14* {.bycopy.} = object + size* {.bitsize: 5.}: U8 + blockType* {.bitsize: 3.}: SetSysBlockType + channelCount* {.bitsize: 3.}: U8 + formatCode* {.bitsize: 4.}: U8 + padding1* {.bitsize: 1.}: U8 + samplingRatesBitmap*: U8 + bitrate*: U8 + + INNER_C_STRUCT_set_15* {.bycopy.} = object + size* {.bitsize: 5.}: U8 + blockType* {.bitsize: 3.}: SetSysBlockType + ieeeRegistrationId*: array[3, U8] + sourcePhysicalAddress*: U16 + modeBitmap*: U8 + maxTmdsFrequency*: U8 + latencyBitmap*: U8 + + SetSysTvSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with TvFlag. + tvResolution*: S32 ## /< \ref SetSysTvResolution + hdmiContentType*: S32 ## /< \ref SetSysHdmiContentType + rgbRange*: S32 ## /< \ref SetSysRgbRange + cmuMode*: S32 ## /< \ref SetSysCmuMode + underscan*: U32 ## /< Underscan. + gamma*: cfloat ## /< Gamma. + contrast*: cfloat ## /< Contrast. + + SetSysModeLine* {.bycopy.} = object + pixelClock*: U16 ## /< In 10 kHz units. + horizontalActivePixelsLsb*: U8 + horizontalBlankingPixelsLsb*: U8 + horizontalBlankingPixelsMsb* {.bitsize: 4.}: U8 + horizontalActivePixelsMsb* {.bitsize: 4.}: U8 + verticalActiveLinesLsb*: U8 + verticalBlankingLinesLsb*: U8 + verticalBlankingLinesMsb* {.bitsize: 4.}: U8 + verticalActiveLinesMsb* {.bitsize: 4.}: U8 + horizontalSyncOffsetPixelsLsb*: U8 + horizontalSyncPulseWidthPixelsLsb*: U8 + horizontalSyncPulseWidthLinesLsb* {.bitsize: 4.}: U8 + horizontalSyncOffsetLinesLsb* {.bitsize: 4.}: U8 + verticalSyncPulseWidthLinesMsb* {.bitsize: 2.}: U8 + verticalSyncOffsetLinesMsb* {.bitsize: 2.}: U8 + horizontalSyncPulseWidthPixelsMsb* {.bitsize: 2.}: U8 + horizontalSyncOffsetPixelsMsb* {.bitsize: 2.}: U8 + horizontalImageSizeMmLsb*: U8 + verticalImageSizeMmLsb*: U8 + verticalImageSizeMmMsb* {.bitsize: 4.}: U8 + horizontalImageSizeMmMsb* {.bitsize: 4.}: U8 + horizontalBorderPixels*: U8 + verticalBorderLines*: U8 + featuresBitmap0* {.bitsize: 1.}: U8 + featuresBitmap1* {.bitsize: 1.}: U8 + featuresBitmap2* {.bitsize: 1.}: U8 + featuresBitmap34* {.bitsize: 2.}: U8 + featuresBitmap56* {.bitsize: 2.}: U8 + interlaced* {.bitsize: 1.}: U8 + + SetSysDataBlock* {.bycopy.} = object + video*: INNER_C_STRUCT_set_12 + audio*: INNER_C_STRUCT_set_14 + vendorSpecific*: INNER_C_STRUCT_set_15 + padding*: array[2, U8] + + +## / Edid + +type + INNER_C_STRUCT_set_20* {.bycopy.} = object + greenYLsb* {.bitsize: 2.}: U8 + greenXLsb* {.bitsize: 2.}: U8 + redYLsb* {.bitsize: 2.}: U8 + redXLsb* {.bitsize: 2.}: U8 + blueLsb* {.bitsize: 4.}: U8 + whiteLsb* {.bitsize: 4.}: U8 + redXMsb*: U8 + redYMsb*: U8 + greenXMsb*: U8 + greenYMsb*: U8 + blueXMsb*: U8 + blueYMsb*: U8 + whiteXMsb*: U8 + whiteYMsb*: U8 + + INNER_C_STRUCT_set_21* {.bycopy.} = object + xResolution*: U8 ## /< Real value is (val + 31) * 8 pixels. + verticalFrequency* {.bitsize: 6.}: U8 ## /< Real value is val + 60 Hz. + aspectRatio* {.bitsize: 2.}: U8 ## /< 0 = 16:10, 1 = 4:3, 2 = 5:4, 3 = 16:9. + + INNER_C_STRUCT_set_22* {.bycopy.} = object + displayDescriptorZero*: U16 + padding1*: U8 + descriptorType*: U8 + padding2*: U8 + name*: array[0xD, char] + + INNER_C_STRUCT_set_23* {.bycopy.} = object + displayDescriptorZero*: U16 + padding1*: U8 + descriptorType*: U8 + rangeLimitOffsets*: U8 + verticalFieldRateMin*: U8 + verticalFieldRateMax*: U8 + horizontalLineRateMin*: U8 + horizontalLineRateMax*: U8 + pixelClockRateMax*: U8 ## /< Rounded up to multiples of 10 MHz. + extendedTimingInfo*: U8 + padding*: array[7, U8] + + SetSysEdid* {.bycopy.} = object + pattern*: array[8, U8] ## /< Fixed pattern 00 FF FF FF FF FF FF 00. + pnpId*: U16 ## /< Big-endian set of 3 5-bit values representing letters, 1 = A .. 26 = Z. + productCode*: U16 + serialNumber*: U32 + manufactureWeek*: U8 + manufactureYear*: U8 + edidVersion*: U8 + edidRevision*: U8 + videoInputParametersBitmap*: U8 + displayWidth*: U8 + displayHeight*: U8 + displayGamma*: U8 + supportedFeaturesBitmap*: U8 + chromaticity*: INNER_C_STRUCT_set_20 + timingBitmap*: array[3, U8] + timingInfo*: array[8, INNER_C_STRUCT_set_21] + timingDescriptor*: array[2, SetSysModeLine] + displayDescriptorName*: INNER_C_STRUCT_set_22 + displayDescriptorRangeLimits*: INNER_C_STRUCT_set_23 + extensionCount*: U8 ## /< Always 1. + checksum*: U8 ## /< Sum of all 128 bytes should equal 0 mod 256. + ## /< Extended data. + extensionTag*: U8 ## /< Always 2 = CEA EDID timing extension. + revision*: U8 + dtdStart*: U8 + nativeDtdCount* {.bitsize: 4.}: U8 + nativeDtdFeatureBitmap* {.bitsize: 4.}: U8 + dataBlock*: SetSysDataBlock + extendedTimingDescriptor*: array[5, SetSysModeLine] + padding*: array[5, U8] + extendedChecksum*: U8 ## /< Sum of 128 extended bytes should equal 0 mod 256. + + +## / DataDeletionSettings + +type + SetSysDataDeletionSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with DataDeletionFlag. + useCount*: S32 ## /< Use count. + + +## / SleepSettings + +type + SetSysSleepSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with SleepFlag. + handheldSleepPlan*: S32 ## /< \ref SetSysHandheldSleepPlan + consoleSleepPlan*: S32 ## /< \ref SetSysConsoleSleepPlan + + +## / InitialLaunchSettings + +type + SetSysInitialLaunchSettings* {.bycopy.} = object + flags*: U32 ## /< Bitmask with InitialLaunchFlag. + pad*: U32 ## /< Padding. + timestamp*: TimeSteadyClockTimePoint ## /< \ref TimeSteadyClockTimePoint timestamp. + + +## / PtmFuelGaugeParameter + +type + SetSysPtmFuelGaugeParameter* {.bycopy.} = object + rcomp0*: U16 + tempc0*: U16 + fullcap*: U16 + fullcapnom*: U16 + lavgempty*: U16 + qresidual00*: U16 + qresidual10*: U16 + qresidual20*: U16 + qresidual30*: U16 + cycles*: U16 ## /< Normally keeps the cycles reg. Unused and contains stack garbage. + cyclesActual*: U32 ## /< Keeps track of cycles. The fuel gauge cycles reg is reset if > 2.00 cycles and added here. + + +## / Actually nn::util::Color4u8Type. + +type + SetSysColor4u8Type* {.bycopy.} = object + field*: array[4, U8] + + +## / NxControllerLegacySettings + +type + SetSysNxControllerLegacySettings* {.bycopy.} = object + address*: BtdrvAddress + `type`*: U8 ## /< \ref SetSysControllerType. + serial*: array[0x10, char] + bodyColor*: SetSysColor4u8Type + buttonColor*: SetSysColor4u8Type + unkX1F*: array[8, U8] + unkX27*: U8 + interfaceType*: U8 ## /< Bitmask with \ref XcdInterfaceType. + + +## / NxControllerSettings + +type + SetSysNxControllerSettings* {.bycopy.} = object + address*: BtdrvAddress + `type`*: U8 ## /< \ref SetSysControllerType. + serial*: array[0x10, char] + bodyColor*: SetSysColor4u8Type + buttonColor*: SetSysColor4u8Type + unkX1F*: array[8, U8] + unkX27*: U8 + interfaceType*: U8 ## /< Bitmask with \ref XcdInterfaceType. + unkX29*: array[0x403, U8] ## /< Unknown + + +## / ConsoleSixAxisSensorAccelerationBias + +type + SetSysConsoleSixAxisSensorAccelerationBias* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + + +## / ConsoleSixAxisSensorAngularVelocityBias + +type + SetSysConsoleSixAxisSensorAngularVelocityBias* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + + +## / ConsoleSixAxisSensorAccelerationGain + +type + SetSysConsoleSixAxisSensorAccelerationGain* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + unkXC*: cfloat + unkX10*: cfloat + unkX14*: cfloat + unkX18*: cfloat + unkX1C*: cfloat + unkX20*: cfloat + + +## / ConsoleSixAxisSensorAngularVelocityGain + +type + SetSysConsoleSixAxisSensorAngularVelocityGain* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + unkXC*: cfloat + unkX10*: cfloat + unkX14*: cfloat + unkX18*: cfloat + unkX1C*: cfloat + unkX20*: cfloat + + +## / AllowedSslHosts + +type + SetSysAllowedSslHosts* {.bycopy.} = object + hosts*: array[0x100, U8] + + +## / HostFsMountPoint + +type + SetSysHostFsMountPoint* {.bycopy.} = object + mount*: array[0x100, char] + + +## / BlePairingSettings + +type + SetSysBlePairingSettings* {.bycopy.} = object + address*: BtdrvAddress + unkX6*: U16 + unkX8*: U16 + unkXA*: U8 + unkXB*: U8 + unkXC*: U8 + unkXD*: U8 + unkXE*: U8 + unkXF*: U8 + padding*: array[0x70, U8] + + +## / ConsoleSixAxisSensorAngularVelocityTimeBias + +type + SetSysConsoleSixAxisSensorAngularVelocityTimeBias* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + + +## / ConsoleSixAxisSensorAngularAcceleration + +type + SetSysConsoleSixAxisSensorAngularAcceleration* {.bycopy.} = object + unkX0*: cfloat + unkX4*: cfloat + unkX8*: cfloat + unkXC*: cfloat + unkX10*: cfloat + unkX14*: cfloat + unkX18*: cfloat + unkX1C*: cfloat + unkX20*: cfloat + + +## / RebootlessSystemUpdateVersion. This is the content of the RebootlessSystemUpdateVersion SystemData, in the "/version" file. + +type + SetSysRebootlessSystemUpdateVersion* {.bycopy.} = object + version*: U32 + reserved*: array[0x1c, U8] + displayVersion*: array[0x20, char] + + +## / AccountOnlineStorageSettings + +type + SetSysAccountOnlineStorageSettings* {.bycopy.} = object + uid*: AccountUid ## /< \ref AccountUid + unkX10*: U32 + unkX14*: U32 + + +## / AnalogStickUserCalibration + +type + SetSysAnalogStickUserCalibration* {.bycopy.} = object + unkX0*: U16 + unkX2*: U16 + unkX4*: U16 + unkX6*: U16 + unkX8*: U16 + unkXA*: U16 + unkXC*: U16 + unkXE*: U16 + + +## / ThemeId + +type + SetSysThemeId* {.bycopy.} = object + themeId*: array[0x10, U64] + + +## / ThemeSettings + +type + SetSysThemeSettings* {.bycopy.} = object + themeSettings*: U64 + + +## / Output from \ref setsysGetHomeMenuScheme. This contains RGBA8 colors which correspond with the physical shell of the system. + +type + SetSysHomeMenuScheme* {.bycopy.} = object + mainColor*: U32 ## /< Main Color. + backColor*: U32 ## /< Back Color. + subColor*: U32 ## /< Sub Color. + bezelColor*: U32 ## /< Bezel Color. + extraColor*: U32 ## /< Extra Color. + + +## / ButtonConfigSettings + +type + SetSysButtonConfigSettings* {.bycopy.} = object + settings*: array[0x5A8, U8] + + +## / ButtonConfigRegisteredSettings + +type + SetSysButtonConfigRegisteredSettings* {.bycopy.} = object + settings*: array[0x5C8, U8] + + SetCalAccelerometerOffset* {.bycopy.} = object + offset*: array[0x6, U8] + + SetCalAccelerometerScale* {.bycopy.} = object + scale*: array[0x6, U8] + + SetCalAmiiboEcdsaCertificate* {.bycopy.} = object + size*: U32 + cert*: array[0x70, U8] + + SetCalAmiiboEcqvBlsCertificate* {.bycopy.} = object + size*: U32 + cert*: array[0x20, U8] + + SetCalAmiiboEcqvBlsKey* {.bycopy.} = object + size*: U32 + key*: array[0x40, U8] + generation*: U32 + + SetCalAmiiboEcqvBlsRootCertificate* {.bycopy.} = object + size*: U32 + cert*: array[0x90, U8] + + SetCalAmiiboEcqvCertificate* {.bycopy.} = object + size*: U32 + cert*: array[0x14, U8] + + SetCalAmiiboKey* {.bycopy.} = object + size*: U32 + key*: array[0x50, U8] + generation*: U32 + + SetCalAnalogStickFactoryCalibration* {.bycopy.} = object + calibration*: array[0x9, U8] + + SetCalAnalogStickModelParameter* {.bycopy.} = object + parameter*: array[0x12, U8] + + SetCalBdAddress* {.bycopy.} = object + bdAddr*: array[0x6, U8] + + SetCalConfigurationId1* {.bycopy.} = object + cfg*: array[0x1E, U8] + + SetCalConsoleSixAxisSensorHorizontalOffset* {.bycopy.} = object + offset*: array[0x6, U8] + + SetCalCountryCode* {.bycopy.} = object + code*: array[0x3, char] ## /< Country code. + + SetCalEccB233DeviceCertificate* {.bycopy.} = object + cert*: array[0x180, U8] + + SetCalEccB233DeviceKey* {.bycopy.} = object + size*: U32 + key*: array[0x50, U8] + generation*: U32 + + SetCalGameCardCertificate* {.bycopy.} = object + cert*: array[0x400, U8] + + SetCalGameCardKey* {.bycopy.} = object + size*: U32 ## /< Size of the entire key. + key*: array[0x130, U8] + generation*: U32 + + SetCalGyroscopeOffset* {.bycopy.} = object + offset*: array[0x6, U8] + + SetCalGyroscopeScale* {.bycopy.} = object + scale*: array[0x6, U8] + + SetCalMacAddress* {.bycopy.} = object + `addr`*: array[0x6, U8] ## /< Mac address. + + SetCalRsa2048DeviceCertificate* {.bycopy.} = object + cert*: array[0x240, U8] + + SetCalRsa2048DeviceKey* {.bycopy.} = object + size*: U32 ## /< Size of the entire key. + key*: array[0x240, U8] + generation*: U32 + + SetCalSerialNumber* = SetSysSerialNumber + SetCalSpeakerParameter* {.bycopy.} = object + parameter*: array[0x5A, U8] + + SetCalSslCertificate* {.bycopy.} = object + size*: U32 ## /< Size of the certificate data. + cert*: array[0x800, U8] + + SetCalSslKey* {.bycopy.} = object + size*: U32 ## /< Size of the entire key. + key*: array[0x130, U8] + generation*: U32 + + SetCalRegionCode* {.bycopy.} = object + code*: U32 ## /< Region code. + +proc setInitialize*(): Result {.cdecl, importc: "setInitialize".} +## / Initialize set. + +proc setExit*() {.cdecl, importc: "setExit".} +## / Exit set. + +proc setGetServiceSession*(): ptr Service {.cdecl, importc: "setGetServiceSession".} +## / Gets the Service object for the actual set service session. + +proc setMakeLanguage*(languageCode: U64; language: ptr SetLanguage): Result {.cdecl, + importc: "setMakeLanguage".} +## / Converts LanguageCode to \ref SetLanguage. + +proc setMakeLanguageCode*(language: SetLanguage; languageCode: ptr U64): Result {. + cdecl, importc: "setMakeLanguageCode".} +## / Converts \ref SetLanguage to LanguageCode. + +proc setGetSystemLanguage*(languageCode: ptr U64): Result {.cdecl, + importc: "setGetSystemLanguage".} +## / Gets the current system LanguageCode. +## / Normally this should be used instead of \ref setGetLanguageCode. +## / LanguageCode is a string, see here: https://switchbrew.org/wiki/Settings_services#LanguageCode + +proc setGetLanguageCode*(languageCode: ptr U64): Result {.cdecl, + importc: "setGetLanguageCode".} +## / Gets the current LanguageCode, \ref setGetSystemLanguage should be used instead normally. + +proc setGetAvailableLanguageCodes*(totalEntries: ptr S32; languageCodes: ptr U64; + maxEntries: csize_t): Result {.cdecl, + importc: "setGetAvailableLanguageCodes".} +## / Gets available LanguageCodes. +## / On system-version <4.0.0, max_entries is set to the output from \ref setGetAvailableLanguageCodeCount if max_entries is larger than that. + +proc setGetAvailableLanguageCodeCount*(total: ptr S32): Result {.cdecl, + importc: "setGetAvailableLanguageCodeCount".} +## / Gets total available LanguageCodes. +## / Output total is overridden with value 0 if the total is <0. + +proc setGetRegionCode*(`out`: ptr SetRegion): Result {.cdecl, + importc: "setGetRegionCode".} +## / Gets the RegionCode. + +proc setGetQuestFlag*(`out`: ptr bool): Result {.cdecl, importc: "setGetQuestFlag".} +## * +## @brief GetQuestFlag +## @note Only available on [5.0.0+]. +## @param[out] out Output flag. +## + +proc setGetDeviceNickname*(nickname: ptr SetSysDeviceNickName): Result {.cdecl, + importc: "setGetDeviceNickname".} +## * +## @brief Gets the system's nickname. +## @note Only available on [10.1.0+]. +## @param[out] nickname \ref SetSysDeviceNickName +## + +proc setsysInitialize*(): Result {.cdecl, importc: "setsysInitialize".} +## / Initialize setsys. + +proc setsysExit*() {.cdecl, importc: "setsysExit".} +## / Exit setsys. + +proc setsysGetServiceSession*(): ptr Service {.cdecl, + importc: "setsysGetServiceSession".} +## / Gets the Service object for the actual setsys service session. + +proc setsysSetLanguageCode*(languageCode: U64): Result {.cdecl, + importc: "setsysSetLanguageCode".} +## * +## @brief SetLanguageCode +## @param[in] LanguageCode LanguageCode. +## + +proc setsysSetNetworkSettings*(settings: ptr SetSysNetworkSettings; count: S32): Result {. + cdecl, importc: "setsysSetNetworkSettings".} +## * +## @brief SetNetworkSettings +## @param[in] settings Input array of \ref SetSysNetworkSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetNetworkSettings*(totalOut: ptr S32; + settings: ptr SetSysNetworkSettings; count: S32): Result {. + cdecl, importc: "setsysGetNetworkSettings".} +## * +## @brief GetNetworkSettings +## @param[out] total_out Total output entries. +## @param[out] versions Output array of \ref SetSysNetworkSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetFirmwareVersion*(`out`: ptr SetSysFirmwareVersion): Result {.cdecl, + importc: "setsysGetFirmwareVersion".} +## * +## @brief Gets the system firmware version. +## @param[out] out Firmware version to populate. +## + +proc setsysGetFirmwareVersionDigest*(`out`: ptr SetSysFirmwareVersionDigest): Result {. + cdecl, importc: "setsysGetFirmwareVersionDigest".} +## * +## @brief GetFirmwareVersionDigest +## @param[out] out \ref SetSysFirmwareVersionDigest +## + +proc setsysGetLockScreenFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetLockScreenFlag".} +## * +## @brief GetLockScreenFlag +## @param[out] out Output flag. +## + +proc setsysSetLockScreenFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetLockScreenFlag".} +## * +## @brief SetLockScreenFlag +## @param[in] flag Input flag. +## + +proc setsysGetBacklightSettings*(`out`: ptr SetSysBacklightSettings): Result {.cdecl, + importc: "setsysGetBacklightSettings".} +## * +## @brief GetBacklightSettings +## @param[out] out \ref SetSysBacklightSettings +## + +proc setsysSetBacklightSettings*(settings: ptr SetSysBacklightSettings): Result {. + cdecl, importc: "setsysSetBacklightSettings".} +## * +## @brief SetBacklightSettings +## @param[in] settings \ref SetSysBacklightSettings +## + +proc setsysSetBluetoothDevicesSettings*(settings: ptr SetSysBluetoothDevicesSettings; + count: S32): Result {.cdecl, + importc: "setsysSetBluetoothDevicesSettings".} +## * +## @brief SetBluetoothDevicesSettings +## @param[in] settings Input array of \ref SetSysBluetoothDevicesSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetBluetoothDevicesSettings*(totalOut: ptr S32; settings: ptr SetSysBluetoothDevicesSettings; + count: S32): Result {.cdecl, + importc: "setsysGetBluetoothDevicesSettings".} +## * +## @brief GetBluetoothDevicesSettings +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysBluetoothDevicesSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetExternalSteadyClockSourceId*(`out`: ptr Uuid): Result {.cdecl, + importc: "setsysGetExternalSteadyClockSourceId".} +## * +## @brief GetExternalSteadyClockSourceId +## @param[out] out \ref Uuid +## + +proc setsysSetExternalSteadyClockSourceId*(uuid: ptr Uuid): Result {.cdecl, + importc: "setsysSetExternalSteadyClockSourceId".} +## * +## @brief SetExternalSteadyClockSourceId +## @param[in] uuid \ref Uuid +## + +proc setsysGetUserSystemClockContext*(`out`: ptr TimeSystemClockContext): Result {. + cdecl, importc: "setsysGetUserSystemClockContext".} +## * +## @brief GetUserSystemClockContext +## @param[out] out \ref TimeSystemClockContext +## + +proc setsysSetUserSystemClockContext*(context: ptr TimeSystemClockContext): Result {. + cdecl, importc: "setsysSetUserSystemClockContext".} +## * +## @brief SetUserSystemClockContext +## @param[in] context \ref TimeSystemClockContext +## + +proc setsysGetAccountSettings*(`out`: ptr SetSysAccountSettings): Result {.cdecl, + importc: "setsysGetAccountSettings".} +## * +## @brief GetAccountSettings +## @param[out] out \ref SetSysAccountSettings +## + +proc setsysSetAccountSettings*(settings: SetSysAccountSettings): Result {.cdecl, + importc: "setsysSetAccountSettings".} +## * +## @brief SetAccountSettings +## @param[in] settings \ref SetSysAccountSettings +## + +proc setsysGetAudioVolume*(device: SetSysAudioDevice; `out`: ptr SetSysAudioVolume): Result {. + cdecl, importc: "setsysGetAudioVolume".} +## * +## @brief GetAudioVolume +## @param[in] device \ref SetSysAudioDevice +## @param[out] out \ref SetSysAudioVolume +## + +proc setsysSetAudioVolume*(device: SetSysAudioDevice; volume: ptr SetSysAudioVolume): Result {. + cdecl, importc: "setsysSetAudioVolume".} +## * +## @brief SetAudioVolume +## @param[in] device \ref SetSysAudioDevice +## @param[in] volume \ref SetSysAudioVolume +## + +proc setsysGetEulaVersions*(totalOut: ptr S32; versions: ptr SetSysEulaVersion; + count: S32): Result {.cdecl, + importc: "setsysGetEulaVersions".} +## * +## @brief GetEulaVersions +## @param[out] total_out Total output entries. +## @param[out] versions Output array of \ref SetSysEulaVersion. +## @param[in] count Size of the versions array in entries. +## + +proc setsysSetEulaVersions*(versions: ptr SetSysEulaVersion; count: S32): Result {. + cdecl, importc: "setsysSetEulaVersions".} +## * +## @brief SetEulaVersions +## @param[in] versions Input array of \ref SetSysEulaVersion. +## @param[in] count Size of the versions array in entries. +## + +proc setsysGetColorSetId*(`out`: ptr ColorSetId): Result {.cdecl, + importc: "setsysGetColorSetId".} +## / Gets the current system theme. + +proc setsysSetColorSetId*(id: ColorSetId): Result {.cdecl, + importc: "setsysSetColorSetId".} +## / Sets the current system theme. + +proc setsysGetConsoleInformationUploadFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetConsoleInformationUploadFlag".} +## * +## @brief GetConsoleInformationUploadFlag +## @param[out] out Output flag. +## + +proc setsysSetConsoleInformationUploadFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetConsoleInformationUploadFlag".} +## * +## @brief SetConsoleInformationUploadFlag +## @param[in] flag Input flag. +## + +proc setsysGetAutomaticApplicationDownloadFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetAutomaticApplicationDownloadFlag".} +## * +## @brief GetAutomaticApplicationDownloadFlag +## @param[out] out Output flag. +## + +proc setsysSetAutomaticApplicationDownloadFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetAutomaticApplicationDownloadFlag".} +## * +## @brief SetAutomaticApplicationDownloadFlag +## @param[in] flag Input flag. +## + +proc setsysGetNotificationSettings*(`out`: ptr SetSysNotificationSettings): Result {. + cdecl, importc: "setsysGetNotificationSettings".} +## * +## @brief GetNotificationSettings +## @param[out] out \ref SetSysNotificationSettings +## + +proc setsysSetNotificationSettings*(settings: ptr SetSysNotificationSettings): Result {. + cdecl, importc: "setsysSetNotificationSettings".} +## * +## @brief SetNotificationSettings +## @param[in] settings \ref SetSysNotificationSettings +## + +proc setsysGetAccountNotificationSettings*(totalOut: ptr S32; + settings: ptr SetSysAccountNotificationSettings; count: S32): Result {.cdecl, + importc: "setsysGetAccountNotificationSettings".} +## * +## @brief GetAccountNotificationSettings +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysAccountNotificationSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetAccountNotificationSettings*( + settings: ptr SetSysAccountNotificationSettings; count: S32): Result {.cdecl, + importc: "setsysSetAccountNotificationSettings".} +## * +## @brief SetAccountNotificationSettings +## @param[in] settings Input array of \ref SetSysAccountNotificationSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetVibrationMasterVolume*(`out`: ptr cfloat): Result {.cdecl, + importc: "setsysGetVibrationMasterVolume".} +## * +## @brief GetVibrationMasterVolume +## @param[out] out Output volume. +## + +proc setsysSetVibrationMasterVolume*(volume: cfloat): Result {.cdecl, + importc: "setsysSetVibrationMasterVolume".} +## * +## @brief SetVibrationMasterVolume +## @param[in] volume Input volume. +## + +proc setsysGetSettingsItemValueSize*(name: cstring; itemKey: cstring; + sizeOut: ptr U64): Result {.cdecl, + importc: "setsysGetSettingsItemValueSize".} +## * +## @brief Gets the size of a settings item value. +## @param name Name string. +## @param item_key Item key string. +## @param size_out Pointer to output the size to. +## + +proc setsysGetSettingsItemValue*(name: cstring; itemKey: cstring; valueOut: pointer; + valueOutSize: csize_t; sizeOut: ptr U64): Result {. + cdecl, importc: "setsysGetSettingsItemValue".} +## * +## @brief Gets the value of a settings item. +## @param name Name string. +## @param item_key Item key string. +## @param value_out Pointer to output the value to. +## @param value_out_size Size of the value_out buffer. +## @param size_out Total size which was copied to value_out. +## + +proc setsysGetTvSettings*(`out`: ptr SetSysTvSettings): Result {.cdecl, + importc: "setsysGetTvSettings".} +## * +## @brief GetTvSettings +## @param[out] out \ref SetSysTvSettings +## + +proc setsysSetTvSettings*(settings: ptr SetSysTvSettings): Result {.cdecl, + importc: "setsysSetTvSettings".} +## * +## @brief SetTvSettings +## @param[in] settings \ref SetSysTvSettings +## + +proc setsysGetEdid*(`out`: ptr SetSysEdid): Result {.cdecl, importc: "setsysGetEdid".} +## * +## @brief GetEdid +## @param[out] out \ref SetSysEdid +## + +proc setsysSetEdid*(edid: ptr SetSysEdid): Result {.cdecl, importc: "setsysSetEdid".} +## * +## @brief SetEdid +## @param[in] edid \ref SetSysEdid +## + +proc setsysGetAudioOutputMode*(target: SetSysAudioOutputModeTarget; + `out`: ptr SetSysAudioOutputMode): Result {.cdecl, + importc: "setsysGetAudioOutputMode".} +## * +## @brief GetAudioOutputMode +## @param[in] target \ref SetSysAudioOutputModeTarget +## @param[out] out \ref SetSysAudioOutputMode +## + +proc setsysSetAudioOutputMode*(target: SetSysAudioOutputModeTarget; + mode: SetSysAudioOutputMode): Result {.cdecl, + importc: "setsysSetAudioOutputMode".} +## * +## @brief SetAudioOutputMode +## @param[in] target \ref SetSysAudioOutputModeTarget +## @param[in] mode \ref SetSysAudioOutputMode +## + +proc setsysGetSpeakerAutoMuteFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetSpeakerAutoMuteFlag".} +## * +## @brief GetSpeakerAutoMuteFlag +## @param[out] out Output flag. +## + +proc setsysSetSpeakerAutoMuteFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetSpeakerAutoMuteFlag".} +## * +## @brief SetSpeakerAutoMuteFlag +## @param[in] flag Input flag. +## + +proc setsysGetQuestFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetQuestFlag".} +## * +## @brief GetQuestFlag +## @param[out] out Output flag. +## + +proc setsysSetQuestFlag*(flag: bool): Result {.cdecl, importc: "setsysSetQuestFlag".} +## * +## @brief SetQuestFlag +## @param[in] flag Input flag. +## + +proc setsysGetDataDeletionSettings*(`out`: ptr SetSysDataDeletionSettings): Result {. + cdecl, importc: "setsysGetDataDeletionSettings".} +## * +## @brief GetDataDeletionSettings +## @param[out] out \ref SetSysDataDeletionSettings +## + +proc setsysSetDataDeletionSettings*(settings: ptr SetSysDataDeletionSettings): Result {. + cdecl, importc: "setsysSetDataDeletionSettings".} +## * +## @brief SetDataDeletionSettings +## @param[in] settings \ref SetSysDataDeletionSettings +## + +proc setsysGetInitialSystemAppletProgramId*(`out`: ptr U64): Result {.cdecl, + importc: "setsysGetInitialSystemAppletProgramId".} +## * +## @brief GetInitialSystemAppletProgramId +## @param[out] out output ProgramId. +## + +proc setsysGetOverlayDispProgramId*(`out`: ptr U64): Result {.cdecl, + importc: "setsysGetOverlayDispProgramId".} +## * +## @brief GetOverlayDispProgramId +## @param[out] out output ProgramId. +## + +proc setsysGetDeviceTimeZoneLocationName*(`out`: ptr TimeLocationName): Result {. + cdecl, importc: "setsysGetDeviceTimeZoneLocationName".} +## * +## @brief GetDeviceTimeZoneLocationName +## @param[out] out \ref TimeLocationName +## + +proc setsysSetDeviceTimeZoneLocationName*(name: ptr TimeLocationName): Result {. + cdecl, importc: "setsysSetDeviceTimeZoneLocationName".} +## * +## @brief SetDeviceTimeZoneLocationName +## @param[in] name \ref TimeLocationName +## + +proc setsysGetWirelessCertificationFileSize*(outSize: ptr U64): Result {.cdecl, + importc: "setsysGetWirelessCertificationFileSize".} +## * +## @brief GetWirelessCertificationFileSize +## @param[out] out_size Output size. +## + +proc setsysGetWirelessCertificationFile*(buffer: pointer; size: csize_t; + outSize: ptr U64): Result {.cdecl, + importc: "setsysGetWirelessCertificationFile".} +## * +## @brief GetWirelessCertificationFile +## @param[out] buffer Output buffer. +## @param[in] size Output buffer size. +## @param[out] out_size Output size. +## + +proc setsysSetRegionCode*(region: SetRegion): Result {.cdecl, + importc: "setsysSetRegionCode".} +## * +## @brief SetRegionCode +## @param[in] region \ref SetRegion +## + +proc setsysGetNetworkSystemClockContext*(`out`: ptr TimeSystemClockContext): Result {. + cdecl, importc: "setsysGetNetworkSystemClockContext".} +## * +## @brief GetNetworkSystemClockContext +## @param[out] out \ref TimeSystemClockContext +## + +proc setsysSetNetworkSystemClockContext*(context: ptr TimeSystemClockContext): Result {. + cdecl, importc: "setsysSetNetworkSystemClockContext".} +## * +## @brief SetNetworkSystemClockContext +## @param[in] context \ref TimeSystemClockContext +## + +proc setsysIsUserSystemClockAutomaticCorrectionEnabled*(`out`: ptr bool): Result {. + cdecl, importc: "setsysIsUserSystemClockAutomaticCorrectionEnabled".} +## * +## @brief IsUserSystemClockAutomaticCorrectionEnabled +## @param[out] out Output flag. +## + +proc setsysSetUserSystemClockAutomaticCorrectionEnabled*(flag: bool): Result {. + cdecl, importc: "setsysSetUserSystemClockAutomaticCorrectionEnabled".} +## * +## @brief SetUserSystemClockAutomaticCorrectionEnabled +## @param[in] flag Input flag. +## + +proc setsysGetDebugModeFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetDebugModeFlag".} +## * +## @brief GetDebugModeFlag +## @param[out] out Output flag. +## + +proc setsysGetPrimaryAlbumStorage*(`out`: ptr SetSysPrimaryAlbumStorage): Result {. + cdecl, importc: "setsysGetPrimaryAlbumStorage".} +## * +## @brief GetPrimaryAlbumStorage +## @param[out] out \ref GetPrimaryAlbumStorage +## + +proc setsysSetPrimaryAlbumStorage*(storage: SetSysPrimaryAlbumStorage): Result {. + cdecl, importc: "setsysSetPrimaryAlbumStorage".} +## * +## @brief SetPrimaryAlbumStorage +## @param[in] storage \ref SetSysPrimaryAlbumStorage +## + +proc setsysGetUsb30EnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetUsb30EnableFlag".} +## * +## @brief GetUsb30EnableFlag +## @param[out] out Output flag. +## + +proc setsysSetUsb30EnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetUsb30EnableFlag".} +## * +## @brief SetUsb30EnableFlag +## @param[in] flag Input flag. +## + +proc setsysGetBatteryLot*(`out`: ptr SetBatteryLot): Result {.cdecl, + importc: "setsysGetBatteryLot".} +## * +## @brief Gets the \ref SetBatteryLot. +## @param[out] out \ref SetBatteryLot +## + +proc setsysGetSerialNumber*(`out`: ptr SetSysSerialNumber): Result {.cdecl, + importc: "setsysGetSerialNumber".} +## * +## @brief Gets the system's serial number. +## @param[out] out \ref SetSysSerialNumber +## + +proc setsysGetNfcEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetNfcEnableFlag".} +## * +## @brief GetNfcEnableFlag +## @param[out] out Output flag. +## + +proc setsysSetNfcEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetNfcEnableFlag".} +## * +## @brief SetNfcEnableFlag +## @param[in] flag Input flag. +## + +proc setsysGetSleepSettings*(`out`: ptr SetSysSleepSettings): Result {.cdecl, + importc: "setsysGetSleepSettings".} +## * +## @brief GetSleepSettings +## @param[out] out \ref SetSysSleepSettings +## + +proc setsysSetSleepSettings*(settings: ptr SetSysSleepSettings): Result {.cdecl, + importc: "setsysSetSleepSettings".} +## * +## @brief SetSleepSettings +## @param[in] settings \ref SetSysSleepSettings +## + +proc setsysGetWirelessLanEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetWirelessLanEnableFlag".} +## * +## @brief GetWirelessLanEnableFlag +## @param[out] out Output flag. +## + +proc setsysSetWirelessLanEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetWirelessLanEnableFlag".} +## * +## @brief SetWirelessLanEnableFlag +## @param[in] flag Input flag. +## + +proc setsysGetInitialLaunchSettings*(`out`: ptr SetSysInitialLaunchSettings): Result {. + cdecl, importc: "setsysGetInitialLaunchSettings".} +## * +## @brief GetInitialLaunchSettings +## @param[out] out \ref SetSysInitialLaunchSettings +## + +proc setsysSetInitialLaunchSettings*(settings: ptr SetSysInitialLaunchSettings): Result {. + cdecl, importc: "setsysSetInitialLaunchSettings".} +## * +## @brief SetInitialLaunchSettings +## @param[in] settings \ref SetSysInitialLaunchSettings +## + +proc setsysGetDeviceNickname*(nickname: ptr SetSysDeviceNickName): Result {.cdecl, + importc: "setsysGetDeviceNickname".} +## * +## @brief Gets the system's nickname. +## @note Same as \ref setGetDeviceNickname, which official sw uses instead on [10.1.0+]. +## @param[out] nickname \ref SetSysDeviceNickName +## + +proc setsysSetDeviceNickname*(nickname: ptr SetSysDeviceNickName): Result {.cdecl, + importc: "setsysSetDeviceNickname".} +## * +## @brief Sets the system's nickname. +## @param[in] nickname \ref SetSysDeviceNickName +## + +proc setsysGetProductModel*(model: ptr SetSysProductModel): Result {.cdecl, + importc: "setsysGetProductModel".} +## * +## @brief GetProductModel +## @param[out] model Output SetSysProductModel. +## + +proc setsysGetLdnChannel*(`out`: ptr S32): Result {.cdecl, + importc: "setsysGetLdnChannel".} +## * +## @brief GetLdnChannel +## @param[out] out Output LdnChannel. +## + +proc setsysSetLdnChannel*(channel: S32): Result {.cdecl, + importc: "setsysSetLdnChannel".} +## * +## @brief SetLdnChannel +## @param[in] channel Input LdnChannel. +## + +proc setsysAcquireTelemetryDirtyFlagEventHandle*(outEvent: ptr Event): Result {. + cdecl, importc: "setsysAcquireTelemetryDirtyFlagEventHandle".} +## * +## @brief Gets an event that settings will signal on flag change. +## @param out_event Event to bind. Output event will have autoclear=false. +## + +proc setsysGetTelemetryDirtyFlags*(flags0: ptr U64; flags1: ptr U64): Result {.cdecl, + importc: "setsysGetTelemetryDirtyFlags".} +## * +## @brief Gets the settings flags that have changed. +## @param flags_0 Pointer to populate with first 64 flags. +## @param flags_1 Pointer to populate with second 64 flags. +## + +proc setsysGetPtmBatteryLot*(`out`: ptr SetBatteryLot): Result {.cdecl, + importc: "setsysGetPtmBatteryLot".} +## * +## @brief GetPtmBatteryLot +## @param[out] out \ref SetBatteryLot +## + +proc setsysSetPtmBatteryLot*(lot: ptr SetBatteryLot): Result {.cdecl, + importc: "setsysSetPtmBatteryLot".} +## * +## @brief SetPtmBatteryLot +## @param[in] lot \ref SetBatteryLot +## + +proc setsysGetPtmFuelGaugeParameter*(`out`: ptr SetSysPtmFuelGaugeParameter): Result {. + cdecl, importc: "setsysGetPtmFuelGaugeParameter".} +## * +## @brief GetPtmFuelGaugeParameter +## @param[out] out \ref SetSysPtmFuelGaugeParameter +## + +proc setsysSetPtmFuelGaugeParameter*(parameter: ptr SetSysPtmFuelGaugeParameter): Result {. + cdecl, importc: "setsysSetPtmFuelGaugeParameter".} +## * +## @brief SetPtmFuelGaugeParameter +## @param[in] parameter \ref SetSysPtmFuelGaugeParameter +## + +proc setsysGetBluetoothEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetBluetoothEnableFlag".} +## * +## @brief GetBluetoothEnableFlag +## @param[out] out Output flag. +## + +proc setsysSetBluetoothEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetBluetoothEnableFlag".} +## * +## @brief SetBluetoothEnableFlag +## @param[in] flag Input flag. +## + +proc setsysGetMiiAuthorId*(`out`: ptr Uuid): Result {.cdecl, + importc: "setsysGetMiiAuthorId".} +## * +## @brief GetMiiAuthorId +## @param[out] out Output MiiAuthorId. +## + +proc setsysSetShutdownRtcValue*(value: U64): Result {.cdecl, + importc: "setsysSetShutdownRtcValue".} +## * +## @brief SetShutdownRtcValue +## @param[in] value Input value. +## + +proc setsysGetShutdownRtcValue*(`out`: ptr U64): Result {.cdecl, + importc: "setsysGetShutdownRtcValue".} +## * +## @brief GetShutdownRtcValue +## @param[out] out Output value. +## + +proc setsysAcquireFatalDirtyFlagEventHandle*(outEvent: ptr Event): Result {.cdecl, + importc: "setsysAcquireFatalDirtyFlagEventHandle".} +## * +## @brief Gets an event that settings will signal on flag change. +## @param out_event Event to bind. Output event will have autoclear=false. +## + +proc setsysGetFatalDirtyFlags*(flags0: ptr U64; flags1: ptr U64): Result {.cdecl, + importc: "setsysGetFatalDirtyFlags".} +## * +## @brief Gets the settings flags that have changed. +## @param flags_0 Pointer to populate with first 64 flags. +## @param flags_1 Pointer to populate with second 64 flags. +## + +proc setsysGetAutoUpdateEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetAutoUpdateEnableFlag".} +## * +## @brief GetAutoUpdateEnableFlag +## @note Only available on [2.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetAutoUpdateEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetAutoUpdateEnableFlag".} +## * +## @brief SetAutoUpdateEnableFlag +## @note Only available on [2.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetNxControllerSettings*(totalOut: ptr S32; settings: ptr SetSysNxControllerLegacySettings; + count: S32): Result {.cdecl, + importc: "setsysGetNxControllerSettings".} +## * +## @brief GetNxControllerSettings +## @note On [13.0.0+] \ref setsysGetNxControllerSettingsEx should be used instead. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysNxControllerLegacySettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetNxControllerSettings*(settings: ptr SetSysNxControllerLegacySettings; + count: S32): Result {.cdecl, + importc: "setsysSetNxControllerSettings".} +## * +## @brief SetNxControllerSettings +## @note On [13.0.0+] \ref setsysSetNxControllerSettingsEx should be used instead. +## @param[in] settings Input array of \ref SetSysNxControllerLegacySettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetBatteryPercentageFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetBatteryPercentageFlag".} +## * +## @brief GetBatteryPercentageFlag +## @note Only available on [2.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetBatteryPercentageFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetBatteryPercentageFlag".} +## * +## @brief SetBatteryPercentageFlag +## @note Only available on [2.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetExternalRtcResetFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetExternalRtcResetFlag".} +## * +## @brief GetExternalRtcResetFlag +## @note Only available on [2.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetExternalRtcResetFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetExternalRtcResetFlag".} +## * +## @brief SetExternalRtcResetFlag +## @note Only available on [2.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetUsbFullKeyEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetUsbFullKeyEnableFlag".} +## * +## @brief GetUsbFullKeyEnableFlag +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetUsbFullKeyEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetUsbFullKeyEnableFlag".} +## * +## @brief SetUsbFullKeyEnableFlag +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysSetExternalSteadyClockInternalOffset*(offset: U64): Result {.cdecl, + importc: "setsysSetExternalSteadyClockInternalOffset".} +## * +## @brief SetExternalSteadyClockInternalOffset +## @note Only available on [3.0.0+]. +## @param[in] offset Input offset. +## + +proc setsysGetExternalSteadyClockInternalOffset*(`out`: ptr U64): Result {.cdecl, + importc: "setsysGetExternalSteadyClockInternalOffset".} +## * +## @brief GetExternalSteadyClockInternalOffset +## @note Only available on [3.0.0+]. +## @param[out] out Output offset. +## + +proc setsysGetBacklightSettingsEx*(`out`: ptr SetSysBacklightSettingsEx): Result {. + cdecl, importc: "setsysGetBacklightSettingsEx".} +## * +## @brief GetBacklightSettingsEx +## @note Only available on [3.0.0+]. +## @param[out] out \ref SetSysBacklightSettingsEx +## + +proc setsysSetBacklightSettingsEx*(settings: ptr SetSysBacklightSettingsEx): Result {. + cdecl, importc: "setsysSetBacklightSettingsEx".} +## * +## @brief SetBacklightSettingsEx +## @note Only available on [3.0.0+]. +## @param[in] settings \ref SetSysBacklightSettingsEx +## + +proc setsysGetHeadphoneVolumeWarningCount*(`out`: ptr U32): Result {.cdecl, + importc: "setsysGetHeadphoneVolumeWarningCount".} +## * +## @brief GetHeadphoneVolumeWarningCount +## @note Only available on [3.0.0+]. +## @param[out] out Output count. +## + +proc setsysSetHeadphoneVolumeWarningCount*(count: U32): Result {.cdecl, + importc: "setsysSetHeadphoneVolumeWarningCount".} +## * +## @brief SetHeadphoneVolumeWarningCount +## @note Only available on [3.0.0+]. +## @param[in] count Input count. +## + +proc setsysGetBluetoothAfhEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetBluetoothAfhEnableFlag".} +## * +## @brief GetBluetoothAfhEnableFlag +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetBluetoothAfhEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetBluetoothAfhEnableFlag".} +## * +## @brief SetBluetoothAfhEnableFlag +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetBluetoothBoostEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetBluetoothBoostEnableFlag".} +## * +## @brief GetBluetoothBoostEnableFlag +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetBluetoothBoostEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetBluetoothBoostEnableFlag".} +## * +## @brief SetBluetoothBoostEnableFlag +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetInRepairProcessEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetInRepairProcessEnableFlag".} +## * +## @brief GetInRepairProcessEnableFlag +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetInRepairProcessEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetInRepairProcessEnableFlag".} +## * +## @brief SetInRepairProcessEnableFlag +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetHeadphoneVolumeUpdateFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetHeadphoneVolumeUpdateFlag".} +## * +## @brief GetHeadphoneVolumeUpdateFlag +## @note Only available on [3.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetHeadphoneVolumeUpdateFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetHeadphoneVolumeUpdateFlag".} +## * +## @brief SetHeadphoneVolumeUpdateFlag +## @note Only available on [3.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysNeedsToUpdateHeadphoneVolume*(a0: ptr U8; a1: ptr U8; a2: ptr U8; flag: bool): Result {. + cdecl, importc: "setsysNeedsToUpdateHeadphoneVolume".} +## * +## @brief NeedsToUpdateHeadphoneVolume +## @note Only available on [3.0.0-14.1.2]. +## @param[out] a0 Output arg. +## @param[out] a1 Output arg. +## @param[out] a2 Output arg. +## @param[in] flag Input flag. +## + +proc setsysGetPushNotificationActivityModeOnSleep*(`out`: ptr U32): Result {.cdecl, + importc: "setsysGetPushNotificationActivityModeOnSleep".} +## * +## @brief GetPushNotificationActivityModeOnSleep +## @note Only available on [3.0.0+]. +## @param[out] out Output mode. +## + +proc setsysSetPushNotificationActivityModeOnSleep*(mode: U32): Result {.cdecl, + importc: "setsysSetPushNotificationActivityModeOnSleep".} +## * +## @brief SetPushNotificationActivityModeOnSleep +## @note Only available on [3.0.0+]. +## @param[in] mode Input mode. +## + +proc setsysGetServiceDiscoveryControlSettings*( + `out`: ptr SetSysServiceDiscoveryControlSettings): Result {.cdecl, + importc: "setsysGetServiceDiscoveryControlSettings".} +## * +## @brief GetServiceDiscoveryControlSettings +## @note Only available on [4.0.0+]. +## @param[out] out \ref ServiceDiscoveryControlSettings +## + +proc setsysSetServiceDiscoveryControlSettings*( + settings: SetSysServiceDiscoveryControlSettings): Result {.cdecl, + importc: "setsysSetServiceDiscoveryControlSettings".} +## * +## @brief SetServiceDiscoveryControlSettings +## @note Only available on [4.0.0+]. +## @param[in] settings \ref ServiceDiscoveryControlSettings +## + +proc setsysGetErrorReportSharePermission*( + `out`: ptr SetSysErrorReportSharePermission): Result {.cdecl, + importc: "setsysGetErrorReportSharePermission".} +## * +## @brief GetErrorReportSharePermission +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysErrorReportSharePermission +## + +proc setsysSetErrorReportSharePermission*( + permission: SetSysErrorReportSharePermission): Result {.cdecl, + importc: "setsysSetErrorReportSharePermission".} +## * +## @brief SetErrorReportSharePermission +## @note Only available on [4.0.0+]. +## @param[in] permission \ref SetSysErrorReportSharePermission +## + +proc setsysGetAppletLaunchFlags*(`out`: ptr U32): Result {.cdecl, + importc: "setsysGetAppletLaunchFlags".} +## * +## @brief GetAppletLaunchFlags +## @note Only available on [4.0.0+]. +## @param[out] out Output AppletLaunchFlags bitmask. +## + +proc setsysSetAppletLaunchFlags*(flags: U32): Result {.cdecl, + importc: "setsysSetAppletLaunchFlags".} +## * +## @brief SetAppletLaunchFlags +## @note Only available on [4.0.0+]. +## @param[in] flags Input AppletLaunchFlags bitmask. +## + +proc setsysGetConsoleSixAxisSensorAccelerationBias*( + `out`: ptr SetSysConsoleSixAxisSensorAccelerationBias): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAccelerationBias".} +## * +## @brief GetConsoleSixAxisSensorAccelerationBias +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAccelerationBias +## + +proc setsysSetConsoleSixAxisSensorAccelerationBias*( + bias: ptr SetSysConsoleSixAxisSensorAccelerationBias): Result {.cdecl, + importc: "setsysSetConsoleSixAxisSensorAccelerationBias".} +## * +## @brief SetConsoleSixAxisSensorAccelerationBias +## @note Only available on [4.0.0+]. +## @param[in] bias \ref SetSysConsoleSixAxisSensorAccelerationBias +## + +proc setsysGetConsoleSixAxisSensorAngularVelocityBias*( + `out`: ptr SetSysConsoleSixAxisSensorAngularVelocityBias): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAngularVelocityBias".} +## * +## @brief GetConsoleSixAxisSensorAngularVelocityBias +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityBias +## + +proc setsysSetConsoleSixAxisSensorAngularVelocityBias*( + bias: ptr SetSysConsoleSixAxisSensorAngularVelocityBias): Result {.cdecl, + importc: "setsysSetConsoleSixAxisSensorAngularVelocityBias".} +## * +## @brief SetConsoleSixAxisSensorAngularVelocityBias +## @note Only available on [4.0.0+]. +## @param[in] bias \ref SetSysConsoleSixAxisSensorAngularVelocityBias +## + +proc setsysGetConsoleSixAxisSensorAccelerationGain*( + `out`: ptr SetSysConsoleSixAxisSensorAccelerationGain): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAccelerationGain".} +## * +## @brief GetConsoleSixAxisSensorAccelerationGain +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAccelerationGain +## + +proc setsysSetConsoleSixAxisSensorAccelerationGain*( + gain: ptr SetSysConsoleSixAxisSensorAccelerationGain): Result {.cdecl, + importc: "setsysSetConsoleSixAxisSensorAccelerationGain".} +## * +## @brief SetConsoleSixAxisSensorAccelerationGain +## @note Only available on [4.0.0+]. +## @param[in] gain \ref SetSysConsoleSixAxisSensorAccelerationGain +## + +proc setsysGetConsoleSixAxisSensorAngularVelocityGain*( + `out`: ptr SetSysConsoleSixAxisSensorAngularVelocityGain): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAngularVelocityGain".} +## * +## @brief GetConsoleSixAxisSensorAngularVelocityGain +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityGain +## + +proc setsysSetConsoleSixAxisSensorAngularVelocityGain*( + gain: ptr SetSysConsoleSixAxisSensorAngularVelocityGain): Result {.cdecl, + importc: "setsysSetConsoleSixAxisSensorAngularVelocityGain".} +## * +## @brief SetConsoleSixAxisSensorAngularVelocityGain +## @note Only available on [4.0.0+]. +## @param[in] gain \ref SetSysConsoleSixAxisSensorAngularVelocityGain +## + +proc setsysGetKeyboardLayout*(`out`: ptr SetKeyboardLayout): Result {.cdecl, + importc: "setsysGetKeyboardLayout".} +## * +## @brief GetKeyboardLayout +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetKeyboardLayout +## + +proc setsysSetKeyboardLayout*(layout: SetKeyboardLayout): Result {.cdecl, + importc: "setsysSetKeyboardLayout".} +## * +## @brief SetKeyboardLayout +## @note Only available on [4.0.0+]. +## @param[in] layout \ref SetKeyboardLayout +## + +proc setsysGetWebInspectorFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetWebInspectorFlag".} +## * +## @brief GetWebInspectorFlag +## @note Only available on [4.0.0+]. +## @param[out] out Output flag. +## + +proc setsysGetAllowedSslHosts*(totalOut: ptr S32; `out`: ptr SetSysAllowedSslHosts; + count: S32): Result {.cdecl, + importc: "setsysGetAllowedSslHosts".} +## * +## @brief GetAllowedSslHosts +## @note Only available on [4.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] out Output array of \ref SetSysAllowedSslHosts. +## @param[in] count Size of the hosts array in entries. +## + +proc setsysGetHostFsMountPoint*(`out`: ptr SetSysHostFsMountPoint): Result {.cdecl, + importc: "setsysGetHostFsMountPoint".} +## * +## @brief GetHostFsMountPoint +## @note Only available on [4.0.0+]. +## @param[out] out \ref SetSysHostFsMountPoint +## + +proc setsysGetRequiresRunRepairTimeReviser*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetRequiresRunRepairTimeReviser".} +## * +## @brief GetRequiresRunRepairTimeReviser +## @note Only available on [5.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetRequiresRunRepairTimeReviser*(flag: bool): Result {.cdecl, + importc: "setsysSetRequiresRunRepairTimeReviser".} +## * +## @brief SetRequiresRunRepairTimeReviser +## @note Only available on [5.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysSetBlePairingSettings*(settings: ptr SetSysBlePairingSettings; count: S32): Result {. + cdecl, importc: "setsysSetBlePairingSettings".} +## * +## @brief SetBlePairingSettings +## @note Only available on [5.0.0+]. +## @param[in] settings Input array of \ref SetSysBlePairingSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetBlePairingSettings*(totalOut: ptr S32; + settings: ptr SetSysBlePairingSettings; count: S32): Result {. + cdecl, importc: "setsysGetBlePairingSettings".} +## * +## @brief GetBlePairingSettings +## @note Only available on [5.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysBlePairingSettings. +## @param[in] count Size of the hosts array in entries. +## + +proc setsysGetConsoleSixAxisSensorAngularVelocityTimeBias*( + `out`: ptr SetSysConsoleSixAxisSensorAngularVelocityTimeBias): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAngularVelocityTimeBias".} +## * +## @brief GetConsoleSixAxisSensorAngularVelocityTimeBias +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAngularVelocityTimeBias +## + +proc setsysSetConsoleSixAxisSensorAngularVelocityTimeBias*( + bias: ptr SetSysConsoleSixAxisSensorAngularVelocityTimeBias): Result {.cdecl, + importc: "setsysSetConsoleSixAxisSensorAngularVelocityTimeBias".} +## * +## @brief SetConsoleSixAxisSensorAngularVelocityTimeBias +## @note Only available on [5.0.0+]. +## @param[in] bias \ref SetSysConsoleSixAxisSensorAngularVelocityTimeBias +## + +proc setsysGetConsoleSixAxisSensorAngularAcceleration*( + `out`: ptr SetSysConsoleSixAxisSensorAngularAcceleration): Result {.cdecl, + importc: "setsysGetConsoleSixAxisSensorAngularAcceleration".} +## * +## @brief GetConsoleSixAxisSensorAngularAcceleration +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetSysConsoleSixAxisSensorAngularAcceleration +## + +proc setsysSetConsoleSixAxisSensorAngularAcceleration*( + acceleration: ptr SetSysConsoleSixAxisSensorAngularAcceleration): Result {. + cdecl, importc: "setsysSetConsoleSixAxisSensorAngularAcceleration".} +## * +## @brief SetConsoleSixAxisSensorAngularAcceleration +## @note Only available on [5.0.0+]. +## @param[in] acceleration \ref SetSysConsoleSixAxisSensorAngularAcceleration +## + +proc setsysGetRebootlessSystemUpdateVersion*( + `out`: ptr SetSysRebootlessSystemUpdateVersion): Result {.cdecl, + importc: "setsysGetRebootlessSystemUpdateVersion".} +## * +## @brief GetRebootlessSystemUpdateVersion +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetSysRebootlessSystemUpdateVersion +## + +proc setsysGetDeviceTimeZoneLocationUpdatedTime*( + `out`: ptr TimeSteadyClockTimePoint): Result {.cdecl, + importc: "setsysGetDeviceTimeZoneLocationUpdatedTime".} +## * +## @brief GetDeviceTimeZoneLocationUpdatedTime +## @note Only available on [5.0.0+]. +## @param[out] out \ref TimeSteadyClockTimePoint +## + +proc setsysSetDeviceTimeZoneLocationUpdatedTime*( + timePoint: ptr TimeSteadyClockTimePoint): Result {.cdecl, + importc: "setsysSetDeviceTimeZoneLocationUpdatedTime".} +## * +## @brief SetDeviceTimeZoneLocationUpdatedTime +## @note Only available on [5.0.0+]. +## @param[in] time_point \ref TimeSteadyClockTimePoint +## + +proc setsysGetUserSystemClockAutomaticCorrectionUpdatedTime*( + `out`: ptr TimeSteadyClockTimePoint): Result {.cdecl, + importc: "setsysGetUserSystemClockAutomaticCorrectionUpdatedTime".} +## * +## @brief GetUserSystemClockAutomaticCorrectionUpdatedTime +## @note Only available on [6.0.0+]. +## @param[out] out \ref TimeSteadyClockTimePoint +## + +proc setsysSetUserSystemClockAutomaticCorrectionUpdatedTime*( + timePoint: ptr TimeSteadyClockTimePoint): Result {.cdecl, + importc: "setsysSetUserSystemClockAutomaticCorrectionUpdatedTime".} +## * +## @brief SetUserSystemClockAutomaticCorrectionUpdatedTime +## @note Only available on [6.0.0+]. +## @param[in] time_point \ref TimeSteadyClockTimePoint +## + +proc setsysGetAccountOnlineStorageSettings*(totalOut: ptr S32; + settings: ptr SetSysAccountOnlineStorageSettings; count: S32): Result {.cdecl, + importc: "setsysGetAccountOnlineStorageSettings".} +## * +## @brief GetAccountOnlineStorageSettings +## @note Only available on [6.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysAccountOnlineStorageSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetAccountOnlineStorageSettings*( + settings: ptr SetSysAccountOnlineStorageSettings; count: S32): Result {.cdecl, + importc: "setsysSetAccountOnlineStorageSettings".} +## * +## @brief SetAccountOnlineStorageSettings +## @note Only available on [6.0.0+]. +## @param[in] settings Input array of \ref SetSysAccountOnlineStorageSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetPctlReadyFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetPctlReadyFlag".} +## * +## @brief GetPctlReadyFlag +## @note Only available on [6.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetPctlReadyFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetPctlReadyFlag".} +## * +## @brief SetPctlReadyFlag +## @note Only available on [6.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetAnalogStickUserCalibrationL*( + `out`: ptr SetSysAnalogStickUserCalibration): Result {.cdecl, + importc: "setsysGetAnalogStickUserCalibrationL".} +## * +## @brief GetAnalogStickUserCalibrationL +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetSysAnalogStickUserCalibration +## + +proc setsysSetAnalogStickUserCalibrationL*( + calibration: ptr SetSysAnalogStickUserCalibration): Result {.cdecl, + importc: "setsysSetAnalogStickUserCalibrationL".} +## * +## @brief SetAnalogStickUserCalibrationL +## @note Only available on [8.1.1+]. +## @param[in] calibration \ref SetSysAnalogStickUserCalibration +## + +proc setsysGetAnalogStickUserCalibrationR*( + `out`: ptr SetSysAnalogStickUserCalibration): Result {.cdecl, + importc: "setsysGetAnalogStickUserCalibrationR".} +## * +## @brief GetAnalogStickUserCalibrationR +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetSysAnalogStickUserCalibration +## + +proc setsysSetAnalogStickUserCalibrationR*( + calibration: ptr SetSysAnalogStickUserCalibration): Result {.cdecl, + importc: "setsysSetAnalogStickUserCalibrationR".} +## * +## @brief SetAnalogStickUserCalibrationR +## @note Only available on [8.1.1+]. +## @param[in] calibration \ref SetSysAnalogStickUserCalibration +## + +proc setsysGetPtmBatteryVersion*(`out`: ptr U8): Result {.cdecl, + importc: "setsysGetPtmBatteryVersion".} +## * +## @brief GetPtmBatteryVersion +## @note Only available on [6.0.0+]. +## @param[out] out Output version. +## + +proc setsysSetPtmBatteryVersion*(version: U8): Result {.cdecl, + importc: "setsysSetPtmBatteryVersion".} +## * +## @brief SetPtmBatteryVersion +## @note Only available on [6.0.0+]. +## @param[in] version Input version. +## + +proc setsysGetUsb30HostEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetUsb30HostEnableFlag".} +## * +## @brief GetUsb30HostEnableFlag +## @note Only available on [6.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetUsb30HostEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetUsb30HostEnableFlag".} +## * +## @brief SetUsb30HostEnableFlag +## @note Only available on [6.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetUsb30DeviceEnableFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetUsb30DeviceEnableFlag".} +## * +## @brief GetUsb30DeviceEnableFlag +## @note Only available on [6.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetUsb30DeviceEnableFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetUsb30DeviceEnableFlag".} +## * +## @brief SetUsb30DeviceEnableFlag +## @note Only available on [6.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetThemeId*(`type`: S32; `out`: ptr SetSysThemeId): Result {.cdecl, + importc: "setsysGetThemeId".} +## * +## @brief GetThemeId +## @note Only available on [7.0.0+]. +## @param[in] type Input theme id type. +## @param[out] out \ref SetSysThemeId +## + +proc setsysSetThemeId*(`type`: S32; themeId: ptr SetSysThemeId): Result {.cdecl, + importc: "setsysSetThemeId".} +## * +## @brief SetThemeId +## @note Only available on [7.0.0+]. +## @param[in] type Input theme id type. +## @param[in] theme_id \ref SetSysThemeId +## + +proc setsysGetChineseTraditionalInputMethod*( + `out`: ptr SetChineseTraditionalInputMethod): Result {.cdecl, + importc: "setsysGetChineseTraditionalInputMethod".} +## * +## @brief GetChineseTraditionalInputMethod +## @note Only available on [7.0.0+]. +## @param[out] out \ref SetChineseTraditionalInputMethod +## + +proc setsysSetChineseTraditionalInputMethod*( + `method`: SetChineseTraditionalInputMethod): Result {.cdecl, + importc: "setsysSetChineseTraditionalInputMethod".} +## * +## @brief SetChineseTraditionalInputMethod +## @note Only available on [7.0.0+]. +## @param[in] method \ref SetChineseTraditionalInputMethod +## + +proc setsysGetPtmCycleCountReliability*(`out`: ptr SetSysPtmCycleCountReliability): Result {. + cdecl, importc: "setsysGetPtmCycleCountReliability".} +## * +## @brief GetPtmCycleCountReliability +## @note Only available on [7.0.0+]. +## @param[out] out \ref SetSysPtmCycleCountReliability +## + +proc setsysSetPtmCycleCountReliability*(reliability: SetSysPtmCycleCountReliability): Result {. + cdecl, importc: "setsysSetPtmCycleCountReliability".} +## * +## @brief SetPtmCycleCountReliability +## @note Only available on [7.0.0+]. +## @param[in] reliability \ref SetSysPtmCycleCountReliability +## + +proc setsysGetHomeMenuScheme*(`out`: ptr SetSysHomeMenuScheme): Result {.cdecl, + importc: "setsysGetHomeMenuScheme".} +## * +## @brief Gets the \ref SetSysHomeMenuScheme. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetSysHomeMenuScheme +## + +proc setsysGetThemeSettings*(`out`: ptr SetSysThemeSettings): Result {.cdecl, + importc: "setsysGetThemeSettings".} +## * +## @brief GetThemeSettings +## @note Only available on [7.0.0+]. +## @param[out] out \ref SetSysThemeSettings +## + +proc setsysSetThemeSettings*(settings: ptr SetSysThemeSettings): Result {.cdecl, + importc: "setsysSetThemeSettings".} +## * +## @brief SetThemeSettings +## @note Only available on [7.0.0+]. +## @param[in] settings \ref SetSysThemeSettings +## + +proc setsysGetThemeKey*(`out`: ptr FsArchiveMacKey): Result {.cdecl, + importc: "setsysGetThemeKey".} +## * +## @brief GetThemeKey +## @note Only available on [7.0.0+]. +## @param[out] out \ref FsArchiveMacKey +## + +proc setsysSetThemeKey*(key: ptr FsArchiveMacKey): Result {.cdecl, + importc: "setsysSetThemeKey".} +## * +## @brief SetThemeKey +## @note Only available on [7.0.0+]. +## @param[in] key \ref FsArchiveMacKey +## + +proc setsysGetZoomFlag*(`out`: ptr bool): Result {.cdecl, importc: "setsysGetZoomFlag".} +## * +## @brief GetZoomFlag +## @note Only available on [8.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetZoomFlag*(flag: bool): Result {.cdecl, importc: "setsysSetZoomFlag".} +## * +## @brief SetZoomFlag +## @note Only available on [8.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetT*(`out`: ptr bool): Result {.cdecl, importc: "setsysGetT".} +## * +## @brief Returns Terra platform type flag. +## @note On [9.0.0+], this is a wrapper for \ref setsysGetPlatFormRegion() == 2. +## @note Only available on [8.0.0+]. +## @param[out] out Output flag. +## + +proc setsysSetT*(flag: bool): Result {.cdecl, importc: "setsysSetT".} +## * +## @brief Sets Terra platform type flag. +## @note On [9.0.0+], this is a wrapper for \ref setsysSetPlatFormRegion(1 + (IsT & 1)). +## @note Only available on [8.0.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetPlatformRegion*(`out`: ptr SetSysPlatformRegion): Result {.cdecl, + importc: "setsysGetPlatformRegion".} +## * +## @brief Gets the \ref SetSysPlatformRegion. +## @note This is used internally by \ref appletGetSettingsPlatformRegion. +## @note Only available on [9.0.0+]. +## @param[out] out \ref SetSysPlatformRegion +## + +proc setsysSetPlatformRegion*(region: SetSysPlatformRegion): Result {.cdecl, + importc: "setsysSetPlatformRegion".} +## * +## @brief Sets the \ref SetSysPlatformRegion. +## @note Only available on [9.0.0+]. +## @param[in] region \ref SetSysPlatformRegion +## + +proc setsysGetHomeMenuSchemeModel*(`out`: ptr U32): Result {.cdecl, + importc: "setsysGetHomeMenuSchemeModel".} +## * +## @brief GetHomeMenuSchemeModel +## @note This will throw an error when loading the "settings_debug!{...}" system-setting which is used with this fails. +## @note Only available on [9.0.0+]. +## @param[out] out HomeMenuSchemeModel. +## + +proc setsysGetMemoryUsageRateFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetMemoryUsageRateFlag".} +## * +## @brief GetMemoryUsageRateFlag +## @note Only available on [9.0.0+]. +## @param[out] out Output flag. +## + +proc setsysGetTouchScreenMode*(`out`: ptr SetSysTouchScreenMode): Result {.cdecl, + importc: "setsysGetTouchScreenMode".} +## * +## @brief Gets the \ref SetSysTouchScreenMode. +## @note Only available on [9.0.0+]. +## @param[out] out \ref SetSysTouchScreenMode +## + +proc setsysSetTouchScreenMode*(mode: SetSysTouchScreenMode): Result {.cdecl, + importc: "setsysSetTouchScreenMode".} +## * +## @brief Sets the \ref SetSysTouchScreenMode. +## @note Only available on [9.0.0+]. +## @param[in] mode \ref SetSysTouchScreenMode +## + +proc setsysGetButtonConfigSettingsFull*(totalOut: ptr S32; settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysGetButtonConfigSettingsFull".} +## * +## @brief GetButtonConfigSettingsFull +## @note Only available on [10.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetButtonConfigSettingsFull*(settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysSetButtonConfigSettingsFull".} +## * +## @brief SetButtonConfigSettingsFull +## @note Only available on [10.0.0+]. +## @param[in] settings Input array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetButtonConfigSettingsEmbedded*(totalOut: ptr S32; + settings: ptr SetSysButtonConfigSettings; count: S32): Result {.cdecl, + importc: "setsysGetButtonConfigSettingsEmbedded".} +## * +## @brief GetButtonConfigSettingsEmbedded +## @note Only available on [10.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetButtonConfigSettingsEmbedded*( + settings: ptr SetSysButtonConfigSettings; count: S32): Result {.cdecl, + importc: "setsysSetButtonConfigSettingsEmbedded".} +## * +## @brief SetButtonConfigSettingsEmbedded +## @note Only available on [10.0.0+]. +## @param[in] settings Input array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetButtonConfigSettingsLeft*(totalOut: ptr S32; settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysGetButtonConfigSettingsLeft".} +## * +## @brief GetButtonConfigSettingsLeft +## @note Only available on [10.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetButtonConfigSettingsLeft*(settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysSetButtonConfigSettingsLeft".} +## * +## @brief SetButtonConfigSettingsLeft +## @note Only available on [10.0.0+]. +## @param[in] settings Input array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetButtonConfigSettingsRight*(totalOut: ptr S32; settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysGetButtonConfigSettingsRight".} +## * +## @brief GetButtonConfigSettingsRight +## @note Only available on [10.0.0+]. +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetButtonConfigSettingsRight*(settings: ptr SetSysButtonConfigSettings; + count: S32): Result {.cdecl, + importc: "setsysSetButtonConfigSettingsRight".} +## * +## @brief SetButtonConfigSettingsRight +## @note Only available on [10.0.0+]. +## @param[in] settings Input array of \ref SetSysButtonConfigSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysGetButtonConfigRegisteredSettingsEmbedded*( + settings: ptr SetSysButtonConfigRegisteredSettings): Result {.cdecl, + importc: "setsysGetButtonConfigRegisteredSettingsEmbedded".} +## * +## @brief GetButtonConfigRegisteredSettingsEmbedded +## @note Only available on [10.0.0+]. +## @param[out] settings \ref SetSysButtonConfigRegisteredSettings +## + +proc setsysSetButtonConfigRegisteredSettingsEmbedded*( + settings: ptr SetSysButtonConfigRegisteredSettings): Result {.cdecl, + importc: "setsysSetButtonConfigRegisteredSettingsEmbedded".} +## * +## @brief SetButtonConfigRegisteredSettingsEmbedded +## @note Only available on [10.0.0+]. +## @param[in] settings \ref SetSysButtonConfigRegisteredSettings +## + +proc setsysGetButtonConfigRegisteredSettings*(totalOut: ptr S32; + settings: ptr SetSysButtonConfigRegisteredSettings; count: S32): Result {.cdecl, + importc: "setsysGetButtonConfigRegisteredSettings".} +## * +## @brief GetButtonConfigRegisteredSettings +## @note Only available on [10.0.0+]. +## @param[out] settings \ref SetSysButtonConfigRegisteredSettings +## + +proc setsysSetButtonConfigRegisteredSettings*( + settings: ptr SetSysButtonConfigRegisteredSettings; count: S32): Result {.cdecl, + importc: "setsysSetButtonConfigRegisteredSettings".} +## * +## @brief SetButtonConfigRegisteredSettings +## @note Only available on [10.0.0+]. +## @param[in] settings \ref SetSysButtonConfigRegisteredSettings +## + +proc setsysGetFieldTestingFlag*(`out`: ptr bool): Result {.cdecl, + importc: "setsysGetFieldTestingFlag".} +## * +## @brief GetFieldTestingFlag +## @note Only available on [10.1.0+]. +## @param[out] out Output flag. +## + +proc setsysSetFieldTestingFlag*(flag: bool): Result {.cdecl, + importc: "setsysSetFieldTestingFlag".} +## * +## @brief SetFieldTestingFlag +## @note Only available on [10.1.0+]. +## @param[in] flag Input flag. +## + +proc setsysGetNxControllerSettingsEx*(totalOut: ptr S32; + settings: ptr SetSysNxControllerSettings; + count: S32): Result {.cdecl, + importc: "setsysGetNxControllerSettingsEx".} +## * +## @brief GetNxControllerSettingsEx +## @param[out] total_out Total output entries. +## @param[out] settings Output array of \ref SetSysNxControllerSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setsysSetNxControllerSettingsEx*(settings: ptr SetSysNxControllerSettings; + count: S32): Result {.cdecl, + importc: "setsysSetNxControllerSettingsEx".} +## * +## @brief SetNxControllerSettingsEx +## @param[in] settings Input array of \ref SetSysNxControllerSettings. +## @param[in] count Size of the settings array in entries. +## + +proc setcalInitialize*(): Result {.cdecl, importc: "setcalInitialize".} +## / Initialize setcal. + +proc setcalExit*() {.cdecl, importc: "setcalExit".} +## / Exit setcal. + +proc setcalGetServiceSession*(): ptr Service {.cdecl, + importc: "setcalGetServiceSession".} +## / Gets the Service object for the actual setcal service session. + +proc setcalGetBdAddress*(`out`: ptr SetCalBdAddress): Result {.cdecl, + importc: "setcalGetBdAddress".} +## * +## @brief Gets the \ref SetCalBdAddress. +## @param[out] out \ref SetCalBdAddress +## + +proc setcalGetConfigurationId1*(`out`: ptr SetCalConfigurationId1): Result {.cdecl, + importc: "setcalGetConfigurationId1".} +## * +## @brief Gets the \ref SetCalConfigurationId1. +## @param[out] out \ref SetCalConfigurationId1 +## + +proc setcalGetAccelerometerOffset*(`out`: ptr SetCalAccelerometerOffset): Result {. + cdecl, importc: "setcalGetAccelerometerOffset".} +## * +## @brief Gets the \ref SetCalAccelerometerOffset. +## @param[out] out \ref SetCalAccelerometerOffset +## + +proc setcalGetAccelerometerScale*(`out`: ptr SetCalAccelerometerScale): Result {. + cdecl, importc: "setcalGetAccelerometerScale".} +## * +## @brief Gets the \ref SetCalAccelerometerScale. +## @param[out] out \ref SetCalAccelerometerScale +## + +proc setcalGetGyroscopeOffset*(`out`: ptr SetCalGyroscopeOffset): Result {.cdecl, + importc: "setcalGetGyroscopeOffset".} +## * +## @brief Gets the \ref SetCalGyroscopeOffset. +## @param[out] out \ref SetCalGyroscopeOffset +## + +proc setcalGetGyroscopeScale*(`out`: ptr SetCalGyroscopeScale): Result {.cdecl, + importc: "setcalGetGyroscopeScale".} +## * +## @brief Gets the \ref SetCalGyroscopeScale. +## @param[out] out \ref SetCalGyroscopeScale +## + +proc setcalGetWirelessLanMacAddress*(`out`: ptr SetCalMacAddress): Result {.cdecl, + importc: "setcalGetWirelessLanMacAddress".} +## * +## @brief Gets the \ref SetCalMacAddress. +## @param[out] out \ref SetCalMacAddress +## + +proc setcalGetWirelessLanCountryCodeCount*(outCount: ptr S32): Result {.cdecl, + importc: "setcalGetWirelessLanCountryCodeCount".} +## * +## @brief GetWirelessLanCountryCodeCount +## @param[out] out_count Output count +## + +proc setcalGetWirelessLanCountryCodes*(totalOut: ptr S32; + codes: ptr SetCalCountryCode; count: S32): Result {. + cdecl, importc: "setcalGetWirelessLanCountryCodes".} +## * +## @brief GetWirelessLanCountryCodes +## @param[out] total_out Total output entries. +## @param[out] codes Output array of \ref SetCalCountryCode. +## @param[in] count Size of the versions array in entries. +## + +proc setcalGetSerialNumber*(`out`: ptr SetCalSerialNumber): Result {.cdecl, + importc: "setcalGetSerialNumber".} +## * +## @brief Gets the \ref SetCalSerialNumber. +## @param[out] out \ref SetCalSerialNumber +## + +proc setcalSetInitialSystemAppletProgramId*(programId: U64): Result {.cdecl, + importc: "setcalSetInitialSystemAppletProgramId".} +## * +## @brief SetInitialSystemAppletProgramId +## @param[in] program_id input ProgramId. +## + +proc setcalSetOverlayDispProgramId*(programId: U64): Result {.cdecl, + importc: "setcalSetOverlayDispProgramId".} +## * +## @brief SetOverlayDispProgramId +## @param[in] program_id input ProgramId. +## + +proc setcalGetBatteryLot*(`out`: ptr SetBatteryLot): Result {.cdecl, + importc: "setcalGetBatteryLot".} +## * +## @brief Gets the \ref SetBatteryLot. +## @param[out] out \ref SetBatteryLot +## + +proc setcalGetEciDeviceCertificate*(`out`: ptr SetCalEccB233DeviceCertificate): Result {. + cdecl, importc: "setcalGetEciDeviceCertificate".} +## * +## @brief Gets the \ref SetCalEccB233DeviceCertificate. +## @param[out] out \ref SetCalEccB233DeviceCertificate +## + +proc setcalGetEticketDeviceCertificate*(`out`: ptr SetCalRsa2048DeviceCertificate): Result {. + cdecl, importc: "setcalGetEticketDeviceCertificate".} +## * +## @brief Gets the \ref SetCalRsa2048DeviceCertificate. +## @param[out] out \ref SetCalRsa2048DeviceCertificate +## + +proc setcalGetSslKey*(`out`: ptr SetCalSslKey): Result {.cdecl, + importc: "setcalGetSslKey".} +## * +## @brief Gets the \ref SetCalSslKey. +## @param[out] out \ref SetCalSslKey +## + +proc setcalGetSslCertificate*(`out`: ptr SetCalSslCertificate): Result {.cdecl, + importc: "setcalGetSslCertificate".} +## * +## @brief Gets the \ref SetCalSslCertificate. +## @param[out] out \ref SetCalSslCertificate +## + +proc setcalGetGameCardKey*(`out`: ptr SetCalGameCardKey): Result {.cdecl, + importc: "setcalGetGameCardKey".} +## * +## @brief Gets the \ref SetCalGameCardKey. +## @param[out] out \ref SetCalGameCardKey +## + +proc setcalGetGameCardCertificate*(`out`: ptr SetCalGameCardCertificate): Result {. + cdecl, importc: "setcalGetGameCardCertificate".} +## * +## @brief Gets the \ref SetCalGameCardCertificate. +## @param[out] out \ref SetCalGameCardCertificate +## + +proc setcalGetEciDeviceKey*(`out`: ptr SetCalEccB233DeviceKey): Result {.cdecl, + importc: "setcalGetEciDeviceKey".} +## * +## @brief Gets the \ref SetCalEccB233DeviceKey. +## @param[out] out \ref SetCalEccB233DeviceKey +## + +proc setcalGetEticketDeviceKey*(`out`: ptr SetCalRsa2048DeviceKey): Result {.cdecl, + importc: "setcalGetEticketDeviceKey".} +## * +## @brief Gets the \ref SetCalRsa2048DeviceKey. +## @param[out] out \ref SetCalRsa2048DeviceKey +## + +proc setcalGetSpeakerParameter*(`out`: ptr SetCalSpeakerParameter): Result {.cdecl, + importc: "setcalGetSpeakerParameter".} +## * +## @brief Gets the \ref SetCalSpeakerParameter. +## @param[out] out \ref SetCalSpeakerParameter +## + +proc setcalGetLcdVendorId*(outVendorId: ptr U32): Result {.cdecl, + importc: "setcalGetLcdVendorId".} +## * +## @brief GetLcdVendorId +## @note Only available on [4.0.0+]. +## @param[out] out_vendor_id Output LcdVendorId. +## + +proc setcalGetEciDeviceCertificate2*(`out`: ptr SetCalRsa2048DeviceCertificate): Result {. + cdecl, importc: "setcalGetEciDeviceCertificate2".} +## * +## @brief Gets the \ref SetCalRsa2048DeviceCertificate. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalRsa2048DeviceCertificate +## + +proc setcalGetEciDeviceKey2*(`out`: ptr SetCalRsa2048DeviceKey): Result {.cdecl, + importc: "setcalGetEciDeviceKey2".} +## * +## @brief Gets the \ref SetCalRsa2048DeviceKey. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalRsa2048DeviceKey +## + +proc setcalGetAmiiboKey*(`out`: ptr SetCalAmiiboKey): Result {.cdecl, + importc: "setcalGetAmiiboKey".} +## * +## @brief Gets the \ref SetCalAmiiboKey. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboKey +## + +proc setcalGetAmiiboEcqvCertificate*(`out`: ptr SetCalAmiiboEcqvCertificate): Result {. + cdecl, importc: "setcalGetAmiiboEcqvCertificate".} +## * +## @brief Gets the \ref SetCalAmiiboEcqvCertificate. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboEcqvCertificate +## + +proc setcalGetAmiiboEcdsaCertificate*(`out`: ptr SetCalAmiiboEcdsaCertificate): Result {. + cdecl, importc: "setcalGetAmiiboEcdsaCertificate".} +## * +## @brief Gets the \ref SetCalAmiiboEcdsaCertificate. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboEcdsaCertificate +## + +proc setcalGetAmiiboEcqvBlsKey*(`out`: ptr SetCalAmiiboEcqvBlsKey): Result {.cdecl, + importc: "setcalGetAmiiboEcqvBlsKey".} +## * +## @brief Gets the \ref SetCalAmiiboEcqvBlsKey. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboEcqvBlsKey +## + +proc setcalGetAmiiboEcqvBlsCertificate*(`out`: ptr SetCalAmiiboEcqvBlsCertificate): Result {. + cdecl, importc: "setcalGetAmiiboEcqvBlsCertificate".} +## * +## @brief Gets the \ref SetCalAmiiboEcqvBlsCertificate. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboEcqvBlsCertificate +## + +proc setcalGetAmiiboEcqvBlsRootCertificate*( + `out`: ptr SetCalAmiiboEcqvBlsRootCertificate): Result {.cdecl, + importc: "setcalGetAmiiboEcqvBlsRootCertificate".} +## * +## @brief Gets the \ref SetCalAmiiboEcqvBlsRootCertificate. +## @note Only available on [5.0.0+]. +## @param[out] out \ref SetCalAmiiboEcqvBlsRootCertificate +## + +proc setcalGetUsbTypeCPowerSourceCircuitVersion*(outVersion: ptr U8): Result {.cdecl, + importc: "setcalGetUsbTypeCPowerSourceCircuitVersion".} +## * +## @brief GetUsbTypeCPowerSourceCircuitVersion +## @note Only available on [5.0.0+]. +## @param[out] out_version Output UsbTypeCPowerSourceCircuitVersion. +## + +proc setcalGetAnalogStickModuleTypeL*(outType: ptr U8): Result {.cdecl, + importc: "setcalGetAnalogStickModuleTypeL".} +## * +## @brief GetAnalogStickModuleTypeL +## @note Only available on [8.1.1+]. +## @param[out] out_version Output AnalogStickModuleType. +## + +proc setcalGetAnalogStickModelParameterL*( + `out`: ptr SetCalAnalogStickModelParameter): Result {.cdecl, + importc: "setcalGetAnalogStickModelParameterL".} +## * +## @brief Gets the \ref SetCalAnalogStickModelParameter. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetCalAnalogStickModelParameter +## + +proc setcalGetAnalogStickFactoryCalibrationL*( + `out`: ptr SetCalAnalogStickFactoryCalibration): Result {.cdecl, + importc: "setcalGetAnalogStickFactoryCalibrationL".} +## * +## @brief Gets the \ref SetCalAnalogStickFactoryCalibration. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetCalAnalogStickFactoryCalibration +## + +proc setcalGetAnalogStickModuleTypeR*(outType: ptr U8): Result {.cdecl, + importc: "setcalGetAnalogStickModuleTypeR".} +## * +## @brief GetAnalogStickModuleTypeR +## @note Only available on [8.1.1+]. +## @param[out] out_version Output AnalogStickModuleType. +## + +proc setcalGetAnalogStickModelParameterR*( + `out`: ptr SetCalAnalogStickModelParameter): Result {.cdecl, + importc: "setcalGetAnalogStickModelParameterR".} +## * +## @brief Gets the \ref SetCalAnalogStickModelParameter. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetCalAnalogStickModelParameter +## + +proc setcalGetAnalogStickFactoryCalibrationR*( + `out`: ptr SetCalAnalogStickFactoryCalibration): Result {.cdecl, + importc: "setcalGetAnalogStickFactoryCalibrationR".} +## * +## @brief Gets the \ref SetCalAnalogStickFactoryCalibration. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetCalAnalogStickFactoryCalibration +## + +proc setcalGetConsoleSixAxisSensorModuleType*(outType: ptr U8): Result {.cdecl, + importc: "setcalGetConsoleSixAxisSensorModuleType".} +## * +## @brief GetConsoleSixAxisSensorModuleType +## @note Only available on [8.1.1+]. +## @param[out] out_version Output ConsoleSixAxisSensorModuleType. +## + +proc setcalGetConsoleSixAxisSensorHorizontalOffset*( + `out`: ptr SetCalConsoleSixAxisSensorHorizontalOffset): Result {.cdecl, + importc: "setcalGetConsoleSixAxisSensorHorizontalOffset".} +## * +## @brief Gets the \ref SetCalConsoleSixAxisSensorHorizontalOffset. +## @note Only available on [8.1.1+]. +## @param[out] out \ref SetCalConsoleSixAxisSensorHorizontalOffset +## + +proc setcalGetBatteryVersion*(outVersion: ptr U8): Result {.cdecl, + importc: "setcalGetBatteryVersion".} +## * +## @brief GetBatteryVersion +## @note Only available on [6.0.0+]. +## @param[out] out_version Output BatteryVersion. +## + +proc setcalGetDeviceId*(outDeviceId: ptr U64): Result {.cdecl, + importc: "setcalGetDeviceId".} +## * +## @brief GetDeviceId +## @note Only available on [10.0.0+]. +## @param[out] out_type Output DeviceId. +## + +proc setcalGetConsoleSixAxisSensorMountType*(outType: ptr U8): Result {.cdecl, + importc: "setcalGetConsoleSixAxisSensorMountType".} +## * +## @brief GetConsoleSixAxisSensorMountType +## @note Only available on [10.0.0+]. +## @param[out] out_type Output ConsoleSixAxisSensorMountType. +## + diff --git a/src/libnx/wrapper/switch/services/sfdnsres.h b/src/libnx/wrapper/switch/services/sfdnsres.h new file mode 100644 index 0000000..37a8407 --- /dev/null +++ b/src/libnx/wrapper/switch/services/sfdnsres.h @@ -0,0 +1,20 @@ +/** + * @file sfdnsres.h + * @brief Domain name resolution service IPC wrapper. Please use the standard interface instead. + * @author TuxSH + * @author fincs + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +// SetDnsAddressesPrivateRequest & GetDnsAddressPrivateRequest are stubbed + +Result sfdnsresGetHostByNameRequest(u32 cancel_handle, bool use_nsd, const char *name, u32 *h_errno_, u32 *errno_, void *out_buffer, size_t out_buffer_size, u32 *out_serialized_size); +Result sfdnsresGetHostByAddrRequest(const void *in_addr, size_t in_addr_len, u32 type, u32 cancel_handle, u32 *h_errno_, u32 *errno_, void *out_buffer, size_t out_buffer_size, u32 *out_serialized_size); +Result sfdnsresGetHostStringErrorRequest(u32 err, char *out_str, size_t out_str_size); +Result sfdnsresGetGaiStringErrorRequest(u32 err, char *out_str, size_t out_str_size); +Result sfdnsresGetAddrInfoRequest(u32 cancel_handle, bool use_nsd, const char *node, const char *service, const void *in_hints, size_t in_hints_size, void *out_buffer, size_t out_buffer_size, u32 *errno_, s32 *ret, u32 *out_serialized_size); +Result sfdnsresGetNameInfoRequest(u32 flags, const void *in_sa, size_t in_sa_size, char *out_host, size_t out_host_size, char *out_serv, size_t out_serv_len, u32 cancel_handle, u32 *errno_, s32 *ret); +Result sfdnsresGetCancelHandleRequest(u32 *out_handle); +Result sfdnsresCancelRequest(u32 handle); diff --git a/src/libnx/wrapper/switch/services/sfdnsres.nim b/src/libnx/wrapper/switch/services/sfdnsres.nim new file mode 100644 index 0000000..a208fdb --- /dev/null +++ b/src/libnx/wrapper/switch/services/sfdnsres.nim @@ -0,0 +1,43 @@ +## * +## @file sfdnsres.h +## @brief Domain name resolution service IPC wrapper. Please use the standard interface instead. +## @author TuxSH +## @author fincs +## @copyright libnx Authors +## + +import + ../types + +## SetDnsAddressesPrivateRequest & GetDnsAddressPrivateRequest are stubbed + +proc sfdnsresGetHostByNameRequest*(cancelHandle: U32; useNsd: bool; name: cstring; + hErrno: ptr U32; errno: ptr U32; outBuffer: pointer; + outBufferSize: csize_t; + outSerializedSize: ptr U32): Result {.cdecl, + importc: "sfdnsresGetHostByNameRequest".} +proc sfdnsresGetHostByAddrRequest*(inAddr: pointer; inAddrLen: csize_t; `type`: U32; + cancelHandle: U32; hErrno: ptr U32; errno: ptr U32; + outBuffer: pointer; outBufferSize: csize_t; + outSerializedSize: ptr U32): Result {.cdecl, + importc: "sfdnsresGetHostByAddrRequest".} +proc sfdnsresGetHostStringErrorRequest*(err: U32; outStr: cstring; + outStrSize: csize_t): Result {.cdecl, + importc: "sfdnsresGetHostStringErrorRequest".} +proc sfdnsresGetGaiStringErrorRequest*(err: U32; outStr: cstring; outStrSize: csize_t): Result {. + cdecl, importc: "sfdnsresGetGaiStringErrorRequest".} +proc sfdnsresGetAddrInfoRequest*(cancelHandle: U32; useNsd: bool; node: cstring; + service: cstring; inHints: pointer; + inHintsSize: csize_t; outBuffer: pointer; + outBufferSize: csize_t; errno: ptr U32; ret: ptr S32; + outSerializedSize: ptr U32): Result {.cdecl, + importc: "sfdnsresGetAddrInfoRequest".} +proc sfdnsresGetNameInfoRequest*(flags: U32; inSa: pointer; inSaSize: csize_t; + outHost: cstring; outHostSize: csize_t; + outServ: cstring; outServLen: csize_t; + cancelHandle: U32; errno: ptr U32; ret: ptr S32): Result {. + cdecl, importc: "sfdnsresGetNameInfoRequest".} +proc sfdnsresGetCancelHandleRequest*(outHandle: ptr U32): Result {.cdecl, + importc: "sfdnsresGetCancelHandleRequest".} +proc sfdnsresCancelRequest*(handle: U32): Result {.cdecl, + importc: "sfdnsresCancelRequest".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/sm.h b/src/libnx/wrapper/switch/services/sm.h new file mode 100644 index 0000000..b8e30b1 --- /dev/null +++ b/src/libnx/wrapper/switch/services/sm.h @@ -0,0 +1,169 @@ +/** + * @file sm.h + * @brief Service manager (sm) IPC wrapper. + * @author plutoo + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/svc.h" +#include "../sf/service.h" +#include "../sf/tipc.h" + +/// Structure representing a service name (null terminated, remaining characters set to zero). +typedef struct SmServiceName { + char name[8]; +} SmServiceName; + +/// Converts a service name into a 64-bit integer. +NX_CONSTEXPR u64 smServiceNameToU64(SmServiceName name) +{ + u64 ret = 0; + __builtin_memcpy(&ret, &name, sizeof(u64)); + return ret; +} + +/// Converts a 64-bit integer into a service name. +NX_CONSTEXPR SmServiceName smServiceNameFromU64(u64 name) +{ + SmServiceName ret = {0}; + __builtin_memcpy(&ret, &name, sizeof(SmServiceName)); + return ret; +} + +/** + * @brief Checks whether two service names are equal. + * @param[in] a First name. + * @param[in] b Second name. + * @return Comparison result. + */ +NX_CONSTEXPR bool smServiceNamesAreEqual(SmServiceName a, SmServiceName b) +{ + return smServiceNameToU64(a) == smServiceNameToU64(b); +} + +#define __COPY_CHAR(_n) if (len > _n) name_encoded.name[_n] = name[_n] +/** + * @brief Encodes a service name string as a \ref SmServiceName structure. + * @param[in] name Name of the service. + * @return Encoded name. + */ +NX_CONSTEXPR SmServiceName smEncodeName(const char* name) +{ + SmServiceName name_encoded = {}; + unsigned len = __builtin_strlen(name); + __COPY_CHAR(0); __COPY_CHAR(1); __COPY_CHAR(2); __COPY_CHAR(3); + __COPY_CHAR(4); __COPY_CHAR(5); __COPY_CHAR(6); __COPY_CHAR(7); + return name_encoded; +} + +/** + * @brief Initializes SM. + * @return Result code. + * @note This function is already called in the default application startup code (before main() is called). + */ +Result smInitialize(void); + +/** + * @brief Uninitializes SM. + * @return Result code. + * @note This function is already handled in the default application exit code (after main() returns). + */ +void smExit(void); + +/** + * @brief Requests a service from SM, allowing overrides. + * @param[out] service_out Service structure which will be filled in. + * @param[in] name Name of the service to request. + * @return Result code. + */ +Result smGetServiceWrapper(Service* service_out, SmServiceName name); + +/** + * @brief Requests a service from SM, as an IPC session handle directly + * @param[out] handle_out Variable containing IPC session handle. + * @param[in] name Name of the service to request. + * @return Result code. + */ +Result smGetServiceOriginal(Handle* handle_out, SmServiceName name); + +/** + * @brief Requests a service from SM. + * @param[out] service_out Service structure which will be filled in. + * @param[in] name Name of the service to request (as a string). + * @return Result code. + */ +NX_INLINE Result smGetService(Service* service_out, const char* name) +{ + return smGetServiceWrapper(service_out, smEncodeName(name)); +} + +/** + * @brief Retrieves an overriden service in the homebrew environment. + * @param[in] name Name of the service to request. + * @return IPC session handle. + */ +Handle smGetServiceOverride(SmServiceName name); + +/** + * @brief Creates and registers a new service within SM. + * @param[out] handle_out Variable containing IPC port handle. + * @param[in] name Name of the service. + * @param[in] is_light "Is light" + * @param[in] max_sessions Maximum number of concurrent sessions that the service will accept. + * @return Result code. + */ +Result smRegisterService(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions); + +/// Same as \ref smRegisterService, but always using cmif serialization. +Result smRegisterServiceCmif(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions); + +/// Same as \ref smRegisterService, but always using tipc serialization. +Result smRegisterServiceTipc(Handle* handle_out, SmServiceName name, bool is_light, s32 max_sessions); + +/** + * @brief Unregisters a previously registered service in SM. + * @param[in] name Name of the service. + * @return Result code. + */ +Result smUnregisterService(SmServiceName name); + +/// Same as \ref smUnregisterService, but always using cmif serialization. +Result smUnregisterServiceCmif(SmServiceName name); + +/// Same as \ref smUnregisterService, but always using tipc serialization. +Result smUnregisterServiceTipc(SmServiceName name); + +/** + * @brief Detaches the current SM session. + * @note After this function is called, the rest of the SM API cannot be used. + * @note Only available on [11.0.0-11.0.1], or Atmosphère. + */ +Result smDetachClient(void); + +/// Same as \ref smDetachClient, but always using cmif serialization. +Result smDetachClientCmif(void); + +/// Same as \ref smDetachClient, but always using tipc serialization. +Result smDetachClientTipc(void); + +/** + * @brief Gets the Service session used to communicate with SM. + * @return Pointer to service session used to communicate with SM. + */ +Service *smGetServiceSession(void); + +/** + * @brief Gets the TipcService session used to communicate with SM. + * @return Pointer to tipc service session used to communicate with SM. + * @note Only available on [12.0.0+], or Atmosphère. + */ +TipcService *smGetServiceSessionTipc(void); + +/** + * @brief Overrides a service with a custom IPC service handle. + * @param[in] name Name of the service. + * @param[in] handle IPC session handle. + */ +void smAddOverrideHandle(SmServiceName name, Handle handle); diff --git a/src/libnx/wrapper/switch/services/sm.nim b/src/libnx/wrapper/switch/services/sm.nim new file mode 100644 index 0000000..e05ca0f --- /dev/null +++ b/src/libnx/wrapper/switch/services/sm.nim @@ -0,0 +1,187 @@ +## * +## @file sm.h +## @brief Service manager (sm) IPC wrapper. +## @author plutoo +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../sf/tipc + +## / Structure representing a service name (null terminated, remaining characters set to zero). + +type + SmServiceName* {.bycopy.} = object + name*: array[8, char] + +proc smServiceNameToU64*(name: SmServiceName): U64 {.inline, cdecl.} = + ## / Converts a service name into a 64-bit integer. + var ret: U64 = 0 + copyMem(addr(ret), addr(name), sizeof((U64))) + return ret + +proc smServiceNameFromU64*(name: U64): SmServiceName {.inline, cdecl.} = + ## / Converts a 64-bit integer into a service name. + var ret: SmServiceName = SmServiceName() + copyMem(addr(ret), addr(name), sizeof((SmServiceName))) + return ret + +proc smServiceNamesAreEqual*(a: SmServiceName; b: SmServiceName): bool {.inline, cdecl.} = + ## * + ## @brief Checks whether two service names are equal. + ## @param[in] a First name. + ## @param[in] b Second name. + ## @return Comparison result. + ## + return smServiceNameToU64(a) == smServiceNameToU64(b) + +proc smEncodeName*(name: cstring): SmServiceName {.inline, cdecl.} = + ## * + ## @brief Encodes a service name string as a \ref SmServiceName structure. + ## @param[in] name Name of the service. + ## @return Encoded name. + ## + + var nameEncoded: SmServiceName = SmServiceName() + var len: cuint = len(name).cuint + if len > 0: + nameEncoded.name[0] = name[0] + if len > 1: + nameEncoded.name[1] = name[1] + if len > 2: + nameEncoded.name[2] = name[2] + if len > 3: + nameEncoded.name[3] = name[3] + if len > 4: + nameEncoded.name[4] = name[4] + if len > 5: + nameEncoded.name[5] = name[5] + if len > 6: + nameEncoded.name[6] = name[6] + if len > 7: + nameEncoded.name[7] = name[7] + return nameEncoded + +proc smInitialize*(): Result {.cdecl, importc: "smInitialize".} +## * +## @brief Initializes SM. +## @return Result code. +## @note This function is already called in the default application startup code (before main() is called). +## + +proc smExit*() {.cdecl, importc: "smExit".} +## * +## @brief Uninitializes SM. +## @return Result code. +## @note This function is already handled in the default application exit code (after main() returns). +## + +proc smGetServiceWrapper*(serviceOut: ptr Service; name: SmServiceName): Result {. + cdecl, importc: "smGetServiceWrapper".} +## * +## @brief Requests a service from SM, allowing overrides. +## @param[out] service_out Service structure which will be filled in. +## @param[in] name Name of the service to request. +## @return Result code. +## + +proc smGetServiceOriginal*(handleOut: ptr Handle; name: SmServiceName): Result {.cdecl, + importc: "smGetServiceOriginal".} +## * +## @brief Requests a service from SM, as an IPC session handle directly +## @param[out] handle_out Variable containing IPC session handle. +## @param[in] name Name of the service to request. +## @return Result code. +## + +proc smGetService*(serviceOut: ptr Service; name: cstring): Result {.inline, cdecl.} = + ## * + ## @brief Requests a service from SM. + ## @param[out] service_out Service structure which will be filled in. + ## @param[in] name Name of the service to request (as a string). + ## @return Result code. + ## + return smGetServiceWrapper(serviceOut, smEncodeName(name)) + +proc smGetServiceOverride*(name: SmServiceName): Handle {.cdecl, + importc: "smGetServiceOverride".} +## * +## @brief Retrieves an overriden service in the homebrew environment. +## @param[in] name Name of the service to request. +## @return IPC session handle. +## + +proc smRegisterService*(handleOut: ptr Handle; name: SmServiceName; isLight: bool; + maxSessions: S32): Result {.cdecl, + importc: "smRegisterService".} +## * +## @brief Creates and registers a new service within SM. +## @param[out] handle_out Variable containing IPC port handle. +## @param[in] name Name of the service. +## @param[in] is_light "Is light" +## @param[in] max_sessions Maximum number of concurrent sessions that the service will accept. +## @return Result code. +## + +proc smRegisterServiceCmif*(handleOut: ptr Handle; name: SmServiceName; isLight: bool; + maxSessions: S32): Result {.cdecl, + importc: "smRegisterServiceCmif".} +## / Same as \ref smRegisterService, but always using cmif serialization. + +proc smRegisterServiceTipc*(handleOut: ptr Handle; name: SmServiceName; isLight: bool; + maxSessions: S32): Result {.cdecl, + importc: "smRegisterServiceTipc".} +## / Same as \ref smRegisterService, but always using tipc serialization. + +proc smUnregisterService*(name: SmServiceName): Result {.cdecl, + importc: "smUnregisterService".} +## * +## @brief Unregisters a previously registered service in SM. +## @param[in] name Name of the service. +## @return Result code. +## + +proc smUnregisterServiceCmif*(name: SmServiceName): Result {.cdecl, + importc: "smUnregisterServiceCmif".} +## / Same as \ref smUnregisterService, but always using cmif serialization. + +proc smUnregisterServiceTipc*(name: SmServiceName): Result {.cdecl, + importc: "smUnregisterServiceTipc".} +## / Same as \ref smUnregisterService, but always using tipc serialization. + +proc smDetachClient*(): Result {.cdecl, importc: "smDetachClient".} +## * +## @brief Detaches the current SM session. +## @note After this function is called, the rest of the SM API cannot be used. +## @note Only available on [11.0.0-11.0.1], or Atmosphère. +## + +proc smDetachClientCmif*(): Result {.cdecl, importc: "smDetachClientCmif".} +## / Same as \ref smDetachClient, but always using cmif serialization. + +proc smDetachClientTipc*(): Result {.cdecl, importc: "smDetachClientTipc".} +## / Same as \ref smDetachClient, but always using tipc serialization. + +proc smGetServiceSession*(): ptr Service {.cdecl, importc: "smGetServiceSession".} +## * +## @brief Gets the Service session used to communicate with SM. +## @return Pointer to service session used to communicate with SM. +## + +proc smGetServiceSessionTipc*(): ptr TipcService {.cdecl, + importc: "smGetServiceSessionTipc".} +## * +## @brief Gets the TipcService session used to communicate with SM. +## @return Pointer to tipc service session used to communicate with SM. +## @note Only available on [12.0.0+], or Atmosphère. +## + +proc smAddOverrideHandle*(name: SmServiceName; handle: Handle) {.cdecl, + importc: "smAddOverrideHandle".} +## * +## @brief Overrides a service with a custom IPC service handle. +## @param[in] name Name of the service. +## @param[in] handle IPC session handle. +## + diff --git a/src/libnx/wrapper/switch/services/smm.h b/src/libnx/wrapper/switch/services/smm.h new file mode 100644 index 0000000..b591e78 --- /dev/null +++ b/src/libnx/wrapper/switch/services/smm.h @@ -0,0 +1,43 @@ +/** + * @file smm.h + * @brief ServiceManager-IManager (sm:m) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../sf/tipc.h" + +/// Initialize sm:m. +Result smManagerInitialize(void); + +/// Exit sm:m. +void smManagerExit(void); + +Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size); +Result smManagerUnregisterProcess(u64 pid); + +/// Initialize sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere). +Result smManagerCmifInitialize(void); + +/// Exit sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere). +void smManagerCmifExit(void); + +/// Gets the Service object for the actual sm:m service session (requires <12.0.0 and non-Atmosphere). +Service* smManagerCmifGetServiceSession(void); + +Result smManagerCmifRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size); +Result smManagerCmifUnregisterProcess(u64 pid); + +/// Initialize sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere). +Result smManagerTipcInitialize(void); + +/// Exit sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere). +void smManagerTipcExit(void); + +/// Gets the TipcService object for the actual sm:m service session (requires 12.0.0+ or Atmosphere). +TipcService* smManagerTipcGetServiceSession(void); + +Result smManagerTipcRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size); +Result smManagerTipcUnregisterProcess(u64 pid); diff --git a/src/libnx/wrapper/switch/services/smm.nim b/src/libnx/wrapper/switch/services/smm.nim new file mode 100644 index 0000000..923206e --- /dev/null +++ b/src/libnx/wrapper/switch/services/smm.nim @@ -0,0 +1,51 @@ +## * +## @file smm.h +## @brief ServiceManager-IManager (sm:m) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../sf/tipc + +## / Initialize sm:m. + +proc smManagerInitialize*(): Result {.cdecl, importc: "smManagerInitialize".} +## / Exit sm:m. + +proc smManagerExit*() {.cdecl, importc: "smManagerExit".} +proc smManagerRegisterProcess*(pid: U64; acidSac: pointer; acidSacSize: csize_t; + aci0Sac: pointer; aci0SacSize: csize_t): Result {. + cdecl, importc: "smManagerRegisterProcess".} +proc smManagerUnregisterProcess*(pid: U64): Result {.cdecl, + importc: "smManagerUnregisterProcess".} +## / Initialize sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere). + +proc smManagerCmifInitialize*(): Result {.cdecl, importc: "smManagerCmifInitialize".} +## / Exit sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere). + +proc smManagerCmifExit*() {.cdecl, importc: "smManagerCmifExit".} +## / Gets the Service object for the actual sm:m service session (requires <12.0.0 and non-Atmosphere). + +proc smManagerCmifGetServiceSession*(): ptr Service {.cdecl, + importc: "smManagerCmifGetServiceSession".} +proc smManagerCmifRegisterProcess*(pid: U64; acidSac: pointer; acidSacSize: csize_t; + aci0Sac: pointer; aci0SacSize: csize_t): Result {. + cdecl, importc: "smManagerCmifRegisterProcess".} +proc smManagerCmifUnregisterProcess*(pid: U64): Result {.cdecl, + importc: "smManagerCmifUnregisterProcess".} +## / Initialize sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere). + +proc smManagerTipcInitialize*(): Result {.cdecl, importc: "smManagerTipcInitialize".} +## / Exit sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere). + +proc smManagerTipcExit*() {.cdecl, importc: "smManagerTipcExit".} +## / Gets the TipcService object for the actual sm:m service session (requires 12.0.0+ or Atmosphere). + +proc smManagerTipcGetServiceSession*(): ptr TipcService {.cdecl, + importc: "smManagerTipcGetServiceSession".} +proc smManagerTipcRegisterProcess*(pid: U64; acidSac: pointer; acidSacSize: csize_t; + aci0Sac: pointer; aci0SacSize: csize_t): Result {. + cdecl, importc: "smManagerTipcRegisterProcess".} +proc smManagerTipcUnregisterProcess*(pid: U64): Result {.cdecl, + importc: "smManagerTipcUnregisterProcess".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/spl.h b/src/libnx/wrapper/switch/services/spl.h new file mode 100644 index 0000000..9761ec2 --- /dev/null +++ b/src/libnx/wrapper/switch/services/spl.h @@ -0,0 +1,129 @@ +/** + * @file spl.h + * @brief Security Processor Liaison (spl*) service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" + +#define SPL_RSA_BUFFER_SIZE (0x100) + +typedef enum { + SplConfigItem_DisableProgramVerification = 1, + SplConfigItem_DramId = 2, + SplConfigItem_SecurityEngineIrqNumber = 3, + SplConfigItem_Version = 4, + SplConfigItem_HardwareType = 5, + SplConfigItem_IsRetail = 6, + SplConfigItem_IsRecoveryBoot = 7, + SplConfigItem_DeviceId = 8, + SplConfigItem_BootReason = 9, + SplConfigItem_MemoryArrange = 10, + SplConfigItem_IsDebugMode = 11, + SplConfigItem_KernelMemoryConfiguration = 12, + SplConfigItem_IsChargerHiZModeEnabled = 13, + SplConfigItem_IsKiosk = 14, + SplConfigItem_NewHardwareType = 15, + SplConfigItem_NewKeyGeneration = 16, + SplConfigItem_Package2Hash = 17, +} SplConfigItem; + +typedef enum { + RsaKeyVersion_Deprecated = 0, + RsaKeyVersion_Extended = 1, +} RsaKeyVersion; + +/// Initialize 'spl:'. +Result splInitialize(void); + +/// Exit 'spl:'. +void splExit(void); + +/// Gets the Service object for the IGeneralInterface usable with spl*(). +Service* splGetServiceSession(void); + +/// Initialize spl:mig. On pre-4.0.0 this just calls \ref splInitialize. +Result splCryptoInitialize(void); + +/// Exit spl:mig. On pre-4.0.0 this just calls \ref splExit. +void splCryptoExit(void); + +/// Gets the Service object for the IGeneralInterface usable with splCrypto*(). +Service* splCryptoGetServiceSession(void); + +/// Initialize spl:ssl. On pre-4.0.0 this just calls \ref splInitialize. +Result splSslInitialize(void); + +/// Exit spl:ssl. On pre-4.0.0 this just calls \ref splExit. +void splSslExit(void); + +/// Gets the Service object for the IGeneralInterface usable with splSsl*(). +Service* splSslGetServiceSession(void); + +/// Initialize spl:es. On pre-4.0.0 this just calls \ref splInitialize. +Result splEsInitialize(void); + +/// Exit spl:es. On pre-4.0.0 this just calls \ref splExit. +void splEsExit(void); + +/// Gets the Service object for the IGeneralInterface usable with splEs*(). +Service* splEsGetServiceSession(void); + +/// Initialize spl:fs. On pre-4.0.0 this just calls \ref splInitialize. +Result splFsInitialize(void); + +/// Exit spl:fs. On pre-4.0.0 this just calls \ref splExit. +void splFsExit(void); + +/// Gets the Service object for the IGeneralInterface usable with splFs*(). +Service* splFsGetServiceSession(void); + +/// Initialize spl:manu. On pre-4.0.0 this just calls \ref splInitialize. +Result splManuInitialize(void); + +/// Exit spl:manu. On pre-4.0.0 this just calls \ref splExit. +void splManuExit(void); + +/// Gets the Service object for the IGeneralInterface usable with splManu*(). +Service* splManuGetServiceSession(void); + +Result splGetConfig(SplConfigItem config_item, u64 *out_config); +Result splUserExpMod(const void *input, const void *modulus, const void *exp, size_t exp_size, void *dst); +Result splSetConfig(SplConfigItem config_item, u64 value); +Result splGetRandomBytes(void *out, size_t out_size); +Result splIsDevelopment(bool *out_is_development); +Result splSetBootReason(u32 value); +Result splGetBootReason(u32 *out_value); + +Result splCryptoGenerateAesKek(const void *wrapped_kek, u32 key_generation, u32 option, void *out_sealed_kek); +Result splCryptoLoadAesKey(const void *sealed_kek, const void *wrapped_key, u32 keyslot); +Result splCryptoGenerateAesKey(const void *sealed_kek, const void *wrapped_key, void *out_sealed_key); +Result splCryptoDecryptAesKey(const void *wrapped_key, u32 key_generation, u32 option, void *out_sealed_key); +Result splCryptoCryptAesCtr(const void *input, void *output, size_t size, u32 keyslot, const void *ctr); +Result splCryptoComputeCmac(const void *input, size_t size, u32 keyslot, void *out_cmac); +Result splCryptoLockAesEngine(u32 *out_keyslot); +Result splCryptoUnlockAesEngine(u32 keyslot); +Result splCryptoGetSecurityEngineEvent(Event *out_event); + +Result splRsaDecryptPrivateKey(const void *sealed_kek, const void *wrapped_key, const void *wrapped_rsa_key, size_t wrapped_rsa_key_size, RsaKeyVersion version, void *dst, size_t dst_size); + +Result splSslLoadSecureExpModKey(const void *sealed_kek, const void *wrapped_key, const void *wrapped_rsa_key, size_t wrapped_rsa_key_size); +Result splSslSecureExpMod(const void *input, const void *modulus, void *dst); + +Result splEsLoadRsaOaepKey(const void *sealed_kek, const void *wrapped_key, const void *wrapped_rsa_key, size_t wrapped_rsa_key_size, RsaKeyVersion version); +Result splEsUnwrapRsaOaepWrappedTitlekey(const void *rsa_wrapped_titlekey, const void *modulus, const void *label_hash, size_t label_hash_size, u32 key_generation, void *out_sealed_titlekey); +Result splEsUnwrapAesWrappedTitlekey(const void *aes_wrapped_titlekey, u32 key_generation, void *out_sealed_titlekey); +Result splEsLoadSecureExpModKey(const void *sealed_kek, const void *wrapped_key, const void *wrapped_rsa_key, size_t wrapped_rsa_key_size); +Result splEsSecureExpMod(const void *input, const void *modulus, void *dst); +Result splEsUnwrapElicenseKey(const void *rsa_wrapped_elicense_key, const void *modulus, const void *label_hash, size_t label_hash_size, u32 key_generation, void *out_sealed_elicense_key); +Result splEsLoadElicenseKey(const void *sealed_elicense_key, u32 keyslot); + +Result splFsLoadSecureExpModKey(const void *sealed_kek, const void *wrapped_key, const void *wrapped_rsa_key, size_t wrapped_rsa_key_size, RsaKeyVersion version); +Result splFsSecureExpMod(const void *input, const void *modulus, void *dst); +Result splFsGenerateSpecificAesKey(const void *wrapped_key, u32 key_generation, u32 option, void *out_sealed_key); +Result splFsLoadTitlekey(const void *sealed_titlekey, u32 keyslot); +Result splFsGetPackage2Hash(void *out_hash); + +Result splManuEncryptRsaKeyForImport(const void *sealed_kek_pre, const void *wrapped_key_pre, const void *sealed_kek_post, const void *wrapped_kek_post, u32 option, const void *wrapped_rsa_key, void *out_wrapped_rsa_key, size_t rsa_key_size); diff --git a/src/libnx/wrapper/switch/services/spl.nim b/src/libnx/wrapper/switch/services/spl.nim new file mode 100644 index 0000000..1c0ad7a --- /dev/null +++ b/src/libnx/wrapper/switch/services/spl.nim @@ -0,0 +1,173 @@ +## * +## @file spl.h +## @brief Security Processor Liaison (spl*) service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +const + SPL_RSA_BUFFER_SIZE* = (0x100) + +type + SplConfigItem* = enum + SplConfigItemDisableProgramVerification = 1, SplConfigItemDramId = 2, + SplConfigItemSecurityEngineIrqNumber = 3, SplConfigItemVersion = 4, + SplConfigItemHardwareType = 5, SplConfigItemIsRetail = 6, + SplConfigItemIsRecoveryBoot = 7, SplConfigItemDeviceId = 8, + SplConfigItemBootReason = 9, SplConfigItemMemoryArrange = 10, + SplConfigItemIsDebugMode = 11, SplConfigItemKernelMemoryConfiguration = 12, + SplConfigItemIsChargerHiZModeEnabled = 13, SplConfigItemIsKiosk = 14, + SplConfigItemNewHardwareType = 15, SplConfigItemNewKeyGeneration = 16, + SplConfigItemPackage2Hash = 17 + RsaKeyVersion* = enum + RsaKeyVersionDeprecated = 0, RsaKeyVersionExtended = 1 + + +proc splInitialize*(): Result {.cdecl, importc: "splInitialize".} +## / Initialize 'spl:'. + +proc splExit*() {.cdecl, importc: "splExit".} +## / Exit 'spl:'. + +proc splGetServiceSession*(): ptr Service {.cdecl, importc: "splGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with spl*(). + +proc splCryptoInitialize*(): Result {.cdecl, importc: "splCryptoInitialize".} +## / Initialize spl:mig. On pre-4.0.0 this just calls \ref splInitialize. + +proc splCryptoExit*() {.cdecl, importc: "splCryptoExit".} +## / Exit spl:mig. On pre-4.0.0 this just calls \ref splExit. + +proc splCryptoGetServiceSession*(): ptr Service {.cdecl, + importc: "splCryptoGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with splCrypto*(). + +proc splSslInitialize*(): Result {.cdecl, importc: "splSslInitialize".} +## / Initialize spl:ssl. On pre-4.0.0 this just calls \ref splInitialize. + +proc splSslExit*() {.cdecl, importc: "splSslExit".} +## / Exit spl:ssl. On pre-4.0.0 this just calls \ref splExit. + +proc splSslGetServiceSession*(): ptr Service {.cdecl, + importc: "splSslGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with splSsl*(). + +proc splEsInitialize*(): Result {.cdecl, importc: "splEsInitialize".} +## / Initialize spl:es. On pre-4.0.0 this just calls \ref splInitialize. + +proc splEsExit*() {.cdecl, importc: "splEsExit".} +## / Exit spl:es. On pre-4.0.0 this just calls \ref splExit. + +proc splEsGetServiceSession*(): ptr Service {.cdecl, + importc: "splEsGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with splEs*(). + +proc splFsInitialize*(): Result {.cdecl, importc: "splFsInitialize".} +## / Initialize spl:fs. On pre-4.0.0 this just calls \ref splInitialize. + +proc splFsExit*() {.cdecl, importc: "splFsExit".} +## / Exit spl:fs. On pre-4.0.0 this just calls \ref splExit. + +proc splFsGetServiceSession*(): ptr Service {.cdecl, + importc: "splFsGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with splFs*(). + +proc splManuInitialize*(): Result {.cdecl, importc: "splManuInitialize".} +## / Initialize spl:manu. On pre-4.0.0 this just calls \ref splInitialize. + +proc splManuExit*() {.cdecl, importc: "splManuExit".} +## / Exit spl:manu. On pre-4.0.0 this just calls \ref splExit. + +proc splManuGetServiceSession*(): ptr Service {.cdecl, + importc: "splManuGetServiceSession".} +## / Gets the Service object for the IGeneralInterface usable with splManu*(). + +proc splGetConfig*(configItem: SplConfigItem; outConfig: ptr U64): Result {.cdecl, + importc: "splGetConfig".} +proc splUserExpMod*(input: pointer; modulus: pointer; exp: pointer; expSize: csize_t; + dst: pointer): Result {.cdecl, importc: "splUserExpMod".} +proc splSetConfig*(configItem: SplConfigItem; value: U64): Result {.cdecl, + importc: "splSetConfig".} +proc splGetRandomBytes*(`out`: pointer; outSize: csize_t): Result {.cdecl, + importc: "splGetRandomBytes".} +proc splIsDevelopment*(outIsDevelopment: ptr bool): Result {.cdecl, + importc: "splIsDevelopment".} +proc splSetBootReason*(value: U32): Result {.cdecl, importc: "splSetBootReason".} +proc splGetBootReason*(outValue: ptr U32): Result {.cdecl, importc: "splGetBootReason".} +proc splCryptoGenerateAesKek*(wrappedKek: pointer; keyGeneration: U32; option: U32; + outSealedKek: pointer): Result {.cdecl, + importc: "splCryptoGenerateAesKek".} +proc splCryptoLoadAesKey*(sealedKek: pointer; wrappedKey: pointer; keyslot: U32): Result {. + cdecl, importc: "splCryptoLoadAesKey".} +proc splCryptoGenerateAesKey*(sealedKek: pointer; wrappedKey: pointer; + outSealedKey: pointer): Result {.cdecl, + importc: "splCryptoGenerateAesKey".} +proc splCryptoDecryptAesKey*(wrappedKey: pointer; keyGeneration: U32; option: U32; + outSealedKey: pointer): Result {.cdecl, + importc: "splCryptoDecryptAesKey".} +proc splCryptoCryptAesCtr*(input: pointer; output: pointer; size: csize_t; + keyslot: U32; ctr: pointer): Result {.cdecl, + importc: "splCryptoCryptAesCtr".} +proc splCryptoComputeCmac*(input: pointer; size: csize_t; keyslot: U32; + outCmac: pointer): Result {.cdecl, + importc: "splCryptoComputeCmac".} +proc splCryptoLockAesEngine*(outKeyslot: ptr U32): Result {.cdecl, + importc: "splCryptoLockAesEngine".} +proc splCryptoUnlockAesEngine*(keyslot: U32): Result {.cdecl, + importc: "splCryptoUnlockAesEngine".} +proc splCryptoGetSecurityEngineEvent*(outEvent: ptr Event): Result {.cdecl, + importc: "splCryptoGetSecurityEngineEvent".} +proc splRsaDecryptPrivateKey*(sealedKek: pointer; wrappedKey: pointer; + wrappedRsaKey: pointer; wrappedRsaKeySize: csize_t; + version: RsaKeyVersion; dst: pointer; dstSize: csize_t): Result {. + cdecl, importc: "splRsaDecryptPrivateKey".} +proc splSslLoadSecureExpModKey*(sealedKek: pointer; wrappedKey: pointer; + wrappedRsaKey: pointer; wrappedRsaKeySize: csize_t): Result {. + cdecl, importc: "splSslLoadSecureExpModKey".} +proc splSslSecureExpMod*(input: pointer; modulus: pointer; dst: pointer): Result {. + cdecl, importc: "splSslSecureExpMod".} +proc splEsLoadRsaOaepKey*(sealedKek: pointer; wrappedKey: pointer; + wrappedRsaKey: pointer; wrappedRsaKeySize: csize_t; + version: RsaKeyVersion): Result {.cdecl, + importc: "splEsLoadRsaOaepKey".} +proc splEsUnwrapRsaOaepWrappedTitlekey*(rsaWrappedTitlekey: pointer; + modulus: pointer; labelHash: pointer; + labelHashSize: csize_t; keyGeneration: U32; + outSealedTitlekey: pointer): Result {.cdecl, + importc: "splEsUnwrapRsaOaepWrappedTitlekey".} +proc splEsUnwrapAesWrappedTitlekey*(aesWrappedTitlekey: pointer; + keyGeneration: U32; outSealedTitlekey: pointer): Result {. + cdecl, importc: "splEsUnwrapAesWrappedTitlekey".} +proc splEsLoadSecureExpModKey*(sealedKek: pointer; wrappedKey: pointer; + wrappedRsaKey: pointer; wrappedRsaKeySize: csize_t): Result {. + cdecl, importc: "splEsLoadSecureExpModKey".} +proc splEsSecureExpMod*(input: pointer; modulus: pointer; dst: pointer): Result {.cdecl, + importc: "splEsSecureExpMod".} +proc splEsUnwrapElicenseKey*(rsaWrappedElicenseKey: pointer; modulus: pointer; + labelHash: pointer; labelHashSize: csize_t; + keyGeneration: U32; outSealedElicenseKey: pointer): Result {. + cdecl, importc: "splEsUnwrapElicenseKey".} +proc splEsLoadElicenseKey*(sealedElicenseKey: pointer; keyslot: U32): Result {.cdecl, + importc: "splEsLoadElicenseKey".} +proc splFsLoadSecureExpModKey*(sealedKek: pointer; wrappedKey: pointer; + wrappedRsaKey: pointer; wrappedRsaKeySize: csize_t; + version: RsaKeyVersion): Result {.cdecl, + importc: "splFsLoadSecureExpModKey".} +proc splFsSecureExpMod*(input: pointer; modulus: pointer; dst: pointer): Result {.cdecl, + importc: "splFsSecureExpMod".} +proc splFsGenerateSpecificAesKey*(wrappedKey: pointer; keyGeneration: U32; + option: U32; outSealedKey: pointer): Result {.cdecl, + importc: "splFsGenerateSpecificAesKey".} +proc splFsLoadTitlekey*(sealedTitlekey: pointer; keyslot: U32): Result {.cdecl, + importc: "splFsLoadTitlekey".} +proc splFsGetPackage2Hash*(outHash: pointer): Result {.cdecl, + importc: "splFsGetPackage2Hash".} +proc splManuEncryptRsaKeyForImport*(sealedKekPre: pointer; wrappedKeyPre: pointer; + sealedKekPost: pointer; + wrappedKekPost: pointer; option: U32; + wrappedRsaKey: pointer; + outWrappedRsaKey: pointer; rsaKeySize: csize_t): Result {. + cdecl, importc: "splManuEncryptRsaKeyForImport".} diff --git a/src/libnx/wrapper/switch/services/spsm.h b/src/libnx/wrapper/switch/services/spsm.h new file mode 100644 index 0000000..6bb0cd4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/spsm.h @@ -0,0 +1,21 @@ +/** + * @file spsm.h + * @brief SPSM service IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Initialize spsm. +Result spsmInitialize(void); + +/// Exit spsm. +void spsmExit(void); + +/// Gets the Service object for the actual spsm service session. +Service* spsmGetServiceSession(void); + +Result spsmShutdown(bool reboot); +Result spsmPutErrorState(void); diff --git a/src/libnx/wrapper/switch/services/spsm.nim b/src/libnx/wrapper/switch/services/spsm.nim new file mode 100644 index 0000000..33c8ec6 --- /dev/null +++ b/src/libnx/wrapper/switch/services/spsm.nim @@ -0,0 +1,21 @@ +## * +## @file spsm.h +## @brief SPSM service IPC wrapper. +## @author SciresM +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Initialize spsm. + +proc spsmInitialize*(): Result {.cdecl, importc: "spsmInitialize".} +## / Exit spsm. + +proc spsmExit*() {.cdecl, importc: "spsmExit".} +## / Gets the Service object for the actual spsm service session. + +proc spsmGetServiceSession*(): ptr Service {.cdecl, importc: "spsmGetServiceSession".} +proc spsmShutdown*(reboot: bool): Result {.cdecl, importc: "spsmShutdown".} +proc spsmPutErrorState*(): Result {.cdecl, importc: "spsmPutErrorState".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/ssl.h b/src/libnx/wrapper/switch/services/ssl.h new file mode 100644 index 0000000..74a4791 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ssl.h @@ -0,0 +1,623 @@ +/** + * @file fs.h + * @brief SSL service IPC wrapper, for using client-mode TLS. See also: https://switchbrew.org/wiki/SSL_services + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// CaCertificateId +typedef enum { + SslCaCertificateId_All = -1, ///< [3.0.0+] All + + SslCaCertificateId_NintendoCAG3 = 1, ///< NintendoCAG3 + SslCaCertificateId_NintendoClass2CAG3 = 2, ///< NintendoClass2CAG3 + + SslCaCertificateId_AmazonRootCA1 = 1000, ///< AmazonRootCA1 + SslCaCertificateId_StarfieldServicesRootCertificateAuthorityG2 = 1001, ///< StarfieldServicesRootCertificateAuthorityG2 + SslCaCertificateId_AddTrustExternalCARoot = 1002, ///< AddTrustExternalCARoot + SslCaCertificateId_COMODOCertificationAuthority = 1003, ///< COMODOCertificationAuthority + SslCaCertificateId_UTNDATACorpSGC = 1004, ///< UTNDATACorpSGC + SslCaCertificateId_UTNUSERFirstHardware = 1005, ///< UTNUSERFirstHardware + SslCaCertificateId_BaltimoreCyberTrustRoot = 1006, ///< BaltimoreCyberTrustRoot + SslCaCertificateId_CybertrustGlobalRoot = 1007, ///< CybertrustGlobalRoot + SslCaCertificateId_VerizonGlobalRootCA = 1008, ///< VerizonGlobalRootCA + SslCaCertificateId_DigiCertAssuredIDRootCA = 1009, ///< DigiCertAssuredIDRootCA + SslCaCertificateId_DigiCertAssuredIDRootG2 = 1010, ///< DigiCertAssuredIDRootG2 + SslCaCertificateId_DigiCertGlobalRootCA = 1011, ///< DigiCertGlobalRootCA + SslCaCertificateId_DigiCertGlobalRootG2 = 1012, ///< DigiCertGlobalRootG2 + SslCaCertificateId_DigiCertHighAssuranceEVRootCA = 1013, ///< DigiCertHighAssuranceEVRootCA + SslCaCertificateId_EntrustnetCertificationAuthority2048 = 1014, ///< EntrustnetCertificationAuthority2048 + SslCaCertificateId_EntrustRootCertificationAuthority = 1015, ///< EntrustRootCertificationAuthority + SslCaCertificateId_EntrustRootCertificationAuthorityG2 = 1016, ///< EntrustRootCertificationAuthorityG2 + SslCaCertificateId_GeoTrustGlobalCA2 = 1017, ///< GeoTrustGlobalCA2 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_GeoTrustGlobalCA = 1018, ///< GeoTrustGlobalCA ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_GeoTrustPrimaryCertificationAuthorityG3 = 1019, ///< GeoTrustPrimaryCertificationAuthorityG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_GeoTrustPrimaryCertificationAuthority = 1020, ///< GeoTrustPrimaryCertificationAuthority ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_GlobalSignRootCA = 1021, ///< GlobalSignRootCA + SslCaCertificateId_GlobalSignRootCAR2 = 1022, ///< GlobalSignRootCAR2 + SslCaCertificateId_GlobalSignRootCAR3 = 1023, ///< GlobalSignRootCAR3 + SslCaCertificateId_GoDaddyClass2CertificationAuthority = 1024, ///< GoDaddyClass2CertificationAuthority + SslCaCertificateId_GoDaddyRootCertificateAuthorityG2 = 1025, ///< GoDaddyRootCertificateAuthorityG2 + SslCaCertificateId_StarfieldClass2CertificationAuthority = 1026, ///< StarfieldClass2CertificationAuthority + SslCaCertificateId_StarfieldRootCertificateAuthorityG2 = 1027, ///< StarfieldRootCertificateAuthorityG2 + SslCaCertificateId_thawtePrimaryRootCAG3 = 1028, ///< thawtePrimaryRootCAG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_thawtePrimaryRootCA = 1029, ///< thawtePrimaryRootCA ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_VeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, ///< VeriSignClass3PublicPrimaryCertificationAuthorityG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_VeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, ///< VeriSignClass3PublicPrimaryCertificationAuthorityG5 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_VeriSignUniversalRootCertificationAuthority = 1032, ///< VeriSignUniversalRootCertificationAuthority ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateId_DSTRootCAX3 = 1033, ///< [6.0.0+] DSTRootCAX3 +} SslCaCertificateId; + +/// TrustedCertStatus +typedef enum { + SslTrustedCertStatus_Invalid = -1, ///< Invalid + SslTrustedCertStatus_Removed = 0, ///< Removed + SslTrustedCertStatus_EnabledTrusted = 1, ///< EnabledTrusted + SslTrustedCertStatus_EnabledNotTrusted = 2, ///< EnabledNotTrusted + SslTrustedCertStatus_Revoked = 3, ///< Revoked +} SslTrustedCertStatus; + +/// FlushSessionCacheOptionType +typedef enum { + SslFlushSessionCacheOptionType_SingleHost = 0, ///< SingleHost. Uses the input string. + SslFlushSessionCacheOptionType_AllHosts = 1, ///< AllHosts. Doesn't use the input string. +} SslFlushSessionCacheOptionType; + +/// DebugOptionType +typedef enum { + SslDebugOptionType_AllowDisableVerifyOption = 0, ///< AllowDisableVerifyOption +} SslDebugOptionType; + +/// SslVersion. This is a bitmask which controls the min/max TLS versions to use, depending on which lowest/highest bits are set (if Auto* isn't set). +typedef enum { + SslVersion_Auto = BIT(0), ///< TLS version min = 1.0, max = 1.2. + SslVersion_TlsV10 = BIT(3), ///< TLS 1.0. + SslVersion_TlsV11 = BIT(4), ///< TLS 1.1. + SslVersion_TlsV12 = BIT(5), ///< TLS 1.2. + SslVersion_TlsV13 = BIT(6), ///< [11.0.0+] TLS 1.3. + SslVersion_Auto24 = BIT(24), ///< [11.0.0+] Same as Auto. +} SslVersion; + +/// CertificateFormat +typedef enum { + SslCertificateFormat_Pem = 1, ///< Pem + SslCertificateFormat_Der = 2, ///< Der +} SslCertificateFormat; + +/// InternalPki +typedef enum { + SslInternalPki_DeviceClientCertDefault = 1, ///< DeviceClientCertDefault. Enables using the DeviceCert. +} SslInternalPki; + +/// ContextOption +typedef enum { + SslContextOption_CrlImportDateCheckEnable = 1, ///< CrlImportDateCheckEnable. The default value at the time of \ref sslCreateContext is value 1. +} SslContextOption; + +/// VerifyOption. The default bitmask value at the time of \ref sslContextCreateConnection is ::SslVerifyOption_PeerCa | ::SslVerifyOption_HostName. +/// [5.0.0+] \ref sslConnectionSetVerifyOption: (::SslVerifyOption_PeerCa | ::SslVerifyOption_HostName) must be set, unless: ::SslOptionType_SkipDefaultVerify is set, or [9.0.0+] ::SslDebugOptionType_AllowDisableVerifyOption is set. +/// [6.0.0+] \ref sslConnectionSetVerifyOption: Following that, if ::SslVerifyOption_EvPolicyOid is set, then the following options must be set (besides the previously mentioned one): ::SslVerifyOption_PeerCa and ::SslVerifyOption_DateCheck. +typedef enum { + SslVerifyOption_PeerCa = BIT(0), ///< PeerCa + SslVerifyOption_HostName = BIT(1), ///< HostName + SslVerifyOption_DateCheck = BIT(2), ///< DateCheck + SslVerifyOption_EvCertPartial = BIT(3), ///< EvCertPartial + SslVerifyOption_EvPolicyOid = BIT(4), ///< [6.0.0+] EvPolicyOid + SslVerifyOption_EvCertFingerprint = BIT(5), ///< [6.0.0+] EvCertFingerprint +} SslVerifyOption; + +/// IoMode. The default value at the time of \ref sslContextCreateConnection is ::SslIoMode_Blocking. +/// The socket non-blocking flag is always set regardless of this field, this is only used internally for calculating the timeout used by various cmds. +typedef enum { + SslIoMode_Blocking = 1, ///< Blocking. Timeout = 5 minutes. + SslIoMode_NonBlocking = 2, ///< NonBlocking. Timeout = 0. +} SslIoMode; + +/// PollEvent +typedef enum { + SslPollEvent_Read = BIT(0), ///< Read + SslPollEvent_Write = BIT(1), ///< Write + SslPollEvent_Except = BIT(2), ///< Except +} SslPollEvent; + +/// SessionCacheMode +typedef enum { + SslSessionCacheMode_None = 0, ///< None + SslSessionCacheMode_SessionId = 1, ///< SessionId + SslSessionCacheMode_SessionTicket = 2, ///< SessionTicket +} SslSessionCacheMode; + +/// RenegotiationMode +typedef enum { + SslRenegotiationMode_None = 0, ///< None + SslRenegotiationMode_Secure = 1, ///< Secure +} SslRenegotiationMode; + +/// OptionType. The default bool flags value for these at the time of \ref sslContextCreateConnection is cleared. +typedef enum { + SslOptionType_DoNotCloseSocket = 0, ///< DoNotCloseSocket. See \ref sslConnectionSetSocketDescriptor. This is only available if \ref sslConnectionSetSocketDescriptor wasn't used yet. + SslOptionType_GetServerCertChain = 1, ///< [3.0.0+] GetServerCertChain. See \ref sslConnectionDoHandshake. + SslOptionType_SkipDefaultVerify = 2, ///< [5.0.0+] SkipDefaultVerify. Checked by \ref sslConnectionSetVerifyOption, see \ref SslVerifyOption. + SslOptionType_EnableAlpn = 3, ///< [9.0.0+] EnableAlpn. Only available with \ref sslConnectionSetOption. \ref sslConnectionSetSocketDescriptor should have been used prior to this - this will optionally use state setup by that, without throwing an error if that cmd wasn't used. +} SslOptionType; + +/// AlpnProtoState +typedef enum { + SslAlpnProtoState_NoSupport = 0, ///< NoSupport + SslAlpnProtoState_Negotiated = 1, ///< Negotiated + SslAlpnProtoState_NoOverlap = 2, ///< NoOverlap + SslAlpnProtoState_Selected = 3, ///< Selected + SslAlpnProtoState_EarlyValue = 4, ///< EarlyValue +} SslAlpnProtoState; + +/// SslContext +typedef struct { + Service s; ///< ISslContext +} SslContext; + +/// SslConnection +typedef struct { + Service s; ///< ISslConnection +} SslConnection; + +/// BuiltInCertificateInfo +typedef struct { + u32 cert_id; ///< \ref SslCaCertificateId + u32 status; ///< \ref SslTrustedCertStatus + u64 cert_size; ///< CertificateSize + u8 *cert_data; ///< CertificateData (converted from an offset to a ptr), in DER format. +} SslBuiltInCertificateInfo; + +/// SslServerCertDetailHeader +typedef struct { + u64 magicnum; ///< Magicnum. + u32 cert_total; ///< Total certs. + u32 pad; ///< Padding. +} SslServerCertDetailHeader; + +/// SslServerCertDetailEntry +typedef struct { + u32 size; ///< Size. + u32 offset; ///< Offset. +} SslServerCertDetailEntry; + +/// CipherInfo +typedef struct { + char cipher[0x40]; ///< Cipher string. + char protocol_version[0x8]; ///< Protocol version string. +} SslCipherInfo; + +/// Initialize ssl. A default value of 0x3 can be used for num_sessions. This must be 0x1-0x4. +Result sslInitialize(u32 num_sessions); + +/// Exit ssl. +void sslExit(void); + +/// Gets the Service object for the actual ssl service session. +Service* sslGetServiceSession(void); + +/** + * @brief CreateContext + * @note The CertStore is used automatically, regardless of what cmds are used. + * @param[out] c \ref SslContext + * @param[in] ssl_version \ref SslVersion + */ +Result sslCreateContext(SslContext *c, u32 ssl_version); + +/** + * @brief GetContextCount + * @note Not used by official sw. + * @param[out] out Output value. + */ +Result sslGetContextCount(u32 *out); + +/** + * @brief GetCertificates + * @param[in] buffer Output buffer. The start of this buffer is an array of \ref SslBuiltInCertificateInfo, with the specified count. The cert data (SslBuiltInCertificateInfo::data) is located after this array. + * @param[in] size Output buffer size, this should be the size from \ref sslGetCertificateBufSize. + * @param[in] ca_cert_ids Input array of \ref SslCaCertificateId. + * @param[in] count Size of the ca_cert_ids array in entries. + * @param[out] total_out [3.0.0+] Total output entries. Will always match count on pre-3.0.0. This will differ from count when ::SslCaCertificateId_All is used. + */ +Result sslGetCertificates(void* buffer, u32 size, u32 *ca_cert_ids, u32 count, u32 *total_out); + +/** + * @brief GetCertificateBufSize + * @param[in] ca_cert_ids Input array of \ref SslCaCertificateId. + * @param[in] count Size of the ca_cert_ids array in entries. + * @param[out] out Output size. + */ +Result sslGetCertificateBufSize(u32 *ca_cert_ids, u32 count, u32 *out); + +/** + * @brief FlushSessionCache + * @note Only available on [5.0.0+]. + * @param[in] str Input string. Must be NULL with ::SslFlushSessionCacheOptionType_AllHosts. + * @param[in] str_bufsize String buffer size, excluding NUL-terminator. Hence, this should be actual_bufsize-1. This must be 0 with ::SslFlushSessionCacheOptionType_AllHosts. + * @param[in] type \ref SslFlushSessionCacheOptionType + * @param[out] out Output value. + */ +Result sslFlushSessionCache(const char *str, size_t str_bufsize, SslFlushSessionCacheOptionType type, u32 *out); + +/** + * @brief SetDebugOption + * @note Only available on [6.0.0+]. + * @note The official impl of this doesn't actually use the cmd. + * @param[in] buffer Input buffer, must not be NULL. The u8 from here is copied to state. + * @param[in] size Buffer size, must not be 0. + * @param[in] type \ref SslDebugOptionType + */ +Result sslSetDebugOption(const void* buffer, size_t size, SslDebugOptionType type); + +/** + * @brief GetDebugOption + * @note Only available on [6.0.0+]. + * @param[out] buffer Output buffer, must not be NULL. An u8 is written here loaded from state. + * @param[in] size Buffer size, must not be 0. + * @param[in] type \ref SslDebugOptionType + */ +Result sslGetDebugOption(void* buffer, size_t size, SslDebugOptionType type); + +///@name ISslContext +///@{ + +/** + * @brief Closes a Context object. + * @param c \ref SslContext + */ +void sslContextClose(SslContext *c); + +/** + * @brief SetOption + * @note Prior to 4.x this is stubbed. + * @param c \ref SslContext + * @param[in] option \ref SslContextOption + * @param[in] value Value to set. With ::SslContextOption_CrlImportDateCheckEnable, this must be 0 or 1. + */ +Result sslContextSetOption(SslContext *c, SslContextOption option, s32 value); + +/** + * @brief GetOption + * @note Prior to 4.x this is stubbed. + * @param c \ref SslContext + * @param[in] option \ref SslContextOption + * @param[out] out Output value. + */ +Result sslContextGetOption(SslContext *c, SslContextOption option, s32 *out); + +/** + * @brief CreateConnection + * @param c \ref SslContext + * @param[out] conn Output \ref SslConnection. + */ +Result sslContextCreateConnection(SslContext *c, SslConnection *conn); + +/** + * @brief GetConnectionCount + * @note Not exposed by official sw. + * @param c \ref SslContext + * @param[out] out Output value. + */ +Result sslContextGetConnectionCount(SslContext *c, u32 *out); + +/** + * @brief ImportServerPki + * @note A maximum of 71 ServerPki objects (associated with the output Id) can be imported. + * @param c \ref SslContext + * @param[in] buffer Input buffer containing the cert data, must not be NULL. This can contain multiple certs. The certs can be CAs or server certs (no pubkeys). + * @param[in] size Input buffer size. + * @param[in] format \ref SslCertificateFormat + * @param[out] id Output Id. Optional, can be NULL. + */ +Result sslContextImportServerPki(SslContext *c, const void* buffer, u32 size, SslCertificateFormat format, u64 *id); + +/** + * @brief ImportClientPki + * @note An error is thrown internally if this cmd or \ref sslContextRegisterInternalPki was already used previously. + * @param c \ref SslContext + * @param[in] pkcs12 PKCS#12 input buffer, must not be NULL. + * @param[in] pkcs12_size pkcs12 buffer size. + * @param[in] pw ASCII password string buffer, this can only be NULL if pw_size is 0. This will be internally copied to another buffer which was allocated with size=pw_size+1, for NUL-termination. + * @param[in] pw_size Password buffer size, this can only be 0 if pw is NULL. + * @param[out] id Output Id. Optional, can be NULL. + */ +Result sslContextImportClientPki(SslContext *c, const void* pkcs12, u32 pkcs12_size, const char *pw, u32 pw_size, u64 *id); + +/** + * @brief Remove the specified *Pki, or on [3.0.0+] Crl. + * @param c \ref SslContext + * @param[in] id Id + */ +Result sslContextRemovePki(SslContext *c, u64 id); + +/** + * @brief RegisterInternalPki + * @note An error is thrown internally if this cmd or \ref sslContextImportClientPki was already used previously. + * @param c \ref SslContext + * @param[in] internal_pki \ref SslInternalPki + * @param[out] id Output Id. Optional, can be NULL. + */ +Result sslContextRegisterInternalPki(SslContext *c, SslInternalPki internal_pki, u64 *id); + +/** + * @brief AddPolicyOid + * @param c \ref SslContext + * @param[in] str Input string. + * @param[in] str_bufsize String buffer size, excluding NUL-terminator (must not match the string length). Hence, this should be actual_bufsize-1. This must not be >0xff. + */ +Result sslContextAddPolicyOid(SslContext *c, const char *str, u32 str_bufsize); + +/** + * @brief ImportCrl + * @note Only available on [3.0.0+]. + * @param c \ref SslContext + * @param[in] buffer Input buffer, must not be NULL. This contains the DER CRL. + * @param[in] size Input buffer size. + * @param[out] id Output Id. Optional, can be NULL. + */ +Result sslContextImportCrl(SslContext *c, const void* buffer, u32 size, u64 *id); + +///@} + +///@name ISslConnection +///@{ + +/** + * @brief Closes a Connection object. + * @param c \ref SslConnection + */ +void sslConnectionClose(SslConnection *c); + +/** + * @brief SetSocketDescriptor. Do not use directly, use \ref socketSslConnectionSetSocketDescriptor instead. + * @note An error is thrown if this was used previously. + * @param c \ref SslConnection + * @param[in] sockfd sockfd + * @param[out] out_sockfd sockfd. Prior to using \ref sslConnectionClose, this must be closed if it's not negative (it will be -1 if ::SslOptionType_DoNotCloseSocket is set). + */ +Result sslConnectionSetSocketDescriptor(SslConnection *c, int sockfd, int *out_sockfd); + +/** + * @brief SetHostName + * @param c \ref SslConnection + * @param[in] str Input string. + * @param[in] str_bufsize String buffer size. This must not be >0xff. + */ +Result sslConnectionSetHostName(SslConnection *c, const char* str, u32 str_bufsize); + +/** + * @brief SetVerifyOption + * @param c \ref SslConnection + * @param[in] verify_option Input bitmask of \ref SslVerifyOption. + */ +Result sslConnectionSetVerifyOption(SslConnection *c, u32 verify_option); + +/** + * @brief SetIoMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[in] mode \ref SslIoMode + */ +Result sslConnectionSetIoMode(SslConnection *c, SslIoMode mode); + +/** + * @brief GetSocketDescriptor. Do not use directly, use \ref socketSslConnectionGetSocketDescriptor instead. + * @note This gets the input sockfd which was previously saved in state by \ref sslConnectionSetSocketDescriptor. + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] sockfd Output sockfd. + */ +Result sslConnectionGetSocketDescriptor(SslConnection *c, int *sockfd); + +/** + * @brief GetHostName + * @param c \ref SslConnection + * @param[out] str Output string buffer. + * @param[in] str_bufsize String buffer size, must be large enough for the entire output string. + * @param[out] out Output string length. + */ +Result sslConnectionGetHostName(SslConnection *c, char *str, u32 str_bufsize, u32 *out); + +/** + * @brief GetVerifyOption + * @param c \ref SslConnection + * @param[out] out Output bitmask of \ref SslVerifyOption. + */ +Result sslConnectionGetVerifyOption(SslConnection *c, u32 *out); + +/** + * @brief GetIoMode + * @param c \ref SslConnection + * @param[out] out \ref SslIoMode + */ +Result sslConnectionGetIoMode(SslConnection *c, SslIoMode *out); + +/** + * @brief DoHandshake + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @note \ref sslConnectionSetHostName must have been used previously with a non-empty string when ::SslVerifyOption_HostName is set. + * @note The DoHandshakeGetServerCert cmd is only used if both server_certbuf/server_certbuf_size are set, otherwise the DoHandshake cmd is used (in which case out_size/total_certs will be left at value 0). + * @note No certs are returned when ::SslVerifyOption_PeerCa is not set. + * @param c \ref SslConnection + * @param[out] out_size Total data size which was written to server_certbuf. Optional, can be NULL. + * @param[out] total_certs Total certs which were written to server_certbuf, can be NULL. + * @param[out] server_certbuf Optional output server cert buffer, can be NULL. Normally this just contains the server cert DER, however with ::SslOptionType_GetServerCertChain set this will contain the full chain (\ref sslConnectionGetServerCertDetail can be used to parse that). With ::SslIoMode_NonBlocking this buffer will be only filled in once - when this cmd returns successfully the buffer will generally be empty. + * @param[in] server_certbuf_size Optional output server cert buffer size, can be 0. + */ +Result sslConnectionDoHandshake(SslConnection *c, u32 *out_size, u32 *total_certs, void* server_certbuf, u32 server_certbuf_size); + +/** + * @brief Parses the output server_certbuf from \ref sslConnectionDoHandshake where ::SslOptionType_GetServerCertChain is set. + * @param[in] certbuf server_certbuf from \ref sslConnectionDoHandshake, must not be NULL. + * @param[in] certbuf_size out_size from \ref sslConnectionDoHandshake. + * @param[in] cert_index Cert index, must be within the range of certs stored in certbuf. + * @param[out] cert Ptr for the ouput DER cert, must not be NULL. + * @param[out] cert_size Size for the ouput cert, must not be NULL. + */ +Result sslConnectionGetServerCertDetail(const void* certbuf, u32 certbuf_size, u32 cert_index, void** cert, u32 *cert_size); + +/** + * @brief Read + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] buffer Output buffer, must not be NULL. + * @param[in] size Output buffer size, must not be 0. + * @param[out] out_size Actual transferred size. + */ +Result sslConnectionRead(SslConnection *c, void* buffer, u32 size, u32 *out_size); + +/** + * @brief Write + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[in] buffer Input buffer, must not be NULL. + * @param[in] size Input buffer size, must not be 0. + * @param[out] out_size Actual transferred size. + */ +Result sslConnectionWrite(SslConnection *c, const void* buffer, u32 size, u32 *out_size); + +/** + * @brief Pending + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] out Output value. + */ +Result sslConnectionPending(SslConnection *c, s32 *out); + +/** + * @brief Peek + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] buffer Output buffer, must not be NULL. + * @param[in] size Output buffer size, must not be 0. + * @param[out] out_size Output size. + */ +Result sslConnectionPeek(SslConnection *c, void* buffer, u32 size, u32 *out_size); + +/** + * @brief Poll + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[in] in_pollevent Input bitmask of \ref SslPollEvent. + * @param[out] out_pollevent Output bitmask of \ref SslPollEvent. + * @param[in] timeout Timeout in milliseconds. + */ +Result sslConnectionPoll(SslConnection *c, u32 in_pollevent, u32 *out_pollevent, u32 timeout); + +/** + * @brief GetVerifyCertError + * @note The value in state is cleared after loading it. + * @param c \ref SslConnection + */ +Result sslConnectionGetVerifyCertError(SslConnection *c); + +/** + * @brief GetNeededServerCertBufferSize + * @param c \ref SslConnection + * @param[out] out Output value. + */ +Result sslConnectionGetNeededServerCertBufferSize(SslConnection *c, u32 *out); + +/** + * @brief SetSessionCacheMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[in] mode \ref SslSessionCacheMode + */ +Result sslConnectionSetSessionCacheMode(SslConnection *c, SslSessionCacheMode mode); + +/** + * @brief GetSessionCacheMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] out \ref SslSessionCacheMode + */ +Result sslConnectionGetSessionCacheMode(SslConnection *c, SslSessionCacheMode *out); + +/** + * @brief GetSessionCacheMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + */ +Result sslConnectionFlushSessionCache(SslConnection *c); + +/** + * @brief SetRenegotiationMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[in] mode \ref SslRenegotiationMode + */ +Result sslConnectionSetRenegotiationMode(SslConnection *c, SslRenegotiationMode mode); + +/** + * @brief GetRenegotiationMode + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] out \ref SslRenegotiationMode + */ +Result sslConnectionGetRenegotiationMode(SslConnection *c, SslRenegotiationMode *out); + +/** + * @brief SetOption + * @param c \ref SslConnection + * @param[in] option \ref SslOptionType + * @param[in] flag Input flag value. + */ +Result sslConnectionSetOption(SslConnection *c, SslOptionType option, bool flag); + +/** + * @brief GetOption + * @param c \ref SslConnection + * @param[in] option \ref SslOptionType + * @param[out] out Output flag value. + */ +Result sslConnectionGetOption(SslConnection *c, SslOptionType option, bool *out); + +/** + * @brief GetVerifyCertErrors + * @note An error is thrown when the cmd is successful, if the two output u32s match. + * @param[out] out0 First output value, must not be NULL. + * @param[out] out1 Second output value. + * @param[out] errors Output array of Result, must not be NULL. + * @param[in] count Size of the errors array in entries. + */ +Result sslConnectionGetVerifyCertErrors(SslConnection *c, u32 *out0, u32 *out1, Result *errors, u32 count); + +/** + * @brief GetCipherInfo + * @note Only available on [4.0.0+]. + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @param c \ref SslConnection + * @param[out] out \ref SslCipherInfo + */ +Result sslConnectionGetCipherInfo(SslConnection *c, SslCipherInfo *out); + +/** + * @brief SetNextAlpnProto + * @note Only available on [9.0.0+]. + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @note ::SslOptionType_EnableAlpn should be set at the time of using \ref sslConnectionDoHandshake, otherwise using this cmd will have no affect. + * @param c \ref SslConnection + * @param[in] buffer Input buffer, must not be NULL. This contains an array of {u8 size, {data with the specified size}}, which must be within the buffer-size bounds. + * @param[in] size Input buffer size, must not be 0. Must be at least 0x2. + */ +Result sslConnectionSetNextAlpnProto(SslConnection *c, const u8 *buffer, u32 size); + +/** + * @brief GetNextAlpnProto + * @note Only available on [9.0.0+]. + * @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. + * @note The output will be all-zero/empty if not available - such as when this was used before \ref sslConnectionDoHandshake. + * @param c \ref SslConnection + * @param[out] state \ref SslAlpnProtoState + * @param[out] out Output string length. + * @param[out] buffer Output string buffer, must not be NULL. + * @param[in] size Output buffer size, must not be 0. + */ +Result sslConnectionGetNextAlpnProto(SslConnection *c, SslAlpnProtoState *state, u32 *out, u8 *buffer, u32 size); + +///@} + diff --git a/src/libnx/wrapper/switch/services/ssl.nim b/src/libnx/wrapper/switch/services/ssl.nim new file mode 100644 index 0000000..c05ee89 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ssl.nim @@ -0,0 +1,727 @@ +## * +## @file fs.h +## @brief SSL service IPC wrapper, for using client-mode TLS. See also: https://switchbrew.org/wiki/SSL_services +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / CaCertificateId + +type + SslCaCertificateId* = enum + SslCaCertificateIdAll = -1, ## /< [3.0.0+] All + SslCaCertificateIdNintendoCAG3 = 1, ## /< NintendoCAG3 + SslCaCertificateIdNintendoClass2CAG3 = 2, ## /< NintendoClass2CAG3 + SslCaCertificateIdAmazonRootCA1 = 1000, ## /< AmazonRootCA1 + SslCaCertificateIdStarfieldServicesRootCertificateAuthorityG2 = 1001, ## /< StarfieldServicesRootCertificateAuthorityG2 + SslCaCertificateIdAddTrustExternalCARoot = 1002, ## /< AddTrustExternalCARoot + SslCaCertificateIdCOMODOCertificationAuthority = 1003, ## /< COMODOCertificationAuthority + SslCaCertificateIdUTNDATACorpSGC = 1004, ## /< UTNDATACorpSGC + SslCaCertificateIdUTNUSERFirstHardware = 1005, ## /< UTNUSERFirstHardware + SslCaCertificateIdBaltimoreCyberTrustRoot = 1006, ## /< BaltimoreCyberTrustRoot + SslCaCertificateIdCybertrustGlobalRoot = 1007, ## /< CybertrustGlobalRoot + SslCaCertificateIdVerizonGlobalRootCA = 1008, ## /< VerizonGlobalRootCA + SslCaCertificateIdDigiCertAssuredIDRootCA = 1009, ## /< DigiCertAssuredIDRootCA + SslCaCertificateIdDigiCertAssuredIDRootG2 = 1010, ## /< DigiCertAssuredIDRootG2 + SslCaCertificateIdDigiCertGlobalRootCA = 1011, ## /< DigiCertGlobalRootCA + SslCaCertificateIdDigiCertGlobalRootG2 = 1012, ## /< DigiCertGlobalRootG2 + SslCaCertificateIdDigiCertHighAssuranceEVRootCA = 1013, ## /< DigiCertHighAssuranceEVRootCA + SslCaCertificateIdEntrustnetCertificationAuthority2048 = 1014, ## /< EntrustnetCertificationAuthority2048 + SslCaCertificateIdEntrustRootCertificationAuthority = 1015, ## /< EntrustRootCertificationAuthority + SslCaCertificateIdEntrustRootCertificationAuthorityG2 = 1016, ## /< EntrustRootCertificationAuthorityG2 + SslCaCertificateIdGeoTrustGlobalCA2 = 1017, ## /< GeoTrustGlobalCA2 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdGeoTrustGlobalCA = 1018, ## /< GeoTrustGlobalCA ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdGeoTrustPrimaryCertificationAuthorityG3 = 1019, ## /< GeoTrustPrimaryCertificationAuthorityG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdGeoTrustPrimaryCertificationAuthority = 1020, ## /< GeoTrustPrimaryCertificationAuthority ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdGlobalSignRootCA = 1021, ## /< GlobalSignRootCA + SslCaCertificateIdGlobalSignRootCAR2 = 1022, ## /< GlobalSignRootCAR2 + SslCaCertificateIdGlobalSignRootCAR3 = 1023, ## /< GlobalSignRootCAR3 + SslCaCertificateIdGoDaddyClass2CertificationAuthority = 1024, ## /< GoDaddyClass2CertificationAuthority + SslCaCertificateIdGoDaddyRootCertificateAuthorityG2 = 1025, ## /< GoDaddyRootCertificateAuthorityG2 + SslCaCertificateIdStarfieldClass2CertificationAuthority = 1026, ## /< StarfieldClass2CertificationAuthority + SslCaCertificateIdStarfieldRootCertificateAuthorityG2 = 1027, ## /< StarfieldRootCertificateAuthorityG2 + SslCaCertificateIdThawtePrimaryRootCAG3 = 1028, ## /< thawtePrimaryRootCAG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdThawtePrimaryRootCA = 1029, ## /< thawtePrimaryRootCA ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdVeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, ## /< VeriSignClass3PublicPrimaryCertificationAuthorityG3 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdVeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, ## /< VeriSignClass3PublicPrimaryCertificationAuthorityG5 ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdVeriSignUniversalRootCertificationAuthority = 1032, ## /< VeriSignUniversalRootCertificationAuthority ([8.0.0+] ::SslTrustedCertStatus is ::SslTrustedCertStatus_EnabledNotTrusted) + SslCaCertificateIdDSTRootCAX3 = 1033 ## /< [6.0.0+] DSTRootCAX3 + + +## / TrustedCertStatus + +type + SslTrustedCertStatus* = enum + SslTrustedCertStatusInvalid = -1, ## /< Invalid + SslTrustedCertStatusRemoved = 0, ## /< Removed + SslTrustedCertStatusEnabledTrusted = 1, ## /< EnabledTrusted + SslTrustedCertStatusEnabledNotTrusted = 2, ## /< EnabledNotTrusted + SslTrustedCertStatusRevoked = 3 ## /< Revoked + + +## / FlushSessionCacheOptionType + +type + SslFlushSessionCacheOptionType* = enum + SslFlushSessionCacheOptionTypeSingleHost = 0, ## /< SingleHost. Uses the input string. + SslFlushSessionCacheOptionTypeAllHosts = 1 ## /< AllHosts. Doesn't use the input string. + + +## / DebugOptionType + +type + SslDebugOptionType* = enum + SslDebugOptionTypeAllowDisableVerifyOption = 0 ## /< AllowDisableVerifyOption + + +## / SslVersion. This is a bitmask which controls the min/max TLS versions to use, depending on which lowest/highest bits are set (if Auto* isn't set). + +type + SslVersion* = enum + SslVersionAuto = bit(0), ## /< TLS version min = 1.0, max = 1.2. + SslVersionTlsV10 = bit(3), ## /< TLS 1.0. + SslVersionTlsV11 = bit(4), ## /< TLS 1.1. + SslVersionTlsV12 = bit(5), ## /< TLS 1.2. + SslVersionTlsV13 = bit(6), ## /< [11.0.0+] TLS 1.3. + SslVersionAuto24 = bit(24) ## /< [11.0.0+] Same as Auto. + + +## / CertificateFormat + +type + SslCertificateFormat* = enum + SslCertificateFormatPem = 1, ## /< Pem + SslCertificateFormatDer = 2 ## /< Der + + +## / InternalPki + +type + SslInternalPki* = enum + SslInternalPkiDeviceClientCertDefault = 1 ## /< DeviceClientCertDefault. Enables using the DeviceCert. + + +## / ContextOption + +type + SslContextOption* = enum + SslContextOptionCrlImportDateCheckEnable = 1 ## /< CrlImportDateCheckEnable. The default value at the time of \ref sslCreateContext is value 1. + + +## / VerifyOption. The default bitmask value at the time of \ref sslContextCreateConnection is ::SslVerifyOption_PeerCa | ::SslVerifyOption_HostName. +## / [5.0.0+] \ref sslConnectionSetVerifyOption: (::SslVerifyOption_PeerCa | ::SslVerifyOption_HostName) must be set, unless: ::SslOptionType_SkipDefaultVerify is set, or [9.0.0+] ::SslDebugOptionType_AllowDisableVerifyOption is set. +## / [6.0.0+] \ref sslConnectionSetVerifyOption: Following that, if ::SslVerifyOption_EvPolicyOid is set, then the following options must be set (besides the previously mentioned one): ::SslVerifyOption_PeerCa and ::SslVerifyOption_DateCheck. + +type + SslVerifyOption* = enum + SslVerifyOptionPeerCa = bit(0), ## /< PeerCa + SslVerifyOptionHostName = bit(1), ## /< HostName + SslVerifyOptionDateCheck = bit(2), ## /< DateCheck + SslVerifyOptionEvCertPartial = bit(3), ## /< EvCertPartial + SslVerifyOptionEvPolicyOid = bit(4), ## /< [6.0.0+] EvPolicyOid + SslVerifyOptionEvCertFingerprint = bit(5) ## /< [6.0.0+] EvCertFingerprint + + +## / IoMode. The default value at the time of \ref sslContextCreateConnection is ::SslIoMode_Blocking. +## / The socket non-blocking flag is always set regardless of this field, this is only used internally for calculating the timeout used by various cmds. + +type + SslIoMode* = enum + SslIoModeBlocking = 1, ## /< Blocking. Timeout = 5 minutes. + SslIoModeNonBlocking = 2 ## /< NonBlocking. Timeout = 0. + + +## / PollEvent + +type + SslPollEvent* = enum + SslPollEventRead = bit(0), ## /< Read + SslPollEventWrite = bit(1), ## /< Write + SslPollEventExcept = bit(2) ## /< Except + + +## / SessionCacheMode + +type + SslSessionCacheMode* = enum + SslSessionCacheModeNone = 0, ## /< None + SslSessionCacheModeSessionId = 1, ## /< SessionId + SslSessionCacheModeSessionTicket = 2 ## /< SessionTicket + + +## / RenegotiationMode + +type + SslRenegotiationMode* = enum + SslRenegotiationModeNone = 0, ## /< None + SslRenegotiationModeSecure = 1 ## /< Secure + + +## / OptionType. The default bool flags value for these at the time of \ref sslContextCreateConnection is cleared. + +type + SslOptionType* = enum + SslOptionTypeDoNotCloseSocket = 0, ## /< DoNotCloseSocket. See \ref sslConnectionSetSocketDescriptor. This is only available if \ref sslConnectionSetSocketDescriptor wasn't used yet. + SslOptionTypeGetServerCertChain = 1, ## /< [3.0.0+] GetServerCertChain. See \ref sslConnectionDoHandshake. + SslOptionTypeSkipDefaultVerify = 2, ## /< [5.0.0+] SkipDefaultVerify. Checked by \ref sslConnectionSetVerifyOption, see \ref SslVerifyOption. + SslOptionTypeEnableAlpn = 3 ## /< [9.0.0+] EnableAlpn. Only available with \ref sslConnectionSetOption. \ref sslConnectionSetSocketDescriptor should have been used prior to this - this will optionally use state setup by that, without throwing an error if that cmd wasn't used. + + +## / AlpnProtoState + +type + SslAlpnProtoState* = enum + SslAlpnProtoStateNoSupport = 0, ## /< NoSupport + SslAlpnProtoStateNegotiated = 1, ## /< Negotiated + SslAlpnProtoStateNoOverlap = 2, ## /< NoOverlap + SslAlpnProtoStateSelected = 3, ## /< Selected + SslAlpnProtoStateEarlyValue = 4 ## /< EarlyValue + + +## / SslContext + +type + SslContext* {.bycopy.} = object + s*: Service ## /< ISslContext + + +## / SslConnection + +type + SslConnection* {.bycopy.} = object + s*: Service ## /< ISslConnection + + +## / BuiltInCertificateInfo + +type + SslBuiltInCertificateInfo* {.bycopy.} = object + certId*: U32 ## /< \ref SslCaCertificateId + status*: U32 ## /< \ref SslTrustedCertStatus + certSize*: U64 ## /< CertificateSize + certData*: ptr U8 ## /< CertificateData (converted from an offset to a ptr), in DER format. + + +## / SslServerCertDetailHeader + +type + SslServerCertDetailHeader* {.bycopy.} = object + magicnum*: U64 ## /< Magicnum. + certTotal*: U32 ## /< Total certs. + pad*: U32 ## /< Padding. + + +## / SslServerCertDetailEntry + +type + SslServerCertDetailEntry* {.bycopy.} = object + size*: U32 ## /< Size. + offset*: U32 ## /< Offset. + + +## / CipherInfo + +type + SslCipherInfo* {.bycopy.} = object + cipher*: array[0x40, char] ## /< Cipher string. + protocolVersion*: array[0x8, char] ## /< Protocol version string. + + +## / Initialize ssl. A default value of 0x3 can be used for num_sessions. This must be 0x1-0x4. + +proc sslInitialize*(numSessions: U32): Result {.cdecl, importc: "sslInitialize".} +## / Exit ssl. + +proc sslExit*() {.cdecl, importc: "sslExit".} +## / Gets the Service object for the actual ssl service session. + +proc sslGetServiceSession*(): ptr Service {.cdecl, importc: "sslGetServiceSession".} +## * +## @brief CreateContext +## @note The CertStore is used automatically, regardless of what cmds are used. +## @param[out] c \ref SslContext +## @param[in] ssl_version \ref SslVersion +## + +proc sslCreateContext*(c: ptr SslContext; sslVersion: U32): Result {.cdecl, + importc: "sslCreateContext".} +## * +## @brief GetContextCount +## @note Not used by official sw. +## @param[out] out Output value. +## + +proc sslGetContextCount*(`out`: ptr U32): Result {.cdecl, + importc: "sslGetContextCount".} +## * +## @brief GetCertificates +## @param[in] buffer Output buffer. The start of this buffer is an array of \ref SslBuiltInCertificateInfo, with the specified count. The cert data (SslBuiltInCertificateInfo::data) is located after this array. +## @param[in] size Output buffer size, this should be the size from \ref sslGetCertificateBufSize. +## @param[in] ca_cert_ids Input array of \ref SslCaCertificateId. +## @param[in] count Size of the ca_cert_ids array in entries. +## @param[out] total_out [3.0.0+] Total output entries. Will always match count on pre-3.0.0. This will differ from count when ::SslCaCertificateId_All is used. +## + +proc sslGetCertificates*(buffer: pointer; size: U32; caCertIds: ptr U32; count: U32; + totalOut: ptr U32): Result {.cdecl, + importc: "sslGetCertificates".} +## * +## @brief GetCertificateBufSize +## @param[in] ca_cert_ids Input array of \ref SslCaCertificateId. +## @param[in] count Size of the ca_cert_ids array in entries. +## @param[out] out Output size. +## + +proc sslGetCertificateBufSize*(caCertIds: ptr U32; count: U32; `out`: ptr U32): Result {. + cdecl, importc: "sslGetCertificateBufSize".} +## * +## @brief FlushSessionCache +## @note Only available on [5.0.0+]. +## @param[in] str Input string. Must be NULL with ::SslFlushSessionCacheOptionType_AllHosts. +## @param[in] str_bufsize String buffer size, excluding NUL-terminator. Hence, this should be actual_bufsize-1. This must be 0 with ::SslFlushSessionCacheOptionType_AllHosts. +## @param[in] type \ref SslFlushSessionCacheOptionType +## @param[out] out Output value. +## + +proc sslFlushSessionCache*(str: cstring; strBufsize: csize_t; + `type`: SslFlushSessionCacheOptionType; `out`: ptr U32): Result {. + cdecl, importc: "sslFlushSessionCache".} +## * +## @brief SetDebugOption +## @note Only available on [6.0.0+]. +## @note The official impl of this doesn't actually use the cmd. +## @param[in] buffer Input buffer, must not be NULL. The u8 from here is copied to state. +## @param[in] size Buffer size, must not be 0. +## @param[in] type \ref SslDebugOptionType +## + +proc sslSetDebugOption*(buffer: pointer; size: csize_t; `type`: SslDebugOptionType): Result {. + cdecl, importc: "sslSetDebugOption".} +## * +## @brief GetDebugOption +## @note Only available on [6.0.0+]. +## @param[out] buffer Output buffer, must not be NULL. An u8 is written here loaded from state. +## @param[in] size Buffer size, must not be 0. +## @param[in] type \ref SslDebugOptionType +## + +proc sslGetDebugOption*(buffer: pointer; size: csize_t; `type`: SslDebugOptionType): Result {. + cdecl, importc: "sslGetDebugOption".} +## /@name ISslContext +## /@{ +## * +## @brief Closes a Context object. +## @param c \ref SslContext +## + +proc sslContextClose*(c: ptr SslContext) {.cdecl, importc: "sslContextClose".} +## * +## @brief SetOption +## @note Prior to 4.x this is stubbed. +## @param c \ref SslContext +## @param[in] option \ref SslContextOption +## @param[in] value Value to set. With ::SslContextOption_CrlImportDateCheckEnable, this must be 0 or 1. +## + +proc sslContextSetOption*(c: ptr SslContext; option: SslContextOption; value: S32): Result {. + cdecl, importc: "sslContextSetOption".} +## * +## @brief GetOption +## @note Prior to 4.x this is stubbed. +## @param c \ref SslContext +## @param[in] option \ref SslContextOption +## @param[out] out Output value. +## + +proc sslContextGetOption*(c: ptr SslContext; option: SslContextOption; `out`: ptr S32): Result {. + cdecl, importc: "sslContextGetOption".} +## * +## @brief CreateConnection +## @param c \ref SslContext +## @param[out] conn Output \ref SslConnection. +## + +proc sslContextCreateConnection*(c: ptr SslContext; conn: ptr SslConnection): Result {. + cdecl, importc: "sslContextCreateConnection".} +## * +## @brief GetConnectionCount +## @note Not exposed by official sw. +## @param c \ref SslContext +## @param[out] out Output value. +## + +proc sslContextGetConnectionCount*(c: ptr SslContext; `out`: ptr U32): Result {.cdecl, + importc: "sslContextGetConnectionCount".} +## * +## @brief ImportServerPki +## @note A maximum of 71 ServerPki objects (associated with the output Id) can be imported. +## @param c \ref SslContext +## @param[in] buffer Input buffer containing the cert data, must not be NULL. This can contain multiple certs. The certs can be CAs or server certs (no pubkeys). +## @param[in] size Input buffer size. +## @param[in] format \ref SslCertificateFormat +## @param[out] id Output Id. Optional, can be NULL. +## + +proc sslContextImportServerPki*(c: ptr SslContext; buffer: pointer; size: U32; + format: SslCertificateFormat; id: ptr U64): Result {. + cdecl, importc: "sslContextImportServerPki".} +## * +## @brief ImportClientPki +## @note An error is thrown internally if this cmd or \ref sslContextRegisterInternalPki was already used previously. +## @param c \ref SslContext +## @param[in] pkcs12 PKCS#12 input buffer, must not be NULL. +## @param[in] pkcs12_size pkcs12 buffer size. +## @param[in] pw ASCII password string buffer, this can only be NULL if pw_size is 0. This will be internally copied to another buffer which was allocated with size=pw_size+1, for NUL-termination. +## @param[in] pw_size Password buffer size, this can only be 0 if pw is NULL. +## @param[out] id Output Id. Optional, can be NULL. +## + +proc sslContextImportClientPki*(c: ptr SslContext; pkcs12: pointer; pkcs12Size: U32; + pw: cstring; pwSize: U32; id: ptr U64): Result {.cdecl, + importc: "sslContextImportClientPki".} +## * +## @brief Remove the specified *Pki, or on [3.0.0+] Crl. +## @param c \ref SslContext +## @param[in] id Id +## + +proc sslContextRemovePki*(c: ptr SslContext; id: U64): Result {.cdecl, + importc: "sslContextRemovePki".} +## * +## @brief RegisterInternalPki +## @note An error is thrown internally if this cmd or \ref sslContextImportClientPki was already used previously. +## @param c \ref SslContext +## @param[in] internal_pki \ref SslInternalPki +## @param[out] id Output Id. Optional, can be NULL. +## + +proc sslContextRegisterInternalPki*(c: ptr SslContext; internalPki: SslInternalPki; + id: ptr U64): Result {.cdecl, + importc: "sslContextRegisterInternalPki".} +## * +## @brief AddPolicyOid +## @param c \ref SslContext +## @param[in] str Input string. +## @param[in] str_bufsize String buffer size, excluding NUL-terminator (must not match the string length). Hence, this should be actual_bufsize-1. This must not be >0xff. +## + +proc sslContextAddPolicyOid*(c: ptr SslContext; str: cstring; strBufsize: U32): Result {. + cdecl, importc: "sslContextAddPolicyOid".} +## * +## @brief ImportCrl +## @note Only available on [3.0.0+]. +## @param c \ref SslContext +## @param[in] buffer Input buffer, must not be NULL. This contains the DER CRL. +## @param[in] size Input buffer size. +## @param[out] id Output Id. Optional, can be NULL. +## + +proc sslContextImportCrl*(c: ptr SslContext; buffer: pointer; size: U32; id: ptr U64): Result {. + cdecl, importc: "sslContextImportCrl".} +## /@} +## /@name ISslConnection +## /@{ +## * +## @brief Closes a Connection object. +## @param c \ref SslConnection +## + +proc sslConnectionClose*(c: ptr SslConnection) {.cdecl, importc: "sslConnectionClose".} +## * +## @brief SetSocketDescriptor. Do not use directly, use \ref socketSslConnectionSetSocketDescriptor instead. +## @note An error is thrown if this was used previously. +## @param c \ref SslConnection +## @param[in] sockfd sockfd +## @param[out] out_sockfd sockfd. Prior to using \ref sslConnectionClose, this must be closed if it's not negative (it will be -1 if ::SslOptionType_DoNotCloseSocket is set). +## + +proc sslConnectionSetSocketDescriptor*(c: ptr SslConnection; sockfd: cint; + outSockfd: ptr cint): Result {.cdecl, + importc: "sslConnectionSetSocketDescriptor".} +## * +## @brief SetHostName +## @param c \ref SslConnection +## @param[in] str Input string. +## @param[in] str_bufsize String buffer size. This must not be >0xff. +## + +proc sslConnectionSetHostName*(c: ptr SslConnection; str: cstring; strBufsize: U32): Result {. + cdecl, importc: "sslConnectionSetHostName".} +## * +## @brief SetVerifyOption +## @param c \ref SslConnection +## @param[in] verify_option Input bitmask of \ref SslVerifyOption. +## + +proc sslConnectionSetVerifyOption*(c: ptr SslConnection; verifyOption: U32): Result {. + cdecl, importc: "sslConnectionSetVerifyOption".} +## * +## @brief SetIoMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[in] mode \ref SslIoMode +## + +proc sslConnectionSetIoMode*(c: ptr SslConnection; mode: SslIoMode): Result {.cdecl, + importc: "sslConnectionSetIoMode".} +## * +## @brief GetSocketDescriptor. Do not use directly, use \ref socketSslConnectionGetSocketDescriptor instead. +## @note This gets the input sockfd which was previously saved in state by \ref sslConnectionSetSocketDescriptor. +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] sockfd Output sockfd. +## + +proc sslConnectionGetSocketDescriptor*(c: ptr SslConnection; sockfd: ptr cint): Result {. + cdecl, importc: "sslConnectionGetSocketDescriptor".} +## * +## @brief GetHostName +## @param c \ref SslConnection +## @param[out] str Output string buffer. +## @param[in] str_bufsize String buffer size, must be large enough for the entire output string. +## @param[out] out Output string length. +## + +proc sslConnectionGetHostName*(c: ptr SslConnection; str: cstring; strBufsize: U32; + `out`: ptr U32): Result {.cdecl, + importc: "sslConnectionGetHostName".} +## * +## @brief GetVerifyOption +## @param c \ref SslConnection +## @param[out] out Output bitmask of \ref SslVerifyOption. +## + +proc sslConnectionGetVerifyOption*(c: ptr SslConnection; `out`: ptr U32): Result {. + cdecl, importc: "sslConnectionGetVerifyOption".} +## * +## @brief GetIoMode +## @param c \ref SslConnection +## @param[out] out \ref SslIoMode +## + +proc sslConnectionGetIoMode*(c: ptr SslConnection; `out`: ptr SslIoMode): Result {. + cdecl, importc: "sslConnectionGetIoMode".} +## * +## @brief DoHandshake +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @note \ref sslConnectionSetHostName must have been used previously with a non-empty string when ::SslVerifyOption_HostName is set. +## @note The DoHandshakeGetServerCert cmd is only used if both server_certbuf/server_certbuf_size are set, otherwise the DoHandshake cmd is used (in which case out_size/total_certs will be left at value 0). +## @note No certs are returned when ::SslVerifyOption_PeerCa is not set. +## @param c \ref SslConnection +## @param[out] out_size Total data size which was written to server_certbuf. Optional, can be NULL. +## @param[out] total_certs Total certs which were written to server_certbuf, can be NULL. +## @param[out] server_certbuf Optional output server cert buffer, can be NULL. Normally this just contains the server cert DER, however with ::SslOptionType_GetServerCertChain set this will contain the full chain (\ref sslConnectionGetServerCertDetail can be used to parse that). With ::SslIoMode_NonBlocking this buffer will be only filled in once - when this cmd returns successfully the buffer will generally be empty. +## @param[in] server_certbuf_size Optional output server cert buffer size, can be 0. +## + +proc sslConnectionDoHandshake*(c: ptr SslConnection; outSize: ptr U32; + totalCerts: ptr U32; serverCertbuf: pointer; + serverCertbufSize: U32): Result {.cdecl, + importc: "sslConnectionDoHandshake".} +## * +## @brief Parses the output server_certbuf from \ref sslConnectionDoHandshake where ::SslOptionType_GetServerCertChain is set. +## @param[in] certbuf server_certbuf from \ref sslConnectionDoHandshake, must not be NULL. +## @param[in] certbuf_size out_size from \ref sslConnectionDoHandshake. +## @param[in] cert_index Cert index, must be within the range of certs stored in certbuf. +## @param[out] cert Ptr for the ouput DER cert, must not be NULL. +## @param[out] cert_size Size for the ouput cert, must not be NULL. +## + +proc sslConnectionGetServerCertDetail*(certbuf: pointer; certbufSize: U32; + certIndex: U32; cert: ptr pointer; + certSize: ptr U32): Result {.cdecl, + importc: "sslConnectionGetServerCertDetail".} +## * +## @brief Read +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] buffer Output buffer, must not be NULL. +## @param[in] size Output buffer size, must not be 0. +## @param[out] out_size Actual transferred size. +## + +proc sslConnectionRead*(c: ptr SslConnection; buffer: pointer; size: U32; + outSize: ptr U32): Result {.cdecl, + importc: "sslConnectionRead".} +## * +## @brief Write +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[in] buffer Input buffer, must not be NULL. +## @param[in] size Input buffer size, must not be 0. +## @param[out] out_size Actual transferred size. +## + +proc sslConnectionWrite*(c: ptr SslConnection; buffer: pointer; size: U32; + outSize: ptr U32): Result {.cdecl, + importc: "sslConnectionWrite".} +## * +## @brief Pending +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] out Output value. +## + +proc sslConnectionPending*(c: ptr SslConnection; `out`: ptr S32): Result {.cdecl, + importc: "sslConnectionPending".} +## * +## @brief Peek +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] buffer Output buffer, must not be NULL. +## @param[in] size Output buffer size, must not be 0. +## @param[out] out_size Output size. +## + +proc sslConnectionPeek*(c: ptr SslConnection; buffer: pointer; size: U32; + outSize: ptr U32): Result {.cdecl, + importc: "sslConnectionPeek".} +## * +## @brief Poll +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[in] in_pollevent Input bitmask of \ref SslPollEvent. +## @param[out] out_pollevent Output bitmask of \ref SslPollEvent. +## @param[in] timeout Timeout in milliseconds. +## + +proc sslConnectionPoll*(c: ptr SslConnection; inPollevent: U32; outPollevent: ptr U32; + timeout: U32): Result {.cdecl, importc: "sslConnectionPoll".} +## * +## @brief GetVerifyCertError +## @note The value in state is cleared after loading it. +## @param c \ref SslConnection +## + +proc sslConnectionGetVerifyCertError*(c: ptr SslConnection): Result {.cdecl, + importc: "sslConnectionGetVerifyCertError".} +## * +## @brief GetNeededServerCertBufferSize +## @param c \ref SslConnection +## @param[out] out Output value. +## + +proc sslConnectionGetNeededServerCertBufferSize*(c: ptr SslConnection; + `out`: ptr U32): Result {.cdecl, + importc: "sslConnectionGetNeededServerCertBufferSize".} +## * +## @brief SetSessionCacheMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[in] mode \ref SslSessionCacheMode +## + +proc sslConnectionSetSessionCacheMode*(c: ptr SslConnection; + mode: SslSessionCacheMode): Result {.cdecl, + importc: "sslConnectionSetSessionCacheMode".} +## * +## @brief GetSessionCacheMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] out \ref SslSessionCacheMode +## + +proc sslConnectionGetSessionCacheMode*(c: ptr SslConnection; + `out`: ptr SslSessionCacheMode): Result {. + cdecl, importc: "sslConnectionGetSessionCacheMode".} +## * +## @brief GetSessionCacheMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## + +proc sslConnectionFlushSessionCache*(c: ptr SslConnection): Result {.cdecl, + importc: "sslConnectionFlushSessionCache".} +## * +## @brief SetRenegotiationMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[in] mode \ref SslRenegotiationMode +## + +proc sslConnectionSetRenegotiationMode*(c: ptr SslConnection; + mode: SslRenegotiationMode): Result {.cdecl, + importc: "sslConnectionSetRenegotiationMode".} +## * +## @brief GetRenegotiationMode +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] out \ref SslRenegotiationMode +## + +proc sslConnectionGetRenegotiationMode*(c: ptr SslConnection; + `out`: ptr SslRenegotiationMode): Result {. + cdecl, importc: "sslConnectionGetRenegotiationMode".} +## * +## @brief SetOption +## @param c \ref SslConnection +## @param[in] option \ref SslOptionType +## @param[in] flag Input flag value. +## + +proc sslConnectionSetOption*(c: ptr SslConnection; option: SslOptionType; flag: bool): Result {. + cdecl, importc: "sslConnectionSetOption".} +## * +## @brief GetOption +## @param c \ref SslConnection +## @param[in] option \ref SslOptionType +## @param[out] out Output flag value. +## + +proc sslConnectionGetOption*(c: ptr SslConnection; option: SslOptionType; + `out`: ptr bool): Result {.cdecl, + importc: "sslConnectionGetOption".} +## * +## @brief GetVerifyCertErrors +## @note An error is thrown when the cmd is successful, if the two output u32s match. +## @param[out] out0 First output value, must not be NULL. +## @param[out] out1 Second output value. +## @param[out] errors Output array of Result, must not be NULL. +## @param[in] count Size of the errors array in entries. +## + +proc sslConnectionGetVerifyCertErrors*(c: ptr SslConnection; out0: ptr U32; + out1: ptr U32; errors: ptr Result; count: U32): Result {. + cdecl, importc: "sslConnectionGetVerifyCertErrors".} +## * +## @brief GetCipherInfo +## @note Only available on [4.0.0+]. +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @param c \ref SslConnection +## @param[out] out \ref SslCipherInfo +## + +proc sslConnectionGetCipherInfo*(c: ptr SslConnection; `out`: ptr SslCipherInfo): Result {. + cdecl, importc: "sslConnectionGetCipherInfo".} +## * +## @brief SetNextAlpnProto +## @note Only available on [9.0.0+]. +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @note ::SslOptionType_EnableAlpn should be set at the time of using \ref sslConnectionDoHandshake, otherwise using this cmd will have no affect. +## @param c \ref SslConnection +## @param[in] buffer Input buffer, must not be NULL. This contains an array of {u8 size, {data with the specified size}}, which must be within the buffer-size bounds. +## @param[in] size Input buffer size, must not be 0. Must be at least 0x2. +## + +proc sslConnectionSetNextAlpnProto*(c: ptr SslConnection; buffer: ptr U8; size: U32): Result {. + cdecl, importc: "sslConnectionSetNextAlpnProto".} +## * +## @brief GetNextAlpnProto +## @note Only available on [9.0.0+]. +## @note \ref sslConnectionSetSocketDescriptor must have been used prior to this successfully. +## @note The output will be all-zero/empty if not available - such as when this was used before \ref sslConnectionDoHandshake. +## @param c \ref SslConnection +## @param[out] state \ref SslAlpnProtoState +## @param[out] out Output string length. +## @param[out] buffer Output string buffer, must not be NULL. +## @param[in] size Output buffer size, must not be 0. +## + +proc sslConnectionGetNextAlpnProto*(c: ptr SslConnection; + state: ptr SslAlpnProtoState; `out`: ptr U32; + buffer: ptr U8; size: U32): Result {.cdecl, + importc: "sslConnectionGetNextAlpnProto".} +## /@} diff --git a/src/libnx/wrapper/switch/services/tc.h b/src/libnx/wrapper/switch/services/tc.h new file mode 100644 index 0000000..56be6c0 --- /dev/null +++ b/src/libnx/wrapper/switch/services/tc.h @@ -0,0 +1,26 @@ +/** + * @file tc.h + * @brief Temperature control (tc) service IPC wrapper. + * @author Behemoth + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Initialize tc. +Result tcInitialize(void); + +/// Exit tc. +void tcExit(void); + +/// Gets the Service for tc. +Service* tcGetServiceSession(void); + +Result tcEnableFanControl(void); +/// @warning Disabling your fan can damage your system. +Result tcDisableFanControl(void); +Result tcIsFanControlEnabled(bool *status); +/// Only available on [5.0.0+]. +Result tcGetSkinTemperatureMilliC(s32 *skinTemp); + diff --git a/src/libnx/wrapper/switch/services/tc.nim b/src/libnx/wrapper/switch/services/tc.nim new file mode 100644 index 0000000..aae3e91 --- /dev/null +++ b/src/libnx/wrapper/switch/services/tc.nim @@ -0,0 +1,29 @@ +## * +## @file tc.h +## @brief Temperature control (tc) service IPC wrapper. +## @author Behemoth +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Initialize tc. + +proc tcInitialize*(): Result {.cdecl, importc: "tcInitialize".} +## / Exit tc. + +proc tcExit*() {.cdecl, importc: "tcExit".} +## / Gets the Service for tc. + +proc tcGetServiceSession*(): ptr Service {.cdecl, importc: "tcGetServiceSession".} +proc tcEnableFanControl*(): Result {.cdecl, importc: "tcEnableFanControl".} +## / @warning Disabling your fan can damage your system. + +proc tcDisableFanControl*(): Result {.cdecl, importc: "tcDisableFanControl".} +proc tcIsFanControlEnabled*(status: ptr bool): Result {.cdecl, + importc: "tcIsFanControlEnabled".} +## / Only available on [5.0.0+]. + +proc tcGetSkinTemperatureMilliC*(skinTemp: ptr S32): Result {.cdecl, + importc: "tcGetSkinTemperatureMilliC".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/time.h b/src/libnx/wrapper/switch/services/time.h new file mode 100644 index 0000000..fdcaa86 --- /dev/null +++ b/src/libnx/wrapper/switch/services/time.h @@ -0,0 +1,133 @@ +/** + * @file time.h + * @brief Time services IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once + +#include "../types.h" +#include "../sf/service.h" + +/// Values for __nx_time_service_type. +typedef enum { + TimeServiceType_User = 0, ///< Default. Initializes time:u. + TimeServiceType_Menu = 1, ///< Initializes time:a + TimeServiceType_System = 2, ///< Initializes time:s. + TimeServiceType_Repair = 3, ///< Initializes time:r. Only available with [9.0.0+]. + TimeServiceType_SystemUser = 4, ///< Initializes time:su. Only available with [9.0.0+]. +} TimeServiceType; + +/// Time clock type. +typedef enum { + TimeType_UserSystemClock, + TimeType_NetworkSystemClock, + TimeType_LocalSystemClock, + TimeType_Default = TimeType_UserSystemClock, +} TimeType; + +typedef struct { + u16 year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; + u8 pad; +} TimeCalendarTime; + +typedef struct { + u32 wday; ///< 0-based day-of-week. + u32 yday; ///< 0-based day-of-year. + char timezoneName[8]; ///< Timezone name string. + u32 DST; ///< 0 = no DST, 1 = DST. + s32 offset; ///< Seconds relative to UTC for this timezone. +} TimeCalendarAdditionalInfo; + +typedef struct { + u8 data[0x4000]; +} TimeZoneRule; + +typedef struct { + char name[0x24]; +} TimeLocationName; + +typedef struct { + s64 time_point; ///< Monotonic count in seconds. + Uuid source_id; ///< An ID representing the clock source. +} TimeSteadyClockTimePoint; + +typedef struct { + s64 base_time; + Uuid source_id; +} TimeStandardSteadyClockTimePointType; + +typedef struct { + s64 offset; + TimeSteadyClockTimePoint timestamp; +} TimeSystemClockContext; + +/// Initialize time. Used automatically during app startup. +Result timeInitialize(void); + +/// Exit time. Used automatically during app startup. +void timeExit(void); + +/// Gets the Service object for the actual time service session. +Service* timeGetServiceSession(void); + +/// Gets the Service object for ISystemClock with the specified \ref TimeType. This will return NULL when the type is invalid. +Service* timeGetServiceSession_SystemClock(TimeType type); + +/// Gets the Service object for ISteadyClock. +Service* timeGetServiceSession_SteadyClock(void); + +/// Gets the Service object for ITimeZoneService. +Service* timeGetServiceSession_TimeZoneService(void); + +/// [6.0.0+] Gets the address of the SharedMemory. +void* timeGetSharedmemAddr(void); + +/** + * @brief Gets the timepoint for the standard steady clock. + * @param[out] out Output timepoint (see \ref TimeSteadyClockTimePoint) + * @remark The standard steady clock counts time since the RTC was configured (usually this happens during manufacturing). + * @return Result code. + */ +Result timeGetStandardSteadyClockTimePoint(TimeSteadyClockTimePoint *out); + +/** + * @brief [3.0.0+] Gets the internal offset for the standard steady clock. + * @param[out] out Output internal offset. + * @return Result code. + */ +Result timeGetStandardSteadyClockInternalOffset(s64 *out); + +/** + * @brief Gets the time for the specified clock. + * @param[in] type Clock to use. + * @param[out] timestamp POSIX UTC timestamp. + * @return Result code. + */ +Result timeGetCurrentTime(TimeType type, u64 *timestamp); + +/** + * @brief Sets the time for the specified clock. + * @param[in] type Clock to use. + * @param[in] timestamp POSIX UTC timestamp. + * @return Result code. + */ +Result timeSetCurrentTime(TimeType type, u64 timestamp); + +Result timeGetDeviceLocationName(TimeLocationName *name); +Result timeSetDeviceLocationName(const TimeLocationName *name); +Result timeGetTotalLocationNameCount(s32 *total_location_name_count); +Result timeLoadLocationNameList(s32 index, TimeLocationName *location_name_array, s32 location_name_max, s32 *location_name_count); + +Result timeLoadTimeZoneRule(const TimeLocationName *name, TimeZoneRule *rule); + +Result timeToCalendarTime(const TimeZoneRule *rule, u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info); +Result timeToCalendarTimeWithMyRule(u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info); +Result timeToPosixTime(const TimeZoneRule *rule, const TimeCalendarTime *caltime, u64 *timestamp_list, s32 timestamp_list_count, s32 *timestamp_count); +Result timeToPosixTimeWithMyRule(const TimeCalendarTime *caltime, u64 *timestamp_list, s32 timestamp_list_count, s32 *timestamp_count); + diff --git a/src/libnx/wrapper/switch/services/time.nim b/src/libnx/wrapper/switch/services/time.nim new file mode 100644 index 0000000..710c685 --- /dev/null +++ b/src/libnx/wrapper/switch/services/time.nim @@ -0,0 +1,148 @@ +## * +## @file time.h +## @brief Time services IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Values for __nx_time_service_type. + +type + TimeServiceType* = enum + TimeServiceTypeUser = 0, ## /< Default. Initializes time:u. + TimeServiceTypeMenu = 1, ## /< Initializes time:a + TimeServiceTypeSystem = 2, ## /< Initializes time:s. + TimeServiceTypeRepair = 3, ## /< Initializes time:r. Only available with [9.0.0+]. + TimeServiceTypeSystemUser = 4 ## /< Initializes time:su. Only available with [9.0.0+]. + + +## / Time clock type. + +type + TimeType* = enum + TimeTypeUserSystemClock, TimeTypeNetworkSystemClock, TimeTypeLocalSystemClock, + + TimeCalendarTime* {.bycopy.} = object + year*: U16 + month*: U8 + day*: U8 + hour*: U8 + minute*: U8 + second*: U8 + pad*: U8 + + TimeCalendarAdditionalInfo* {.bycopy.} = object + wday*: U32 ## /< 0-based day-of-week. + yday*: U32 ## /< 0-based day-of-year. + timezoneName*: array[8, char] ## /< Timezone name string. + dst*: U32 ## /< 0 = no DST, 1 = DST. + offset*: S32 ## /< Seconds relative to UTC for this timezone. + + TimeZoneRule* {.bycopy.} = object + data*: array[0x4000, U8] + + TimeLocationName* {.bycopy.} = object + name*: array[0x24, char] + + TimeSteadyClockTimePoint* {.bycopy.} = object + timePoint*: S64 ## /< Monotonic count in seconds. + sourceId*: Uuid ## /< An ID representing the clock source. + + TimeStandardSteadyClockTimePointType* {.bycopy.} = object + baseTime*: S64 + sourceId*: Uuid + + TimeSystemClockContext* {.bycopy.} = object + offset*: S64 + timestamp*: TimeSteadyClockTimePoint + +const TimeTypeDefault* = TimeTypeUserSystemClock + +proc timeInitialize*(): Result {.cdecl, importc: "timeInitialize".} +## / Initialize time. Used automatically during app startup. + +proc timeExit*() {.cdecl, importc: "timeExit".} +## / Exit time. Used automatically during app startup. + +proc timeGetServiceSession*(): ptr Service {.cdecl, importc: "timeGetServiceSession".} +## / Gets the Service object for the actual time service session. + +proc timeGetServiceSessionSystemClock*(`type`: TimeType): ptr Service {.cdecl, + importc: "timeGetServiceSession_SystemClock".} +## / Gets the Service object for ISystemClock with the specified \ref TimeType. This will return NULL when the type is invalid. + +proc timeGetServiceSessionSteadyClock*(): ptr Service {.cdecl, + importc: "timeGetServiceSession_SteadyClock".} +## / Gets the Service object for ISteadyClock. + +proc timeGetServiceSessionTimeZoneService*(): ptr Service {.cdecl, + importc: "timeGetServiceSession_TimeZoneService".} +## / Gets the Service object for ITimeZoneService. + +proc timeGetSharedmemAddr*(): pointer {.cdecl, importc: "timeGetSharedmemAddr".} +## / [6.0.0+] Gets the address of the SharedMemory. + +proc timeGetStandardSteadyClockTimePoint*(`out`: ptr TimeSteadyClockTimePoint): Result {. + cdecl, importc: "timeGetStandardSteadyClockTimePoint".} +## * +## @brief Gets the timepoint for the standard steady clock. +## @param[out] out Output timepoint (see \ref TimeSteadyClockTimePoint) +## @remark The standard steady clock counts time since the RTC was configured (usually this happens during manufacturing). +## @return Result code. +## + +proc timeGetStandardSteadyClockInternalOffset*(`out`: ptr S64): Result {.cdecl, + importc: "timeGetStandardSteadyClockInternalOffset".} +## * +## @brief [3.0.0+] Gets the internal offset for the standard steady clock. +## @param[out] out Output internal offset. +## @return Result code. +## + +proc timeGetCurrentTime*(`type`: TimeType; timestamp: ptr U64): Result {.cdecl, + importc: "timeGetCurrentTime".} +## * +## @brief Gets the time for the specified clock. +## @param[in] type Clock to use. +## @param[out] timestamp POSIX UTC timestamp. +## @return Result code. +## + +proc timeSetCurrentTime*(`type`: TimeType; timestamp: U64): Result {.cdecl, + importc: "timeSetCurrentTime".} +## * +## @brief Sets the time for the specified clock. +## @param[in] type Clock to use. +## @param[in] timestamp POSIX UTC timestamp. +## @return Result code. +## + +proc timeGetDeviceLocationName*(name: ptr TimeLocationName): Result {.cdecl, + importc: "timeGetDeviceLocationName".} +proc timeSetDeviceLocationName*(name: ptr TimeLocationName): Result {.cdecl, + importc: "timeSetDeviceLocationName".} +proc timeGetTotalLocationNameCount*(totalLocationNameCount: ptr S32): Result {.cdecl, + importc: "timeGetTotalLocationNameCount".} +proc timeLoadLocationNameList*(index: S32; locationNameArray: ptr TimeLocationName; + locationNameMax: S32; locationNameCount: ptr S32): Result {. + cdecl, importc: "timeLoadLocationNameList".} +proc timeLoadTimeZoneRule*(name: ptr TimeLocationName; rule: ptr TimeZoneRule): Result {. + cdecl, importc: "timeLoadTimeZoneRule".} +proc timeToCalendarTime*(rule: ptr TimeZoneRule; timestamp: U64; + caltime: ptr TimeCalendarTime; + info: ptr TimeCalendarAdditionalInfo): Result {.cdecl, + importc: "timeToCalendarTime".} +proc timeToCalendarTimeWithMyRule*(timestamp: U64; caltime: ptr TimeCalendarTime; + info: ptr TimeCalendarAdditionalInfo): Result {. + cdecl, importc: "timeToCalendarTimeWithMyRule".} +proc timeToPosixTime*(rule: ptr TimeZoneRule; caltime: ptr TimeCalendarTime; + timestampList: ptr U64; timestampListCount: S32; + timestampCount: ptr S32): Result {.cdecl, + importc: "timeToPosixTime".} +proc timeToPosixTimeWithMyRule*(caltime: ptr TimeCalendarTime; + timestampList: ptr U64; timestampListCount: S32; + timestampCount: ptr S32): Result {.cdecl, + importc: "timeToPosixTimeWithMyRule".} diff --git a/src/libnx/wrapper/switch/services/ts.h b/src/libnx/wrapper/switch/services/ts.h new file mode 100644 index 0000000..4f94b5e --- /dev/null +++ b/src/libnx/wrapper/switch/services/ts.h @@ -0,0 +1,47 @@ +/** + * @file ts.h + * @brief Temperature measurement (ts) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// Location +typedef enum { + TsLocation_Internal = 0, ///< TMP451 Internal: PCB + TsLocation_External = 1, ///< TMP451 External: SoC +} TsLocation; + +/// Initialize ts. +Result tsInitialize(void); + +/// Exit ts. +void tsExit(void); + +/// Gets the Service for ts. +Service* tsGetServiceSession(void); + +/** + * @brief Gets the min/max temperature for the specified \ref TsLocation. + * @param[in] location \ref TsLocation + * @param[out] min_temperature Output minimum temperature in Celsius. + * @param[out] max_temperature Output maximum temperature in Celsius. + */ +Result tsGetTemperatureRange(TsLocation location, s32 *min_temperature, s32 *max_temperature); + +/** + * @brief Gets the temperature for the specified \ref TsLocation. + * @param[in] location \ref TsLocation + * @param[out] temperature Output temperature in Celsius. + */ +Result tsGetTemperature(TsLocation location, s32 *temperature); + +/** + * @brief Gets the temperature for the specified \ref TsLocation, in MilliC. [1.0.0-13.2.1] + * @param[in] location \ref TsLocation + * @param[out] temperature Output temperature in MilliC. + */ +Result tsGetTemperatureMilliC(TsLocation location, s32 *temperature); + diff --git a/src/libnx/wrapper/switch/services/ts.nim b/src/libnx/wrapper/switch/services/ts.nim new file mode 100644 index 0000000..a063f87 --- /dev/null +++ b/src/libnx/wrapper/switch/services/ts.nim @@ -0,0 +1,53 @@ +## * +## @file ts.h +## @brief Temperature measurement (ts) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / Location + +type + TsLocation* = enum + TsLocationInternal = 0, ## /< TMP451 Internal: PCB + TsLocationExternal = 1 ## /< TMP451 External: SoC + + +## / Initialize ts. + +proc tsInitialize*(): Result {.cdecl, importc: "tsInitialize".} +## / Exit ts. + +proc tsExit*() {.cdecl, importc: "tsExit".} +## / Gets the Service for ts. + +proc tsGetServiceSession*(): ptr Service {.cdecl, importc: "tsGetServiceSession".} +## * +## @brief Gets the min/max temperature for the specified \ref TsLocation. +## @param[in] location \ref TsLocation +## @param[out] min_temperature Output minimum temperature in Celsius. +## @param[out] max_temperature Output maximum temperature in Celsius. +## + +proc tsGetTemperatureRange*(location: TsLocation; minTemperature: ptr S32; + maxTemperature: ptr S32): Result {.cdecl, + importc: "tsGetTemperatureRange".} +## * +## @brief Gets the temperature for the specified \ref TsLocation. +## @param[in] location \ref TsLocation +## @param[out] temperature Output temperature in Celsius. +## + +proc tsGetTemperature*(location: TsLocation; temperature: ptr S32): Result {.cdecl, + importc: "tsGetTemperature".} +## * +## @brief Gets the temperature for the specified \ref TsLocation, in MilliC. [1.0.0-13.2.1] +## @param[in] location \ref TsLocation +## @param[out] temperature Output temperature in MilliC. +## + +proc tsGetTemperatureMilliC*(location: TsLocation; temperature: ptr S32): Result {. + cdecl, importc: "tsGetTemperatureMilliC".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/uart.h b/src/libnx/wrapper/switch/services/uart.h new file mode 100644 index 0000000..dccee01 --- /dev/null +++ b/src/libnx/wrapper/switch/services/uart.h @@ -0,0 +1,243 @@ +/** + * @file uart.h + * @brief UART service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +/// UartPort +typedef enum { + UartPort_Bluetooth = 1, ///< Bluetooth + UartPort_JoyConR = 2, ///< Joy-Con(R) + UartPort_JoyConL = 3, ///< Joy-Con(L) + UartPort_MCU = 4, ///< MCU +} UartPort; + +/// UartPortForDev +typedef enum { + UartPortForDev_JoyConR = 1, ///< Joy-Con(R) + UartPortForDev_JoyConL = 2, ///< Joy-Con(L) + UartPortForDev_Bluetooth = 3, ///< Bluetooth +} UartPortForDev; + +/// FlowControlMode +typedef enum { + UartFlowControlMode_None = 0, ///< None + UartFlowControlMode_Hardware = 1, ///< Hardware +} UartFlowControlMode; + +/// PortEventType +typedef enum { + UartPortEventType_SendBufferEmpty = 0, ///< SendBufferEmpty + UartPortEventType_SendBufferReady = 1, ///< SendBufferReady + UartPortEventType_ReceiveBufferReady = 2, ///< ReceiveBufferReady + UartPortEventType_ReceiveEnd = 3, ///< ReceiveEnd +} UartPortEventType; + +/// PortSession +typedef struct { + Service s; ///< IPortSession +} UartPortSession; + +/// Initialize uart. +Result uartInitialize(void); + +/// Exit uart. +void uartExit(void); + +/// Gets the Service object for the actual uart service session. +Service* uartGetServiceSession(void); + +/** + * @brief HasPort + * @param[in] port \ref UartPort + * @param[out] out Output success flag. + */ +Result uartHasPort(UartPort port, bool *out); + +/** + * @brief HasPortForDev + * @param[in] port \ref UartPortForDev + * @param[out] out Output success flag. + */ +Result uartHasPortForDev(UartPortForDev port, bool *out); + +/** + * @brief IsSupportedBaudRate + * @param[in] port \ref UartPort + * @param[in] baud_rate BaudRate + * @param[out] out Output success flag. + */ +Result uartIsSupportedBaudRate(UartPort port, u32 baud_rate, bool *out); + +/** + * @brief IsSupportedBaudRateForDev + * @param[in] port \ref UartPortForDev + * @param[in] baud_rate BaudRate + * @param[out] out Output success flag. + */ +Result uartIsSupportedBaudRateForDev(UartPortForDev port, u32 baud_rate, bool *out); + +/** + * @brief IsSupportedFlowControlMode + * @param[in] port \ref UartPort + * @param[in] flow_control_mode \ref UartFlowControlMode + * @param[out] out Output success flag. + */ +Result uartIsSupportedFlowControlMode(UartPort port, UartFlowControlMode flow_control_mode, bool *out); + +/** + * @brief IsSupportedFlowControlModeForDev + * @param[in] port \ref UartPortForDev + * @param[in] flow_control_mode \ref UartFlowControlMode + * @param[out] out Output success flag. + */ +Result uartIsSupportedFlowControlModeForDev(UartPortForDev port, UartFlowControlMode flow_control_mode, bool *out); + +/** + * @brief Creates an \ref UartPortSession. + * @note Use \ref uartPortSessionOpenPort or \ref uartPortSessionOpenPortForDev before using any other cmds. + * @param[out] s \ref UartPortSession + */ +Result uartCreatePortSession(UartPortSession *s); + +/** + * @brief IsSupportedPortEvent + * @param[in] port \ref UartPort + * @param[in] port_event_type \ref UartPortEventType + * @param[out] out Output success flag. + */ +Result uartIsSupportedPortEvent(UartPort port, UartPortEventType port_event_type, bool *out); + +/** + * @brief IsSupportedPortEventForDev + * @param[in] port \ref UartPortForDev + * @param[in] port_event_type \ref UartPortEventType + * @param[out] out Output success flag. + */ +Result uartIsSupportedPortEventForDev(UartPortForDev port, UartPortEventType port_event_type, bool *out); + +/** + * @brief IsSupportedDeviceVariation + * @note Only available on [7.0.0+]. + * @param[in] port \ref UartPort + * @param[in] device_variation DeviceVariation + * @param[out] out Output success flag. + */ +Result uartIsSupportedDeviceVariation(UartPort port, u32 device_variation, bool *out); + +/** + * @brief IsSupportedDeviceVariationForDev + * @note Only available on [7.0.0+]. + * @param[in] port \ref UartPortForDev + * @param[in] device_variation DeviceVariation + * @param[out] out Output success flag. + */ +Result uartIsSupportedDeviceVariationForDev(UartPortForDev port, u32 device_variation, bool *out); + +///@name IPortSession +///@{ + +/** + * @brief Close an \ref UartPortSession. + * @param s \ref UartPortSession + */ +void uartPortSessionClose(UartPortSession* s); + +/** + * @brief OpenPort + * @note This is not usable when the specified \ref UartPort is already being used. + * @param s \ref UartPortSession + * @param[out] out Output success flag. + * @param[in] port \ref UartPort + * @param[in] baud_rate BaudRate + * @param[in] flow_control_mode \ref UartFlowControlMode + * @param[in] device_variation [7.0.0+] DeviceVariation + * @param[in] is_invert_tx [6.0.0+] IsInvertTx + * @param[in] is_invert_rx [6.0.0+] IsInvertRx + * @param[in] is_invert_rts [6.0.0+] IsInvertRts + * @param[in] is_invert_cts [6.0.0+] IsInvertCts + * @param[in] send_buffer Send buffer, must be 0x1000-byte aligned. + * @param[in] send_buffer_length Send buffer size, must be 0x1000-byte aligned. + * @param[in] receive_buffer Receive buffer, must be 0x1000-byte aligned. + * @param[in] receive_buffer_length Receive buffer size, must be 0x1000-byte aligned. + */ +Result uartPortSessionOpenPort(UartPortSession* s, bool *out, UartPort port, u32 baud_rate, UartFlowControlMode flow_control_mode, u32 device_variation, bool is_invert_tx, bool is_invert_rx, bool is_invert_rts, bool is_invert_cts, void* send_buffer, u64 send_buffer_length, void* receive_buffer, u64 receive_buffer_length); + +/** + * @brief OpenPortForDev + * @note See the notes for \ref uartPortSessionOpenPort. + * @param s \ref UartPortSession + * @param[out] out Output success flag. + * @param[in] port \ref UartPortForDev + * @param[in] baud_rate BaudRate + * @param[in] flow_control_mode \ref UartFlowControlMode + * @param[in] device_variation [7.0.0+] DeviceVariation + * @param[in] is_invert_tx [6.0.0+] IsInvertTx + * @param[in] is_invert_rx [6.0.0+] IsInvertRx + * @param[in] is_invert_rts [6.0.0+] IsInvertRts + * @param[in] is_invert_cts [6.0.0+] IsInvertCts + * @param[in] send_buffer Send buffer, must be 0x1000-byte aligned. + * @param[in] send_buffer_length Send buffer size, must be 0x1000-byte aligned. + * @param[in] receive_buffer Receive buffer, must be 0x1000-byte aligned. + * @param[in] receive_buffer_length Receive buffer size, must be 0x1000-byte aligned. + */ +Result uartPortSessionOpenPortForDev(UartPortSession* s, bool *out, UartPortForDev port, u32 baud_rate, UartFlowControlMode flow_control_mode, u32 device_variation, bool is_invert_tx, bool is_invert_rx, bool is_invert_rts, bool is_invert_cts, void* send_buffer, u64 send_buffer_length, void* receive_buffer, u64 receive_buffer_length); + +/** + * @brief GetWritableLength + * @param s \ref UartPortSession + * @param[out] out Output WritableLength. + */ +Result uartPortSessionGetWritableLength(UartPortSession* s, u64 *out); + +/** + * @brief Send + * @param s \ref UartPortSession + * @param[in] in_data Input data buffer. + * @param[in] size Input data buffer size. + * @param[out] out Output size. + */ +Result uartPortSessionSend(UartPortSession* s, const void* in_data, size_t size, u64 *out); + +/** + * @brief GetReadableLength + * @param s \ref UartPortSession + * @param[out] out Output ReadableLength. + */ +Result uartPortSessionGetReadableLength(UartPortSession* s, u64 *out); + +/** + * @brief Receive + * @param s \ref UartPortSession + * @param[out] out_data Output data buffer. + * @param[in] size Output data buffer size. + * @param[out] out Output size. + */ +Result uartPortSessionReceive(UartPortSession* s, void* out_data, size_t size, u64 *out); + +/** + * @brief BindPortEvent + * @note The Event must be closed by the user after using \ref uartPortSessionUnbindPortEvent. + * @param s \ref UartPortSession + * @param[in] port_event_type \ref UartPortEventType + * @param[in] threshold Threshold + * @param[out] out Output success flag. + * @param[out] out_event Output Event with autoclear=false. + */ +Result uartPortSessionBindPortEvent(UartPortSession* s, UartPortEventType port_event_type, s64 threshold, bool *out, Event *out_event); + +/** + * @brief UnbindPortEvent + * @param s \ref UartPortSession + * @param[in] port_event_type \ref UartPortEventType + * @param[out] out Output success flag. + */ +Result uartPortSessionUnbindPortEvent(UartPortSession* s, UartPortEventType port_event_type, bool *out); + +///@} + diff --git a/src/libnx/wrapper/switch/services/uart.nim b/src/libnx/wrapper/switch/services/uart.nim new file mode 100644 index 0000000..d63b5c4 --- /dev/null +++ b/src/libnx/wrapper/switch/services/uart.nim @@ -0,0 +1,298 @@ +## * +## @file uart.h +## @brief UART service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +## / UartPort + +type + UartPort* = enum + UartPortBluetooth = 1, ## /< Bluetooth + UartPortJoyConR = 2, ## /< Joy-Con(R) + UartPortJoyConL = 3, ## /< Joy-Con(L) + UartPortMCU = 4 ## /< MCU + + +## / UartPortForDev + +type + UartPortForDev* = enum + UartPortForDevJoyConR = 1, ## /< Joy-Con(R) + UartPortForDevJoyConL = 2, ## /< Joy-Con(L) + UartPortForDevBluetooth = 3 ## /< Bluetooth + + +## / FlowControlMode + +type + UartFlowControlMode* = enum + UartFlowControlModeNone = 0, ## /< None + UartFlowControlModeHardware = 1 ## /< Hardware + + +## / PortEventType + +type + UartPortEventType* = enum + UartPortEventTypeSendBufferEmpty = 0, ## /< SendBufferEmpty + UartPortEventTypeSendBufferReady = 1, ## /< SendBufferReady + UartPortEventTypeReceiveBufferReady = 2, ## /< ReceiveBufferReady + UartPortEventTypeReceiveEnd = 3 ## /< ReceiveEnd + + +## / PortSession + +type + UartPortSession* {.bycopy.} = object + s*: Service ## /< IPortSession + + +## / Initialize uart. + +proc uartInitialize*(): Result {.cdecl, importc: "uartInitialize".} +## / Exit uart. + +proc uartExit*() {.cdecl, importc: "uartExit".} +## / Gets the Service object for the actual uart service session. + +proc uartGetServiceSession*(): ptr Service {.cdecl, importc: "uartGetServiceSession".} +## * +## @brief HasPort +## @param[in] port \ref UartPort +## @param[out] out Output success flag. +## + +proc uartHasPort*(port: UartPort; `out`: ptr bool): Result {.cdecl, + importc: "uartHasPort".} +## * +## @brief HasPortForDev +## @param[in] port \ref UartPortForDev +## @param[out] out Output success flag. +## + +proc uartHasPortForDev*(port: UartPortForDev; `out`: ptr bool): Result {.cdecl, + importc: "uartHasPortForDev".} +## * +## @brief IsSupportedBaudRate +## @param[in] port \ref UartPort +## @param[in] baud_rate BaudRate +## @param[out] out Output success flag. +## + +proc uartIsSupportedBaudRate*(port: UartPort; baudRate: U32; `out`: ptr bool): Result {. + cdecl, importc: "uartIsSupportedBaudRate".} +## * +## @brief IsSupportedBaudRateForDev +## @param[in] port \ref UartPortForDev +## @param[in] baud_rate BaudRate +## @param[out] out Output success flag. +## + +proc uartIsSupportedBaudRateForDev*(port: UartPortForDev; baudRate: U32; + `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedBaudRateForDev".} +## * +## @brief IsSupportedFlowControlMode +## @param[in] port \ref UartPort +## @param[in] flow_control_mode \ref UartFlowControlMode +## @param[out] out Output success flag. +## + +proc uartIsSupportedFlowControlMode*(port: UartPort; + flowControlMode: UartFlowControlMode; + `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedFlowControlMode".} +## * +## @brief IsSupportedFlowControlModeForDev +## @param[in] port \ref UartPortForDev +## @param[in] flow_control_mode \ref UartFlowControlMode +## @param[out] out Output success flag. +## + +proc uartIsSupportedFlowControlModeForDev*(port: UartPortForDev; + flowControlMode: UartFlowControlMode; `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedFlowControlModeForDev".} +## * +## @brief Creates an \ref UartPortSession. +## @note Use \ref uartPortSessionOpenPort or \ref uartPortSessionOpenPortForDev before using any other cmds. +## @param[out] s \ref UartPortSession +## + +proc uartCreatePortSession*(s: ptr UartPortSession): Result {.cdecl, + importc: "uartCreatePortSession".} +## * +## @brief IsSupportedPortEvent +## @param[in] port \ref UartPort +## @param[in] port_event_type \ref UartPortEventType +## @param[out] out Output success flag. +## + +proc uartIsSupportedPortEvent*(port: UartPort; portEventType: UartPortEventType; + `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedPortEvent".} +## * +## @brief IsSupportedPortEventForDev +## @param[in] port \ref UartPortForDev +## @param[in] port_event_type \ref UartPortEventType +## @param[out] out Output success flag. +## + +proc uartIsSupportedPortEventForDev*(port: UartPortForDev; + portEventType: UartPortEventType; + `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedPortEventForDev".} +## * +## @brief IsSupportedDeviceVariation +## @note Only available on [7.0.0+]. +## @param[in] port \ref UartPort +## @param[in] device_variation DeviceVariation +## @param[out] out Output success flag. +## + +proc uartIsSupportedDeviceVariation*(port: UartPort; deviceVariation: U32; + `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedDeviceVariation".} +## * +## @brief IsSupportedDeviceVariationForDev +## @note Only available on [7.0.0+]. +## @param[in] port \ref UartPortForDev +## @param[in] device_variation DeviceVariation +## @param[out] out Output success flag. +## + +proc uartIsSupportedDeviceVariationForDev*(port: UartPortForDev; + deviceVariation: U32; `out`: ptr bool): Result {.cdecl, + importc: "uartIsSupportedDeviceVariationForDev".} +## /@name IPortSession +## /@{ +## * +## @brief Close an \ref UartPortSession. +## @param s \ref UartPortSession +## + +proc uartPortSessionClose*(s: ptr UartPortSession) {.cdecl, + importc: "uartPortSessionClose".} +## * +## @brief OpenPort +## @note This is not usable when the specified \ref UartPort is already being used. +## @param s \ref UartPortSession +## @param[out] out Output success flag. +## @param[in] port \ref UartPort +## @param[in] baud_rate BaudRate +## @param[in] flow_control_mode \ref UartFlowControlMode +## @param[in] device_variation [7.0.0+] DeviceVariation +## @param[in] is_invert_tx [6.0.0+] IsInvertTx +## @param[in] is_invert_rx [6.0.0+] IsInvertRx +## @param[in] is_invert_rts [6.0.0+] IsInvertRts +## @param[in] is_invert_cts [6.0.0+] IsInvertCts +## @param[in] send_buffer Send buffer, must be 0x1000-byte aligned. +## @param[in] send_buffer_length Send buffer size, must be 0x1000-byte aligned. +## @param[in] receive_buffer Receive buffer, must be 0x1000-byte aligned. +## @param[in] receive_buffer_length Receive buffer size, must be 0x1000-byte aligned. +## + +proc uartPortSessionOpenPort*(s: ptr UartPortSession; `out`: ptr bool; port: UartPort; + baudRate: U32; flowControlMode: UartFlowControlMode; + deviceVariation: U32; isInvertTx: bool; + isInvertRx: bool; isInvertRts: bool; isInvertCts: bool; + sendBuffer: pointer; sendBufferLength: U64; + receiveBuffer: pointer; receiveBufferLength: U64): Result {. + cdecl, importc: "uartPortSessionOpenPort".} +## * +## @brief OpenPortForDev +## @note See the notes for \ref uartPortSessionOpenPort. +## @param s \ref UartPortSession +## @param[out] out Output success flag. +## @param[in] port \ref UartPortForDev +## @param[in] baud_rate BaudRate +## @param[in] flow_control_mode \ref UartFlowControlMode +## @param[in] device_variation [7.0.0+] DeviceVariation +## @param[in] is_invert_tx [6.0.0+] IsInvertTx +## @param[in] is_invert_rx [6.0.0+] IsInvertRx +## @param[in] is_invert_rts [6.0.0+] IsInvertRts +## @param[in] is_invert_cts [6.0.0+] IsInvertCts +## @param[in] send_buffer Send buffer, must be 0x1000-byte aligned. +## @param[in] send_buffer_length Send buffer size, must be 0x1000-byte aligned. +## @param[in] receive_buffer Receive buffer, must be 0x1000-byte aligned. +## @param[in] receive_buffer_length Receive buffer size, must be 0x1000-byte aligned. +## + +proc uartPortSessionOpenPortForDev*(s: ptr UartPortSession; `out`: ptr bool; + port: UartPortForDev; baudRate: U32; + flowControlMode: UartFlowControlMode; + deviceVariation: U32; isInvertTx: bool; + isInvertRx: bool; isInvertRts: bool; + isInvertCts: bool; sendBuffer: pointer; + sendBufferLength: U64; receiveBuffer: pointer; + receiveBufferLength: U64): Result {.cdecl, + importc: "uartPortSessionOpenPortForDev".} +## * +## @brief GetWritableLength +## @param s \ref UartPortSession +## @param[out] out Output WritableLength. +## + +proc uartPortSessionGetWritableLength*(s: ptr UartPortSession; `out`: ptr U64): Result {. + cdecl, importc: "uartPortSessionGetWritableLength".} +## * +## @brief Send +## @param s \ref UartPortSession +## @param[in] in_data Input data buffer. +## @param[in] size Input data buffer size. +## @param[out] out Output size. +## + +proc uartPortSessionSend*(s: ptr UartPortSession; inData: pointer; size: csize_t; + `out`: ptr U64): Result {.cdecl, + importc: "uartPortSessionSend".} +## * +## @brief GetReadableLength +## @param s \ref UartPortSession +## @param[out] out Output ReadableLength. +## + +proc uartPortSessionGetReadableLength*(s: ptr UartPortSession; `out`: ptr U64): Result {. + cdecl, importc: "uartPortSessionGetReadableLength".} +## * +## @brief Receive +## @param s \ref UartPortSession +## @param[out] out_data Output data buffer. +## @param[in] size Output data buffer size. +## @param[out] out Output size. +## + +proc uartPortSessionReceive*(s: ptr UartPortSession; outData: pointer; size: csize_t; + `out`: ptr U64): Result {.cdecl, + importc: "uartPortSessionReceive".} +## * +## @brief BindPortEvent +## @note The Event must be closed by the user after using \ref uartPortSessionUnbindPortEvent. +## @param s \ref UartPortSession +## @param[in] port_event_type \ref UartPortEventType +## @param[in] threshold Threshold +## @param[out] out Output success flag. +## @param[out] out_event Output Event with autoclear=false. +## + +proc uartPortSessionBindPortEvent*(s: ptr UartPortSession; + portEventType: UartPortEventType; + threshold: S64; `out`: ptr bool; + outEvent: ptr Event): Result {.cdecl, + importc: "uartPortSessionBindPortEvent".} +## * +## @brief UnbindPortEvent +## @param s \ref UartPortSession +## @param[in] port_event_type \ref UartPortEventType +## @param[out] out Output success flag. +## + +proc uartPortSessionUnbindPortEvent*(s: ptr UartPortSession; + portEventType: UartPortEventType; + `out`: ptr bool): Result {.cdecl, + importc: "uartPortSessionUnbindPortEvent".} +## /@} diff --git a/src/libnx/wrapper/switch/services/usb.h b/src/libnx/wrapper/switch/services/usb.h new file mode 100644 index 0000000..685b696 --- /dev/null +++ b/src/libnx/wrapper/switch/services/usb.h @@ -0,0 +1,220 @@ +/** + * @file usb.h + * @brief Common USB (usb:*) service IPC header. + * @author SciresM, yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +/// Names starting with "libusb" were changed to "usb" to avoid collision with actual libusb if it's ever used. + +/// Imported from libusb with changed names. +/* Descriptor sizes per descriptor type */ +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_DEVICE_SIZE 0x12 +#define USB_DT_SS_ENDPOINT_COMPANION_SIZE 6 + +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/// Imported from libusb, with some adjustments. +struct usb_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; ///< Must match USB_DT_ENDPOINT. + uint8_t bEndpointAddress; ///< Should be one of the usb_endpoint_direction values, the endpoint-number is automatically allocated. + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} PACKED; + +/// Imported from libusb, with some adjustments. +struct usb_interface_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; ///< Must match USB_DT_INTERFACE. + uint8_t bInterfaceNumber; ///< See also USBDS_DEFAULT_InterfaceNumber. + uint8_t bAlternateSetting; ///< Must match 0. + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; ///< Ignored. +}; + +/// Imported from libusb, with some adjustments. +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; ///< Must match USB_DT_Device. + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +}; + +/// Imported from libusb, with some adjustments. +struct usb_config_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t MaxPower; +} PACKED; + +/// Imported from libusb, with some adjustments. +struct usb_ss_endpoint_companion_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; ///< Must match USB_DT_SS_ENDPOINT_COMPANION. + uint8_t bMaxBurst; + uint8_t bmAttributes; + uint16_t wBytesPerInterval; +}; + +/// Imported from libusb, with some adjustments. +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; ///< Must match USB_DT_STRING. + uint16_t wData[0x40]; +}; + +/// Imported from libusb, with changed names. +enum usb_class_code { + USB_CLASS_PER_INTERFACE = 0, + USB_CLASS_AUDIO = 1, + USB_CLASS_COMM = 2, + USB_CLASS_HID = 3, + USB_CLASS_PHYSICAL = 5, + USB_CLASS_PRINTER = 7, + USB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + USB_CLASS_IMAGE = 6, + USB_CLASS_MASS_STORAGE = 8, + USB_CLASS_HUB = 9, + USB_CLASS_DATA = 10, + USB_CLASS_SMART_CARD = 0x0b, + USB_CLASS_CONTENT_SECURITY = 0x0d, + USB_CLASS_VIDEO = 0x0e, + USB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + USB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + USB_CLASS_WIRELESS = 0xe0, + USB_CLASS_APPLICATION = 0xfe, + USB_CLASS_VENDOR_SPEC = 0xff +}; + +/// Imported from libusb, with changed names. +enum usb_descriptor_type { + USB_DT_DEVICE = 0x01, + USB_DT_CONFIG = 0x02, + USB_DT_STRING = 0x03, + USB_DT_INTERFACE = 0x04, + USB_DT_ENDPOINT = 0x05, + USB_DT_BOS = 0x0f, + USB_DT_DEVICE_CAPABILITY = 0x10, + USB_DT_HID = 0x21, + USB_DT_REPORT = 0x22, + USB_DT_PHYSICAL = 0x23, + USB_DT_HUB = 0x29, + USB_DT_SUPERSPEED_HUB = 0x2a, + USB_DT_SS_ENDPOINT_COMPANION = 0x30 +}; + +/// Imported from libusb, with changed names. +enum usb_endpoint_direction { + USB_ENDPOINT_IN = 0x80, + USB_ENDPOINT_OUT = 0x00 +}; + +/// Imported from libusb, with changed names. +enum usb_transfer_type { + USB_TRANSFER_TYPE_CONTROL = 0, + USB_TRANSFER_TYPE_ISOCHRONOUS = 1, + USB_TRANSFER_TYPE_BULK = 2, + USB_TRANSFER_TYPE_INTERRUPT = 3, + USB_TRANSFER_TYPE_BULK_STREAM = 4, +}; + +/// Imported from libusb, with changed names. +enum usb_standard_request { + /** Request status of the specific recipient */ + USB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + USB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + USB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + USB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + USB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + USB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + USB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + USB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + USB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + USB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + USB_REQUEST_SYNCH_FRAME = 0x0C, + + /** Sets both the U1 and U2 Exit Latency */ + USB_REQUEST_SET_SEL = 0x30, + + /** Delay from the time a host transmits a packet to the time it is + * received by the device. */ + USB_SET_ISOCH_DELAY = 0x31, +}; + +/// Imported from libusb, with changed names. +enum usb_iso_sync_type { + USB_ISO_SYNC_TYPE_NONE = 0, + USB_ISO_SYNC_TYPE_ASYNC = 1, + USB_ISO_SYNC_TYPE_ADAPTIVE = 2, + USB_ISO_SYNC_TYPE_SYNC = 3 +}; + +/// Imported from libusb, with changed names. +enum usb_iso_usage_type { + USB_ISO_USAGE_TYPE_DATA = 0, + USB_ISO_USAGE_TYPE_FEEDBACK = 1, + USB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/// USB Device States, per USB 2.0 spec +typedef enum { + UsbState_Detached = 0, ///< Device is not attached to USB. + UsbState_Attached = 1, ///< Device is attached, but is not powered. + UsbState_Powered = 2, ///< Device is attached and powered, but has not been reset. + UsbState_Default = 3, ///< Device is attached, powered, and has been reset, but does not have an address. + UsbState_Address = 4, ///< Device is attached, powered, has been reset, has an address, but is not configured. + UsbState_Configured = 5, ///< Device is attached, powered, has been reset, has an address, configured, and may be used. + UsbState_Suspended = 6, ///< Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used. +} UsbState; + diff --git a/src/libnx/wrapper/switch/services/usb.nim b/src/libnx/wrapper/switch/services/usb.nim new file mode 100644 index 0000000..0d5a89d --- /dev/null +++ b/src/libnx/wrapper/switch/services/usb.nim @@ -0,0 +1,194 @@ +## * +## @file usb.h +## @brief Common USB (usb:*) service IPC header. +## @author SciresM, yellows8 +## @copyright libnx Authors +## + +## / Names starting with "libusb" were changed to "usb" to avoid collision with actual libusb if it's ever used. +## / Imported from libusb with changed names. +## Descriptor sizes per descriptor type + +const + USB_DT_INTERFACE_SIZE* = 9 + USB_DT_ENDPOINT_SIZE* = 7 + USB_DT_DEVICE_SIZE* = 0x12 + USB_DT_SS_ENDPOINT_COMPANION_SIZE* = 6 + USB_ENDPOINT_ADDRESS_MASK* = 0x0f + USB_ENDPOINT_DIR_MASK* = 0x80 + USB_TRANSFER_TYPE_MASK* = 0x03 + +## / Imported from libusb, with some adjustments. + +type + UsbEndpointDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 ## /< Must match USB_DT_ENDPOINT. + bEndpointAddress*: uint8 ## /< Should be one of the usb_endpoint_direction values, the endpoint-number is automatically allocated. + bmAttributes*: uint8 + wMaxPacketSize*: uint16 + bInterval*: uint8 + + +## / Imported from libusb, with some adjustments. + +type + UsbInterfaceDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 ## /< Must match USB_DT_INTERFACE. + bInterfaceNumber*: uint8 ## /< See also USBDS_DEFAULT_InterfaceNumber. + bAlternateSetting*: uint8 ## /< Must match 0. + bNumEndpoints*: uint8 + bInterfaceClass*: uint8 + bInterfaceSubClass*: uint8 + bInterfaceProtocol*: uint8 + iInterface*: uint8 ## /< Ignored. + + +## / Imported from libusb, with some adjustments. + +type + UsbDeviceDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 ## /< Must match USB_DT_Device. + bcdUSB*: uint16 + bDeviceClass*: uint8 + bDeviceSubClass*: uint8 + bDeviceProtocol*: uint8 + bMaxPacketSize0*: uint8 + idVendor*: uint16 + idProduct*: uint16 + bcdDevice*: uint16 + iManufacturer*: uint8 + iProduct*: uint8 + iSerialNumber*: uint8 + bNumConfigurations*: uint8 + + +## / Imported from libusb, with some adjustments. + +type + UsbConfigDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 + wTotalLength*: uint16 + bNumInterfaces*: uint8 + bConfigurationValue*: uint8 + iConfiguration*: uint8 + bmAttributes*: uint8 + maxPower*: uint8 + + +## / Imported from libusb, with some adjustments. + +type + UsbSsEndpointCompanionDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 ## /< Must match USB_DT_SS_ENDPOINT_COMPANION. + bMaxBurst*: uint8 + bmAttributes*: uint8 + wBytesPerInterval*: uint16 + + +## / Imported from libusb, with some adjustments. + +type + UsbStringDescriptor* {.bycopy.} = object + bLength*: uint8 + bDescriptorType*: uint8 ## /< Must match USB_DT_STRING. + wData*: array[0x40, uint16] + + +## / Imported from libusb, with changed names. + +type + UsbClassCode* = enum + USB_CLASS_PER_INTERFACE = 0, USB_CLASS_AUDIO = 1, USB_CLASS_COMM = 2, + USB_CLASS_HID = 3, USB_CLASS_PHYSICAL = 5, USB_CLASS_PTP = 6, ## legacy name from libusb-0.1 usb.h + USB_CLASS_PRINTER = 7, USB_CLASS_MASS_STORAGE = 8, USB_CLASS_HUB = 9, + USB_CLASS_DATA = 10, USB_CLASS_SMART_CARD = 0x0b, + USB_CLASS_CONTENT_SECURITY = 0x0d, USB_CLASS_VIDEO = 0x0e, + USB_CLASS_PERSONAL_HEALTHCARE = 0x0f, USB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + USB_CLASS_WIRELESS = 0xe0, USB_CLASS_APPLICATION = 0xfe, + USB_CLASS_VENDOR_SPEC = 0xff + +const + USB_CLASS_IMAGE* = USB_CLASS_PTP + +## / Imported from libusb, with changed names. + +type + UsbDescriptorType* = enum + USB_DT_DEVICE = 0x01, USB_DT_CONFIG = 0x02, USB_DT_STRING = 0x03, + USB_DT_INTERFACE = 0x04, USB_DT_ENDPOINT = 0x05, USB_DT_BOS = 0x0f, + USB_DT_DEVICE_CAPABILITY = 0x10, USB_DT_HID = 0x21, USB_DT_REPORT = 0x22, + USB_DT_PHYSICAL = 0x23, USB_DT_HUB = 0x29, USB_DT_SUPERSPEED_HUB = 0x2a, + USB_DT_SS_ENDPOINT_COMPANION = 0x30 + + +## / Imported from libusb, with changed names. + +type + UsbEndpointDirection* = enum + USB_ENDPOINT_OUT = 0x00, USB_ENDPOINT_IN = 0x80 + + +## / Imported from libusb, with changed names. + +type + UsbTransferType* = enum + USB_TRANSFER_TYPE_CONTROL = 0, USB_TRANSFER_TYPE_ISOCHRONOUS = 1, + USB_TRANSFER_TYPE_BULK = 2, USB_TRANSFER_TYPE_INTERRUPT = 3, + USB_TRANSFER_TYPE_BULK_STREAM = 4 + + +## / Imported from libusb, with changed names. + +type + UsbStandardRequest* = enum ## * Request status of the specific recipient + USB_REQUEST_GET_STATUS = 0x00, ## * Clear or disable a specific feature + USB_REQUEST_CLEAR_FEATURE = 0x01, ## 0x02 is reserved + ## * Set or enable a specific feature + USB_REQUEST_SET_FEATURE = 0x03, ## 0x04 is reserved + ## * Set device address for all future accesses + USB_REQUEST_SET_ADDRESS = 0x05, ## * Get the specified descriptor + USB_REQUEST_GET_DESCRIPTOR = 0x06, ## * Used to update existing descriptors or add new descriptors + USB_REQUEST_SET_DESCRIPTOR = 0x07, ## * Get the current device configuration value + USB_REQUEST_GET_CONFIGURATION = 0x08, ## * Set device configuration + USB_REQUEST_SET_CONFIGURATION = 0x09, ## * Return the selected alternate setting for the specified interface + USB_REQUEST_GET_INTERFACE = 0x0A, ## * Select an alternate interface for the specified interface + USB_REQUEST_SET_INTERFACE = 0x0B, ## * Set then report an endpoint's synchronization frame + USB_REQUEST_SYNCH_FRAME = 0x0C, ## * Sets both the U1 and U2 Exit Latency + USB_REQUEST_SET_SEL = 0x30, ## * Delay from the time a host transmits a packet to the time it is + ## received by the device. + USB_SET_ISOCH_DELAY = 0x31 + + +## / Imported from libusb, with changed names. + +type + UsbIsoSyncType* = enum + USB_ISO_SYNC_TYPE_NONE = 0, USB_ISO_SYNC_TYPE_ASYNC = 1, + USB_ISO_SYNC_TYPE_ADAPTIVE = 2, USB_ISO_SYNC_TYPE_SYNC = 3 + + +## / Imported from libusb, with changed names. + +type + UsbIsoUsageType* = enum + USB_ISO_USAGE_TYPE_DATA = 0, USB_ISO_USAGE_TYPE_FEEDBACK = 1, + USB_ISO_USAGE_TYPE_IMPLICIT = 2 + + +## / USB Device States, per USB 2.0 spec + +type + UsbState* = enum + UsbStateDetached = 0, ## /< Device is not attached to USB. + UsbStateAttached = 1, ## /< Device is attached, but is not powered. + UsbStatePowered = 2, ## /< Device is attached and powered, but has not been reset. + UsbStateDefault = 3, ## /< Device is attached, powered, and has been reset, but does not have an address. + UsbStateAddress = 4, ## /< Device is attached, powered, has been reset, has an address, but is not configured. + UsbStateConfigured = 5, ## /< Device is attached, powered, has been reset, has an address, configured, and may be used. + UsbStateSuspended = 6 ## /< Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used. + diff --git a/src/libnx/wrapper/switch/services/usbds.h b/src/libnx/wrapper/switch/services/usbds.h new file mode 100644 index 0000000..1e70c6f --- /dev/null +++ b/src/libnx/wrapper/switch/services/usbds.h @@ -0,0 +1,161 @@ +/** + * @file usbds.h + * @brief USB (usb:ds) service IPC wrapper. + * @brief Switch-as-device<>host USB comms, see also here: https://switchbrew.org/wiki/USB_services + * @author SciresM, yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/usb.h" +#include "../kernel/event.h" + +#define USBDS_DEFAULT_InterfaceNumber 0x4 ///Value for usb_interface_descriptor bInterfaceNumber for automatically allocating the actual bInterfaceNumber. + +typedef struct { + bool initialized; + u8 interface_index; + Service s; + + Event SetupEvent; + Event CtrlInCompletionEvent; + Event CtrlOutCompletionEvent; +} UsbDsInterface; + +typedef struct { + bool initialized; + Service s; + Event CompletionEvent; +} UsbDsEndpoint; + +typedef struct { + u16 idVendor; ///< VID + u16 idProduct; ///< PID + u16 bcdDevice; + char Manufacturer[0x20]; + char Product[0x20]; + char SerialNumber[0x20]; +} UsbDsDeviceInfo; + +typedef struct { + u32 id; ///< urbId from post-buffer cmds + u32 requestedSize; + u32 transferredSize; + u32 urb_status; +} UsbDsReportEntry; + +typedef struct { + UsbDsReportEntry report[8]; + u32 report_count; +} UsbDsReportData; + +typedef enum { + UsbComplexId_Default = 0x2 +} UsbComplexId; + +typedef enum { + UsbDeviceSpeed_Full = 0x2, ///< USB 1.1 Full Speed + UsbDeviceSpeed_High = 0x3, ///< USB 2.0 High Speed + UsbDeviceSpeed_Super = 0x4, ///< USB 3.0 Super Speed +} UsbDeviceSpeed; + +/// Opens a session with usb:ds. +Result usbDsInitialize(void); + +/// Closes the usb:ds session. Any interfaces/endpoints which are left open are automatically closed, since otherwise usb-sysmodule won't fully reset usb:ds to defaults. +void usbDsExit(void); + +/// Gets the Service object for the actual usb:ds service session. +Service* usbDsGetServiceSession(void); + +/// Helper func. +Result usbDsWaitReady(u64 timeout); + +/// Helper func. +Result usbDsParseReportData(UsbDsReportData *reportdata, u32 urbId, u32 *requestedSize, u32 *transferredSize); + +///@name IDsService +///@{ + +Event* usbDsGetStateChangeEvent(void); + +/// Gets the device state. See \ref UsbState. +Result usbDsGetState(UsbState* out); + +/// Removed in [5.0.0+]. +Result usbDsGetDsInterface(UsbDsInterface** out, struct usb_interface_descriptor* descriptor, const char* interface_name); + +/// Removed in [5.0.0+]. +Result usbDsSetVidPidBcd(const UsbDsDeviceInfo* deviceinfo); + +/// Only available on [5.0.0+]. +Result usbDsRegisterInterface(UsbDsInterface** out); + +/// Only available on [5.0.0+]. +Result usbDsRegisterInterfaceEx(UsbDsInterface** out, u8 intf_num); + +/// Only available on [5.0.0+]. +Result usbDsClearDeviceData(void); + +/// Only available on [5.0.0+]. +Result usbDsAddUsbStringDescriptor(u8* out_index, const char* string); + +/// Only available on [5.0.0+]. +Result usbDsAddUsbLanguageStringDescriptor(u8* out_index, const u16* lang_ids, u16 num_langs); + +/// Only available on [5.0.0+]. +Result usbDsDeleteUsbStringDescriptor(u8 index); + +/// Only available on [5.0.0+]. +Result usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed speed, struct usb_device_descriptor* descriptor); + +/// Only available on [5.0.0+]. +Result usbDsSetBinaryObjectStore(const void* bos, size_t bos_size); + +/// Only available on [5.0.0+]. +Result usbDsEnable(void); + +/// Only available on [5.0.0+]. +Result usbDsDisable(void); + +///@} + +///@name IDsInterface +///@{ + +void usbDsInterface_Close(UsbDsInterface* interface); + +Result usbDsInterface_GetSetupPacket(UsbDsInterface* interface, void* buffer, size_t size); +Result usbDsInterface_EnableInterface(UsbDsInterface* interface); +Result usbDsInterface_DisableInterface(UsbDsInterface* interface); +Result usbDsInterface_CtrlInPostBufferAsync(UsbDsInterface* interface, void* buffer, size_t size, u32* urbId); +Result usbDsInterface_CtrlOutPostBufferAsync(UsbDsInterface* interface, void* buffer, size_t size, u32* urbId); +Result usbDsInterface_GetCtrlInReportData(UsbDsInterface* interface, UsbDsReportData* out); +Result usbDsInterface_GetCtrlOutReportData(UsbDsInterface* interface, UsbDsReportData* out); +Result usbDsInterface_StallCtrl(UsbDsInterface* interface); + +/// Removed in [5.0.0+]. +Result usbDsInterface_GetDsEndpoint(UsbDsInterface* interface, UsbDsEndpoint** endpoint, struct usb_endpoint_descriptor* descriptor); + +/// Only available on [5.0.0+]. +Result usbDsInterface_RegisterEndpoint(UsbDsInterface* interface, UsbDsEndpoint** endpoint, u8 endpoint_address); + +/// Only available on [5.0.0+]. +Result usbDsInterface_AppendConfigurationData(UsbDsInterface* interface, UsbDeviceSpeed speed, const void* buffer, size_t size); + +///@} + +///@name IDsEndpoint +///@{ + +void usbDsEndpoint_Close(UsbDsEndpoint* endpoint); + +Result usbDsEndpoint_Cancel(UsbDsEndpoint* endpoint); +Result usbDsEndpoint_PostBufferAsync(UsbDsEndpoint* endpoint, void* buffer, size_t size, u32* urbId); +Result usbDsEndpoint_GetReportData(UsbDsEndpoint* endpoint, UsbDsReportData* out); +Result usbDsEndpoint_Stall(UsbDsEndpoint* endpoint); +Result usbDsEndpoint_SetZlt(UsbDsEndpoint* endpoint, bool zlt); // Sets Zero Length Termination for endpoint + +///@} + diff --git a/src/libnx/wrapper/switch/services/usbds.nim b/src/libnx/wrapper/switch/services/usbds.nim new file mode 100644 index 0000000..a0a167a --- /dev/null +++ b/src/libnx/wrapper/switch/services/usbds.nim @@ -0,0 +1,193 @@ +## * +## @file usbds.h +## @brief USB (usb:ds) service IPC wrapper. +## @brief Switch-as-device<>host USB comms, see also here: https://switchbrew.org/wiki/USB_services +## @author SciresM, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/usb, ../kernel/event + +const + USBDS_DEFAULT_InterfaceNumber* = 0x4 + +type + UsbDsInterface* {.bycopy.} = object + initialized*: bool + interfaceIndex*: U8 + s*: Service + setupEvent*: Event + ctrlInCompletionEvent*: Event + ctrlOutCompletionEvent*: Event + + UsbDsEndpoint* {.bycopy.} = object + initialized*: bool + s*: Service + completionEvent*: Event + + UsbDsDeviceInfo* {.bycopy.} = object + idVendor*: U16 ## /< VID + idProduct*: U16 ## /< PID + bcdDevice*: U16 + manufacturer*: array[0x20, char] + product*: array[0x20, char] + serialNumber*: array[0x20, char] + + UsbDsReportEntry* {.bycopy.} = object + id*: U32 ## /< urbId from post-buffer cmds + requestedSize*: U32 + transferredSize*: U32 + urbStatus*: U32 + + UsbDsReportData* {.bycopy.} = object + report*: array[8, UsbDsReportEntry] + reportCount*: U32 + + UsbComplexId* = enum + UsbComplexIdDefault = 0x2 + UsbDeviceSpeed* = enum + UsbDeviceSpeedFull = 0x2, ## /< USB 1.1 Full Speed + UsbDeviceSpeedHigh = 0x3, ## /< USB 2.0 High Speed + UsbDeviceSpeedSuper = 0x4 ## /< USB 3.0 Super Speed + + + +## / Opens a session with usb:ds. + +proc usbDsInitialize*(): Result {.cdecl, importc: "usbDsInitialize".} +## / Closes the usb:ds session. Any interfaces/endpoints which are left open are automatically closed, since otherwise usb-sysmodule won't fully reset usb:ds to defaults. + +proc usbDsExit*() {.cdecl, importc: "usbDsExit".} +## / Gets the Service object for the actual usb:ds service session. + +proc usbDsGetServiceSession*(): ptr Service {.cdecl, + importc: "usbDsGetServiceSession".} +## / Helper func. + +proc usbDsWaitReady*(timeout: U64): Result {.cdecl, importc: "usbDsWaitReady".} +## / Helper func. + +proc usbDsParseReportData*(reportdata: ptr UsbDsReportData; urbId: U32; + requestedSize: ptr U32; transferredSize: ptr U32): Result {. + cdecl, importc: "usbDsParseReportData".} +## /@name IDsService +## /@{ + +proc usbDsGetStateChangeEvent*(): ptr Event {.cdecl, + importc: "usbDsGetStateChangeEvent".} +## / Gets the device state. See \ref UsbState. + +proc usbDsGetState*(`out`: ptr UsbState): Result {.cdecl, importc: "usbDsGetState".} +## / Removed in [5.0.0+]. + +proc usbDsGetDsInterface*(`out`: ptr ptr UsbDsInterface; + descriptor: ptr UsbInterfaceDescriptor; + interfaceName: cstring): Result {.cdecl, + importc: "usbDsGetDsInterface".} +## / Removed in [5.0.0+]. + +proc usbDsSetVidPidBcd*(deviceinfo: ptr UsbDsDeviceInfo): Result {.cdecl, + importc: "usbDsSetVidPidBcd".} +## / Only available on [5.0.0+]. + +proc usbDsRegisterInterface*(`out`: ptr ptr UsbDsInterface): Result {.cdecl, + importc: "usbDsRegisterInterface".} +## / Only available on [5.0.0+]. + +proc usbDsRegisterInterfaceEx*(`out`: ptr ptr UsbDsInterface; intfNum: U8): Result {. + cdecl, importc: "usbDsRegisterInterfaceEx".} +## / Only available on [5.0.0+]. + +proc usbDsClearDeviceData*(): Result {.cdecl, importc: "usbDsClearDeviceData".} +## / Only available on [5.0.0+]. + +proc usbDsAddUsbStringDescriptor*(outIndex: ptr U8; string: cstring): Result {.cdecl, + importc: "usbDsAddUsbStringDescriptor".} +## / Only available on [5.0.0+]. + +proc usbDsAddUsbLanguageStringDescriptor*(outIndex: ptr U8; langIds: ptr U16; + numLangs: U16): Result {.cdecl, importc: "usbDsAddUsbLanguageStringDescriptor".} +## / Only available on [5.0.0+]. + +proc usbDsDeleteUsbStringDescriptor*(index: U8): Result {.cdecl, + importc: "usbDsDeleteUsbStringDescriptor".} +## / Only available on [5.0.0+]. + +proc usbDsSetUsbDeviceDescriptor*(speed: UsbDeviceSpeed; + descriptor: ptr UsbDeviceDescriptor): Result {. + cdecl, importc: "usbDsSetUsbDeviceDescriptor".} +## / Only available on [5.0.0+]. + +proc usbDsSetBinaryObjectStore*(bos: pointer; bosSize: csize_t): Result {.cdecl, + importc: "usbDsSetBinaryObjectStore".} +## / Only available on [5.0.0+]. + +proc usbDsEnable*(): Result {.cdecl, importc: "usbDsEnable".} +## / Only available on [5.0.0+]. + +proc usbDsDisable*(): Result {.cdecl, importc: "usbDsDisable".} +## /@} +## /@name IDsInterface +## /@{ + +proc usbDsInterfaceClose*(`interface`: ptr UsbDsInterface) {.cdecl, + importc: "usbDsInterface_Close".} +proc usbDsInterfaceGetSetupPacket*(`interface`: ptr UsbDsInterface; buffer: pointer; + size: csize_t): Result {.cdecl, + importc: "usbDsInterface_GetSetupPacket".} +proc usbDsInterfaceEnableInterface*(`interface`: ptr UsbDsInterface): Result {.cdecl, + importc: "usbDsInterface_EnableInterface".} +proc usbDsInterfaceDisableInterface*(`interface`: ptr UsbDsInterface): Result {. + cdecl, importc: "usbDsInterface_DisableInterface".} +proc usbDsInterfaceCtrlInPostBufferAsync*(`interface`: ptr UsbDsInterface; + buffer: pointer; size: csize_t; urbId: ptr U32): Result {.cdecl, + importc: "usbDsInterface_CtrlInPostBufferAsync".} +proc usbDsInterfaceCtrlOutPostBufferAsync*(`interface`: ptr UsbDsInterface; + buffer: pointer; size: csize_t; urbId: ptr U32): Result {.cdecl, + importc: "usbDsInterface_CtrlOutPostBufferAsync".} +proc usbDsInterfaceGetCtrlInReportData*(`interface`: ptr UsbDsInterface; + `out`: ptr UsbDsReportData): Result {.cdecl, + importc: "usbDsInterface_GetCtrlInReportData".} +proc usbDsInterfaceGetCtrlOutReportData*(`interface`: ptr UsbDsInterface; + `out`: ptr UsbDsReportData): Result {.cdecl, + importc: "usbDsInterface_GetCtrlOutReportData".} +proc usbDsInterfaceStallCtrl*(`interface`: ptr UsbDsInterface): Result {.cdecl, + importc: "usbDsInterface_StallCtrl".} +## / Removed in [5.0.0+]. + +proc usbDsInterfaceGetDsEndpoint*(`interface`: ptr UsbDsInterface; + endpoint: ptr ptr UsbDsEndpoint; + descriptor: ptr UsbEndpointDescriptor): Result {. + cdecl, importc: "usbDsInterface_GetDsEndpoint".} +## / Only available on [5.0.0+]. + +proc usbDsInterfaceRegisterEndpoint*(`interface`: ptr UsbDsInterface; + endpoint: ptr ptr UsbDsEndpoint; + endpointAddress: U8): Result {.cdecl, + importc: "usbDsInterface_RegisterEndpoint".} +## / Only available on [5.0.0+]. + +proc usbDsInterfaceAppendConfigurationData*(`interface`: ptr UsbDsInterface; + speed: UsbDeviceSpeed; buffer: pointer; size: csize_t): Result {.cdecl, + importc: "usbDsInterface_AppendConfigurationData".} +## /@} +## /@name IDsEndpoint +## /@{ + +proc usbDsEndpointClose*(endpoint: ptr UsbDsEndpoint) {.cdecl, + importc: "usbDsEndpoint_Close".} +proc usbDsEndpointCancel*(endpoint: ptr UsbDsEndpoint): Result {.cdecl, + importc: "usbDsEndpoint_Cancel".} +proc usbDsEndpointPostBufferAsync*(endpoint: ptr UsbDsEndpoint; buffer: pointer; + size: csize_t; urbId: ptr U32): Result {.cdecl, + importc: "usbDsEndpoint_PostBufferAsync".} +proc usbDsEndpointGetReportData*(endpoint: ptr UsbDsEndpoint; + `out`: ptr UsbDsReportData): Result {.cdecl, + importc: "usbDsEndpoint_GetReportData".} +proc usbDsEndpointStall*(endpoint: ptr UsbDsEndpoint): Result {.cdecl, + importc: "usbDsEndpoint_Stall".} +proc usbDsEndpointSetZlt*(endpoint: ptr UsbDsEndpoint; zlt: bool): Result {.cdecl, + importc: "usbDsEndpoint_SetZlt".} +## Sets Zero Length Termination for endpoint +## /@} diff --git a/src/libnx/wrapper/switch/services/usbhs.h b/src/libnx/wrapper/switch/services/usbhs.h new file mode 100644 index 0000000..88cef72 --- /dev/null +++ b/src/libnx/wrapper/switch/services/usbhs.h @@ -0,0 +1,231 @@ +/** + * @file usbhs.h + * @brief USB (usb:hs) devices service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../sf/service.h" +#include "../services/usb.h" +#include "../kernel/event.h" + +typedef enum { + ///< These use \ref usb_device_descriptor. Bit2..6 require [6.0.0+], these are ignored on eariler versions. + UsbHsInterfaceFilterFlags_idVendor = BIT(0), + UsbHsInterfaceFilterFlags_idProduct = BIT(1), + UsbHsInterfaceFilterFlags_bcdDevice_Min = BIT(2), + UsbHsInterfaceFilterFlags_bcdDevice_Max = BIT(3), + UsbHsInterfaceFilterFlags_bDeviceClass = BIT(4), + UsbHsInterfaceFilterFlags_bDeviceSubClass = BIT(5), + UsbHsInterfaceFilterFlags_bDeviceProtocol = BIT(6), + + ///< These use \ref usb_interface_descriptor. + UsbHsInterfaceFilterFlags_bInterfaceClass = BIT(7), + UsbHsInterfaceFilterFlags_bInterfaceSubClass = BIT(8), + UsbHsInterfaceFilterFlags_bInterfaceProtocol = BIT(9), +} UsbHsInterfaceFilterFlags; + +/// Interface filtering struct. When the associated flag bit is set, the associated descriptor field and struct field are compared, on mismatch the interface is filtered out. +/// [7.0.0+]: The filter struct has to be unique, it can't be used by anything else (including other processes). Hence, Flags has to be non-zero. When initialized with usb:hs:a and VID and/or PID filtering is enabled, the VID/PID will be checked against a blacklist. +typedef struct { + u16 Flags; ///< See \ref UsbHsInterfaceFilterFlags. Setting this to 0 is equivalent to disabling filtering. + u16 idVendor; + u16 idProduct; + u16 bcdDevice_Min; ///< Descriptor value must be >= bcdDevice_Min. + u16 bcdDevice_Max; ///< Descriptor value must be <= bcdDevice_Max. + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; +} UsbHsInterfaceFilter; + +/// Descriptors which are not available are set to all-zero. +/// The INPUT/OUTPUT endpoint descriptors were swapped with [8.0.0+], libnx converts this struct to the newer layout when running on pre-8.0.0. +typedef struct { + s32 ID; + u32 deviceID_2; + u32 unk_x8; + + struct usb_interface_descriptor interface_desc; + u8 pad_x15[0x7]; + struct usb_endpoint_descriptor input_endpoint_descs[15]; + u8 pad_x85[0x7]; + struct usb_endpoint_descriptor output_endpoint_descs[15]; + u8 pad_xf5[0x6]; + struct usb_ss_endpoint_companion_descriptor input_ss_endpoint_companion_descs[15]; ///< ? + u8 pad_x155[0x6]; + struct usb_ss_endpoint_companion_descriptor output_ss_endpoint_companion_descs[15]; ///< ? + u8 pad_x1b5[0x3]; +} PACKED UsbHsInterfaceInfo; + +/// Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface. +typedef struct { + UsbHsInterfaceInfo inf; + + char pathstr[0x40]; + u32 busID; + u32 deviceID; + + struct usb_device_descriptor device_desc; + struct usb_config_descriptor config_desc; + u8 pad_x21b[0x5]; + + u64 timestamp; ///< Unknown u64 timestamp for when the device was inserted? +} PACKED UsbHsInterface; + +typedef struct { + u32 xferId; + Result res; + u32 requestedSize; + u32 transferredSize; + u64 unk_x10; +} UsbHsXferReport; + +/// The interface service object. These Events have autoclear=false. +typedef struct { + Service s; + Event event0; ///< Unknown. + Event eventCtrlXfer; ///< [2.0.0+] Signaled when CtrlXferAsync finishes. + s32 ID; + + UsbHsInterface inf; ///< Initialized with the input interface from \ref usbHsAcquireUsbIf, then overwritten with the cmd output. Pre-3.0.0 this only overwrites the first 0x1B8-bytes (data before pathstr). +} UsbHsClientIfSession; + +typedef struct { + Service s; + Event eventXfer; ///< [2.0.0+] Signaled when PostBufferAsync finishes. + + struct usb_endpoint_descriptor desc; +} UsbHsClientEpSession; + +/// Initialize usb:hs. +Result usbHsInitialize(void); + +/// Exit usb:hs. +void usbHsExit(void); + +/// Gets the Service object for the actual usb:hs service session. +Service* usbHsGetServiceSession(void); + +/// Returns the Event loaded during init with autoclear=false. +/// Signaled when a device was removed. +/// When signaled, the user should use \ref usbHsQueryAcquiredInterfaces and cleanup state for all interfaces which are not listed in the output interfaces (none of the IDs match \ref usbHsIfGetID output). +Event* usbHsGetInterfaceStateChangeEvent(void); + +/** + * @brief Returns an array of all \ref UsbHsInterface. Internally this loads the same interfaces as \ref usbHsQueryAvailableInterfaces, followed by \ref usbHsQueryAcquiredInterfaces. However, ID in \ref UsbHsInterface is set to -1, hence the output from this should not be used with \ref usbHsAcquireUsbIf. + * @param[in] filter \ref UsbHsInterfaceFilter. + * @param[out] interfaces Array of output interfaces. + * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. + * @param[out] total_entries Total number of output interfaces. + */ +Result usbHsQueryAllInterfaces(const UsbHsInterfaceFilter* filter, UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries); + +/** + * @brief Returns an array of \ref UsbHsInterface which are available. + * @param[in] filter \ref UsbHsInterfaceFilter. + * @param[out] interfaces Array of output interfaces. + * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. + * @param[out] total_entries Total number of output interfaces. + */ +Result usbHsQueryAvailableInterfaces(const UsbHsInterfaceFilter* filter, UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries); + +/** + * @brief Returns an array of \ref UsbHsInterface which were previously acquired. + * @param[out] interfaces Array of output interfaces. + * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. + * @param[out] total_entries Total number of output interfaces. + */ +Result usbHsQueryAcquiredInterfaces(UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries); + +/** + * @brief Creates an event which is signaled when an interface is available which passes the filtering checks. + * @param[out] out_event Event object. + * @param[in] autoclear Event autoclear. + * @param[in] index Event index, must be 0..2. + * @param[in] filter \ref UsbHsInterfaceFilter. + */ +Result usbHsCreateInterfaceAvailableEvent(Event* out_event, bool autoclear, u8 index, const UsbHsInterfaceFilter* filter); + +/** + * @brief Destroys an event setup by \ref usbHsCreateInterfaceAvailableEvent. This *must* be used at some point during cleanup. + * @param[in] event Event object to close. + * @param[in] index Event index, must be 0..2. + */ +Result usbHsDestroyInterfaceAvailableEvent(Event* event, u8 index); + +/** + * @brief Acquires/opens the specified interface. This returns an error if the interface was already acquired by another process. + * @param[in] s The service object. + * @param[in] interface Interface to use. + */ +Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface); + +/// UsbHsClientIfSession + +/// Closes the specified interface session. +void usbHsIfClose(UsbHsClientIfSession* s); + +/// Returns whether the specified interface session was initialized. +static inline bool usbHsIfIsActive(UsbHsClientIfSession* s) { + return serviceIsActive(&s->s); +} + +/// Returns the ID which can be used for comparing with the ID in the output interfaces from \ref usbHsQueryAcquiredInterfaces. +static inline s32 usbHsIfGetID(UsbHsClientIfSession* s) { + return s->ID; +} + +/** + * @brief Selects an interface. + * @param[in] s The service object. + * @param[out] inf The output interface info. If NULL, the output is stored within s instead. + * @param[in] id ID + */ +Result usbHsIfSetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id); + +/** + * @brief Gets an interface. + * @param[in] s The service object. + * @param[out] inf The output interface info. If NULL, the output is stored within s instead. + */ +Result usbHsIfGetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf); + +/** + * @brief Gets an alternate interface. + * @param[in] s The service object. + * @param[out] inf The output interface info. If NULL, the output is stored within s instead. + * @param[in] id ID + */ +Result usbHsIfGetAlternateInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id); + +/// On [1.0.0] this is stubbed, just returns 0 with out=0. +Result usbHsIfGetCurrentFrame(UsbHsClientIfSession* s, u32* out); + +/// Uses a control transfer, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where wLength is the original size. +Result usbHsIfCtrlXfer(UsbHsClientIfSession* s, u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, void* buffer, u32* transferredSize); + +/** + * @brief Opens an endpoint. maxUrbCount*maxXferSize must be non-zero. + * @param[in] s The interface object. + * @param[out] ep The endpoint object. + * @param[in] maxUrbCount maxUrbCount, must be <0x11. + * @param[in] maxXferSize Max transfer size for a packet. This can be desc->wMaxPacketSize. Must be <=0xFF0000. + * @param[in] desc Endpoint descriptor. + */ +Result usbHsIfOpenUsbEp(UsbHsClientIfSession* s, UsbHsClientEpSession* ep, u16 maxUrbCount, u32 maxXferSize, struct usb_endpoint_descriptor *desc); + +/// Resets the device: has the same affect as unplugging the device and plugging it back in. +Result usbHsIfResetDevice(UsbHsClientIfSession* s); + +/// UsbHsClientEpSession + +/// Closes the specified endpoint session. +void usbHsEpClose(UsbHsClientEpSession* s); + +/// Uses a data transfer with the specified endpoint, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where the input size is the original size. +Result usbHsEpPostBuffer(UsbHsClientEpSession* s, void* buffer, u32 size, u32* transferredSize); + diff --git a/src/libnx/wrapper/switch/services/usbhs.nim b/src/libnx/wrapper/switch/services/usbhs.nim new file mode 100644 index 0000000..86b6a3f --- /dev/null +++ b/src/libnx/wrapper/switch/services/usbhs.nim @@ -0,0 +1,256 @@ +## * +## @file usbhs.h +## @brief USB (usb:hs) devices service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service, ../services/usb, ../kernel/event + +type ## /< These use \ref usb_device_descriptor. Bit2..6 require [6.0.0+], these are ignored on eariler versions. + UsbHsInterfaceFilterFlags* = enum + UsbHsInterfaceFilterFlagsIdVendor = bit(0), + UsbHsInterfaceFilterFlagsIdProduct = bit(1), + UsbHsInterfaceFilterFlagsBcdDeviceMin = bit(2), + UsbHsInterfaceFilterFlagsBcdDeviceMax = bit(3), + UsbHsInterfaceFilterFlagsBDeviceClass = bit(4), + UsbHsInterfaceFilterFlagsBDeviceSubClass = bit(5), UsbHsInterfaceFilterFlagsBDeviceProtocol = bit( + 6), ## /< These use \ref usb_interface_descriptor. + UsbHsInterfaceFilterFlagsBInterfaceClass = bit(7), + UsbHsInterfaceFilterFlagsBInterfaceSubClass = bit(8), + UsbHsInterfaceFilterFlagsBInterfaceProtocol = bit(9) + + +## / Interface filtering struct. When the associated flag bit is set, the associated descriptor field and struct field are compared, on mismatch the interface is filtered out. +## / [7.0.0+]: The filter struct has to be unique, it can't be used by anything else (including other processes). Hence, Flags has to be non-zero. When initialized with usb:hs:a and VID and/or PID filtering is enabled, the VID/PID will be checked against a blacklist. + +type + UsbHsInterfaceFilter* {.bycopy.} = object + flags*: U16 ## /< See \ref UsbHsInterfaceFilterFlags. Setting this to 0 is equivalent to disabling filtering. + idVendor*: U16 + idProduct*: U16 + bcdDeviceMin*: U16 ## /< Descriptor value must be >= bcdDevice_Min. + bcdDeviceMax*: U16 ## /< Descriptor value must be <= bcdDevice_Max. + bDeviceClass*: U8 + bDeviceSubClass*: U8 + bDeviceProtocol*: U8 + bInterfaceClass*: U8 + bInterfaceSubClass*: U8 + bInterfaceProtocol*: U8 + + +## / Descriptors which are not available are set to all-zero. +## / The INPUT/OUTPUT endpoint descriptors were swapped with [8.0.0+], libnx converts this struct to the newer layout when running on pre-8.0.0. + +type + UsbHsInterfaceInfo* {.bycopy.} = object + id*: S32 + deviceID_2*: U32 + unkX8*: U32 + interfaceDesc*: UsbInterfaceDescriptor + padX15*: array[0x7, U8] + inputEndpointDescs*: array[15, UsbEndpointDescriptor] + padX85*: array[0x7, U8] + outputEndpointDescs*: array[15, UsbEndpointDescriptor] + padXf5*: array[0x6, U8] + inputSsEndpointCompanionDescs*: array[15, UsbSsEndpointCompanionDescriptor] ## /< ? + padX155*: array[0x6, U8] + outputSsEndpointCompanionDescs*: array[15, UsbSsEndpointCompanionDescriptor] ## /< ? + padX1b5*: array[0x3, U8] + + +## / Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface. + +type + UsbHsInterface* {.bycopy.} = object + inf*: UsbHsInterfaceInfo + pathstr*: array[0x40, char] + busID*: U32 + deviceID*: U32 + deviceDesc*: UsbDeviceDescriptor + configDesc*: UsbConfigDescriptor + padX21b*: array[0x5, U8] + timestamp*: U64 ## /< Unknown u64 timestamp for when the device was inserted? + + UsbHsXferReport* {.bycopy.} = object + xferId*: U32 + res*: Result + requestedSize*: U32 + transferredSize*: U32 + unkX10*: U64 + + +## / The interface service object. These Events have autoclear=false. + +type + UsbHsClientIfSession* {.bycopy.} = object + s*: Service + event0*: Event ## /< Unknown. + eventCtrlXfer*: Event ## /< [2.0.0+] Signaled when CtrlXferAsync finishes. + id*: S32 + inf*: UsbHsInterface ## /< Initialized with the input interface from \ref usbHsAcquireUsbIf, then overwritten with the cmd output. Pre-3.0.0 this only overwrites the first 0x1B8-bytes (data before pathstr). + + UsbHsClientEpSession* {.bycopy.} = object + s*: Service + eventXfer*: Event ## /< [2.0.0+] Signaled when PostBufferAsync finishes. + desc*: UsbEndpointDescriptor + + +## / Initialize usb:hs. + +proc usbHsInitialize*(): Result {.cdecl, importc: "usbHsInitialize".} +## / Exit usb:hs. + +proc usbHsExit*() {.cdecl, importc: "usbHsExit".} +## / Gets the Service object for the actual usb:hs service session. + +proc usbHsGetServiceSession*(): ptr Service {.cdecl, + importc: "usbHsGetServiceSession".} +## / Returns the Event loaded during init with autoclear=false. +## / Signaled when a device was removed. +## / When signaled, the user should use \ref usbHsQueryAcquiredInterfaces and cleanup state for all interfaces which are not listed in the output interfaces (none of the IDs match \ref usbHsIfGetID output). + +proc usbHsGetInterfaceStateChangeEvent*(): ptr Event {.cdecl, + importc: "usbHsGetInterfaceStateChangeEvent".} +## * +## @brief Returns an array of all \ref UsbHsInterface. Internally this loads the same interfaces as \ref usbHsQueryAvailableInterfaces, followed by \ref usbHsQueryAcquiredInterfaces. However, ID in \ref UsbHsInterface is set to -1, hence the output from this should not be used with \ref usbHsAcquireUsbIf. +## @param[in] filter \ref UsbHsInterfaceFilter. +## @param[out] interfaces Array of output interfaces. +## @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. +## @param[out] total_entries Total number of output interfaces. +## + +proc usbHsQueryAllInterfaces*(filter: ptr UsbHsInterfaceFilter; + interfaces: ptr UsbHsInterface; + interfacesMaxsize: csize_t; totalEntries: ptr S32): Result {. + cdecl, importc: "usbHsQueryAllInterfaces".} +## * +## @brief Returns an array of \ref UsbHsInterface which are available. +## @param[in] filter \ref UsbHsInterfaceFilter. +## @param[out] interfaces Array of output interfaces. +## @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. +## @param[out] total_entries Total number of output interfaces. +## + +proc usbHsQueryAvailableInterfaces*(filter: ptr UsbHsInterfaceFilter; + interfaces: ptr UsbHsInterface; + interfacesMaxsize: csize_t; + totalEntries: ptr S32): Result {.cdecl, + importc: "usbHsQueryAvailableInterfaces".} +## * +## @brief Returns an array of \ref UsbHsInterface which were previously acquired. +## @param[out] interfaces Array of output interfaces. +## @param[in] interfaces_maxsize Max byte-size of the interfaces buffer. +## @param[out] total_entries Total number of output interfaces. +## + +proc usbHsQueryAcquiredInterfaces*(interfaces: ptr UsbHsInterface; + interfacesMaxsize: csize_t; + totalEntries: ptr S32): Result {.cdecl, + importc: "usbHsQueryAcquiredInterfaces".} +## * +## @brief Creates an event which is signaled when an interface is available which passes the filtering checks. +## @param[out] out_event Event object. +## @param[in] autoclear Event autoclear. +## @param[in] index Event index, must be 0..2. +## @param[in] filter \ref UsbHsInterfaceFilter. +## + +proc usbHsCreateInterfaceAvailableEvent*(outEvent: ptr Event; autoclear: bool; + index: U8; + filter: ptr UsbHsInterfaceFilter): Result {. + cdecl, importc: "usbHsCreateInterfaceAvailableEvent".} +## * +## @brief Destroys an event setup by \ref usbHsCreateInterfaceAvailableEvent. This *must* be used at some point during cleanup. +## @param[in] event Event object to close. +## @param[in] index Event index, must be 0..2. +## + +proc usbHsDestroyInterfaceAvailableEvent*(event: ptr Event; index: U8): Result {.cdecl, + importc: "usbHsDestroyInterfaceAvailableEvent".} +## * +## @brief Acquires/opens the specified interface. This returns an error if the interface was already acquired by another process. +## @param[in] s The service object. +## @param[in] interface Interface to use. +## + +proc usbHsAcquireUsbIf*(s: ptr UsbHsClientIfSession; `interface`: ptr UsbHsInterface): Result {. + cdecl, importc: "usbHsAcquireUsbIf".} +## / UsbHsClientIfSession +## / Closes the specified interface session. + +proc usbHsIfClose*(s: ptr UsbHsClientIfSession) {.cdecl, importc: "usbHsIfClose".} +## / Returns whether the specified interface session was initialized. + +proc usbHsIfIsActive*(s: ptr UsbHsClientIfSession): bool {.inline, cdecl.} = + return serviceIsActive(addr(s.s)) + +## / Returns the ID which can be used for comparing with the ID in the output interfaces from \ref usbHsQueryAcquiredInterfaces. + +proc usbHsIfGetID*(s: ptr UsbHsClientIfSession): S32 {.inline, cdecl.} = + return s.id + +## * +## @brief Selects an interface. +## @param[in] s The service object. +## @param[out] inf The output interface info. If NULL, the output is stored within s instead. +## @param[in] id ID +## + +proc usbHsIfSetInterface*(s: ptr UsbHsClientIfSession; inf: ptr UsbHsInterfaceInfo; + id: U8): Result {.cdecl, importc: "usbHsIfSetInterface".} +## * +## @brief Gets an interface. +## @param[in] s The service object. +## @param[out] inf The output interface info. If NULL, the output is stored within s instead. +## + +proc usbHsIfGetInterface*(s: ptr UsbHsClientIfSession; inf: ptr UsbHsInterfaceInfo): Result {. + cdecl, importc: "usbHsIfGetInterface".} +## * +## @brief Gets an alternate interface. +## @param[in] s The service object. +## @param[out] inf The output interface info. If NULL, the output is stored within s instead. +## @param[in] id ID +## + +proc usbHsIfGetAlternateInterface*(s: ptr UsbHsClientIfSession; + inf: ptr UsbHsInterfaceInfo; id: U8): Result {. + cdecl, importc: "usbHsIfGetAlternateInterface".} +## / On [1.0.0] this is stubbed, just returns 0 with out=0. + +proc usbHsIfGetCurrentFrame*(s: ptr UsbHsClientIfSession; `out`: ptr U32): Result {. + cdecl, importc: "usbHsIfGetCurrentFrame".} +## / Uses a control transfer, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where wLength is the original size. + +proc usbHsIfCtrlXfer*(s: ptr UsbHsClientIfSession; bmRequestType: U8; bRequest: U8; + wValue: U16; wIndex: U16; wLength: U16; buffer: pointer; + transferredSize: ptr U32): Result {.cdecl, + importc: "usbHsIfCtrlXfer".} +## * +## @brief Opens an endpoint. maxUrbCount*maxXferSize must be non-zero. +## @param[in] s The interface object. +## @param[out] ep The endpoint object. +## @param[in] maxUrbCount maxUrbCount, must be <0x11. +## @param[in] maxXferSize Max transfer size for a packet. This can be desc->wMaxPacketSize. Must be <=0xFF0000. +## @param[in] desc Endpoint descriptor. +## + +proc usbHsIfOpenUsbEp*(s: ptr UsbHsClientIfSession; ep: ptr UsbHsClientEpSession; + maxUrbCount: U16; maxXferSize: U32; + desc: ptr UsbEndpointDescriptor): Result {.cdecl, + importc: "usbHsIfOpenUsbEp".} +## / Resets the device: has the same affect as unplugging the device and plugging it back in. + +proc usbHsIfResetDevice*(s: ptr UsbHsClientIfSession): Result {.cdecl, + importc: "usbHsIfResetDevice".} +## / UsbHsClientEpSession +## / Closes the specified endpoint session. + +proc usbHsEpClose*(s: ptr UsbHsClientEpSession) {.cdecl, importc: "usbHsEpClose".} +## / Uses a data transfer with the specified endpoint, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where the input size is the original size. + +proc usbHsEpPostBuffer*(s: ptr UsbHsClientEpSession; buffer: pointer; size: U32; + transferredSize: ptr U32): Result {.cdecl, + importc: "usbHsEpPostBuffer".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/services/vi.h b/src/libnx/wrapper/switch/services/vi.h new file mode 100644 index 0000000..f71f5e6 --- /dev/null +++ b/src/libnx/wrapper/switch/services/vi.h @@ -0,0 +1,118 @@ +/** + * @file vi.h + * @brief Display (vi:*) service IPC wrapper. + * @author yellows8 + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" +#include "../kernel/event.h" +#include "../sf/service.h" + +typedef struct { + char data[0x40]; +} ViDisplayName; + +typedef struct { + u64 display_id; + ViDisplayName display_name; + bool initialized; +} ViDisplay; + +typedef struct { + u64 layer_id; + u32 igbp_binder_obj_id; + bool initialized : 1; + bool stray_layer : 1; +} ViLayer; + +typedef enum { + ViServiceType_Default = -1, + ViServiceType_Application = 0, + ViServiceType_System = 1, + ViServiceType_Manager = 2, +} ViServiceType; + +/// Used by viCreateLayer when CreateStrayLayer is used internally. +typedef enum { + ViLayerFlags_Default = 0x1, +} ViLayerFlags; + +/// Used with viSetLayerScalingMode. +typedef enum { + ViScalingMode_None = 0x0, + ViScalingMode_FitToLayer = 0x2, + ViScalingMode_PreserveAspectRatio = 0x4, + + ViScalingMode_Default = ViScalingMode_FitToLayer, +} ViScalingMode; + +/// Used with viSetDisplayPowerState. +typedef enum { + ViPowerState_Off = 0, ///< Screen is off. + ViPowerState_NotScanning = 1, ///< [3.0.0+] Screen is on, but not scanning content. + ViPowerState_On = 2, ///< [3.0.0+] Screen is on. + + ViPowerState_On_Deprecated = 1, ///< [1.0.0 - 2.3.0] Screen is on. +} ViPowerState; + +/// Used as argument to many capture functions. +typedef enum { + ViLayerStack_Default = 0, ///< Default layer stack, includes all layers. + ViLayerStack_Lcd = 1, ///< Includes only layers for the LCD. + ViLayerStack_Screenshot = 2, ///< Includes only layers for user screenshots. + ViLayerStack_Recording = 3, ///< Includes only layers for recording videos. + ViLayerStack_LastFrame = 4, ///< Includes only layers for the last applet-transition frame. + ViLayerStack_Arbitrary = 5, ///< Captures some arbitrary layer. This is normally only for am. + ViLayerStack_ApplicationForDebug = 6, ///< Captures layers for the current application. This is normally used by creport/debugging tools. + ViLayerStack_Null = 10, ///< Layer stack for the empty display. +} ViLayerStack; + +Result viInitialize(ViServiceType service_type); +void viExit(void); + +Service* viGetSession_IApplicationDisplayService(void); +Service* viGetSession_IHOSBinderDriverRelay(void); +Service* viGetSession_ISystemDisplayService(void); +Service* viGetSession_IManagerDisplayService(void); +Service* viGetSession_IHOSBinderDriverIndirect(void); + +// Misc functions +Result viSetContentVisibility(bool v); + +// Display functions + +Result viOpenDisplay(const char *display_name, ViDisplay *display); +Result viCloseDisplay(ViDisplay *display); + +static inline Result viOpenDefaultDisplay(ViDisplay *display) +{ + return viOpenDisplay("Default", display); +} + +Result viGetDisplayResolution(ViDisplay *display, s32 *width, s32 *height); +Result viGetDisplayLogicalResolution(ViDisplay *display, s32 *width, s32 *height); +/// Only available on [3.0.0+]. +Result viSetDisplayMagnification(ViDisplay *display, s32 x, s32 y, s32 width, s32 height); +Result viGetDisplayVsyncEvent(ViDisplay *display, Event *event_out); +Result viSetDisplayPowerState(ViDisplay *display, ViPowerState state); +Result viSetDisplayAlpha(ViDisplay *display, float alpha); +Result viGetZOrderCountMin(ViDisplay *display, s32 *z); +Result viGetZOrderCountMax(ViDisplay *display, s32 *z); + +// Layer functions + +Result viCreateLayer(const ViDisplay *display, ViLayer *layer); +Result viCreateManagedLayer(const ViDisplay *display, ViLayerFlags layer_flags, u64 aruid, u64 *layer_id); +Result viSetLayerSize(ViLayer *layer, s32 width, s32 height); +Result viSetLayerZ(ViLayer *layer, s32 z); +Result viSetLayerPosition(ViLayer *layer, float x, float y); +Result viCloseLayer(ViLayer *layer); +Result viDestroyManagedLayer(ViLayer *layer); + +Result viSetLayerScalingMode(ViLayer *layer, ViScalingMode scaling_mode); + +// IndirectLayer functions + +Result viGetIndirectLayerImageMap(void* buffer, size_t size, s32 width, s32 height, u64 IndirectLayerConsumerHandle, u64 *out_size, u64 *out_stride); +Result viGetIndirectLayerImageRequiredMemoryInfo(s32 width, s32 height, u64 *out_size, u64 *out_alignment); diff --git a/src/libnx/wrapper/switch/services/vi.nim b/src/libnx/wrapper/switch/services/vi.nim new file mode 100644 index 0000000..b2953af --- /dev/null +++ b/src/libnx/wrapper/switch/services/vi.nim @@ -0,0 +1,148 @@ +## * +## @file vi.h +## @brief Display (vi:*) service IPC wrapper. +## @author yellows8 +## @copyright libnx Authors +## + +import + ../types, ../kernel/event, ../sf/service + +type + ViDisplayName* {.bycopy.} = object + data*: array[0x40, char] + + ViDisplay* {.bycopy.} = object + displayId*: U64 + displayName*: ViDisplayName + initialized*: bool + + ViLayer* {.bycopy.} = object + layerId*: U64 + igbpBinderObjId*: U32 + initialized* {.bitsize: 1.}: bool + strayLayer* {.bitsize: 1.}: bool + + ViServiceType* = enum + ViServiceTypeDefault = -1, ViServiceTypeApplication = 0, ViServiceTypeSystem = 1, + ViServiceTypeManager = 2 + + +## / Used by viCreateLayer when CreateStrayLayer is used internally. + +type + ViLayerFlags* = enum + ViLayerFlagsDefault = 0x1 + + +## / Used with viSetLayerScalingMode. + +type + ViScalingMode* = enum + ViScalingModeNone = 0x0, ViScalingModeFitToLayer = 0x2, + ViScalingModePreserveAspectRatio = 0x4, + +const ViScalingModeDefault* = ViScalingModeFitToLayer + + +## / Used with viSetDisplayPowerState. + +type + ViPowerState* = enum + ViPowerStateOff = 0, ## /< Screen is off. + ViPowerStateNotScanning = 1, ## /< [3.0.0+] Screen is on, but not scanning content. + ViPowerStateOn = 2 ## /< [3.0.0+] Screen is on. + +const + ViPowerStateOnDeprecated* = ViPowerStateNotScanning + +## / Used as argument to many capture functions. + +type + ViLayerStack* = enum + ViLayerStackDefault = 0, ## /< Default layer stack, includes all layers. + ViLayerStackLcd = 1, ## /< Includes only layers for the LCD. + ViLayerStackScreenshot = 2, ## /< Includes only layers for user screenshots. + ViLayerStackRecording = 3, ## /< Includes only layers for recording videos. + ViLayerStackLastFrame = 4, ## /< Includes only layers for the last applet-transition frame. + ViLayerStackArbitrary = 5, ## /< Captures some arbitrary layer. This is normally only for am. + ViLayerStackApplicationForDebug = 6, ## /< Captures layers for the current application. This is normally used by creport/debugging tools. + ViLayerStackNull = 10 ## /< Layer stack for the empty display. + + +proc viInitialize*(serviceType: ViServiceType): Result {.cdecl, + importc: "viInitialize".} +proc viExit*() {.cdecl, importc: "viExit".} +proc viGetSessionIApplicationDisplayService*(): ptr Service {.cdecl, + importc: "viGetSession_IApplicationDisplayService".} +proc viGetSessionIHOSBinderDriverRelay*(): ptr Service {.cdecl, + importc: "viGetSession_IHOSBinderDriverRelay".} +proc viGetSessionISystemDisplayService*(): ptr Service {.cdecl, + importc: "viGetSession_ISystemDisplayService".} +proc viGetSessionIManagerDisplayService*(): ptr Service {.cdecl, + importc: "viGetSession_IManagerDisplayService".} +proc viGetSessionIHOSBinderDriverIndirect*(): ptr Service {.cdecl, + importc: "viGetSession_IHOSBinderDriverIndirect".} + +## Misc functions + +proc viSetContentVisibility*(v: bool): Result {.cdecl, + importc: "viSetContentVisibility".} + +## Display functions + +proc viOpenDisplay*(displayName: cstring; display: ptr ViDisplay): Result {.cdecl, + importc: "viOpenDisplay".} +proc viCloseDisplay*(display: ptr ViDisplay): Result {.cdecl, + importc: "viCloseDisplay".} +proc viOpenDefaultDisplay*(display: ptr ViDisplay): Result {.inline, cdecl.} = + return viOpenDisplay("Default", display) + +proc viGetDisplayResolution*(display: ptr ViDisplay; width: ptr S32; height: ptr S32): Result {. + cdecl, importc: "viGetDisplayResolution".} +proc viGetDisplayLogicalResolution*(display: ptr ViDisplay; width: ptr S32; + height: ptr S32): Result {.cdecl, + importc: "viGetDisplayLogicalResolution".} + +proc viSetDisplayMagnification*(display: ptr ViDisplay; x: S32; y: S32; width: S32; + height: S32): Result {.cdecl, + importc: "viSetDisplayMagnification".} +## / Only available on [3.0.0+]. +proc viGetDisplayVsyncEvent*(display: ptr ViDisplay; eventOut: ptr Event): Result {. + cdecl, importc: "viGetDisplayVsyncEvent".} +proc viSetDisplayPowerState*(display: ptr ViDisplay; state: ViPowerState): Result {. + cdecl, importc: "viSetDisplayPowerState".} +proc viSetDisplayAlpha*(display: ptr ViDisplay; alpha: cfloat): Result {.cdecl, + importc: "viSetDisplayAlpha".} +proc viGetZOrderCountMin*(display: ptr ViDisplay; z: ptr S32): Result {.cdecl, + importc: "viGetZOrderCountMin".} +proc viGetZOrderCountMax*(display: ptr ViDisplay; z: ptr S32): Result {.cdecl, + importc: "viGetZOrderCountMax".} + +## Layer functions + +proc viCreateLayer*(display: ptr ViDisplay; layer: ptr ViLayer): Result {.cdecl, + importc: "viCreateLayer".} +proc viCreateManagedLayer*(display: ptr ViDisplay; layerFlags: ViLayerFlags; + aruid: U64; layerId: ptr U64): Result {.cdecl, + importc: "viCreateManagedLayer".} +proc viSetLayerSize*(layer: ptr ViLayer; width: S32; height: S32): Result {.cdecl, + importc: "viSetLayerSize".} +proc viSetLayerZ*(layer: ptr ViLayer; z: S32): Result {.cdecl, importc: "viSetLayerZ".} +proc viSetLayerPosition*(layer: ptr ViLayer; x: cfloat; y: cfloat): Result {.cdecl, + importc: "viSetLayerPosition".} +proc viCloseLayer*(layer: ptr ViLayer): Result {.cdecl, importc: "viCloseLayer".} +proc viDestroyManagedLayer*(layer: ptr ViLayer): Result {.cdecl, + importc: "viDestroyManagedLayer".} +proc viSetLayerScalingMode*(layer: ptr ViLayer; scalingMode: ViScalingMode): Result {. + cdecl, importc: "viSetLayerScalingMode".} + +## IndirectLayer functions + +proc viGetIndirectLayerImageMap*(buffer: pointer; size: csize_t; width: S32; + height: S32; indirectLayerConsumerHandle: U64; + outSize: ptr U64; outStride: ptr U64): Result {.cdecl, + importc: "viGetIndirectLayerImageMap".} +proc viGetIndirectLayerImageRequiredMemoryInfo*(width: S32; height: S32; + outSize: ptr U64; outAlignment: ptr U64): Result {.cdecl, + importc: "viGetIndirectLayerImageRequiredMemoryInfo".} diff --git a/src/libnx/wrapper/switch/services/wlaninf.h b/src/libnx/wrapper/switch/services/wlaninf.h new file mode 100644 index 0000000..c3aba65 --- /dev/null +++ b/src/libnx/wrapper/switch/services/wlaninf.h @@ -0,0 +1,33 @@ +/** + * @file wlaninf.h + * @brief WLAN InfraManager service IPC wrapper. + * @author natinusala, yellows8 + * @copyright libnx Authors + */ + +#pragma once +#include "../types.h" +#include "../sf/service.h" + +/// WLAN State. +typedef enum { + WlanInfState_NotConnected = 1, ///< WLAN is disabled or enabled and not connected. + WlanInfState_Connecting, ///< WLAN is connecting. + WlanInfState_Connected, ///< WLAN is connected. +} WlanInfState; + +/// [1.0.0-14.1.2] Initialize wlan:inf. +Result wlaninfInitialize(void); + +/// Exit wlan:inf. +void wlaninfExit(void); + +/// Gets the Service object for the actual wlan:inf service session. +Service* wlaninfGetServiceSession(void); + +/// Gets \ref WlanInfState. +Result wlaninfGetState(WlanInfState* out); + +/// Value goes from -30 (really good signal) to -90 (barely enough to stay connected) +/// on a logarithmic scale +Result wlaninfGetRSSI(s32* out); diff --git a/src/libnx/wrapper/switch/services/wlaninf.nim b/src/libnx/wrapper/switch/services/wlaninf.nim new file mode 100644 index 0000000..c90c465 --- /dev/null +++ b/src/libnx/wrapper/switch/services/wlaninf.nim @@ -0,0 +1,37 @@ +## * +## @file wlaninf.h +## @brief WLAN InfraManager service IPC wrapper. +## @author natinusala, yellows8 +## @copyright libnx Authors +## + +import + ../types, ../sf/service + +## / WLAN State. + +type + WlanInfState* = enum + WlanInfStateNotConnected = 1, ## /< WLAN is disabled or enabled and not connected. + WlanInfStateConnecting, ## /< WLAN is connecting. + WlanInfStateConnected ## /< WLAN is connected. + + +## / [1.0.0-14.1.2] Initialize wlan:inf. + +proc wlaninfInitialize*(): Result {.cdecl, importc: "wlaninfInitialize".} +## / Exit wlan:inf. + +proc wlaninfExit*() {.cdecl, importc: "wlaninfExit".} +## / Gets the Service object for the actual wlan:inf service session. + +proc wlaninfGetServiceSession*(): ptr Service {.cdecl, + importc: "wlaninfGetServiceSession".} +## / Gets \ref WlanInfState. + +proc wlaninfGetState*(`out`: ptr WlanInfState): Result {.cdecl, + importc: "wlaninfGetState".} +## / Value goes from -30 (really good signal) to -90 (barely enough to stay connected) +## / on a logarithmic scale + +proc wlaninfGetRSSI*(`out`: ptr S32): Result {.cdecl, importc: "wlaninfGetRSSI".} \ No newline at end of file diff --git a/src/libnx/wrapper/switch/sf/cmif.h b/src/libnx/wrapper/switch/sf/cmif.h new file mode 100644 index 0000000..f066803 --- /dev/null +++ b/src/libnx/wrapper/switch/sf/cmif.h @@ -0,0 +1,370 @@ +/** + * @file cmif.h + * @brief Common Message Interface Framework protocol + * @author fincs + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "hipc.h" + +#define CMIF_IN_HEADER_MAGIC 0x49434653 // "SFCI" +#define CMIF_OUT_HEADER_MAGIC 0x4F434653 // "SFCO" + +typedef enum CmifCommandType { + CmifCommandType_Invalid = 0, + CmifCommandType_LegacyRequest = 1, + CmifCommandType_Close = 2, + CmifCommandType_LegacyControl = 3, + CmifCommandType_Request = 4, + CmifCommandType_Control = 5, + CmifCommandType_RequestWithContext = 6, + CmifCommandType_ControlWithContext = 7, +} CmifCommandType; + +typedef enum CmifDomainRequestType { + CmifDomainRequestType_Invalid = 0, + CmifDomainRequestType_SendMessage = 1, + CmifDomainRequestType_Close = 2, +} CmifDomainRequestType; + +typedef struct CmifInHeader { + u32 magic; + u32 version; + u32 command_id; + u32 token; +} CmifInHeader; + +typedef struct CmifOutHeader { + u32 magic; + u32 version; + Result result; + u32 token; +} CmifOutHeader; + +typedef struct CmifDomainInHeader { + u8 type; + u8 num_in_objects; + u16 data_size; + u32 object_id; + u32 padding; + u32 token; +} CmifDomainInHeader; + +typedef struct CmifDomainOutHeader { + u32 num_out_objects; + u32 padding[3]; +} CmifDomainOutHeader; + +typedef struct CmifRequestFormat { + u32 object_id; + u32 request_id; + u32 context; + u32 data_size; + u32 server_pointer_size; + u32 num_in_auto_buffers; + u32 num_out_auto_buffers; + u32 num_in_buffers; + u32 num_out_buffers; + u32 num_inout_buffers; + u32 num_in_pointers; + u32 num_out_pointers; + u32 num_out_fixed_pointers; + u32 num_objects; + u32 num_handles; + u32 send_pid; +} CmifRequestFormat; + +typedef struct CmifRequest { + HipcRequest hipc; + void* data; + u16* out_pointer_sizes; + u32* objects; + u32 server_pointer_size; + u32 cur_in_ptr_id; +} CmifRequest; + +typedef struct CmifResponse { + void* data; + u32* objects; + Handle* copy_handles; + Handle* move_handles; +} CmifResponse; + +NX_CONSTEXPR void* cmifGetAlignedDataStart(u32* data_words, void* base) +{ + intptr_t data_start = ((u8*)data_words - (u8*)base + 15) &~ 15; + return (u8*)base + data_start; +} + +NX_CONSTEXPR CmifRequest cmifMakeRequest(void* base, CmifRequestFormat fmt) +{ + // First of all, we need to figure out what size we need. + u32 actual_size = 16; + if (fmt.object_id) + actual_size += sizeof(CmifDomainInHeader) + fmt.num_objects*sizeof(u32); + actual_size += sizeof(CmifInHeader) + fmt.data_size; + actual_size = (actual_size + 1) &~ 1; // hword-align + u32 out_pointer_size_table_offset = actual_size; + u32 out_pointer_size_table_size = fmt.num_out_auto_buffers + fmt.num_out_pointers; + actual_size += sizeof(u16)*out_pointer_size_table_size; + u32 num_data_words = (actual_size + 3) / 4; + + CmifRequest req = {}; + req.hipc = hipcMakeRequestInline(base, + .type = fmt.context ? CmifCommandType_RequestWithContext : CmifCommandType_Request, + .num_send_statics = fmt.num_in_auto_buffers + fmt.num_in_pointers, + .num_send_buffers = fmt.num_in_auto_buffers + fmt.num_in_buffers, + .num_recv_buffers = fmt.num_out_auto_buffers + fmt.num_out_buffers, + .num_exch_buffers = fmt.num_inout_buffers, + .num_data_words = num_data_words, + .num_recv_statics = out_pointer_size_table_size + fmt.num_out_fixed_pointers, + .send_pid = fmt.send_pid, + .num_copy_handles = fmt.num_handles, + .num_move_handles = 0, + ); + + CmifInHeader* hdr = NULL; + void* start = cmifGetAlignedDataStart(req.hipc.data_words, base); + if (fmt.object_id) { + CmifDomainInHeader* domain_hdr = (CmifDomainInHeader*)start; + u32 payload_size = sizeof(CmifInHeader) + fmt.data_size; + *domain_hdr = (CmifDomainInHeader){ + .type = CmifDomainRequestType_SendMessage, + .num_in_objects = (u8)fmt.num_objects, + .data_size = (u16)payload_size, + .object_id = fmt.object_id, + .padding = 0, + .token = fmt.context, + }; + hdr = (CmifInHeader*)(domain_hdr+1); + req.objects = (u32*)((u8*)hdr + payload_size); + } else + hdr = (CmifInHeader*)start; + + *hdr = (CmifInHeader){ + .magic = CMIF_IN_HEADER_MAGIC, + .version = fmt.context ? 1U : 0U, + .command_id = fmt.request_id, + .token = fmt.object_id ? 0U : fmt.context, + }; + + req.data = hdr+1; + req.out_pointer_sizes = (u16*)(void*)((u8*)(void*)req.hipc.data_words + out_pointer_size_table_offset); + req.server_pointer_size = fmt.server_pointer_size; + + return req; +} + +NX_CONSTEXPR void* cmifMakeControlRequest(void* base, u32 request_id, u32 size) +{ + u32 actual_size = 16 + sizeof(CmifInHeader) + size; + HipcRequest hipc = hipcMakeRequestInline(base, + .type = CmifCommandType_Control, + .num_data_words = (actual_size + 3) / 4, + ); + CmifInHeader* hdr = (CmifInHeader*)cmifGetAlignedDataStart(hipc.data_words, base); + *hdr = (CmifInHeader){ + .magic = CMIF_IN_HEADER_MAGIC, + .version = 0, + .command_id = request_id, + .token = 0, + }; + return hdr+1; +} + +NX_CONSTEXPR void cmifMakeCloseRequest(void* base, u32 object_id) +{ + if (object_id) { + HipcRequest hipc = hipcMakeRequestInline(base, + .type = CmifCommandType_Request, + .num_data_words = (16 + sizeof(CmifDomainInHeader)) / 4, + ); + CmifDomainInHeader* domain_hdr = (CmifDomainInHeader*)cmifGetAlignedDataStart(hipc.data_words, base); + *domain_hdr = (CmifDomainInHeader){ + .type = CmifDomainRequestType_Close, + .object_id = object_id, + }; + } else { + hipcMakeRequestInline(base, + .type = CmifCommandType_Close, + ); + } +} + +NX_CONSTEXPR void cmifRequestInBuffer(CmifRequest* req, const void* buffer, size_t size, HipcBufferMode mode) +{ + *req->hipc.send_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void cmifRequestOutBuffer(CmifRequest* req, void* buffer, size_t size, HipcBufferMode mode) +{ + *req->hipc.recv_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void cmifRequestInOutBuffer(CmifRequest* req, void* buffer, size_t size, HipcBufferMode mode) +{ + *req->hipc.exch_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void cmifRequestInPointer(CmifRequest* req, const void* buffer, size_t size) +{ + *req->hipc.send_statics++ = hipcMakeSendStatic(buffer, size, req->cur_in_ptr_id++); + req->server_pointer_size -= size; +} + +NX_CONSTEXPR void cmifRequestOutFixedPointer(CmifRequest* req, void* buffer, size_t size) +{ + *req->hipc.recv_list++ = hipcMakeRecvStatic(buffer, size); + req->server_pointer_size -= size; +} + +NX_CONSTEXPR void cmifRequestOutPointer(CmifRequest* req, void* buffer, size_t size) +{ + cmifRequestOutFixedPointer(req, buffer, size); + *req->out_pointer_sizes++ = size; +} + +NX_CONSTEXPR void cmifRequestInAutoBuffer(CmifRequest* req, const void* buffer, size_t size, HipcBufferMode mode) +{ + if (req->server_pointer_size && size <= req->server_pointer_size) { + cmifRequestInPointer(req, buffer, size); + cmifRequestInBuffer(req, NULL, 0, mode); + } else { + cmifRequestInPointer(req, NULL, 0); + cmifRequestInBuffer(req, buffer, size, mode); + } +} + +NX_CONSTEXPR void cmifRequestOutAutoBuffer(CmifRequest* req, void* buffer, size_t size, HipcBufferMode mode) +{ + if (req->server_pointer_size && size <= req->server_pointer_size) { + cmifRequestOutPointer(req, buffer, size); + cmifRequestOutBuffer(req, NULL, 0, mode); + } else { + cmifRequestOutPointer(req, NULL, 0); + cmifRequestOutBuffer(req, buffer, size, mode); + } +} + +NX_CONSTEXPR void cmifRequestObject(CmifRequest* req, u32 object_id) +{ + *req->objects++ = object_id; +} + +NX_CONSTEXPR void cmifRequestHandle(CmifRequest* req, Handle handle) +{ + *req->hipc.copy_handles++ = handle; +} + +NX_CONSTEXPR Result cmifParseResponse(CmifResponse* res, void* base, bool is_domain, u32 size) +{ + HipcResponse hipc = hipcParseResponse(base); + void* start = cmifGetAlignedDataStart(hipc.data_words, base); + + CmifOutHeader* hdr = NULL; + u32* objects = NULL; + if (is_domain) { + CmifDomainOutHeader* domain_hdr = (CmifDomainOutHeader*)start; + hdr = (CmifOutHeader*)(domain_hdr+1); + objects = (u32*)((u8*)hdr + sizeof(CmifOutHeader) + size); + } + else + hdr = (CmifOutHeader*)start; + + if (hdr->magic != CMIF_OUT_HEADER_MAGIC) + return MAKERESULT(Module_Libnx, LibnxError_InvalidCmifOutHeader); + if (R_FAILED(hdr->result)) + return hdr->result; + + *res = (CmifResponse){ + .data = hdr+1, + .objects = objects, + .copy_handles = hipc.copy_handles, + .move_handles = hipc.move_handles, + }; + + return 0; +} + +NX_CONSTEXPR u32 cmifResponseGetObject(CmifResponse* res) +{ + return *res->objects++; +} + +NX_CONSTEXPR Handle cmifResponseGetCopyHandle(CmifResponse* res) +{ + return *res->copy_handles++; +} + +NX_CONSTEXPR Handle cmifResponseGetMoveHandle(CmifResponse* res) +{ + return *res->move_handles++; +} + +NX_INLINE Result cmifConvertCurrentObjectToDomain(Handle h, u32* out_object_id) +{ + cmifMakeControlRequest(armGetTls(), 0, 0); + Result rc = svcSendSyncRequest(h); + if (R_SUCCEEDED(rc)) { + CmifResponse resp = {}; + rc = cmifParseResponse(&resp, armGetTls(), false, sizeof(u32)); + if (R_SUCCEEDED(rc) && out_object_id) + *out_object_id = *(u32*)resp.data; + } + return rc; +} + +NX_INLINE Result cmifCopyFromCurrentDomain(Handle h, u32 object_id, Handle* out_h) +{ + void* raw = cmifMakeControlRequest(armGetTls(), 1, sizeof(u32)); + *(u32*)raw = object_id; + Result rc = svcSendSyncRequest(h); + if (R_SUCCEEDED(rc)) { + CmifResponse resp = {}; + rc = cmifParseResponse(&resp, armGetTls(), false, 0); + if (R_SUCCEEDED(rc) && out_h) + *out_h = resp.move_handles[0]; + } + return rc; +} + +NX_INLINE Result cmifCloneCurrentObject(Handle h, Handle* out_h) +{ + cmifMakeControlRequest(armGetTls(), 2, 0); + Result rc = svcSendSyncRequest(h); + if (R_SUCCEEDED(rc)) { + CmifResponse resp = {}; + rc = cmifParseResponse(&resp, armGetTls(), false, 0); + if (R_SUCCEEDED(rc) && out_h) + *out_h = resp.move_handles[0]; + } + return rc; +} + +NX_INLINE Result cmifQueryPointerBufferSize(Handle h, u16* out_size) +{ + cmifMakeControlRequest(armGetTls(), 3, 0); + Result rc = svcSendSyncRequest(h); + if (R_SUCCEEDED(rc)) { + CmifResponse resp = {}; + rc = cmifParseResponse(&resp, armGetTls(), false, sizeof(u16)); + if (R_SUCCEEDED(rc) && out_size) + *out_size = *(u16*)resp.data; + } + return rc; +} + +NX_INLINE Result cmifCloneCurrentObjectEx(Handle h, u32 tag, Handle* out_h) +{ + void* raw = cmifMakeControlRequest(armGetTls(), 4, sizeof(u32)); + *(u32*)raw = tag; + Result rc = svcSendSyncRequest(h); + if (R_SUCCEEDED(rc)) { + CmifResponse resp = {}; + rc = cmifParseResponse(&resp, armGetTls(), false, 0); + if (R_SUCCEEDED(rc) && out_h) + *out_h = resp.move_handles[0]; + } + return rc; +} diff --git a/src/libnx/wrapper/switch/sf/cmif.nim b/src/libnx/wrapper/switch/sf/cmif.nim new file mode 100644 index 0000000..ed3fb0d --- /dev/null +++ b/src/libnx/wrapper/switch/sf/cmif.nim @@ -0,0 +1,321 @@ +## * +## @file cmif.h +## @brief Common Message Interface Framework protocol +## @author fincs +## @author SciresM +## @copyright libnx Authors +## + +import + hipc, ../types, ../result, ../arm/tls, ../kernel/svc + +const + CMIF_IN_HEADER_MAGIC* = 0x49434653 + CMIF_OUT_HEADER_MAGIC* = 0x4F434653 + +type + CmifCommandType* = enum + CmifCommandTypeInvalid = 0, CmifCommandTypeLegacyRequest = 1, + CmifCommandTypeClose = 2, CmifCommandTypeLegacyControl = 3, + CmifCommandTypeRequest = 4, CmifCommandTypeControl = 5, + CmifCommandTypeRequestWithContext = 6, CmifCommandTypeControlWithContext = 7 + CmifDomainRequestType* = enum + CmifDomainRequestTypeInvalid = 0, CmifDomainRequestTypeSendMessage = 1, + CmifDomainRequestTypeClose = 2 + CmifInHeader* {.bycopy.} = object + magic*: U32 + version*: U32 + commandId*: U32 + token*: U32 + + CmifOutHeader* {.bycopy.} = object + magic*: U32 + version*: U32 + result*: Result + token*: U32 + + CmifDomainInHeader* {.bycopy.} = object + `type`*: U8 + numInObjects*: U8 + dataSize*: U16 + objectId*: U32 + padding*: U32 + token*: U32 + + CmifDomainOutHeader* {.bycopy.} = object + numOutObjects*: U32 + padding*: array[3, U32] + + CmifRequestFormat* {.bycopy.} = object + objectId*: U32 + requestId*: U32 + context*: U32 + dataSize*: U32 + serverPointerSize*: U32 + numInAutoBuffers*: U32 + numOutAutoBuffers*: U32 + numInBuffers*: U32 + numOutBuffers*: U32 + numInoutBuffers*: U32 + numInPointers*: U32 + numOutPointers*: U32 + numOutFixedPointers*: U32 + numObjects*: U32 + numHandles*: U32 + sendPid*: U32 + + CmifRequest* {.bycopy.} = object + hipc*: HipcRequest + data*: pointer + outPointerSizes*: ptr U16 + objects*: ptr U32 + serverPointerSize*: U32 + curInPtrId*: U32 + + CmifResponse* {.bycopy.} = object + data*: pointer + objects*: ptr U32 + copyHandles*: ptr Handle + moveHandles*: ptr Handle + + +proc cmifGetAlignedDataStart*(dataWords: ptr U32; base: pointer): pointer {.inline, + cdecl.} = + {.emit: " intptr_t data_start = ((u8*)`dataWords` - (u8*)`base` + 15) &~ 15;".} + {.emit: " `result` = (u8*)base + data_start;".} + +proc cmifMakeRequest*(base: pointer; fmt: CmifRequestFormat): CmifRequest {.inline, + cdecl.} = + {.emit: " u32 actual_size = 16;".} + {.emit: " if (`fmt`.object_id)".} + {.emit: " actual_size += sizeof(CmifDomainInHeader) + `fmt`.num_objects*sizeof(u32);".} + {.emit: " actual_size += sizeof(CmifInHeader) + `fmt`.data_size;".} + {.emit: " actual_size = (actual_size + 1) &~ 1; // hword-align".} + {.emit: " u32 out_pointer_size_table_offset = actual_size;".} + {.emit: " u32 out_pointer_size_table_size = `fmt`.num_out_auto_buffers + `fmt`.num_out_pointers;".} + {.emit: " actual_size += sizeof(u16)*out_pointer_size_table_size;".} + {.emit: " u32 num_data_words = (actual_size + 3) / 4;".} + {.emit: " CmifRequest req = {};".} + {.emit: " req.hipc = hipcMakeRequestInline(`base`,".} + {.emit: " .type = `fmt`.context ? CmifCommandType_RequestWithContext : CmifCommandType_Request,".} + {.emit: " .num_send_statics = `fmt`.num_in_auto_buffers + `fmt`.num_in_pointers,".} + {.emit: " .num_send_buffers = `fmt`.num_in_auto_buffers + `fmt`.num_in_buffers,".} + {.emit: " .num_recv_buffers = `fmt`.num_out_auto_buffers + `fmt`.num_out_buffers,".} + {.emit: " .num_exch_buffers = `fmt`.num_inout_buffers,".} + {.emit: " .num_data_words = num_data_words,".} + {.emit: " .num_recv_statics = out_pointer_size_table_size + `fmt`.num_out_fixed_pointers,".} + {.emit: " .send_pid = `fmt`.send_pid,".} + {.emit: " .num_copy_handles = `fmt`.num_handles,".} + {.emit: " .num_move_handles = 0,".} + {.emit: " );".} + {.emit: " CmifInHeader* hdr = NULL;".} + {.emit: " void* start = cmifGetAlignedDataStart(req.hipc.data_words, `base`);".} + {.emit: " if (`fmt`.object_id) {".} + {.emit: " CmifDomainInHeader* domain_hdr = (CmifDomainInHeader*)start;".} + {.emit: " u32 payload_size = sizeof(CmifInHeader) + `fmt`.data_size;".} + {.emit: " *domain_hdr = (CmifDomainInHeader){".} + {.emit: " .type = CmifDomainRequestType_SendMessage,".} + {.emit: " .num_in_objects = (u8)`fmt`.num_objects,".} + {.emit: " .data_size = (u16)payload_size,".} + {.emit: " .object_id = `fmt`.object_id,".} + {.emit: " .padding = 0,".} + {.emit: " .token = `fmt`.context,".} + {.emit: " };".} + {.emit: " hdr = (CmifInHeader*)(domain_hdr+1);".} + {.emit: " req.objects = (u32*)((u8*)hdr + payload_size);".} + {.emit: " } else".} + {.emit: " hdr = (CmifInHeader*)start;".} + {.emit: " *hdr = (CmifInHeader){".} + {.emit: " .magic = CMIF_IN_HEADER_MAGIC,".} + {.emit: " .version = `fmt`.context ? 1U : 0U,".} + {.emit: " .command_id = `fmt`.request_id,".} + {.emit: " .token = `fmt`.object_id ? 0U : `fmt`.context,".} + {.emit: " };".} + {.emit: " req.data = hdr+1;".} + {.emit: " req.out_pointer_sizes = (u16*)(void*)((u8*)(void*)req.hipc.data_words + out_pointer_size_table_offset);".} + {.emit: " req.server_pointer_size = `fmt`.server_pointer_size;".} + {.emit: " `result` = req;".} + +proc cmifMakeControlRequest*(base: pointer; requestId: U32; size: U32): pointer {. + inline, cdecl.} = + var base = base + var actualSize: U32 = 16 + sizeof((CmifInHeader)) + size + var hipc = hipcMakeRequestInline(base, + `type` = CmifCommandType_Control.U32, + num_data_words = ((actual_size + 3).int / 4).U32 + ) + var hdr: ptr CmifInHeader = cast[ptr CmifInHeader](cmifGetAlignedDataStart( + hipc.dataWords, base)) + hdr.magic = CMIF_IN_HEADER_MAGIC + hdr.version = 0 + hdr.commandId = requestId + hdr.token = 0 + return hdr + 1 + +proc cmifMakeCloseRequest*(base: pointer; objectId: U32) {.inline, cdecl.} = + var base = base + if objectId.bool: + var hipc = hipcMakeRequestInline(base, + `type` = CmifCommandTypeRequest.U32, + num_data_words = ((16 + sizeof(CmifDomainInHeader))/4).U32 + ) + var domainHdr: ptr CmifDomainInHeader = cast[ptr CmifDomainInHeader](cmifGetAlignedDataStart( + hipc.dataWords, base)) + domainHdr.`type` = CmifDomainRequestTypeClose.U8 + domainHdr.objectId = objectId + else: + discard hipcMakeRequestInline(base, + `type` = CmifCommandType_Close.U32 + ); + +proc cmifRequestInBuffer*(req: ptr CmifRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.hipc.sendBuffers += 1 + req.hipc.sendBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc cmifRequestOutBuffer*(req: ptr CmifRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.hipc.recvBuffers += 1 + req.hipc.recvBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc cmifRequestInOutBuffer*(req: ptr CmifRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.hipc.exchBuffers += 1 + req.hipc.exchBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc cmifRequestInPointer*(req: ptr CmifRequest; buffer: pointer; size: csize_t) {. + inline, cdecl.} = + req.hipc.sendStatics += 1 + req.hipc.sendStatics[] = hipcMakeSendStatic(buffer, size, req.curInPtrId.U8) + req.curInPtrId += 1 + dec(req.serverPointerSize, size) + +proc cmifRequestOutFixedPointer*(req: ptr CmifRequest; buffer: pointer; size: csize_t) {. + inline, cdecl.} = + req.hipc.recvList += 1 + req.hipc.recvList[] = hipcMakeRecvStatic(buffer, size) + dec(req.serverPointerSize, size) + +proc cmifRequestOutPointer*(req: ptr CmifRequest; buffer: pointer; size: csize_t) {. + inline, cdecl.} = + cmifRequestOutFixedPointer(req, buffer, size) + req.outPointerSizes += 1 + req.outPointerSizes[] = size.U16 + +proc cmifRequestInAutoBuffer*(req: ptr CmifRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + if req.serverPointerSize.bool and size <= req.serverPointerSize: + cmifRequestInPointer(req, buffer, size) + cmifRequestInBuffer(req, nil, 0, mode) + else: + cmifRequestInPointer(req, nil, 0) + cmifRequestInBuffer(req, buffer, size, mode) + +proc cmifRequestOutAutoBuffer*(req: ptr CmifRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + if req.serverPointerSize.bool and size <= req.serverPointerSize: + cmifRequestOutPointer(req, buffer, size) + cmifRequestOutBuffer(req, nil, 0, mode) + else: + cmifRequestOutPointer(req, nil, 0) + cmifRequestOutBuffer(req, buffer, size, mode) + +proc cmifRequestObject*(req: ptr CmifRequest; objectId: U32) {.inline, cdecl.} = + req.objects += 1 + req.objects[] = objectId + +proc cmifRequestHandle*(req: ptr CmifRequest; handle: Handle) {.inline, cdecl.} = + req.hipc.copyHandles += 1 + req.hipc.copyHandles[] = handle + +proc cmifParseResponse*(res: ptr CmifResponse; base: pointer; isDomain: bool; size: U32): Result {. + inline, cdecl.} = + var base = base + var hipc: HipcResponse = hipcParseResponse(base) + var start: pointer = cmifGetAlignedDataStart(hipc.dataWords, base) + var hdr: ptr CmifOutHeader = nil + var objects: ptr U32 = nil + if isDomain: + var domainHdr: ptr CmifDomainOutHeader = cast[ptr CmifDomainOutHeader](start) + hdr = cast[ptr CmifOutHeader]((domainHdr + 1)) + objects = cast[ptr U32]((cast[ptr U8](hdr) + sizeof((CmifOutHeader)) + + size)) + else: + hdr = cast[ptr CmifOutHeader](start) + if hdr.magic != Cmif_Out_Header_Magic: + return makeResult(ModuleLibnx, LibnxErrorInvalidCmifOutHeader) + if r_Failed(hdr.result): + return hdr.result + ## !!!Ignored construct: * res = ( CmifResponse ) { . data = hdr + 1 , . objects = objects , . copy_handles = hipc . copy_handles , . move_handles = hipc . move_handles , } ; + ## Error: expected ';'!!! + return 0 + +proc cmifResponseGetObject*(res: ptr CmifResponse): U32 {.inline, cdecl.} = + res.objects += 1 + return res.objects[] + +proc cmifResponseGetCopyHandle*(res: ptr CmifResponse): Handle {.inline, cdecl.} = + res.copyHandles += 1 + return res.copyHandles[] + +proc cmifResponseGetMoveHandle*(res: ptr CmifResponse): Handle {.inline, cdecl.} = + res.moveHandles += 1 + return res.moveHandles[] + +proc cmifConvertCurrentObjectToDomain*(h: Handle; outObjectId: ptr U32): Result {. + inline, cdecl.} = + var p = armGetTls() + discard cmifMakeControlRequest(p, 0, 0) + var rc: Result = svcSendSyncRequest(h) + if r_Succeeded(rc): + var resp: CmifResponse = CmifResponse() + var p = armGetTls() + rc = cmifParseResponse(addr(resp), p, false, sizeof((U32)).U32) + if r_Succeeded(rc) and outObjectId != nil: + outObjectId[] = cast[ptr U32](resp.data)[] + return rc + +proc cmifCopyFromCurrentDomain*(h: Handle; objectId: U32; outH: ptr Handle): Result {. + inline, cdecl.} = + var p = armGetTls() + var raw: pointer = cmifMakeControlRequest(p, 1, sizeof((U32)).U32) + cast[ptr U32](raw)[] = objectId + var rc: Result = svcSendSyncRequest(h) + if r_Succeeded(rc): + var resp: CmifResponse = CmifResponse() + p = armGetTls() + rc = cmifParseResponse(addr(resp), p, false, 0) + if r_Succeeded(rc) and outH != nil: + outH[] = resp.moveHandles[0] + return rc + +proc cmifCloneCurrentObject*(h: Handle; outH: ptr Handle): Result {.inline, cdecl.} = + discard cmifMakeControlRequest(armGetTls(), 2, 0) + var rc: Result = svcSendSyncRequest(h) + if r_Succeeded(rc): + var resp: CmifResponse = CmifResponse() + rc = cmifParseResponse(addr(resp), armGetTls(), false, 0.U32) + if r_Succeeded(rc) and outH != nil: + outH[] = resp.moveHandles[0] + return rc + +proc cmifQueryPointerBufferSize*(h: Handle; outSize: ptr U16): Result {.inline, cdecl.} = + discard cmifMakeControlRequest(armGetTls(), 3, 0) + var rc: Result = svcSendSyncRequest(h) + if r_Succeeded(rc): + var resp: CmifResponse = CmifResponse() + rc = cmifParseResponse(addr(resp), armGetTls(), false, sizeof((U16)).U32) + if r_Succeeded(rc) and outSize != nil: + outSize[] = cast[ptr U16](resp.data)[] + return rc + +proc cmifCloneCurrentObjectEx*(h: Handle; tag: U32; outH: ptr Handle): Result {.inline, cdecl.} = + var raw: pointer = cmifMakeControlRequest(armGetTls(), 4, sizeof((U32)).U32) + cast[ptr U32](raw)[] = tag + var rc: Result = svcSendSyncRequest(h) + if r_Succeeded(rc): + var resp: CmifResponse = CmifResponse() + rc = cmifParseResponse(addr(resp), armGetTls(), false, 0) + if r_Succeeded(rc) and outH != nil: + outH[] = resp.moveHandles[0] + return rc diff --git a/src/libnx/wrapper/switch/sf/hipc.h b/src/libnx/wrapper/switch/sf/hipc.h new file mode 100644 index 0000000..e383600 --- /dev/null +++ b/src/libnx/wrapper/switch/sf/hipc.h @@ -0,0 +1,363 @@ +/** + * @file hipc.h + * @brief Horizon Inter-Process Communication protocol + * @author fincs + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../result.h" +#include "../arm/tls.h" +#include "../kernel/svc.h" + +#define HIPC_AUTO_RECV_STATIC UINT8_MAX +#define HIPC_RESPONSE_NO_PID UINT32_MAX + +typedef struct HipcMetadata { + u32 type; + u32 num_send_statics; + u32 num_send_buffers; + u32 num_recv_buffers; + u32 num_exch_buffers; + u32 num_data_words; + u32 num_recv_statics; // also accepts HIPC_AUTO_RECV_STATIC + u32 send_pid; + u32 num_copy_handles; + u32 num_move_handles; +} HipcMetadata; + +typedef struct HipcHeader { + u32 type : 16; + u32 num_send_statics : 4; + u32 num_send_buffers : 4; + u32 num_recv_buffers : 4; + u32 num_exch_buffers : 4; + u32 num_data_words : 10; + u32 recv_static_mode : 4; + u32 padding : 6; + u32 recv_list_offset : 11; // Unused. + u32 has_special_header : 1; +} HipcHeader; + +typedef struct HipcSpecialHeader { + u32 send_pid : 1; + u32 num_copy_handles : 4; + u32 num_move_handles : 4; + u32 padding : 23; +} HipcSpecialHeader; + +typedef struct HipcStaticDescriptor { + u32 index : 6; + u32 address_high : 6; + u32 address_mid : 4; + u32 size : 16; + u32 address_low; +} HipcStaticDescriptor; + +typedef struct HipcBufferDescriptor { + u32 size_low; + u32 address_low; + u32 mode : 2; + u32 address_high : 22; + u32 size_high : 4; + u32 address_mid : 4; +} HipcBufferDescriptor; + +typedef struct HipcRecvListEntry { + u32 address_low; + u32 address_high : 16; + u32 size : 16; +} HipcRecvListEntry; + +typedef struct HipcRequest { + HipcStaticDescriptor* send_statics; + HipcBufferDescriptor* send_buffers; + HipcBufferDescriptor* recv_buffers; + HipcBufferDescriptor* exch_buffers; + u32* data_words; + HipcRecvListEntry* recv_list; + Handle* copy_handles; + Handle* move_handles; +} HipcRequest; + +typedef struct HipcParsedRequest { + HipcMetadata meta; + HipcRequest data; + u64 pid; +} HipcParsedRequest; + +typedef struct HipcResponse { + u64 pid; + u32 num_statics; + u32 num_data_words; + u32 num_copy_handles; + u32 num_move_handles; + HipcStaticDescriptor* statics; + u32* data_words; + Handle* copy_handles; + Handle* move_handles; +} HipcResponse; + +typedef enum HipcBufferMode { + HipcBufferMode_Normal = 0, + HipcBufferMode_NonSecure = 1, + HipcBufferMode_Invalid = 2, + HipcBufferMode_NonDevice = 3, +} HipcBufferMode; + +NX_CONSTEXPR HipcStaticDescriptor hipcMakeSendStatic(const void* buffer, size_t size, u8 index) +{ + return (HipcStaticDescriptor){ + .index = index, + .address_high = (u32)((uintptr_t)buffer >> 36), + .address_mid = (u32)((uintptr_t)buffer >> 32), + .size = (u32)size, + .address_low = (u32)(uintptr_t)buffer, + }; +} + +NX_CONSTEXPR HipcBufferDescriptor hipcMakeBuffer(const void* buffer, size_t size, HipcBufferMode mode) +{ + return (HipcBufferDescriptor){ + .size_low = (u32)size, + .address_low = (u32)(uintptr_t)buffer, + .mode = mode, + .address_high = (u32)((uintptr_t)buffer >> 36), + .size_high = (u32)(size >> 32), + .address_mid = (u32)((uintptr_t)buffer >> 32), + }; +} + +NX_CONSTEXPR HipcRecvListEntry hipcMakeRecvStatic(void* buffer, size_t size) +{ + return (HipcRecvListEntry){ + .address_low = (u32)((uintptr_t)buffer), + .address_high = (u32)((uintptr_t)buffer >> 32), + .size = (u32)size, + }; +} + +NX_CONSTEXPR void* hipcGetStaticAddress(const HipcStaticDescriptor* desc) +{ + return (void*)(desc->address_low | ((uintptr_t)desc->address_mid << 32) | ((uintptr_t)desc->address_high << 36)); +} + +NX_CONSTEXPR size_t hipcGetStaticSize(const HipcStaticDescriptor* desc) +{ + return desc->size; +} + +NX_CONSTEXPR void* hipcGetBufferAddress(const HipcBufferDescriptor* desc) +{ + return (void*)(desc->address_low | ((uintptr_t)desc->address_mid << 32) | ((uintptr_t)desc->address_high << 36)); +} + +NX_CONSTEXPR size_t hipcGetBufferSize(const HipcBufferDescriptor* desc) +{ + return desc->size_low | ((size_t)desc->size_high << 32); +} + +NX_CONSTEXPR HipcRequest hipcCalcRequestLayout(HipcMetadata meta, void* base) +{ + // Copy handles + Handle* copy_handles = NULL; + if (meta.num_copy_handles) { + copy_handles = (Handle*)base; + base = copy_handles + meta.num_copy_handles; + } + + // Move handles + Handle* move_handles = NULL; + if (meta.num_move_handles) { + move_handles = (Handle*)base; + base = move_handles + meta.num_move_handles; + } + + // Send statics + HipcStaticDescriptor* send_statics = NULL; + if (meta.num_send_statics) { + send_statics = (HipcStaticDescriptor*)base; + base = send_statics + meta.num_send_statics; + } + + // Send buffers + HipcBufferDescriptor* send_buffers = NULL; + if (meta.num_send_buffers) { + send_buffers = (HipcBufferDescriptor*)base; + base = send_buffers + meta.num_send_buffers; + } + + // Recv buffers + HipcBufferDescriptor* recv_buffers = NULL; + if (meta.num_recv_buffers) { + recv_buffers = (HipcBufferDescriptor*)base; + base = recv_buffers + meta.num_recv_buffers; + } + + // Exch buffers + HipcBufferDescriptor* exch_buffers = NULL; + if (meta.num_exch_buffers) { + exch_buffers = (HipcBufferDescriptor*)base; + base = exch_buffers + meta.num_exch_buffers; + } + + // Data words + u32* data_words = NULL; + if (meta.num_data_words) { + data_words = (u32*)base; + base = data_words + meta.num_data_words; + } + + // Recv list + HipcRecvListEntry* recv_list = NULL; + if (meta.num_recv_statics) + recv_list = (HipcRecvListEntry*)base; + + return (HipcRequest){ + .send_statics = send_statics, + .send_buffers = send_buffers, + .recv_buffers = recv_buffers, + .exch_buffers = exch_buffers, + .data_words = data_words, + .recv_list = recv_list, + .copy_handles = copy_handles, + .move_handles = move_handles, + }; +} + +NX_CONSTEXPR HipcRequest hipcMakeRequest(void* base, HipcMetadata meta) +{ + // Write message header + bool has_special_header = meta.send_pid || meta.num_copy_handles || meta.num_move_handles; + HipcHeader* hdr = (HipcHeader*)base; + base = hdr+1; + *hdr = (HipcHeader){ + .type = meta.type, + .num_send_statics = meta.num_send_statics, + .num_send_buffers = meta.num_send_buffers, + .num_recv_buffers = meta.num_recv_buffers, + .num_exch_buffers = meta.num_exch_buffers, + .num_data_words = meta.num_data_words, + .recv_static_mode = meta.num_recv_statics ? (meta.num_recv_statics != HIPC_AUTO_RECV_STATIC ? 2u + meta.num_recv_statics : 2u) : 0u, + .padding = 0, + .recv_list_offset = 0, + .has_special_header = has_special_header, + }; + + // Write special header + if (has_special_header) { + HipcSpecialHeader* sphdr = (HipcSpecialHeader*)base; + base = sphdr+1; + *sphdr = (HipcSpecialHeader){ + .send_pid = meta.send_pid, + .num_copy_handles = meta.num_copy_handles, + .num_move_handles = meta.num_move_handles, + }; + if (meta.send_pid) + base = (u8*)base + sizeof(u64); + } + + // Calculate layout + return hipcCalcRequestLayout(meta, base); +} + +#define hipcMakeRequestInline(_base,...) hipcMakeRequest((_base),(HipcMetadata){ __VA_ARGS__ }) + +NX_CONSTEXPR HipcParsedRequest hipcParseRequest(void* base) +{ + // Parse message header + HipcHeader hdr = {}; + __builtin_memcpy(&hdr, base, sizeof(hdr)); + base = (u8*)base + sizeof(hdr); + u32 num_recv_statics = 0; + u64 pid = 0; + + // Parse recv static mode + if (hdr.recv_static_mode) { + if (hdr.recv_static_mode == 2u) + num_recv_statics = HIPC_AUTO_RECV_STATIC; + else if (hdr.recv_static_mode > 2u) + num_recv_statics = hdr.recv_static_mode - 2u; + } + + // Parse special header + HipcSpecialHeader sphdr = {}; + if (hdr.has_special_header) { + __builtin_memcpy(&sphdr, base, sizeof(sphdr)); + base = (u8*)base + sizeof(sphdr); + + // Read PID descriptor + if (sphdr.send_pid) { + pid = *(u64*)base; + base = (u8*)base + sizeof(u64); + } + } + + const HipcMetadata meta = { + .type = hdr.type, + .num_send_statics = hdr.num_send_statics, + .num_send_buffers = hdr.num_send_buffers, + .num_recv_buffers = hdr.num_recv_buffers, + .num_exch_buffers = hdr.num_exch_buffers, + .num_data_words = hdr.num_data_words, + .num_recv_statics = num_recv_statics, + .send_pid = sphdr.send_pid, + .num_copy_handles = sphdr.num_copy_handles, + .num_move_handles = sphdr.num_move_handles, + }; + + return (HipcParsedRequest){ + .meta = meta, + .data = hipcCalcRequestLayout(meta, base), + .pid = pid, + }; +} + +NX_CONSTEXPR HipcResponse hipcParseResponse(void* base) +{ + // Parse header + HipcHeader hdr = {}; + __builtin_memcpy(&hdr, base, sizeof(hdr)); + base = (u8*)base + sizeof(hdr); + + // Initialize response + HipcResponse response = {}; + response.num_statics = hdr.num_send_statics; + response.num_data_words = hdr.num_data_words; + response.pid = HIPC_RESPONSE_NO_PID; + + // Parse special header + if (hdr.has_special_header) + { + HipcSpecialHeader sphdr = {}; + __builtin_memcpy(&sphdr, base, sizeof(sphdr)); + base = (u8*)base + sizeof(sphdr); + + // Update response + response.num_copy_handles = sphdr.num_copy_handles; + response.num_move_handles = sphdr.num_move_handles; + + // Parse PID descriptor + if (sphdr.send_pid) { + response.pid = *(u64*)base; + base = (u8*)base + sizeof(u64); + } + } + + // Copy handles + response.copy_handles = (Handle*)base; + base = response.copy_handles + response.num_copy_handles; + + // Move handles + response.move_handles = (Handle*)base; + base = response.move_handles + response.num_move_handles; + + // Send statics + response.statics = (HipcStaticDescriptor*)base; + base = response.statics + response.num_statics; + + // Data words + response.data_words = (u32*)base; + + return response; +} diff --git a/src/libnx/wrapper/switch/sf/hipc.nim b/src/libnx/wrapper/switch/sf/hipc.nim new file mode 100644 index 0000000..fdf631c --- /dev/null +++ b/src/libnx/wrapper/switch/sf/hipc.nim @@ -0,0 +1,359 @@ +## * +## @file hipc.h +## @brief Horizon Inter-Process Communication protocol +## @author fincs +## @author SciresM +## @copyright libnx Authors +## +import ../types +import + ../result, ../arm/tls + +const + HIPC_AUTO_RECV_STATIC* = uint8.high + HIPC_RESPONSE_NO_PID* = uint32.high + +type + HipcMetadata* {.bycopy.} = object + `type`*: U32 + numSendStatics*: U32 + numSendBuffers*: U32 + numRecvBuffers*: U32 + numExchBuffers*: U32 + numDataWords*: U32 + numRecvStatics*: U32 ## also accepts HIPC_AUTO_RECV_STATIC + sendPid*: U32 + numCopyHandles*: U32 + numMoveHandles*: U32 + + HipcHeader* {.bycopy.} = object + `type`* {.bitsize: 16.}: U32 + numSendStatics* {.bitsize: 4.}: U32 + numSendBuffers* {.bitsize: 4.}: U32 + numRecvBuffers* {.bitsize: 4.}: U32 + numExchBuffers* {.bitsize: 4.}: U32 + numDataWords* {.bitsize: 10.}: U32 + recvStaticMode* {.bitsize: 4.}: U32 + padding* {.bitsize: 6.}: U32 + recvListOffset* {.bitsize: 11.}: U32 ## Unused. + hasSpecialHeader* {.bitsize: 1.}: U32 + + HipcSpecialHeader* {.bycopy.} = object + sendPid* {.bitsize: 1.}: U32 + numCopyHandles* {.bitsize: 4.}: U32 + numMoveHandles* {.bitsize: 4.}: U32 + padding* {.bitsize: 23.}: U32 + + HipcStaticDescriptor* {.bycopy.} = object + index* {.bitsize: 6.}: U32 + addressHigh* {.bitsize: 6.}: U32 + addressMid* {.bitsize: 4.}: U32 + size* {.bitsize: 16.}: U32 + addressLow*: U32 + + HipcBufferDescriptor* {.bycopy.} = object + sizeLow*: U32 + addressLow*: U32 + mode* {.bitsize: 2.}: U32 + addressHigh* {.bitsize: 22.}: U32 + sizeHigh* {.bitsize: 4.}: U32 + addressMid* {.bitsize: 4.}: U32 + + HipcRecvListEntry* {.bycopy.} = object + addressLow*: U32 + addressHigh* {.bitsize: 16.}: U32 + size* {.bitsize: 16.}: U32 + + HipcRequest* {.bycopy.} = object + sendStatics*: ptr HipcStaticDescriptor + sendBuffers*: ptr HipcBufferDescriptor + recvBuffers*: ptr HipcBufferDescriptor + exchBuffers*: ptr HipcBufferDescriptor + dataWords*: ptr U32 + recvList*: ptr HipcRecvListEntry + copyHandles*: ptr Handle + moveHandles*: ptr Handle + + HipcParsedRequest* {.bycopy.} = object + meta*: HipcMetadata + data*: HipcRequest + pid*: U64 + + HipcResponse* {.bycopy.} = object + pid*: U64 + numStatics*: U32 + numDataWords*: U32 + numCopyHandles*: U32 + numMoveHandles*: U32 + statics*: ptr HipcStaticDescriptor + dataWords*: ptr U32 + copyHandles*: ptr Handle + moveHandles*: ptr Handle + + HipcBufferMode* = enum + HipcBufferModeNormal = 0, HipcBufferModeNonSecure = 1, HipcBufferModeInvalid = 2, + HipcBufferModeNonDevice = 3 + + +proc hipcMakeSendStatic*(buffer: pointer; size: csize_t; index: U8): HipcStaticDescriptor {. + inline, cdecl.} = + return HipcStaticDescriptor( + index: index, + address_high: (U32)(cast[uintptr_t](buffer) shr 36), + address_mid: (U32)(cast[uintptr_t](buffer) shr 32), + size: (U32)size, + address_low: cast[U32](buffer), + ) + +proc hipcMakeBuffer*(buffer: pointer; size: csize_t; mode: HipcBufferMode): HipcBufferDescriptor {. + inline, cdecl.} = + return HipcBufferDescriptor( + size_low: (U32)size, + address_low: (U32)cast[uintptr_t](buffer), + mode: mode.U32, + address_high: (U32)(cast[uintptr_t](buffer) shr 36), + size_high: (U32)(size shr 32), + address_mid: (U32)(cast[uintptr_t](buffer) shr 32), + ) + +proc hipcMakeRecvStatic*(buffer: pointer; size: csize_t): HipcRecvListEntry {.inline, cdecl.} = + return HipcRecvListEntry( + address_low: (U32)(cast[uintptr_t](buffer)), + address_high: (U32)(cast[uintptr_t](buffer) shr 32), + size: (U32)size, + ) + +proc hipcGetStaticAddress*(desc: ptr HipcStaticDescriptor): pointer {.inline, cdecl.} = + return cast[pointer]((desc.addressLow or + (cast[uintptrT](desc.addressMid) shl 32) or + (cast[uintptrT](desc.addressHigh) shl 36))) + +proc hipcGetStaticSize*(desc: ptr HipcStaticDescriptor): csize_t {.inline, cdecl.} = + return desc.size + +proc hipcGetBufferAddress*(desc: ptr HipcBufferDescriptor): pointer {.inline, cdecl.} = + return cast[pointer]((desc.addressLow or + (cast[uintptrT](desc.addressMid) shl 32) or + (cast[uintptrT](desc.addressHigh) shl 36))) + +proc hipcGetBufferSize*(desc: ptr HipcBufferDescriptor): csize_t {.inline, cdecl.} = + return desc.sizeLow or (cast[csize_t](desc.sizeHigh) shl 32) + +proc hipcCalcRequestLayout*(meta: HipcMetadata; base: pointer): HipcRequest {.inline, cdecl.} = + var base = base + ## Copy handles + var copyHandles: ptr Handle = nil + if meta.numCopyHandles.bool: + copyHandles = cast[ptr Handle](base) + base = copyHandles + meta.numCopyHandles + var moveHandles: ptr Handle = nil + if meta.numMoveHandles.bool: + moveHandles = cast[ptr Handle](base) + base = moveHandles + meta.numMoveHandles + var sendStatics: ptr HipcStaticDescriptor = nil + if meta.numSendStatics.bool: + sendStatics = cast[ptr HipcStaticDescriptor](base) + base = sendStatics + meta.numSendStatics + var sendBuffers: ptr HipcBufferDescriptor = nil + if meta.numSendBuffers.bool: + sendBuffers = cast[ptr HipcBufferDescriptor](base) + base = sendBuffers + meta.numSendBuffers + var recvBuffers: ptr HipcBufferDescriptor = nil + if meta.numRecvBuffers.bool: + recvBuffers = cast[ptr HipcBufferDescriptor](base) + base = recvBuffers + meta.numRecvBuffers + var exchBuffers: ptr HipcBufferDescriptor = nil + if meta.numExchBuffers.bool: + exchBuffers = cast[ptr HipcBufferDescriptor](base) + base = exchBuffers + meta.numExchBuffers + var dataWords: ptr U32 = nil + if meta.numDataWords.bool: + dataWords = cast[ptr U32](base) + base = dataWords + meta.numDataWords + var recvList: ptr HipcRecvListEntry = nil + if meta.numRecvStatics.bool: + recvList = cast[ptr HipcRecvListEntry](base) + + return HipcRequest( + send_statics: send_statics, + send_buffers: send_buffers, + recv_buffers: recv_buffers, + exch_buffers: exch_buffers, + data_words: data_words, + recv_list: recv_list, + copy_handles: copy_handles, + move_handles: move_handles, + ) + + +proc hipcMakeRequest*(base: pointer; meta: HipcMetadata): HipcRequest {.inline, cdecl.} = + ## Write message header + var base = base + var hasSpecialHeader = (meta.sendPid or meta.numCopyHandles or + meta.numMoveHandles) + var hdr: ptr HipcHeader = cast[ptr HipcHeader](base) + base = hdr + 1 + hdr[] = HipcHeader( + `type`: meta.`type`, + num_send_statics: meta.num_send_statics, + num_send_buffers: meta.num_send_buffers, + num_recv_buffers: meta.num_recv_buffers, + num_exch_buffers: meta.num_exch_buffers, + num_data_words: meta.num_data_words, + recv_static_mode: if meta.num_recv_statics.bool: + if meta.num_recv_statics != HIPC_AUTO_RECV_STATIC: 2'u32 + meta.num_recv_statics + else: 2'u32 + else: 0'u32, + padding: 0, + recv_list_offset: 0, + has_special_header: has_special_header, + ) + ## Write special header + if hasSpecialHeader.bool: + var sphdr: ptr HipcSpecialHeader = cast[ptr HipcSpecialHeader](base) + base = sphdr + 1 + sphdr[] = HipcSpecialHeader( + send_pid : meta.send_pid, + num_copy_handles : meta.num_copy_handles, + num_move_handles : meta.num_move_handles + ) + if meta.sendPid.bool: + base = cast[ptr U8](base) + sizeof((U64)) + return hipcCalcRequestLayout(meta, base) + +#define hipcMakeRequestInline(_base,...) hipcMakeRequest((_base),(HipcMetadata){ __VA_ARGS__ }) +proc hipcMakeRequestInline*(base: pointer, `type`: U32 = 0, numSendStatics: U32 = 0, + numSendBuffers: U32 = 0, numRecvBuffers: U32 = 0, numExchBuffers: U32 = 0, + numDataWords: U32 = 0, numRecvStatics: U32 = 0, sendPid: U32 = 0, + numCopyHandles: U32 = 0, numMoveHandles: U32 = 0): HipcRequest {.inline, cdecl.} = + var base = base + hipcMakeRequest(base, HipcMetadata( + `type`: `type`, + numSendStatics: numSendStatics, + numSendBuffers: numSendBuffers, + numRecvBuffers: numRecvBuffers, + numExchBuffers: numExchBuffers, + numDataWords: numDataWords, + numRecvStatics: numRecvStatics, ## also accepts HIPC_AUTO_RECV_STATIC + sendPid: sendPid, + numCopyHandles: numCopyHandles, + numMoveHandles: numMoveHandles + ) + ) + +## !!!Ignored construct: # ( _base , ... ) hipcMakeRequest ( ( _base ) , ( HipcMetadata ) { __VA_ARGS__ } ) [NewLine] static inline HipcParsedRequest hipcParseRequest ( void * base ) { Parse message header HipcHeader hdr = { } ; __builtin_memcpy ( & hdr , base , sizeof ( hdr ) ) ; base = ( u8 * ) base + sizeof ( hdr ) ; u32 num_recv_statics = 0 ; u64 pid = 0 ; Parse recv static mode if ( hdr . recv_static_mode ) { if ( hdr . recv_static_mode == 2u ) num_recv_statics = HIPC_AUTO_RECV_STATIC ; else if ( hdr . recv_static_mode > 2u ) num_recv_statics = hdr . recv_static_mode - 2u ; } Parse special header HipcSpecialHeader sphdr = { } ; if ( hdr . has_special_header ) { __builtin_memcpy ( & sphdr , base , sizeof ( sphdr ) ) ; base = ( u8 * ) base + sizeof ( sphdr ) ; Read PID descriptor if ( sphdr . send_pid ) { pid = * ( u64 * ) base ; base = ( u8 * ) base + sizeof ( u64 ) ; } } const HipcMetadata meta = { . type = hdr . type , . num_send_statics = hdr . num_send_statics , . num_send_buffers = hdr . num_send_buffers , . num_recv_buffers = hdr . num_recv_buffers , . num_exch_buffers = hdr . num_exch_buffers , . num_data_words = hdr . num_data_words , . num_recv_statics = num_recv_statics , . send_pid = sphdr . send_pid , . num_copy_handles = sphdr . num_copy_handles , . num_move_handles = sphdr . num_move_handles , } ; return ( HipcParsedRequest ) { . meta = meta , . data = hipcCalcRequestLayout ( meta , base ) , . pid = pid , } ; } static inline HipcResponse hipcParseResponse ( void * base ) { Parse header HipcHeader hdr = { } ; __builtin_memcpy ( & hdr , base , sizeof ( hdr ) ) ; base = ( u8 * ) base + sizeof ( hdr ) ; Initialize response HipcResponse response = { } ; response . num_statics = hdr . num_send_statics ; response . num_data_words = hdr . num_data_words ; response . pid = HIPC_RESPONSE_NO_PID ; Parse special header if ( hdr . has_special_header ) { HipcSpecialHeader sphdr = { } ; __builtin_memcpy ( & sphdr , base , sizeof ( sphdr ) ) ; base = ( u8 * ) base + sizeof ( sphdr ) ; Update response response . num_copy_handles = sphdr . num_copy_handles ; response . num_move_handles = sphdr . num_move_handles ; Parse PID descriptor if ( sphdr . send_pid ) { response . pid = * ( u64 * ) base ; base = ( u8 * ) base + sizeof ( u64 ) ; } } Copy handles response . copy_handles = ( Handle * ) base ; base = response . copy_handles + response . num_copy_handles ; Move handles response . move_handles = ( Handle * ) base ; base = response . move_handles + response . num_move_handles ; Send statics response . statics = ( HipcStaticDescriptor * ) base ; base = response . statics + response . num_statics ; Data words response . data_words = ( u32 * ) base ; return response ; } +## Error: identifier expected, but got: (!!! + +proc hipcParseRequest*(base: pointer): HipcParsedRequest {.inline, cdecl.} = + ## Parse message header + # {.emit: " // Parse message header".} + # {.emit: " HipcHeader hdr = {};".} + # {.emit: " __builtin_memcpy(&hdr, `base`, sizeof(hdr));".} + # {.emit: " `base` = (u8*)`base` + sizeof(hdr);".} + # {.emit: " u32 num_recv_statics = 0;".} + # {.emit: " u64 pid = 0;".} + # {.emit: " // Parse recv static mode".} + # {.emit: " if (hdr.recv_static_mode) {".} + # {.emit: " if (hdr.recv_static_mode == 2u)".} + # {.emit: " num_recv_statics = HIPC_AUTO_RECV_STATIC;".} + # {.emit: " else if (hdr.recv_static_mode > 2u)".} + # {.emit: " num_recv_statics = hdr.recv_static_mode - 2u;".} + # {.emit: " }".} + # {.emit: " // Parse special header".} + # {.emit: " HipcSpecialHeader sphdr = {};".} + # {.emit: " if (hdr.has_special_header) {".} + # {.emit: " __builtin_memcpy(&sphdr, `base`, sizeof(sphdr));".} + # {.emit: " `base` = (u8*)`base` + sizeof(sphdr);".} + # {.emit: " if (sphdr.send_pid) {".} + # {.emit: " pid = *(u64*)`base`;".} + # {.emit: " `base` = (u8*)`base` + sizeof(u64);".} + # {.emit: " }".} + # {.emit: " }".} + # {.emit: " const HipcMetadata meta = {".} + # {.emit: " .type = hdr.type,".} + # {.emit: " .num_send_statics = hdr.num_send_statics,".} + # {.emit: " .num_send_buffers = hdr.num_send_buffers,".} + # {.emit: " .num_recv_buffers = hdr.num_recv_buffers,".} + # {.emit: " .num_exch_buffers = hdr.num_exch_buffers,".} + # {.emit: " .num_data_words = hdr.num_data_words,".} + # {.emit: " .num_recv_statics = num_recv_statics,".} + # {.emit: " .send_pid = sphdr.send_pid,".} + # {.emit: " .num_copy_handles = sphdr.num_copy_handles,".} + # {.emit: " .num_move_handles = sphdr.num_move_handles,".} + # {.emit: " };".} + # {.emit: " `result` = (HipcParsedRequest){".} + # {.emit: " .meta = meta,".} + # {.emit: " .data = hipcCalcRequestLayout(meta, `base`),".} + # {.emit: " .pid = pid,".} + # {.emit: " };".} + var base = base + var hdr: HipcHeader = HipcHeader() + copyMem(addr(hdr), base, sizeof((hdr))) + base = cast[ptr U8](base) + sizeof((hdr)) + var numRecvStatics: U32 = 0 + var pid: U64 = 0 + ## Parse recv static mode + if hdr.recvStaticMode.bool: + if hdr.recvStaticMode == 2'u: + numRecvStatics = Hipc_Auto_Recv_Static + elif hdr.recvStaticMode > 2'u: + numRecvStatics = hdr.recvStaticMode - 2'u32 + var sphdr: HipcSpecialHeader = HipcSpecialHeader() + if hdr.hasSpecialHeader.bool: + copyMem(addr(sphdr), base, sizeof((sphdr))) + base = cast[ptr U8](base) + sizeof((sphdr)) + ## Read PID descriptor + if sphdr.sendPid.bool: + pid = cast[ptr U64](base)[] + base = cast[ptr U8](base) + sizeof((U64)) + let meta: HipcMetadata = HipcMetadata(`type`: hdr.`type`, + numSendStatics: hdr.numSendStatics, + numSendBuffers: hdr.numSendBuffers, + numRecvBuffers: hdr.numRecvBuffers, + numExchBuffers: hdr.numExchBuffers, + numDataWords: hdr.numDataWords, + numRecvStatics: numRecvStatics, + sendPid: sphdr.sendPid, + numCopyHandles: sphdr.numCopyHandles, + numMoveHandles: sphdr.numMoveHandles) + return HipcParsedRequest( + meta: meta, + data: hipcCalcRequestLayout(meta, base), + pid: pid + ) + +proc hipcParseResponse*(base: pointer): HipcResponse {.inline, cdecl.} = + ## Parse header + var base = base + var hdr: HipcHeader = HipcHeader() + copyMem(addr(hdr), base, sizeof((hdr))) + base = cast[ptr U8](base) + sizeof((hdr)) + ## Initialize response + var response: HipcResponse = HipcResponse() + response.numStatics = hdr.numSendStatics + response.numDataWords = hdr.numDataWords + response.pid = Hipc_Response_No_Pid + ## Parse special header + if hdr.hasSpecialHeader.bool: + var sphdr: HipcSpecialHeader = HipcSpecialHeader() + copyMem(addr(sphdr), base, sizeof((sphdr))) + base = cast[ptr U8](base) + sizeof((sphdr)) + ## Update response + response.numCopyHandles = sphdr.numCopyHandles + response.numMoveHandles = sphdr.numMoveHandles + ## Parse PID descriptor + if sphdr.sendPid.bool: + response.pid = cast[ptr U64](base)[] + base = cast[ptr U8](base) + sizeof((U64)) + response.copyHandles = cast[ptr Handle](base) + base = response.copyHandles + response.numCopyHandles + ## Move handles + response.moveHandles = cast[ptr Handle](base) + base = response.moveHandles + response.numMoveHandles + ## Send statics + response.statics = cast[ptr HipcStaticDescriptor](base) + base = response.statics + response.numStatics + ## Data words + response.dataWords = cast[ptr U32](base) + return response + diff --git a/src/libnx/wrapper/switch/sf/hipc2.h b/src/libnx/wrapper/switch/sf/hipc2.h new file mode 100644 index 0000000..529d41a --- /dev/null +++ b/src/libnx/wrapper/switch/sf/hipc2.h @@ -0,0 +1,362 @@ +/** + * @file hipc.h + * @brief Horizon Inter-Process Communication protocol + * @author fincs + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "../result.h" +#include "../arm/tls.h" +#include "../kernel/svc.h" + +#define HIPC_AUTO_RECV_STATIC UINT8_MAX +#define HIPC_RESPONSE_NO_PID UINT32_MAX + +typedef struct HipcMetadata { + u32 type; + u32 num_send_statics; + u32 num_send_buffers; + u32 num_recv_buffers; + u32 num_exch_buffers; + u32 num_data_words; + u32 num_recv_statics; // also accepts HIPC_AUTO_RECV_STATIC + u32 send_pid; + u32 num_copy_handles; + u32 num_move_handles; +} HipcMetadata; + +typedef struct HipcHeader { + u32 type : 16; + u32 num_send_statics : 4; + u32 num_send_buffers : 4; + u32 num_recv_buffers : 4; + u32 num_exch_buffers : 4; + u32 num_data_words : 10; + u32 recv_static_mode : 4; + u32 padding : 6; + u32 recv_list_offset : 11; // Unused. + u32 has_special_header : 1; +} HipcHeader; + +typedef struct HipcSpecialHeader { + u32 send_pid : 1; + u32 num_copy_handles : 4; + u32 num_move_handles : 4; + u32 padding : 23; +} HipcSpecialHeader; + +typedef struct HipcStaticDescriptor { + u32 index : 6; + u32 address_high : 6; + u32 address_mid : 4; + u32 size : 16; + u32 address_low; +} HipcStaticDescriptor; + +typedef struct HipcBufferDescriptor { + u32 size_low; + u32 address_low; + u32 mode : 2; + u32 address_high : 22; + u32 size_high : 4; + u32 address_mid : 4; +} HipcBufferDescriptor; + +typedef struct HipcRecvListEntry { + u32 address_low; + u32 address_high : 16; + u32 size : 16; +} HipcRecvListEntry; + +typedef struct HipcRequest { + HipcStaticDescriptor* send_statics; + HipcBufferDescriptor* send_buffers; + HipcBufferDescriptor* recv_buffers; + HipcBufferDescriptor* exch_buffers; + u32* data_words; + HipcRecvListEntry* recv_list; + Handle* copy_handles; + Handle* move_handles; +} HipcRequest; + +typedef struct HipcParsedRequest { + HipcMetadata meta; + HipcRequest data; + u64 pid; +} HipcParsedRequest; + +typedef struct HipcResponse { + u64 pid; + u32 num_statics; + u32 num_data_words; + u32 num_copy_handles; + u32 num_move_handles; + HipcStaticDescriptor* statics; + u32* data_words; + Handle* copy_handles; + Handle* move_handles; +} HipcResponse; + +typedef enum HipcBufferMode { + HipcBufferMode_Normal = 0, + HipcBufferMode_NonSecure = 1, + HipcBufferMode_Invalid = 2, + HipcBufferMode_NonDevice = 3, +} HipcBufferMode; + +NX_CONSTEXPR HipcStaticDescriptor hipcMakeSendStatic(const void* buffer, size_t size, u8 index) +{ + return (HipcStaticDescriptor){ + .index = index, + .address_high = (u32)((uintptr_t)buffer >> 36), + .address_mid = (u32)((uintptr_t)buffer >> 32), + .size = (u32)size, + .address_low = (u32)(uintptr_t)buffer, + }; +} + +NX_CONSTEXPR HipcBufferDescriptor hipcMakeBuffer(const void* buffer, size_t size, HipcBufferMode mode) +{ + return (HipcBufferDescriptor){ + .size_low = (u32)size, + .address_low = (u32)(uintptr_t)buffer, + .mode = mode, + .address_high = (u32)((uintptr_t)buffer >> 36), + .size_high = (u32)(size >> 32), + .address_mid = (u32)((uintptr_t)buffer >> 32), + }; +} + +NX_CONSTEXPR HipcRecvListEntry hipcMakeRecvStatic(void* buffer, size_t size) +{ + return (HipcRecvListEntry){ + .address_low = (u32)((uintptr_t)buffer), + .address_high = (u32)((uintptr_t)buffer >> 32), + .size = (u32)size, + }; +} + +NX_CONSTEXPR void* hipcGetStaticAddress(const HipcStaticDescriptor* desc) +{ + return (void*)(desc->address_low | ((uintptr_t)desc->address_mid << 32) | ((uintptr_t)desc->address_high << 36)); +} + +NX_CONSTEXPR size_t hipcGetStaticSize(const HipcStaticDescriptor* desc) +{ + return desc->size; +} + +NX_CONSTEXPR void* hipcGetBufferAddress(const HipcBufferDescriptor* desc) +{ + return (void*)(desc->address_low | ((uintptr_t)desc->address_mid << 32) | ((uintptr_t)desc->address_high << 36)); +} + +NX_CONSTEXPR size_t hipcGetBufferSize(const HipcBufferDescriptor* desc) +{ + return desc->size_low | ((size_t)desc->size_high << 32); +} + +NX_CONSTEXPR HipcRequest hipcCalcRequestLayout(HipcMetadata meta, void* base) +{ + // Copy handles + Handle* copy_handles = NULL; + if (meta.num_copy_handles) { + copy_handles = (Handle*)base; + base = copy_handles + meta.num_copy_handles; + } + + // Move handles + Handle* move_handles = NULL; + if (meta.num_move_handles) { + move_handles = (Handle*)base; + base = move_handles + meta.num_move_handles; + } + + // Send statics + HipcStaticDescriptor* send_statics = NULL; + if (meta.num_send_statics) { + send_statics = (HipcStaticDescriptor*)base; + base = send_statics + meta.num_send_statics; + } + + // Send buffers + HipcBufferDescriptor* send_buffers = NULL; + if (meta.num_send_buffers) { + send_buffers = (HipcBufferDescriptor*)base; + base = send_buffers + meta.num_send_buffers; + } + + // Recv buffers + HipcBufferDescriptor* recv_buffers = NULL; + if (meta.num_recv_buffers) { + recv_buffers = (HipcBufferDescriptor*)base; + base = recv_buffers + meta.num_recv_buffers; + } + + // Exch buffers + HipcBufferDescriptor* exch_buffers = NULL; + if (meta.num_exch_buffers) { + exch_buffers = (HipcBufferDescriptor*)base; + base = exch_buffers + meta.num_exch_buffers; + } + + // Data words + u32* data_words = NULL; + if (meta.num_data_words) { + data_words = (u32*)base; + base = data_words + meta.num_data_words; + } + + // Recv list + HipcRecvListEntry* recv_list = NULL; + if (meta.num_recv_statics) + recv_list = (HipcRecvListEntry*)base; + + return (HipcRequest){ + .send_statics = send_statics, + .send_buffers = send_buffers, + .recv_buffers = recv_buffers, + .exch_buffers = exch_buffers, + .data_words = data_words, + .recv_list = recv_list, + .copy_handles = copy_handles, + .move_handles = move_handles, + }; +} + +NX_CONSTEXPR HipcRequest hipcMakeRequest(void* base, HipcMetadata meta) +{ + // Write message header + bool has_special_header = meta.send_pid || meta.num_copy_handles || meta.num_move_handles; + HipcHeader* hdr = (HipcHeader*)base; + base = hdr+1; + *hdr = (HipcHeader){ + .type = meta.type, + .num_send_statics = meta.num_send_statics, + .num_send_buffers = meta.num_send_buffers, + .num_recv_buffers = meta.num_recv_buffers, + .num_exch_buffers = meta.num_exch_buffers, + .num_data_words = meta.num_data_words, + .recv_static_mode = meta.num_recv_statics ? (meta.num_recv_statics != HIPC_AUTO_RECV_STATIC ? 2u + meta.num_recv_statics : 2u) : 0u, + .padding = 0, + .recv_list_offset = 0, + .has_special_header = has_special_header, + }; + + // Write special header + if (has_special_header) { + HipcSpecialHeader* sphdr = (HipcSpecialHeader*)base; + base = sphdr+1; + *sphdr = (HipcSpecialHeader){ + .send_pid = meta.send_pid, + .num_copy_handles = meta.num_copy_handles, + .num_move_handles = meta.num_move_handles, + }; + if (meta.send_pid) + base = (u8*)base + sizeof(u64); + } + + // Calculate layout + return hipcCalcRequestLayout(meta, base); +} + + +NX_CONSTEXPR HipcParsedRequest hipcParseRequest(void* base) +{ + // Parse message header + HipcHeader hdr = {}; + __builtin_memcpy(&hdr, base, sizeof(hdr)); + base = (u8*)base + sizeof(hdr); + u32 num_recv_statics = 0; + u64 pid = 0; + + // Parse recv static mode + if (hdr.recv_static_mode) { + if (hdr.recv_static_mode == 2u) + num_recv_statics = HIPC_AUTO_RECV_STATIC; + else if (hdr.recv_static_mode > 2u) + num_recv_statics = hdr.recv_static_mode - 2u; + } + + // Parse special header + HipcSpecialHeader sphdr = {}; + if (hdr.has_special_header) { + __builtin_memcpy(&sphdr, base, sizeof(sphdr)); + base = (u8*)base + sizeof(sphdr); + + // Read PID descriptor + if (sphdr.send_pid) { + pid = *(u64*)base; + base = (u8*)base + sizeof(u64); + } + } + + const HipcMetadata meta = { + .type = hdr.type, + .num_send_statics = hdr.num_send_statics, + .num_send_buffers = hdr.num_send_buffers, + .num_recv_buffers = hdr.num_recv_buffers, + .num_exch_buffers = hdr.num_exch_buffers, + .num_data_words = hdr.num_data_words, + .num_recv_statics = num_recv_statics, + .send_pid = sphdr.send_pid, + .num_copy_handles = sphdr.num_copy_handles, + .num_move_handles = sphdr.num_move_handles, + }; + + return (HipcParsedRequest){ + .meta = meta, + .data = hipcCalcRequestLayout(meta, base), + .pid = pid, + }; +} + +NX_CONSTEXPR HipcResponse hipcParseResponse(void* base) +{ + // Parse header + HipcHeader hdr = {}; + __builtin_memcpy(&hdr, base, sizeof(hdr)); + base = (u8*)base + sizeof(hdr); + + // Initialize response + HipcResponse response = {}; + response.num_statics = hdr.num_send_statics; + response.num_data_words = hdr.num_data_words; + response.pid = HIPC_RESPONSE_NO_PID; + + // Parse special header + if (hdr.has_special_header) + { + HipcSpecialHeader sphdr = {}; + __builtin_memcpy(&sphdr, base, sizeof(sphdr)); + base = (u8*)base + sizeof(sphdr); + + // Update response + response.num_copy_handles = sphdr.num_copy_handles; + response.num_move_handles = sphdr.num_move_handles; + + // Parse PID descriptor + if (sphdr.send_pid) { + response.pid = *(u64*)base; + base = (u8*)base + sizeof(u64); + } + } + + // Copy handles + response.copy_handles = (Handle*)base; + base = response.copy_handles + response.num_copy_handles; + + // Move handles + response.move_handles = (Handle*)base; + base = response.move_handles + response.num_move_handles; + + // Send statics + response.statics = (HipcStaticDescriptor*)base; + base = response.statics + response.num_statics; + + // Data words + response.data_words = (u32*)base; + + return response; +} diff --git a/src/libnx/wrapper/switch/sf/hipc2.nim b/src/libnx/wrapper/switch/sf/hipc2.nim new file mode 100644 index 0000000..135d84b --- /dev/null +++ b/src/libnx/wrapper/switch/sf/hipc2.nim @@ -0,0 +1,293 @@ +## * +## @file hipc.h +## @brief Horizon Inter-Process Communication protocol +## @author fincs +## @author SciresM +## @copyright libnx Authors +## + +import + ../result, ../arm/tls + +const + HIPC_AUTO_RECV_STATIC* = uint8.high + HIPC_RESPONSE_NO_PID* = uint32.high + +type + HipcMetadata* {.bycopy.} = object + `type`*: U32 + numSendStatics*: U32 + numSendBuffers*: U32 + numRecvBuffers*: U32 + numExchBuffers*: U32 + numDataWords*: U32 + numRecvStatics*: U32 ## also accepts HIPC_AUTO_RECV_STATIC + sendPid*: U32 + numCopyHandles*: U32 + numMoveHandles*: U32 + + HipcHeader* {.bycopy.} = object + `type`* {.bitsize: 16.}: U32 + numSendStatics* {.bitsize: 4.}: U32 + numSendBuffers* {.bitsize: 4.}: U32 + numRecvBuffers* {.bitsize: 4.}: U32 + numExchBuffers* {.bitsize: 4.}: U32 + numDataWords* {.bitsize: 10.}: U32 + recvStaticMode* {.bitsize: 4.}: U32 + padding* {.bitsize: 6.}: U32 + recvListOffset* {.bitsize: 11.}: U32 ## Unused. + hasSpecialHeader* {.bitsize: 1.}: U32 + + HipcSpecialHeader* {.bycopy.} = object + sendPid* {.bitsize: 1.}: U32 + numCopyHandles* {.bitsize: 4.}: U32 + numMoveHandles* {.bitsize: 4.}: U32 + padding* {.bitsize: 23.}: U32 + + HipcStaticDescriptor* {.bycopy.} = object + index* {.bitsize: 6.}: U32 + addressHigh* {.bitsize: 6.}: U32 + addressMid* {.bitsize: 4.}: U32 + size* {.bitsize: 16.}: U32 + addressLow*: U32 + + HipcBufferDescriptor* {.bycopy.} = object + sizeLow*: U32 + addressLow*: U32 + mode* {.bitsize: 2.}: U32 + addressHigh* {.bitsize: 22.}: U32 + sizeHigh* {.bitsize: 4.}: U32 + addressMid* {.bitsize: 4.}: U32 + + HipcRecvListEntry* {.bycopy.} = object + addressLow*: U32 + addressHigh* {.bitsize: 16.}: U32 + size* {.bitsize: 16.}: U32 + + HipcRequest* {.bycopy.} = object + sendStatics*: ptr HipcStaticDescriptor + sendBuffers*: ptr HipcBufferDescriptor + recvBuffers*: ptr HipcBufferDescriptor + exchBuffers*: ptr HipcBufferDescriptor + dataWords*: ptr U32 + recvList*: ptr HipcRecvListEntry + copyHandles*: ptr Handle + moveHandles*: ptr Handle + + HipcParsedRequest* {.bycopy.} = object + meta*: HipcMetadata + data*: HipcRequest + pid*: U64 + + HipcResponse* {.bycopy.} = object + pid*: U64 + numStatics*: U32 + numDataWords*: U32 + numCopyHandles*: U32 + numMoveHandles*: U32 + statics*: ptr HipcStaticDescriptor + dataWords*: ptr U32 + copyHandles*: ptr Handle + moveHandles*: ptr Handle + + HipcBufferMode* = enum + HipcBufferModeNormal = 0, HipcBufferModeNonSecure = 1, HipcBufferModeInvalid = 2, + HipcBufferModeNonDevice = 3 + + +proc hipcMakeSendStatic*(buffer: pointer; size: csize_t; index: U8): HipcStaticDescriptor {. + inline, cdecl.} = + return HipcStaticDescriptor( + index : index, + address_high : (U32)(cast[uintptr_t](buffer) shr 36), + address_mid : (U32)(cast[uintptr_t](buffer) shr 32), + size : (U32)size, + address_low : (U32)cast[uintptr_t](buffer) + ) + +proc hipcMakeBuffer*(buffer: pointer; size: csize_t; mode: HipcBufferMode): HipcBufferDescriptor {. + inline, cdecl.} = + return HipcBufferDescriptor( + size_low : (U32)size, + address_low : (U32)cast[uintptr_t](buffer), + mode : mode.U32, + address_high : (U32)(cast[uintptr_t](buffer) shr 36), + size_high : (U32)(size shr 32), + address_mid : (U32)(cast[uintptr_t](buffer) shr 32), + ) + +proc hipcMakeRecvStatic*(buffer: pointer; size: csize_t): HipcRecvListEntry {.inline, cdecl.} = + return HipcRecvListEntry( + address_low : (U32)(cast[uintptr_t](buffer)), + address_high : (U32)(cast[uintptr_t](buffer) shr 32), + size : (U32)size, + ) + +proc hipcGetStaticAddress*(desc: ptr HipcStaticDescriptor): pointer {.inline, cdecl.} = + return cast[pointer]((desc.addressLow or + (cast[uintptrT](desc.addressMid) shl 32) or + (cast[uintptrT](desc.addressHigh) shl 36))) + +proc hipcGetStaticSize*(desc: ptr HipcStaticDescriptor): csize_t {.inline, cdecl.} = + return desc.size + +proc hipcGetBufferAddress*(desc: ptr HipcBufferDescriptor): pointer {.inline, cdecl.} = + return cast[pointer]((desc.addressLow or + (cast[uintptrT](desc.addressMid) shl 32) or + (cast[uintptrT](desc.addressHigh) shl 36))) + +proc hipcGetBufferSize*(desc: ptr HipcBufferDescriptor): csize_t {.inline, cdecl.} = + return desc.sizeLow or (cast[csize_t](desc.sizeHigh) shl 32) + +proc hipcCalcRequestLayout*(meta: HipcMetadata; base: pointer): HipcRequest {.inline, cdecl.} = + ## Copy handles + var base = base + var copyHandles: ptr Handle = nil + if meta.numCopyHandles.bool: + copyHandles = cast[ptr Handle](base) + base = copyHandles + meta.numCopyHandles + var moveHandles: ptr Handle = nil + if meta.numMoveHandles.bool: + moveHandles = cast[ptr Handle](base) + base = moveHandles + meta.numMoveHandles + var sendStatics: ptr HipcStaticDescriptor = nil + if meta.numSendStatics.bool: + sendStatics = cast[ptr HipcStaticDescriptor](base) + base = sendStatics + meta.numSendStatics + var sendBuffers: ptr HipcBufferDescriptor = nil + if meta.numSendBuffers.bool: + sendBuffers = cast[ptr HipcBufferDescriptor](base) + base = sendBuffers + meta.numSendBuffers + var recvBuffers: ptr HipcBufferDescriptor = nil + if meta.numRecvBuffers.bool: + recvBuffers = cast[ptr HipcBufferDescriptor](base) + base = recvBuffers + meta.numRecvBuffers + var exchBuffers: ptr HipcBufferDescriptor = nil + if meta.numExchBuffers.bool: + exchBuffers = cast[ptr HipcBufferDescriptor](base) + base = exchBuffers + meta.numExchBuffers + var dataWords: ptr U32 = nil + if meta.numDataWords.bool: + dataWords = cast[ptr U32](base) + base = dataWords + meta.numDataWords + var recvList: ptr HipcRecvListEntry = nil + if meta.numRecvStatics.bool: + recvList = cast[ptr HipcRecvListEntry](base) + return HipcRequest( + send_statics: send_statics, + send_buffers: send_buffers, + recv_buffers: recv_buffers, + exch_buffers: exch_buffers, + data_words: data_words, + recv_list: recv_list, + copy_handles: copy_handles, + move_handles: move_handles, + ) + +proc hipcMakeRequest*(base: pointer; meta: HipcMetadata): HipcRequest {.inline, cdecl.} = + ## Write message header + var base = base + var hasSpecialHeader: bool = (meta.sendPid or meta.numCopyHandles or meta.numMoveHandles).bool + var hdr: ptr HipcHeader = cast[ptr HipcHeader](base) + base = hdr + 1 + hdr[] = HipcHeader( + type: meta.type, + num_send_statics: meta.num_send_statics, + num_send_buffers: meta.num_send_buffers, + num_recv_buffers: meta.num_recv_buffers, + num_exch_buffers: meta.num_exch_buffers, + num_data_words: meta.num_data_words, + recv_static_mode: if meta.num_recv_statics.bool: + if meta.num_recv_statics != HIPC_AUTO_RECV_STATIC: + 2'U32 + meta.num_recv_statics.U32 + else: 2.U32 + else: 0.U32, + padding: 0, + recv_list_offset: 0, + has_special_header: has_special_header.U32, + ) + ## Write special header + if hasSpecialHeader: + var sphdr: ptr HipcSpecialHeader = cast[ptr HipcSpecialHeader](base) + base = sphdr + 1 + sphdr[] = HipcSpecialHeader( + send_pid: meta.send_pid, + num_copy_handles: meta.num_copy_handles, + num_move_handles: meta.num_move_handles, + ) + if meta.sendPid.bool: + base = cast[ptr U8](base) + sizeof((U64)) + return hipcCalcRequestLayout(meta, base) + +proc hipcParseRequest*(base: pointer): HipcParsedRequest {.inline, cdecl.} = + ## Parse message header + var hdr: HipcHeader = HipcHeader() + var base = base + copyMem(addr(hdr), base, sizeof((hdr))) + base = cast[ptr U8](base) + sizeof((hdr)) + var numRecvStatics: U32 = 0 + var pid: U64 = 0 + ## Parse recv static mode + if hdr.recvStaticMode.bool: + if hdr.recvStaticMode == 2'u: + numRecvStatics = Hipc_Auto_Recv_Static + elif hdr.recvStaticMode > 2'u: + numRecvStatics = hdr.recvStaticMode - 2.U32 + var sphdr: HipcSpecialHeader = HipcSpecialHeader() + if hdr.hasSpecialHeader.bool: + copyMem(addr(sphdr), base, sizeof((sphdr))) + base = cast[ptr U8](base) + sizeof((sphdr)) + ## Read PID descriptor + if sphdr.sendPid.bool: + pid = cast[ptr U64](base)[] + base = cast[ptr U8](base) + sizeof((U64)) + let meta: HipcMetadata = HipcMetadata(`type`: hdr.`type`, + numSendStatics: hdr.numSendStatics, + numSendBuffers: hdr.numSendBuffers, + numRecvBuffers: hdr.numRecvBuffers, + numExchBuffers: hdr.numExchBuffers, + numDataWords: hdr.numDataWords, + numRecvStatics: numRecvStatics, + sendPid: sphdr.sendPid, + numCopyHandles: sphdr.numCopyHandles, + numMoveHandles: sphdr.numMoveHandles) + return HipcParsedRequest( + meta: meta, + data: hipcCalcRequestLayout(meta, base), + pid: pid, + ) + +proc hipcParseResponse*(base: pointer): HipcResponse {.inline, cdecl.} = + ## Parse header + var hdr: HipcHeader = HipcHeader() + copyMem(addr(hdr), base, sizeof((hdr))) + var base = base + base = cast[ptr U8](base) + sizeof((hdr)) + ## Initialize response + var response: HipcResponse = HipcResponse() + response.numStatics = hdr.numSendStatics + response.numDataWords = hdr.numDataWords + response.pid = Hipc_Response_No_Pid + ## Parse special header + if hdr.hasSpecialHeader.bool: + var sphdr: HipcSpecialHeader = HipcSpecialHeader() + copyMem(addr(sphdr), base, sizeof((sphdr))) + base = cast[ptr U8](base) + sizeof((sphdr)) + ## Update response + response.numCopyHandles = sphdr.numCopyHandles + response.numMoveHandles = sphdr.numMoveHandles + ## Parse PID descriptor + if sphdr.sendPid.bool: + response.pid = cast[ptr U64](base)[] + base = cast[ptr U8](base) + sizeof((U64)) + response.copyHandles = cast[ptr Handle](base) + base = response.copyHandles + response.numCopyHandles + ## Move handles + response.moveHandles = cast[ptr Handle](base) + base = response.moveHandles + response.numMoveHandles + ## Send statics + response.statics = cast[ptr HipcStaticDescriptor](base) + base = response.statics + response.numStatics + ## Data words + response.dataWords = cast[ptr U32](base) + return response diff --git a/src/libnx/wrapper/switch/sf/service b/src/libnx/wrapper/switch/sf/service new file mode 100755 index 0000000..2d97ab3 Binary files /dev/null and b/src/libnx/wrapper/switch/sf/service differ diff --git a/src/libnx/wrapper/switch/sf/service.h b/src/libnx/wrapper/switch/sf/service.h new file mode 100644 index 0000000..971468f --- /dev/null +++ b/src/libnx/wrapper/switch/sf/service.h @@ -0,0 +1,486 @@ +/** + * @file service.h + * @brief Service wrapper object + * @author fincs + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "hipc.h" +#include "cmif.h" + +/// Service object structure +typedef struct Service { + Handle session; + u32 own_handle; + u32 object_id; + u16 pointer_buffer_size; +} Service; + +enum { + SfBufferAttr_In = BIT(0), + SfBufferAttr_Out = BIT(1), + SfBufferAttr_HipcMapAlias = BIT(2), + SfBufferAttr_HipcPointer = BIT(3), + SfBufferAttr_FixedSize = BIT(4), + SfBufferAttr_HipcAutoSelect = BIT(5), + SfBufferAttr_HipcMapTransferAllowsNonSecure = BIT(6), + SfBufferAttr_HipcMapTransferAllowsNonDevice = BIT(7), +}; + +typedef struct SfBufferAttrs { + u32 attr0; + u32 attr1; + u32 attr2; + u32 attr3; + u32 attr4; + u32 attr5; + u32 attr6; + u32 attr7; +} SfBufferAttrs; + +typedef struct SfBuffer { + const void* ptr; + size_t size; +} SfBuffer; + +typedef enum SfOutHandleAttr { + SfOutHandleAttr_None = 0, + SfOutHandleAttr_HipcCopy = 1, + SfOutHandleAttr_HipcMove = 2, +} SfOutHandleAttr; + +typedef struct SfOutHandleAttrs { + SfOutHandleAttr attr0; + SfOutHandleAttr attr1; + SfOutHandleAttr attr2; + SfOutHandleAttr attr3; + SfOutHandleAttr attr4; + SfOutHandleAttr attr5; + SfOutHandleAttr attr6; + SfOutHandleAttr attr7; +} SfOutHandleAttrs; + +typedef struct SfDispatchParams { + Handle target_session; + u32 context; + + SfBufferAttrs buffer_attrs; + SfBuffer buffers[8]; + + bool in_send_pid; + + u32 in_num_objects; + const Service* in_objects[8]; + + u32 in_num_handles; + Handle in_handles[8]; + + u32 out_num_objects; + Service* out_objects; + + SfOutHandleAttrs out_handle_attrs; + Handle* out_handles; +} SfDispatchParams; + +/** + * @brief Returns whether a service has been initialized. + * @param[in] s Service object. + * @return true if initialized. + */ +NX_CONSTEXPR bool serviceIsActive(Service* s) { + return s->session != INVALID_HANDLE; +} + +/** + * @brief Returns whether a service is overriden in the homebrew environment. + * @param[in] s Service object. + * @return true if overriden. + */ +NX_CONSTEXPR bool serviceIsOverride(Service* s) { + return serviceIsActive(s) && !s->own_handle && !s->object_id; +} + +/** + * @brief Returns whether a service is a domain. + * @param[in] s Service object. + * @return true if a domain. + */ +NX_CONSTEXPR bool serviceIsDomain(Service* s) { + return serviceIsActive(s) && s->own_handle && s->object_id; +} + +/** + * @brief Returns whether a service is a domain subservice. + * @param[in] s Service object. + * @return true if a domain subservice. + */ +NX_CONSTEXPR bool serviceIsDomainSubservice(Service* s) { + return serviceIsActive(s) && !s->own_handle && s->object_id; +} + +/** + * @brief For a domain/domain subservice, return the associated object ID. + * @param[in] s Service object, necessarily a domain or domain subservice. + * @return The object ID. + */ +NX_CONSTEXPR u32 serviceGetObjectId(Service* s) { + return s->object_id; +} + +/** + * @brief Creates a service object from an IPC session handle. + * @param[out] s Service object. + * @param[in] h IPC session handle. + */ +NX_INLINE void serviceCreate(Service* s, Handle h) +{ + s->session = h; + s->own_handle = 1; + s->object_id = 0; + s->pointer_buffer_size = 0; + cmifQueryPointerBufferSize(h, &s->pointer_buffer_size); +} + +/** + * @brief Creates a non-domain subservice object from a parent service. + * @param[out] s Service object. + * @param[in] parent Parent service. + * @param[in] h IPC session handle for this subservice. + */ +NX_INLINE void serviceCreateNonDomainSubservice(Service* s, Service* parent, Handle h) +{ + if (h != INVALID_HANDLE) { + s->session = h; + s->own_handle = 1; + s->object_id = 0; + s->pointer_buffer_size = parent->pointer_buffer_size; + } else { + *s = (Service){}; + } +} + +/** + * @brief Creates a domain subservice object from a parent service. + * @param[out] s Service object. + * @param[in] parent Parent service, necessarily a domain or domain subservice. + * @param[in] object_id Object ID for this subservice. + */ +NX_CONSTEXPR void serviceCreateDomainSubservice(Service* s, Service* parent, u32 object_id) +{ + if (object_id != 0) { + s->session = parent->session; + s->own_handle = 0; + s->object_id = object_id; + s->pointer_buffer_size = parent->pointer_buffer_size; + } else { + *s = (Service){}; + } +} + +/** + * @brief Hints the compiler that a service will always contain a domain object. + * @param[in] _s Service object. + */ +#define serviceAssumeDomain(_s) do { \ + if (!(_s)->object_id) \ + __builtin_unreachable(); \ +} while(0) + +/** + * @brief Closes a service. + * @param[in] s Service object. + */ +NX_INLINE void serviceClose(Service* s) +{ +#if defined(NX_SERVICE_ASSUME_NON_DOMAIN) + if (s->object_id) + __builtin_unreachable(); +#endif + + if (s->own_handle || s->object_id) { + cmifMakeCloseRequest(armGetTls(), s->own_handle ? 0 : s->object_id); + svcSendSyncRequest(s->session); + if (s->own_handle) + svcCloseHandle(s->session); + } + *s = (Service){}; +} + +/** + * @brief Clones a service. + * @param[in] s Service object. + * @param[out] out_s Output service object. + */ +NX_INLINE Result serviceClone(Service* s, Service* out_s) +{ +#if defined(NX_SERVICE_ASSUME_NON_DOMAIN) + if (s->object_id) + __builtin_unreachable(); +#endif + + out_s->session = 0; + out_s->own_handle = 1; + out_s->object_id = s->object_id; + out_s->pointer_buffer_size = s->pointer_buffer_size; + return cmifCloneCurrentObject(s->session, &out_s->session); +} + +/** + * @brief Clones a service with a session manager tag. + * @param[in] s Service object. + * @param[in] tag Session manager tag (unused in current official server code) + * @param[out] out_s Output service object. + */ +NX_INLINE Result serviceCloneEx(Service* s, u32 tag, Service* out_s) +{ +#if defined(NX_SERVICE_ASSUME_NON_DOMAIN) + if (s->object_id) + __builtin_unreachable(); +#endif + + out_s->session = 0; + out_s->own_handle = 1; + out_s->object_id = s->object_id; + out_s->pointer_buffer_size = s->pointer_buffer_size; + return cmifCloneCurrentObjectEx(s->session, tag, &out_s->session); +} + +/** + * @brief Converts a regular service to a domain. + * @param[in] s Service object. + * @return Result code. + */ +NX_INLINE Result serviceConvertToDomain(Service* s) +{ + if (!s->own_handle) { + // For overridden services, create a clone first. + Result rc = cmifCloneCurrentObjectEx(s->session, 0, &s->session); + if (R_FAILED(rc)) + return rc; + s->own_handle = 1; + } + + return cmifConvertCurrentObjectToDomain(s->session, &s->object_id); +} + +NX_CONSTEXPR void _serviceRequestFormatProcessBuffer(CmifRequestFormat* fmt, u32 attr) +{ + if (!attr) return; + const bool is_in = (attr & SfBufferAttr_In) != 0; + const bool is_out = (attr & SfBufferAttr_Out) != 0; + + if (attr & SfBufferAttr_HipcAutoSelect) { + if (is_in) + fmt->num_in_auto_buffers ++; + if (is_out) + fmt->num_out_auto_buffers ++; + } else if (attr & SfBufferAttr_HipcPointer) { + if (is_in) + fmt->num_in_pointers ++; + if (is_out) { + if (attr & SfBufferAttr_FixedSize) + fmt->num_out_fixed_pointers ++; + else + fmt->num_out_pointers ++; + } + } else if (attr & SfBufferAttr_HipcMapAlias) { + if (is_in && is_out) + fmt->num_inout_buffers ++; + else if (is_in) + fmt->num_in_buffers ++; + else if (is_out) + fmt->num_out_buffers ++; + } +} + +NX_CONSTEXPR void _serviceRequestProcessBuffer(CmifRequest* req, const SfBuffer* buf, u32 attr) +{ + if (!attr) return; + const bool is_in = (attr & SfBufferAttr_In); + const bool is_out = (attr & SfBufferAttr_Out); + + if (attr & SfBufferAttr_HipcAutoSelect) { + HipcBufferMode mode = HipcBufferMode_Normal; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonSecure) + mode = HipcBufferMode_NonSecure; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonDevice) + mode = HipcBufferMode_NonDevice; + if (is_in) + cmifRequestInAutoBuffer(req, buf->ptr, buf->size, mode); + if (is_out) + cmifRequestOutAutoBuffer(req, (void*)buf->ptr, buf->size, mode); + } else if (attr & SfBufferAttr_HipcPointer) { + if (is_in) + cmifRequestInPointer(req, buf->ptr, buf->size); + if (is_out) { + if (attr & SfBufferAttr_FixedSize) + cmifRequestOutFixedPointer(req, (void*)buf->ptr, buf->size); + else + cmifRequestOutPointer(req, (void*)buf->ptr, buf->size); + } + } else if (attr & SfBufferAttr_HipcMapAlias) { + HipcBufferMode mode = HipcBufferMode_Normal; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonSecure) + mode = HipcBufferMode_NonSecure; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonDevice) + mode = HipcBufferMode_NonDevice; + + if (is_in && is_out) + cmifRequestInOutBuffer(req, (void*)buf->ptr, buf->size, mode); + else if (is_in) + cmifRequestInBuffer(req, buf->ptr, buf->size, mode); + else if (is_out) + cmifRequestOutBuffer(req, (void*)buf->ptr, buf->size, mode); + } +} + +NX_INLINE void* serviceMakeRequest( + Service* s, u32 request_id, u32 context, u32 data_size, bool send_pid, + const SfBufferAttrs buffer_attrs, const SfBuffer* buffers, + u32 num_objects, const Service* const* objects, + u32 num_handles, const Handle* handles +) { +#if defined(NX_SERVICE_ASSUME_NON_DOMAIN) + if (s->object_id) + __builtin_unreachable(); +#endif + + CmifRequestFormat fmt = {}; + fmt.object_id = s->object_id; + fmt.request_id = request_id; + fmt.context = context; + fmt.data_size = data_size; + fmt.server_pointer_size = s->pointer_buffer_size; + fmt.num_objects = num_objects; + fmt.num_handles = num_handles; + fmt.send_pid = send_pid; + + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr0); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr1); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr2); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr3); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr4); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr5); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr6); + _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr7); + + CmifRequest req = cmifMakeRequest(armGetTls(), fmt); + + if (s->object_id) // TODO: Check behavior of input objects in non-domain sessions + for (u32 i = 0; i < num_objects; i ++) + cmifRequestObject(&req, objects[i]->object_id); + + for (u32 i = 0; i < num_handles; i ++) + cmifRequestHandle(&req, handles[i]); + + _serviceRequestProcessBuffer(&req, &buffers[0], buffer_attrs.attr0); + _serviceRequestProcessBuffer(&req, &buffers[1], buffer_attrs.attr1); + _serviceRequestProcessBuffer(&req, &buffers[2], buffer_attrs.attr2); + _serviceRequestProcessBuffer(&req, &buffers[3], buffer_attrs.attr3); + _serviceRequestProcessBuffer(&req, &buffers[4], buffer_attrs.attr4); + _serviceRequestProcessBuffer(&req, &buffers[5], buffer_attrs.attr5); + _serviceRequestProcessBuffer(&req, &buffers[6], buffer_attrs.attr6); + _serviceRequestProcessBuffer(&req, &buffers[7], buffer_attrs.attr7); + + return req.data; +} + +NX_CONSTEXPR void _serviceResponseGetHandle(CmifResponse* res, SfOutHandleAttr type, Handle* out) +{ + switch (type) { + default: + case SfOutHandleAttr_None: + break; + case SfOutHandleAttr_HipcCopy: + *out = cmifResponseGetCopyHandle(res); + break; + case SfOutHandleAttr_HipcMove: + *out = cmifResponseGetMoveHandle(res); + break; + } +} + +NX_INLINE Result serviceParseResponse( + Service* s, u32 out_size, void** out_data, + u32 num_out_objects, Service* out_objects, + const SfOutHandleAttrs out_handle_attrs, Handle* out_handles +) { +#if defined(NX_SERVICE_ASSUME_NON_DOMAIN) + if (s->object_id) + __builtin_unreachable(); +#endif + + CmifResponse res = {}; + bool is_domain = s->object_id != 0; + Result rc = cmifParseResponse(&res, armGetTls(), is_domain, out_size); + if (R_FAILED(rc)) + return rc; + + if (out_size) + *out_data = res.data; + + for (u32 i = 0; i < num_out_objects; i ++) { + if (is_domain) + serviceCreateDomainSubservice(&out_objects[i], s, cmifResponseGetObject(&res)); + else // Output objects are marshalled as move handles at the beginning of the list. + serviceCreateNonDomainSubservice(&out_objects[i], s, cmifResponseGetMoveHandle(&res)); + } + + _serviceResponseGetHandle(&res, out_handle_attrs.attr0, &out_handles[0]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr1, &out_handles[1]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr2, &out_handles[2]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr3, &out_handles[3]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr4, &out_handles[4]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr5, &out_handles[5]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr6, &out_handles[6]); + _serviceResponseGetHandle(&res, out_handle_attrs.attr7, &out_handles[7]); + + return 0; +} + +NX_INLINE Result serviceDispatchImpl( + Service* s, u32 request_id, + const void* in_data, u32 in_data_size, + void* out_data, u32 out_data_size, + SfDispatchParams disp +) +{ + // Make a copy of the service struct, so that the compiler can assume that it won't be modified by function calls. + Service srv = *s; + + void* in = serviceMakeRequest(&srv, request_id, disp.context, + in_data_size, disp.in_send_pid, + disp.buffer_attrs, disp.buffers, + disp.in_num_objects, disp.in_objects, + disp.in_num_handles, disp.in_handles); + + if (in_data_size) + __builtin_memcpy(in, in_data, in_data_size); + + Result rc = svcSendSyncRequest(disp.target_session == INVALID_HANDLE ? s->session : disp.target_session); + if (R_SUCCEEDED(rc)) { + void* out = NULL; + rc = serviceParseResponse(&srv, + out_data_size, &out, + disp.out_num_objects, disp.out_objects, + disp.out_handle_attrs, disp.out_handles); + + if (R_SUCCEEDED(rc) && out_data && out_data_size) + __builtin_memcpy(out_data, out, out_data_size); + } + + return rc; +} + +#define serviceDispatch(_s,_rid,...) \ + serviceDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ }) + +#define serviceDispatchIn(_s,_rid,_in,...) \ + serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ }) + +#define serviceDispatchOut(_s,_rid,_out,...) \ + serviceDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) + +#define serviceDispatchInOut(_s,_rid,_in,_out,...) \ + serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) diff --git a/src/libnx/wrapper/switch/sf/service.nim b/src/libnx/wrapper/switch/sf/service.nim new file mode 100644 index 0000000..86c67f5 --- /dev/null +++ b/src/libnx/wrapper/switch/sf/service.nim @@ -0,0 +1,421 @@ +## * +## @file service.h +## @brief Service wrapper object +## @author fincs +## @author SciresM +## @copyright libnx Authors +## + +import + hipc, cmif, ../types, ../arm/tls, ../kernel/svc, ../result + +## / Service object structure + +type + Service* {.bycopy.} = object + session*: Handle + ownHandle*: U32 + objectId*: U32 + pointerBufferSize*: U16 + + +const + SfBufferAttrIn* = bit(0) + SfBufferAttrOut* = bit(1) + SfBufferAttrHipcMapAlias* = bit(2) + SfBufferAttrHipcPointer* = bit(3) + SfBufferAttrFixedSize* = bit(4) + SfBufferAttrHipcAutoSelect* = bit(5) + SfBufferAttrHipcMapTransferAllowsNonSecure* = bit(6) + SfBufferAttrHipcMapTransferAllowsNonDevice* = bit(7) + +type + SfBufferAttrs* {.bycopy.} = object + attr0*: U32 + attr1*: U32 + attr2*: U32 + attr3*: U32 + attr4*: U32 + attr5*: U32 + attr6*: U32 + attr7*: U32 + + SfBuffer* {.bycopy.} = object + `ptr`*: pointer + size*: csize_t + + SfOutHandleAttr* = enum + SfOutHandleAttrNone = 0, SfOutHandleAttrHipcCopy = 1, SfOutHandleAttrHipcMove = 2 + SfOutHandleAttrs* {.bycopy.} = object + attr0*: SfOutHandleAttr + attr1*: SfOutHandleAttr + attr2*: SfOutHandleAttr + attr3*: SfOutHandleAttr + attr4*: SfOutHandleAttr + attr5*: SfOutHandleAttr + attr6*: SfOutHandleAttr + attr7*: SfOutHandleAttr + + SfDispatchParams* {.bycopy.} = object + targetSession*: Handle + context*: U32 + bufferAttrs*: SfBufferAttrs + buffers*: array[8, SfBuffer] + inSendPid*: bool + inNumObjects*: U32 + inObjects*: array[8, ptr Service] + inNumHandles*: U32 + inHandles*: array[8, Handle] + outNumObjects*: U32 + outObjects*: ptr Service + outHandleAttrs*: SfOutHandleAttrs + outHandles*: ptr Handle + + +proc serviceIsActive*(s: ptr Service): bool {.inline, cdecl.} = + ## * + ## @brief Returns whether a service has been initialized. + ## @param[in] s Service object. + ## @return true if initialized. + ## + return s.session != Invalid_Handle + +proc serviceIsOverride*(s: ptr Service): bool {.inline, cdecl.} = + ## * + ## @brief Returns whether a service is overriden in the homebrew environment. + ## @param[in] s Service object. + ## @return true if overriden. + ## + return serviceIsActive(s) and not s.ownHandle.bool and not s.objectId.bool + +proc serviceIsDomain*(s: ptr Service): bool {.inline, cdecl.} = + ## * + ## @brief Returns whether a service is a domain. + ## @param[in] s Service object. + ## @return true if a domain. + ## + return serviceIsActive(s) and s.ownHandle.bool and s.objectId.bool + +proc serviceIsDomainSubservice*(s: ptr Service): bool {.inline, cdecl.} = + ## * + ## @brief Returns whether a service is a domain subservice. + ## @param[in] s Service object. + ## @return true if a domain subservice. + ## + return serviceIsActive(s) and not s.ownHandle.bool and s.objectId.bool + +proc serviceGetObjectId*(s: ptr Service): U32 {.inline, cdecl.} = + ## * + ## @brief For a domain/domain subservice, return the associated object ID. + ## @param[in] s Service object, necessarily a domain or domain subservice. + ## @return The object ID. + ## + return s.objectId + +proc serviceCreate*(s: ptr Service; h: Handle) {.inline, cdecl.} = + ## * + ## @brief Creates a service object from an IPC session handle. + ## @param[out] s Service object. + ## @param[in] h IPC session handle. + ## + + s.session = h + s.ownHandle = 1 + s.objectId = 0 + s.pointerBufferSize = 0 + discard cmifQueryPointerBufferSize(h, addr(s.pointerBufferSize)) + +proc serviceCreateNonDomainSubservice*(s: ptr Service; parent: ptr Service; h: Handle) {. + inline, cdecl.} = + ## * + ## @brief Creates a non-domain subservice object from a parent service. + ## @param[out] s Service object. + ## @param[in] parent Parent service. + ## @param[in] h IPC session handle for this subservice. + ## + + if h != Invalid_Handle: + s.session = h + s.ownHandle = 1 + s.objectId = 0 + s.pointerBufferSize = parent.pointerBufferSize + else: + s[] = Service() + +proc serviceCreateDomainSubservice*(s: ptr Service; parent: ptr Service; objectId: U32) {. + inline, cdecl.} = + ## * + ## @brief Creates a domain subservice object from a parent service. + ## @param[out] s Service object. + ## @param[in] parent Parent service, necessarily a domain or domain subservice. + ## @param[in] object_id Object ID for this subservice. + ## + + if objectId != 0: + s.session = parent.session + s.ownHandle = 0 + s.objectId = objectId + s.pointerBufferSize = parent.pointerBufferSize + else: + s[] = Service() + +template serviceAssumeDomain*(s: untyped): void = + ## * + ## @brief Hints the compiler that a service will always contain a domain object. + ## @param[in] _s Service object. + ## + + while true: + if not (s).objectId.bool: + builtinUnreachable() + if not 0: + break + + +proc serviceClose*(s: ptr Service) {.inline, cdecl.} = + ## * + ## @brief Closes a service. + ## @param[in] s Service object. + ## + {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} + {.emit: " if (`s`->object_id)".} + {.emit: " __builtin_unreachable();".} + {.emit: "#endif".} + {.emit: " if (`s`->own_handle || `s`->object_id) {".} + {.emit: " cmifMakeCloseRequest(armGetTls(), `s`->own_handle ? 0 : `s`->object_id);".} + {.emit: " svcSendSyncRequest(`s`->session);".} + {.emit: " if (`s`->own_handle)".} + {.emit: " svcCloseHandle(`s`->session);".} + {.emit: " }".} + {.emit: " *`s` = (Service){};".} + +proc serviceClone*(s: ptr Service; outS: ptr Service): Result {.inline, cdecl.} = + ## * + ## @brief Clones a service. + ## @param[in] s Service object. + ## @param[out] out_s Output service object. + ## + {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} + {.emit: " if (`s`->object_id)".} + {.emit: " __builtin_unreachable();".} + {.emit: "#endif".} + {.emit: " `outS`->session = 0;".} + {.emit: " `outS`->own_handle = 1;".} + {.emit: " `outS`->object_id = `s`->object_id;".} + {.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".} + {.emit: " `result` = cmifCloneCurrentObject(`s`->session, &`outS`->session);".} + + +proc serviceCloneEx*(s: ptr Service; tag: U32; outS: ptr Service): Result {.inline, cdecl.} = + ## * + ## @brief Clones a service with a session manager tag. + ## @param[in] s Service object. + ## @param[in] tag Session manager tag (unused in current official server code) + ## @param[out] out_s Output service object. + ## + {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} + {.emit: " if (`s`->object_id)".} + {.emit: " __builtin_unreachable();".} + {.emit: "#endif".} + {.emit: " `outS`->session = 0;".} + {.emit: " `outS`->own_handle = 1;".} + {.emit: " `outS`->object_id = `s`->object_id;".} + {.emit: " `outS`->pointer_buffer_size = `s`->pointer_buffer_size;".} + {.emit: " `result` = cmifCloneCurrentObjectEx(`s`->session, `tag`, &`outS`->session);".} + + +proc serviceConvertToDomain*(s: ptr Service): Result {.inline, cdecl.} = + ## * + ## @brief Converts a regular service to a domain. + ## @param[in] s Service object. + ## @return Result code. + ## + if not s.ownHandle.bool: + ## For overridden services, create a clone first. + var rc: Result = cmifCloneCurrentObjectEx(s.session, 0, addr(s.session)) + if r_Failed(rc): + return rc + s.ownHandle = 1 + return cmifConvertCurrentObjectToDomain(s.session, addr(s.objectId)) + +proc serviceRequestFormatProcessBuffer*(fmt: ptr CmifRequestFormat; attr: U32) {. + inline, cdecl.} = + if attr == 0: + return + + let isIn: bool = (attr and SfBufferAttrIn) != 0 + let isOut: bool = (attr and SfBufferAttrOut) != 0 + if (attr and SfBufferAttrHipcAutoSelect).bool: + if isIn: + inc(fmt.numInAutoBuffers) + if isOut: + inc(fmt.numOutAutoBuffers) + elif (attr and SfBufferAttrHipcPointer).bool: + if isIn: + inc(fmt.numInPointers) + if isOut: + if (attr and SfBufferAttrFixedSize).bool: + inc(fmt.numOutFixedPointers) + else: + inc(fmt.numOutPointers) + elif (attr and SfBufferAttrHipcMapAlias).bool: + if isIn and isOut: + inc(fmt.numInoutBuffers) + elif isIn: + inc(fmt.numInBuffers) + elif isOut: + inc(fmt.numOutBuffers) + +proc serviceRequestProcessBuffer*(req: ptr CmifRequest; buf: ptr SfBuffer; attr: U32) {. + inline, cdecl.} = + if attr == 0: + return + let isIn: bool = (attr and SfBufferAttrIn).bool + let isOut: bool = (attr and SfBufferAttrOut).bool + if (attr and SfBufferAttrHipcAutoSelect).bool: + var mode: HipcBufferMode = HipcBufferModeNormal + if (attr and SfBufferAttrHipcMapTransferAllowsNonSecure).bool: + mode = HipcBufferModeNonSecure + if (attr and SfBufferAttrHipcMapTransferAllowsNonDevice).bool: + mode = HipcBufferModeNonDevice + if isIn: + cmifRequestInAutoBuffer(req, buf.`ptr`, buf.size, mode) + if isOut: + cmifRequestOutAutoBuffer(req, cast[pointer](buf.`ptr`), buf.size, mode) + elif (attr and SfBufferAttrHipcPointer).bool: + if isIn: + cmifRequestInPointer(req, buf.`ptr`, buf.size) + if isOut: + if (attr and SfBufferAttrFixedSize).bool: + cmifRequestOutFixedPointer(req, cast[pointer](buf.`ptr`), buf.size) + else: + cmifRequestOutPointer(req, cast[pointer](buf.`ptr`), buf.size) + elif (attr and SfBufferAttrHipcMapAlias).bool: + var mode: HipcBufferMode = HipcBufferModeNormal + if (attr and SfBufferAttrHipcMapTransferAllowsNonSecure).bool: + mode = HipcBufferModeNonSecure + if (attr and SfBufferAttrHipcMapTransferAllowsNonDevice).bool: + mode = HipcBufferModeNonDevice + if isIn and isOut: + cmifRequestInOutBuffer(req, cast[pointer](buf.`ptr`), buf.size, mode) + elif isIn: + cmifRequestInBuffer(req, buf.`ptr`, buf.size, mode) + elif isOut: + cmifRequestOutBuffer(req, cast[pointer](buf.`ptr`), buf.size, mode) + +proc serviceMakeRequest*(s: ptr Service; requestId: U32; context: U32; dataSize: U32; + sendPid: bool; bufferAttrs: SfBufferAttrs; + buffers: openArray[SfBuffer]; numObjects: U32; + objects: openArray[ptr Service]; numHandles: U32; handles: openArray[Handle]): pointer {. + inline, cdecl.} = + when defined(nx_Service_Assume_Non_Domain): + if s.objectId: + builtinUnreachable() + var fmt: CmifRequestFormat + fmt.objectId = s.objectId + fmt.requestId = requestId + fmt.context = context + fmt.dataSize = dataSize + fmt.serverPointerSize = s.pointerBufferSize + fmt.numObjects = numObjects + fmt.numHandles = numHandles + fmt.sendPid = sendPid.U32 + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr0) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr1) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr2) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr3) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr4) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr5) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr6) + serviceRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr7) + var req: CmifRequest = cmifMakeRequest(armGetTls(), fmt) + if s.objectId.bool: + var i: U32 = 0 + while i < numObjects: + cmifRequestObject(addr(req), objects[i].objectId) + inc(i) + var i: U32 = 0 + while i < numHandles: + cmifRequestHandle(addr(req), handles[i]) + inc(i) + serviceRequestProcessBuffer(addr(req), addr(buffers[0]), bufferAttrs.attr0) + serviceRequestProcessBuffer(addr(req), addr(buffers[1]), bufferAttrs.attr1) + serviceRequestProcessBuffer(addr(req), addr(buffers[2]), bufferAttrs.attr2) + serviceRequestProcessBuffer(addr(req), addr(buffers[3]), bufferAttrs.attr3) + serviceRequestProcessBuffer(addr(req), addr(buffers[4]), bufferAttrs.attr4) + serviceRequestProcessBuffer(addr(req), addr(buffers[5]), bufferAttrs.attr5) + serviceRequestProcessBuffer(addr(req), addr(buffers[6]), bufferAttrs.attr6) + serviceRequestProcessBuffer(addr(req), addr(buffers[7]), bufferAttrs.attr7) + return req.data + +proc serviceResponseGetHandle*(res: ptr CmifResponse; ty: SfOutHandleAttr; + `out`: ptr Handle) {.inline, cdecl.} = + {.emit: " switch (`ty`) {".} + {.emit: " default:".} + {.emit: " case SfOutHandleAttr_None:".} + {.emit: " break;".} + {.emit: " case SfOutHandleAttr_HipcCopy:".} + {.emit: " *`out` = cmifResponseGetCopyHandle(`res`);".} + {.emit: " break;".} + {.emit: " case SfOutHandleAttr_HipcMove:".} + {.emit: " *`out` = cmifResponseGetMoveHandle(`res`);".} + {.emit: " break;".} + {.emit: " }".} + +proc serviceParseResponse*(s: ptr Service; outSize: U32; outData: ptr pointer; + numOutObjects: U32; outObjects: ptr Service; + outHandleAttrs: SfOutHandleAttrs; outHandles: ptr Handle): Result {. + inline, cdecl.} = + {.emit: "#if defined(NX_SERVICE_ASSUME_NON_DOMAIN)".} + {.emit: " if (`s`->object_id)".} + {.emit: " __builtin_unreachable();".} + {.emit: "#endif".} + {.emit: " CmifResponse res = {};".} + {.emit: " bool is_domain = `s`->object_id != 0;".} + {.emit: " Result rc = cmifParseResponse(&res, armGetTls(), is_domain, `outSize`);".} + {.emit: " if (R_FAILED(rc))".} + {.emit: " return rc;".} + {.emit: " if (`outSize`)".} + {.emit: " *`outData` = res.data;".} + {.emit: " for (u32 i = 0; i < `numOutObjects`; i ++) {".} + {.emit: " if (is_domain)".} + {.emit: " serviceCreateDomainSubservice(&`outObjects`[i], `s`, cmifResponseGetObject(&res));".} + {.emit: " else // Output objects are marshalled as move handles at the beginning of the list.".} + {.emit: " serviceCreateNonDomainSubservice(&`outObjects`[i], `s`, cmifResponseGetMoveHandle(&res));".} + {.emit: " }".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr0, &`outHandles`[0]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr1, &`outHandles`[1]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr2, &`outHandles`[2]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr3, &`outHandles`[3]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr4, &`outHandles`[4]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr5, &`outHandles`[5]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr6, &`outHandles`[6]);".} + {.emit: " _serviceResponseGetHandle(&res, `outHandleAttrs`.attr7, &`outHandles`[7]);".} + {.emit: " `result` = 0;".} + +proc serviceDispatchImpl*(s: ptr Service; requestId: U32; inData: pointer; + inDataSize: U32; outData: pointer; outDataSize: U32; + disp: SfDispatchParams): Result {.inline, cdecl.} = + ## Make a copy of the service struct, so that the compiler can assume that it won't be modified by function calls. + var srv: Service + var `in`: pointer = serviceMakeRequest(addr(srv), requestId, disp.context, + inDataSize, disp.inSendPid, disp.bufferAttrs, + disp.buffers, disp.inNumObjects, + disp.inObjects, disp.inNumHandles, + disp.inHandles) + if inDataSize.bool: + copyMem(`in`, inData, inDataSize) + + var rc: Result = svcSendSyncRequest(if disp.targetSession == Invalid_Handle: s.session else: disp.targetSession) + + if r_Succeeded(rc): + var `out`: pointer = nil + rc = serviceParseResponse(addr(srv), outDataSize, addr(`out`), + disp.outNumObjects, disp.outObjects, + disp.outHandleAttrs, disp.outHandles) + if r_Succeeded(rc) and outData != nil and outDataSize.bool: + copyMem(outData, `out`, outDataSize) + return rc + +## !!!Ignored construct: # ( _s , _rid , ... ) serviceDispatchImpl ( ( _s ) , ( _rid ) , NULL , 0 , NULL , 0 , ( SfDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _in , ... ) serviceDispatchImpl ( ( _s ) , ( _rid ) , & ( _in ) , sizeof ( _in ) , NULL , 0 , ( SfDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _out , ... ) serviceDispatchImpl ( ( _s ) , ( _rid ) , NULL , 0 , & ( _out ) , sizeof ( _out ) , ( SfDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _in , _out , ... ) serviceDispatchImpl ( ( _s ) , ( _rid ) , & ( _in ) , sizeof ( _in ) , & ( _out ) , sizeof ( _out ) , ( SfDispatchParams ) { __VA_ARGS__ } ) [NewLine] +## Error: identifier expected, but got: (!!! diff --git a/src/libnx/wrapper/switch/sf/sessionmgr.h b/src/libnx/wrapper/switch/sf/sessionmgr.h new file mode 100644 index 0000000..409df7b --- /dev/null +++ b/src/libnx/wrapper/switch/sf/sessionmgr.h @@ -0,0 +1,26 @@ +#pragma once +#include "../types.h" +#include "../kernel/mutex.h" +#include "../kernel/condvar.h" + +#define NX_SESSION_MGR_MAX_SESSIONS 16 + +typedef struct SessionMgr +{ + Handle sessions[NX_SESSION_MGR_MAX_SESSIONS]; + u32 num_sessions; + u32 free_mask; + Mutex mutex; + CondVar condvar; + u32 num_waiters; +} SessionMgr; + +Result sessionmgrCreate(SessionMgr* mgr, Handle root_session, u32 num_sessions); +void sessionmgrClose(SessionMgr* mgr); +int sessionmgrAttachClient(SessionMgr* mgr); +void sessionmgrDetachClient(SessionMgr* mgr, int slot); + +NX_CONSTEXPR Handle sessionmgrGetClientSession(SessionMgr* mgr, int slot) +{ + return mgr->sessions[slot]; +} diff --git a/src/libnx/wrapper/switch/sf/sessionmgr.nim b/src/libnx/wrapper/switch/sf/sessionmgr.nim new file mode 100644 index 0000000..dcb73de --- /dev/null +++ b/src/libnx/wrapper/switch/sf/sessionmgr.nim @@ -0,0 +1,25 @@ +import + ../types, ../kernel/mutex, ../kernel/condvar + +const + NX_SESSION_MGR_MAX_SESSIONS* = 16 + +type + SessionMgr* {.bycopy.} = object + sessions*: array[Nx_Session_Mgr_Max_Sessions, Handle] + numSessions*: U32 + freeMask*: U32 + mutex*: Mutex + condvar*: CondVar + numWaiters*: U32 + + +proc sessionmgrCreate*(mgr: ptr SessionMgr; rootSession: Handle; numSessions: U32): Result {. + cdecl, importc: "sessionmgrCreate".} +proc sessionmgrClose*(mgr: ptr SessionMgr) {.cdecl, importc: "sessionmgrClose".} +proc sessionmgrAttachClient*(mgr: ptr SessionMgr): cint {.cdecl, + importc: "sessionmgrAttachClient".} +proc sessionmgrDetachClient*(mgr: ptr SessionMgr; slot: cint) {.cdecl, + importc: "sessionmgrDetachClient".} +proc sessionmgrGetClientSession*(mgr: ptr SessionMgr; slot: cint): Handle {.inline, cdecl.} = + return mgr.sessions[slot] diff --git a/src/libnx/wrapper/switch/sf/tipc.h b/src/libnx/wrapper/switch/sf/tipc.h new file mode 100644 index 0000000..52f74cb --- /dev/null +++ b/src/libnx/wrapper/switch/sf/tipc.h @@ -0,0 +1,269 @@ +/** + * @file tipc.h + * @brief Tiny IPC protocol + * @author fincs + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include "hipc.h" +#include "cmif.h" +#include "service.h" + +typedef enum TipcCommandType { + TipcCommandType_Close = 15, +} TipcCommandType; + +/// tipc Service object structure +typedef struct TipcService { + Handle session; +} TipcService; + +typedef struct TipcDispatchParams { + SfBufferAttrs buffer_attrs; + SfBuffer buffers[8]; + + bool in_send_pid; + + u32 in_num_handles; + Handle in_handles[8]; + + u32 out_num_objects; + TipcService* out_objects; + + SfOutHandleAttrs out_handle_attrs; + Handle* out_handles; +} TipcDispatchParams; + +typedef struct TipcRequestFormat { + u32 request_id; + u32 data_size; + u32 num_in_buffers; + u32 num_out_buffers; + u32 num_inout_buffers; + u32 num_handles; + u32 send_pid; +} TipcRequestFormat; + +/** + * @brief Creates a tipc service object from an IPC session handle. + * @param[out] s TIPC service object. + * @param[in] h IPC session handle. + */ +NX_CONSTEXPR void tipcCreate(TipcService* s, Handle h) { + s->session = h; +} + +/** + * @brief Closes a tipc service. + * @param[in] s TIPC service object. + */ +NX_INLINE void tipcClose(TipcService* s) +{ + hipcMakeRequestInline(armGetTls(), .type = TipcCommandType_Close); + svcSendSyncRequest(s->session); + svcCloseHandle(s->session); + *s = (TipcService){}; +} + +NX_CONSTEXPR void tipcRequestInBuffer(HipcRequest* req, const void* buffer, size_t size, HipcBufferMode mode) +{ + *req->send_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void tipcRequestOutBuffer(HipcRequest* req, void* buffer, size_t size, HipcBufferMode mode) +{ + *req->recv_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void tipcRequestInOutBuffer(HipcRequest* req, void* buffer, size_t size, HipcBufferMode mode) +{ + *req->exch_buffers++ = hipcMakeBuffer(buffer, size, mode); +} + +NX_CONSTEXPR void tipcRequestHandle(HipcRequest* req, Handle handle) +{ + *req->copy_handles++ = handle; +} + +NX_CONSTEXPR void _tipcRequestFormatProcessBuffer(TipcRequestFormat* fmt, u32 attr) +{ + if (!attr) return; + const bool is_in = (attr & SfBufferAttr_In) != 0; + const bool is_out = (attr & SfBufferAttr_Out) != 0; + + if (attr & SfBufferAttr_HipcMapAlias) { + if (is_in && is_out) + fmt->num_inout_buffers ++; + else if (is_in) + fmt->num_in_buffers ++; + else if (is_out) + fmt->num_out_buffers ++; + } +} + +NX_CONSTEXPR void _tipcRequestProcessBuffer(HipcRequest* req, const SfBuffer* buf, u32 attr) +{ + if (!attr) return; + const bool is_in = (attr & SfBufferAttr_In); + const bool is_out = (attr & SfBufferAttr_Out); + + if (attr & SfBufferAttr_HipcMapAlias) { + HipcBufferMode mode = HipcBufferMode_Normal; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonSecure) + mode = HipcBufferMode_NonSecure; + if (attr & SfBufferAttr_HipcMapTransferAllowsNonDevice) + mode = HipcBufferMode_NonDevice; + + if (is_in && is_out) + tipcRequestInOutBuffer(req, (void*)buf->ptr, buf->size, mode); + else if (is_in) + tipcRequestInBuffer(req, buf->ptr, buf->size, mode); + else if (is_out) + tipcRequestOutBuffer(req, (void*)buf->ptr, buf->size, mode); + } +} + +NX_INLINE void* tipcMakeRequest( + u32 request_id, u32 data_size, bool send_pid, + const SfBufferAttrs buffer_attrs, const SfBuffer* buffers, + u32 num_handles, const Handle* handles) { + TipcRequestFormat fmt = {}; + fmt.request_id = request_id + 16; + fmt.data_size = data_size; + fmt.num_handles = num_handles; + fmt.send_pid = send_pid; + + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr0); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr1); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr2); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr3); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr4); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr5); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr6); + _tipcRequestFormatProcessBuffer(&fmt, buffer_attrs.attr7); + + HipcRequest req = hipcMakeRequestInline(armGetTls(), + .type = fmt.request_id, + .num_send_statics = 0, + .num_send_buffers = fmt.num_in_buffers, + .num_recv_buffers = fmt.num_out_buffers, + .num_exch_buffers = fmt.num_inout_buffers, + .num_data_words = (data_size + 3) / 4, + .num_recv_statics = 0, + .send_pid = fmt.send_pid, + .num_copy_handles = fmt.num_handles, + .num_move_handles = 0, + ); + + for (u32 i = 0; i < num_handles; i ++) + tipcRequestHandle(&req, handles[i]); + + _tipcRequestProcessBuffer(&req, &buffers[0], buffer_attrs.attr0); + _tipcRequestProcessBuffer(&req, &buffers[1], buffer_attrs.attr1); + _tipcRequestProcessBuffer(&req, &buffers[2], buffer_attrs.attr2); + _tipcRequestProcessBuffer(&req, &buffers[3], buffer_attrs.attr3); + _tipcRequestProcessBuffer(&req, &buffers[4], buffer_attrs.attr4); + _tipcRequestProcessBuffer(&req, &buffers[5], buffer_attrs.attr5); + _tipcRequestProcessBuffer(&req, &buffers[6], buffer_attrs.attr6); + _tipcRequestProcessBuffer(&req, &buffers[7], buffer_attrs.attr7); + + return req.data_words; +} + +NX_CONSTEXPR Handle tipcResponseGetCopyHandle(HipcResponse* res) +{ + return *res->copy_handles++; +} + +NX_CONSTEXPR Handle tipcResponseGetMoveHandle(HipcResponse* res) +{ + return *res->move_handles++; +} + +NX_CONSTEXPR void _tipcResponseGetHandle(HipcResponse* res, SfOutHandleAttr type, Handle* out) +{ + switch (type) { + default: + case SfOutHandleAttr_None: + break; + case SfOutHandleAttr_HipcCopy: + *out = tipcResponseGetCopyHandle(res); + break; + case SfOutHandleAttr_HipcMove: + *out = tipcResponseGetMoveHandle(res); + break; + } +} + +NX_INLINE Result tipcParseResponse( + u32 out_size, void** out_data, + u32 num_out_objects, TipcService* out_objects, + const SfOutHandleAttrs out_handle_attrs, Handle* out_handles +) { + + HipcResponse res = hipcParseResponse(armGetTls()); + + Result rc = *res.data_words++; + if (R_FAILED(rc)) + return rc; + + if (out_size) + *out_data = res.data_words; + + for (u32 i = 0; i < num_out_objects; i ++) { + tipcCreate(&out_objects[i], tipcResponseGetMoveHandle(&res)); + } + + _tipcResponseGetHandle(&res, out_handle_attrs.attr0, &out_handles[0]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr1, &out_handles[1]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr2, &out_handles[2]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr3, &out_handles[3]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr4, &out_handles[4]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr5, &out_handles[5]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr6, &out_handles[6]); + _tipcResponseGetHandle(&res, out_handle_attrs.attr7, &out_handles[7]); + + return 0; +} + +NX_INLINE Result tipcDispatchImpl( + TipcService* s, u32 request_id, + const void* in_data, u32 in_data_size, + void* out_data, u32 out_data_size, + TipcDispatchParams disp +) +{ + void* in = tipcMakeRequest(request_id, + in_data_size, disp.in_send_pid, + disp.buffer_attrs, disp.buffers, + disp.in_num_handles, disp.in_handles); + + if (in_data_size) + __builtin_memcpy(in, in_data, in_data_size); + + Result rc = svcSendSyncRequest(s->session); + if (R_SUCCEEDED(rc)) { + void* out = NULL; + rc = tipcParseResponse(out_data_size, &out, + disp.out_num_objects, disp.out_objects, + disp.out_handle_attrs, disp.out_handles); + + if (R_SUCCEEDED(rc) && out_data && out_data_size) + __builtin_memcpy(out_data, out, out_data_size); + } + + return rc; +} + +#define tipcDispatch(_s,_rid,...) \ + tipcDispatchImpl((_s),(_rid),NULL,0,NULL,0,(TipcDispatchParams){ __VA_ARGS__ }) + +#define tipcDispatchIn(_s,_rid,_in,...) \ + tipcDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(TipcDispatchParams){ __VA_ARGS__ }) + +#define tipcDispatchOut(_s,_rid,_out,...) \ + tipcDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(TipcDispatchParams){ __VA_ARGS__ }) + +#define tipcDispatchInOut(_s,_rid,_in,_out,...) \ + tipcDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(TipcDispatchParams){ __VA_ARGS__ }) diff --git a/src/libnx/wrapper/switch/sf/tipc.nim b/src/libnx/wrapper/switch/sf/tipc.nim new file mode 100644 index 0000000..5906351 --- /dev/null +++ b/src/libnx/wrapper/switch/sf/tipc.nim @@ -0,0 +1,220 @@ +## * +## @file tipc.h +## @brief Tiny IPC protocol +## @author fincs +## @author SciresM +## @copyright libnx Authors +## + +import + hipc, service, ../types, ../kernel/svc, ../result, ../arm/tls + +type + TipcCommandType* = enum + TipcCommandTypeClose = 15 + + +## / tipc Service object structure + +type + TipcService* {.bycopy.} = object + session*: Handle + + TipcDispatchParams* {.bycopy.} = object + bufferAttrs*: SfBufferAttrs + buffers*: array[8, SfBuffer] + inSendPid*: bool + inNumHandles*: U32 + inHandles*: array[8, Handle] + outNumObjects*: U32 + outObjects*: ptr TipcService + outHandleAttrs*: SfOutHandleAttrs + outHandles*: ptr Handle + + TipcRequestFormat* {.bycopy.} = object + requestId*: U32 + dataSize*: U32 + numInBuffers*: U32 + numOutBuffers*: U32 + numInoutBuffers*: U32 + numHandles*: U32 + sendPid*: U32 + + +proc tipcCreate*(s: ptr TipcService; h: Handle) {.inline, cdecl.} = + ## * + ## @brief Creates a tipc service object from an IPC session handle. + ## @param[out] s TIPC service object. + ## @param[in] h IPC session handle. + ## + s.session = h + +proc tipcClose*(s: ptr TipcService) {.inline, cdecl.} = + ## * + ## @brief Closes a tipc service. + ## @param[in] s TIPC service object. + ## + discard hipcMakeRequestInline(armGetTls(), `type` = TipcCommandType_Close.U32) + discard svcSendSyncRequest(s.session) + discard svcCloseHandle(s.session) + s[] = TipcService() + +proc tipcRequestInBuffer*(req: ptr HipcRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.sendBuffers += 1 + req.sendBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc tipcRequestOutBuffer*(req: ptr HipcRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.recvBuffers += 1 + req.recvBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc tipcRequestInOutBuffer*(req: ptr HipcRequest; buffer: pointer; size: csize_t; + mode: HipcBufferMode) {.inline, cdecl.} = + req.exchBuffers += 1 + req.exchBuffers[] = hipcMakeBuffer(buffer, size, mode) + +proc tipcRequestHandle*(req: ptr HipcRequest; handle: Handle) {.inline, cdecl.} = + req.copyHandles += 1 + req.copyHandles[] = handle + +proc tipcRequestFormatProcessBuffer*(fmt: ptr TipcRequestFormat; attr: U32) {.inline, cdecl.} = + if not attr.bool: + return + let isIn: bool = (attr and SfBufferAttrIn) != 0 + let isOut: bool = (attr and SfBufferAttrOut) != 0 + if (attr and SfBufferAttrHipcMapAlias).bool: + if isIn and isOut: + inc(fmt.numInoutBuffers) + elif isIn: + inc(fmt.numInBuffers) + elif isOut: + inc(fmt.numOutBuffers) + +proc tipcRequestProcessBuffer*(req: ptr HipcRequest; buf: ptr SfBuffer; attr: U32) {. + inline, cdecl.} = + if not attr.bool: + return + let isIn: bool = (attr and SfBufferAttrIn).bool + let isOut: bool = (attr and SfBufferAttrOut).bool + if (attr and SfBufferAttrHipcMapAlias).bool: + var mode: HipcBufferMode = HipcBufferModeNormal + if (attr and SfBufferAttrHipcMapTransferAllowsNonSecure).bool: + mode = HipcBufferModeNonSecure + if (attr and SfBufferAttrHipcMapTransferAllowsNonDevice).bool: + mode = HipcBufferModeNonDevice + if isIn and isOut: + tipcRequestInOutBuffer(req, cast[pointer](buf.`ptr`), buf.size, mode) + elif isIn: + tipcRequestInBuffer(req, buf.`ptr`, buf.size, mode) + elif isOut: + tipcRequestOutBuffer(req, cast[pointer](buf.`ptr`), buf.size, mode) + +proc tipcMakeRequest*(requestId: U32; dataSize: U32; sendPid: bool; + bufferAttrs: SfBufferAttrs; buffers: openArray[SfBuffer]; + numHandles: U32; handles: openArray[Handle]): pointer {.inline, cdecl.} = + var fmt: TipcRequestFormat = TipcRequestFormat() + fmt.requestId = requestId + 16 + fmt.dataSize = dataSize + fmt.numHandles = numHandles + fmt.sendPid = sendPid.U32 + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr0) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr1) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr2) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr3) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr4) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr5) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr6) + tipcRequestFormatProcessBuffer(addr(fmt), bufferAttrs.attr7) + var req = hipcMakeRequestInline(armGetTls(), + `type` = fmt.request_id, + num_send_statics = 0, + num_send_buffers = fmt.num_in_buffers, + num_recv_buffers = fmt.num_out_buffers, + num_exch_buffers = fmt.num_inout_buffers, + num_data_words = ((data_size + 3).int / 4).U32, + num_recv_statics = 0, + send_pid = fmt.send_pid, + num_copy_handles = fmt.num_handles, + num_move_handles = 0, + ); + var i: U32 = 0 + while i < numHandles: + tipcRequestHandle(addr(req), handles[i]) + inc(i) + tipcRequestProcessBuffer(addr(req), addr(buffers[0]), bufferAttrs.attr0) + tipcRequestProcessBuffer(addr(req), addr(buffers[1]), bufferAttrs.attr1) + tipcRequestProcessBuffer(addr(req), addr(buffers[2]), bufferAttrs.attr2) + tipcRequestProcessBuffer(addr(req), addr(buffers[3]), bufferAttrs.attr3) + tipcRequestProcessBuffer(addr(req), addr(buffers[4]), bufferAttrs.attr4) + tipcRequestProcessBuffer(addr(req), addr(buffers[5]), bufferAttrs.attr5) + tipcRequestProcessBuffer(addr(req), addr(buffers[6]), bufferAttrs.attr6) + tipcRequestProcessBuffer(addr(req), addr(buffers[7]), bufferAttrs.attr7) + return req.dataWords + +proc tipcResponseGetCopyHandle*(res: ptr HipcResponse): Handle {.inline, cdecl.} = + res.copyHandles += 1 + return res.copyHandles[] + +proc tipcResponseGetMoveHandle*(res: ptr HipcResponse): Handle {.inline, cdecl.} = + res.moveHandles += 1 + return res.moveHandles[] + +proc tipcResponseGetHandle*(res: ptr HipcResponse; ty: SfOutHandleAttr; + outHandle: ptr Handle) {.inline, cdecl.} = + {.emit: " switch (`ty`) {".} + {.emit: " default:".} + {.emit: " case SfOutHandleAttr_None:".} + {.emit: " break;".} + {.emit: " case SfOutHandleAttr_HipcCopy:".} + {.emit: " *`outHandle` = tipcResponseGetCopyHandle(`res`);".} + {.emit: " break;".} + {.emit: " case SfOutHandleAttr_HipcMove:".} + {.emit: " *`outHandle` = tipcResponseGetMoveHandle(`res`);".} + {.emit: " break;".} + {.emit: " }".} + +proc tipcParseResponse*(outSize: U32; outData: ptr pointer; numOutObjects: U32; + outObjects: ptr TipcService; + outHandleAttrs: SfOutHandleAttrs; outHandles: ptr Handle): Result {. + inline, cdecl.} = + var res: HipcResponse = hipcParseResponse(armGetTls()) + res.dataWords += 1 + var rc: Result = res.dataWords[] + if r_Failed(rc): + return rc + if outSize.bool: + outData[] = res.dataWords + var i: U32 = 0 + while i < numOutObjects: + tipcCreate(addr(outObjects[i]), tipcResponseGetMoveHandle(addr(res))) + inc(i) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr0, addr(outHandles[0])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr1, addr(outHandles[1])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr2, addr(outHandles[2])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr3, addr(outHandles[3])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr4, addr(outHandles[4])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr5, addr(outHandles[5])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr6, addr(outHandles[6])) + tipcResponseGetHandle(addr(res), outHandleAttrs.attr7, addr(outHandles[7])) + return 0 + +proc tipcDispatchImpl*(s: ptr TipcService; requestId: U32; inData: pointer; + inDataSize: U32; outData: pointer; outDataSize: U32; + disp: TipcDispatchParams): Result {.inline, cdecl.} = + var `in`: pointer = tipcMakeRequest(requestId, inDataSize, disp.inSendPid, + disp.bufferAttrs, disp.buffers, + disp.inNumHandles, disp.inHandles) + if inDataSize.bool: + copyMem(`in`, inData, inDataSize) + var rc: Result = svcSendSyncRequest(s.session) + if r_Succeeded(rc): + var `out`: pointer = nil + rc = tipcParseResponse(outDataSize, addr(`out`), disp.outNumObjects, + disp.outObjects, disp.outHandleAttrs, disp.outHandles) + if r_Succeeded(rc) and outData != nil and outDataSize.bool: + copyMem(outData, `out`, outDataSize) + return rc + +## !!!Ignored construct: # ( _s , _rid , ... ) tipcDispatchImpl ( ( _s ) , ( _rid ) , NULL , 0 , NULL , 0 , ( TipcDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _in , ... ) tipcDispatchImpl ( ( _s ) , ( _rid ) , & ( _in ) , sizeof ( _in ) , NULL , 0 , ( TipcDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _out , ... ) tipcDispatchImpl ( ( _s ) , ( _rid ) , NULL , 0 , & ( _out ) , sizeof ( _out ) , ( TipcDispatchParams ) { __VA_ARGS__ } ) [NewLine] # ( _s , _rid , _in , _out , ... ) tipcDispatchImpl ( ( _s ) , ( _rid ) , & ( _in ) , sizeof ( _in ) , & ( _out ) , sizeof ( _out ) , ( TipcDispatchParams ) { __VA_ARGS__ } ) [NewLine] +## Error: identifier expected, but got: (!!! diff --git a/src/libnx/wrapper/switch/switch.c2nim b/src/libnx/wrapper/switch/switch.c2nim new file mode 100644 index 0000000..65bbf0b --- /dev/null +++ b/src/libnx/wrapper/switch/switch.c2nim @@ -0,0 +1,14 @@ +#nep1 +#skipinclude +#cdecl +#mangle uint8_t uint8 +#mangle uint16_t uint16 +#mangle uint32_t uint32 +#mangle uint64_t uint64 +#mangle "'__uint128_t'" "u128" +#mangle int8_t int8 +#mangle int16_t int16 +#mangle int32_t int32 +#mangle int64_t int64 +#mangle "'__int128_t'" "s128" +#dynlib libobjc diff --git a/src/libnx/wrapper/switch/types.h b/src/libnx/wrapper/switch/types.h new file mode 100644 index 0000000..165eb00 --- /dev/null +++ b/src/libnx/wrapper/switch/types.h @@ -0,0 +1,96 @@ +/** + * @file switch/types.h + * @brief Various system types. + * @copyright libnx Authors + */ +#pragma once + +#include +#include +#include +#include + +#ifndef SSIZE_MAX +#ifdef SIZE_MAX +#define SSIZE_MAX ((SIZE_MAX) >> 1) +#endif +#endif + +typedef uint8_t u8; ///< 8-bit unsigned integer. +typedef uint16_t u16; ///< 16-bit unsigned integer. +typedef uint32_t u32; ///< 32-bit unsigned integer. +typedef uint64_t u64; ///< 64-bit unsigned integer. +typedef __uint128_t u128; ///< 128-bit unsigned integer. + +typedef int8_t s8; ///< 8-bit signed integer. +typedef int16_t s16; ///< 16-bit signed integer. +typedef int32_t s32; ///< 32-bit signed integer. +typedef int64_t s64; ///< 64-bit signed integer. +typedef __int128_t s128; ///< 128-bit unsigned integer. + +typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer. +typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer. +typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer. +typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer. +typedef volatile u128 vu128; ///< 128-bit volatile unsigned integer. + +typedef volatile s8 vs8; ///< 8-bit volatile signed integer. +typedef volatile s16 vs16; ///< 16-bit volatile signed integer. +typedef volatile s32 vs32; ///< 32-bit volatile signed integer. +typedef volatile s64 vs64; ///< 64-bit volatile signed integer. +typedef volatile s128 vs128; ///< 128-bit volatile signed integer. + +typedef u32 Handle; ///< Kernel object handle. +typedef u32 Result; ///< Function error code result type. +typedef void (*ThreadFunc)(void *); ///< Thread entrypoint function. +typedef void (*VoidFn)(void); ///< Function without arguments nor return value. + +typedef struct { u8 uuid[0x10]; } Uuid; ///< Unique identifier. + +typedef struct { float value[3]; } UtilFloat3; ///< 3 floats. + +/// Creates a bitmask from a bit number. +#ifndef BIT +#define BIT(n) (1U<<(n)) +#endif + +#ifndef BITL +#define BITL(n) (1UL<<(n)) +#endif + +/// Packs a struct so that it won't include padding bytes. +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif + +/// Marks a function as not returning, for the purposes of compiler optimization. +#ifndef NORETURN +#define NORETURN __attribute__((noreturn)) +#endif + +/// Performs a dummy operation on the specified argument in order to silence compiler warnings about unused arguments. +#ifndef IGNORE_ARG +#define IGNORE_ARG(x) (void)(x) +#endif + +/// Flags a function as deprecated. +#ifndef DEPRECATED +#ifndef LIBNX_NO_DEPRECATION +#define DEPRECATED __attribute__ ((deprecated)) +#else +#define DEPRECATED +#endif +#endif + +/// Flags a function as (always) inline. +#define NX_INLINE __attribute__((always_inline)) static inline + +/// Flags a function as constexpr in C++14 and above; or as (always) inline otherwise. +#if __cplusplus >= 201402L +#define NX_CONSTEXPR NX_INLINE constexpr +#else +#define NX_CONSTEXPR NX_INLINE +#endif + +/// Invalid handle. +#define INVALID_HANDLE ((Handle) 0) diff --git a/src/libnx/wrapper/switch/types.nim b/src/libnx/wrapper/switch/types.nim new file mode 100644 index 0000000..c6ea3ed --- /dev/null +++ b/src/libnx/wrapper/switch/types.nim @@ -0,0 +1,174 @@ +## * +## @file switch/types.h +## @brief Various system types. +## @copyright libnx Authors +## +import integer128 + +when not defined(SSIZE_MAX): + when defined(SIZE_MAX): + const + SSIZE_MAX* = ((size_Max) shr 1) +type + U8* = uint8 + uintptrT* = culong + intptrT* = clong + +## /< 8-bit unsigned integer. + +type + U16* = uint16 + Ssize_t* = clong + +## /< 16-bit unsigned integer. + +type + U32* = uint32 + +## /< 32-bit unsigned integer. + +type + U64* = uint64 + +## /< 64-bit unsigned integer. + +type + U128* = u128 + +## /< 128-bit unsigned integer. + +type + S8* = int8 + +## /< 8-bit signed integer. + +type + S16* = int16 + +## /< 16-bit signed integer. + +type + S32* = int32 + +## /< 32-bit signed integer. + +type + S64* = int64 + +## /< 64-bit signed integer. + +type + S128* = s128 + +## /< 128-bit unsigned integer. + +type + Vu8* = U8 + +## /< 8-bit volatile unsigned integer. + +type + Vu16* = U16 + +## /< 16-bit volatile unsigned integer. + +type + Vu32* = U32 + +## /< 32-bit volatile unsigned integer. + +type + Vu64* = U64 + +## /< 64-bit volatile unsigned integer. + +type + Vu128* = U128 + +## /< 128-bit volatile unsigned integer. + +type + Vs8* = S8 + +## /< 8-bit volatile signed integer. + +type + Vs16* = S16 + +## /< 16-bit volatile signed integer. + +type + Vs32* = S32 + +## /< 32-bit volatile signed integer. + +type + Vs64* = S64 + +## /< 64-bit volatile signed integer. + +type + Vs128* = S128 + +## /< 128-bit volatile signed integer. + +type + Handle* = U32 + +## /< Kernel object handle. + +type + Result* = U32 + +## /< Function error code result type. + +type + ThreadFunc* = proc (a1: pointer) {.cdecl.} + +## /< Thread entrypoint function. + +type + VoidFn* = proc () {.cdecl.} + +## /< Function without arguments nor return value. + +type + Uuid* {.importc: "Uuid", header: "types.h", bycopy.} = object + uuid* {.importc: "uuid".}: array[0x10, U8] + + +## /< Unique identifier. + +type + UtilFloat3* {.importc: "UtilFloat3", header: "types.h", bycopy.} = object + value* {.importc: "value".}: array[3, cfloat] + + +## /< 3 floats. +## / Creates a bitmask from a bit number. + +template bit*(n: untyped): untyped = + (1'u32 shl (n).int) + +template bitl*(n: untyped): untyped = + (1'u64 shl (n).int) + +const INVALID_HANDLE* = 0.uint32 + +template `+`*[T](p: ptr T, off: SomeInteger): ptr T = + cast[ptr type(p[])](cast[ByteAddress](p) +% (off * (off.type)sizeof(p[])).int64) + +template `+=`*[T](p: ptr T, off: SomeInteger) = + p = p + off + +template `-`*[T](p: ptr T, off: SomeInteger): ptr T = + cast[ptr type(p[])](cast[ByteAddress](p) -% (off * (off.type)sizeof(p[])).int64) + +template `-=`*[T](p: ptr T, off: SomeInteger) = + p = p - off + +template `[]`*[T](p: ptr T, off: SomeInteger): T = + (p + off)[] + +template `[]=`*[T](p: ptr T, off: SomeInteger, val: T) = + (p + off)[] = val