mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
time: Updated for new-ipc. Renamed _timeGetClockSession to timeGetServiceSession_SystemClock, and added it to the .h. Added timeGetServiceSession_TimeZoneService. Fixed the order of cmds. Fixed param types for timeGetTotalLocationNameCount, timeLoadLocationNameList, timeToPosixTime, and timeToPosixTimeWithMyRule. The location_name_size param for timeLoadLocationNameList was replaced with location_name_max, which is max entries instead of buffer byte-size. Internal improvements and improved docs.
This commit is contained in:
parent
ae582d8cb4
commit
040b33c457
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../types.h"
|
||||
#include "../services/sm.h"
|
||||
#include "../sf/service.h"
|
||||
|
||||
/// Time clock type.
|
||||
typedef enum {
|
||||
@ -28,11 +28,11 @@ typedef struct {
|
||||
} 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.
|
||||
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 {
|
||||
@ -43,11 +43,27 @@ typedef struct {
|
||||
char name[0x24];
|
||||
} TimeLocationName;
|
||||
|
||||
/// 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 ITimeZoneService.
|
||||
Service* timeGetServiceSession_TimeZoneService(void);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
@ -60,13 +76,13 @@ Result timeSetCurrentTime(TimeType type, u64 timestamp);
|
||||
|
||||
Result timeGetDeviceLocationName(TimeLocationName *name);
|
||||
Result timeSetDeviceLocationName(const TimeLocationName *name);
|
||||
Result timeGetTotalLocationNameCount(u32 *total_location_name_count);
|
||||
Result timeLoadLocationNameList(u32 index, TimeLocationName *location_name_array, size_t location_name_size, u32 *location_name_count);
|
||||
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 timeToPosixTime(const TimeZoneRule *rule, const TimeCalendarTime *caltime, u64 *timestamp_list, size_t timestamp_list_count, u32 *timestamp_count);
|
||||
Result timeToPosixTimeWithMyRule(const TimeCalendarTime *caltime, u64 *timestamp_list, size_t timestamp_list_count, u32 *timestamp_count);
|
||||
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);
|
||||
|
||||
|
@ -1,28 +1,19 @@
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "result.h"
|
||||
#include "arm/atomics.h"
|
||||
#include "kernel/ipc.h"
|
||||
#define NX_SERVICE_ASSUME_NON_DOMAIN
|
||||
#include "service_guard.h"
|
||||
#include "services/time.h"
|
||||
#include "services/sm.h"
|
||||
|
||||
static Service g_timeSrv;
|
||||
static Service g_timeUserSystemClock;
|
||||
static Service g_timeNetworkSystemClock;
|
||||
static Service g_timeTimeZoneService;
|
||||
static Service g_timeLocalSystemClock;
|
||||
static u64 g_refCnt;
|
||||
|
||||
static Result _timeGetSession(Service* srv_out, u64 cmd_id);
|
||||
static Result _timeCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id);
|
||||
|
||||
Result timeInitialize(void)
|
||||
{
|
||||
atomicIncrement64(&g_refCnt);
|
||||
NX_GENERATE_SERVICE_GUARD(time);
|
||||
|
||||
if (serviceIsActive(&g_timeSrv))
|
||||
return 0;
|
||||
|
||||
Result rc;
|
||||
Result _timeInitialize(void) {
|
||||
Result rc=0;
|
||||
|
||||
rc = smGetService(&g_timeSrv, "time:s");
|
||||
if (R_FAILED(rc))
|
||||
@ -31,75 +22,33 @@ Result timeInitialize(void)
|
||||
if (R_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
rc = _timeGetSession(&g_timeUserSystemClock, 0);
|
||||
rc = _timeCmdGetSession(&g_timeSrv, &g_timeUserSystemClock, 0);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = _timeGetSession(&g_timeNetworkSystemClock, 1);
|
||||
rc = _timeCmdGetSession(&g_timeSrv, &g_timeNetworkSystemClock, 1);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = _timeGetSession(&g_timeTimeZoneService, 3);
|
||||
rc = _timeCmdGetSession(&g_timeSrv, &g_timeTimeZoneService, 3);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = _timeGetSession(&g_timeLocalSystemClock, 4);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
timeExit();
|
||||
rc = _timeCmdGetSession(&g_timeSrv, &g_timeLocalSystemClock, 4);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void timeExit(void)
|
||||
{
|
||||
if (atomicDecrement64(&g_refCnt) == 0)
|
||||
{
|
||||
serviceClose(&g_timeLocalSystemClock);
|
||||
serviceClose(&g_timeTimeZoneService);
|
||||
serviceClose(&g_timeNetworkSystemClock);
|
||||
serviceClose(&g_timeUserSystemClock);
|
||||
serviceClose(&g_timeSrv);
|
||||
}
|
||||
void _timeCleanup(void) {
|
||||
serviceClose(&g_timeLocalSystemClock);
|
||||
serviceClose(&g_timeTimeZoneService);
|
||||
serviceClose(&g_timeNetworkSystemClock);
|
||||
serviceClose(&g_timeUserSystemClock);
|
||||
serviceClose(&g_timeSrv);
|
||||
}
|
||||
|
||||
Service* timeGetServiceSession(void) {
|
||||
return &g_timeSrv;
|
||||
}
|
||||
|
||||
static Result _timeGetSession(Service* srv_out, u64 cmd_id) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
serviceCreate(srv_out, r.Handles[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Service* _timeGetClockSession(TimeType type) {
|
||||
Service* timeGetServiceSession_SystemClock(TimeType type) {
|
||||
if (type==TimeType_UserSystemClock) {
|
||||
return &g_timeUserSystemClock;
|
||||
}
|
||||
@ -114,409 +63,143 @@ static Service* _timeGetClockSession(TimeType type) {
|
||||
}
|
||||
}
|
||||
|
||||
Service* timeGetServiceSession_TimeZoneService(void) {
|
||||
return &g_timeTimeZoneService;
|
||||
}
|
||||
|
||||
static Result _timeCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id) {
|
||||
return serviceDispatch(srv, cmd_id,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = srv_out,
|
||||
);
|
||||
}
|
||||
|
||||
static Result _timeCmdInU64NoOut(Service* srv, u64 inval, u32 cmd_id) {
|
||||
return serviceDispatchIn(srv, cmd_id, inval);
|
||||
}
|
||||
|
||||
static Result _timeCmdNoInOutU64(Service* srv, u64 *out, u32 cmd_id) {
|
||||
return serviceDispatchOut(srv, cmd_id, *out);
|
||||
}
|
||||
|
||||
static Result _appletCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) {
|
||||
return serviceDispatchOut(srv, cmd_id, *out);
|
||||
}
|
||||
|
||||
Result timeGetCurrentTime(TimeType type, u64 *timestamp) {
|
||||
Service *srv = _timeGetClockSession(type);
|
||||
Service *srv = timeGetServiceSession_SystemClock(type);
|
||||
|
||||
if (srv==NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
|
||||
Result rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 timestamp;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && timestamp) *timestamp = resp->timestamp;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return _timeCmdNoInOutU64(srv, timestamp, 0);
|
||||
}
|
||||
|
||||
Result timeSetCurrentTime(TimeType type, u64 timestamp) {
|
||||
Service *srv = _timeGetClockSession(type);
|
||||
Service *srv = timeGetServiceSession_SystemClock(type);
|
||||
|
||||
if (srv==NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 timestamp;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->timestamp = timestamp;
|
||||
|
||||
Result rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return _timeCmdInU64NoOut(srv, timestamp, 1);
|
||||
}
|
||||
|
||||
Result timeGetDeviceLocationName(TimeLocationName *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
TimeLocationName name;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && name) memcpy(name, &resp->name, sizeof(TimeLocationName));
|
||||
}
|
||||
|
||||
return rc;
|
||||
return serviceDispatchOut(&g_timeTimeZoneService, 0, *name);
|
||||
}
|
||||
|
||||
Result timeSetDeviceLocationName(const TimeLocationName *name) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
TimeLocationName name;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
memcpy(&raw->name, name, sizeof(TimeLocationName));
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return serviceDispatchIn(&g_timeTimeZoneService, 1, *name);
|
||||
}
|
||||
|
||||
Result timeGetTotalLocationNameCount(u32 *total_location_name_count) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
Result timeGetTotalLocationNameCount(s32 *total_location_name_count) {
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 total_location_name_count;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && total_location_name_count) *total_location_name_count = resp->total_location_name_count;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return _appletCmdNoInOutU32(&g_timeTimeZoneService, (u32*)total_location_name_count, 2);
|
||||
}
|
||||
|
||||
Result timeLoadLocationNameList(u32 index, TimeLocationName *location_name_array, size_t location_name_size, u32 *location_name_count) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, location_name_array, location_name_size, BufferType_Normal);
|
||||
Result timeLoadLocationNameList(s32 index, TimeLocationName *location_name_array, s32 location_name_max, s32 *location_name_count) {
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 index;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 3;
|
||||
raw->index = index;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 location_name_count;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && location_name_count) *location_name_count = resp->location_name_count;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return serviceDispatchInOut(&g_timeTimeZoneService, 3, index, *location_name_count,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { location_name_array, sizeof(TimeLocationName)*location_name_max } },
|
||||
);
|
||||
}
|
||||
|
||||
Result timeLoadTimeZoneRule(const TimeLocationName *name, TimeZoneRule *rule) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, rule, sizeof(TimeZoneRule), BufferType_Normal);
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
TimeLocationName name;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 4;
|
||||
memcpy(&raw->name, name, sizeof(TimeLocationName));
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return serviceDispatchIn(&g_timeTimeZoneService, 4, *name,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||
.buffers = { { rule, sizeof(TimeZoneRule) } },
|
||||
);
|
||||
}
|
||||
|
||||
Result timeToCalendarTime(const TimeZoneRule *rule, u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendBuffer(&c, rule, sizeof(TimeZoneRule), BufferType_Normal);
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 timestamp;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 100;
|
||||
raw->timestamp = timestamp;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
TimeCalendarTime caltime;
|
||||
TimeCalendarAdditionalInfo info;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && caltime) memcpy(caltime, &resp->caltime, sizeof(TimeCalendarTime));
|
||||
if (R_SUCCEEDED(rc) && info) memcpy(info, &resp->info, sizeof(TimeCalendarAdditionalInfo));
|
||||
}
|
||||
TimeCalendarTime caltime;
|
||||
TimeCalendarAdditionalInfo info;
|
||||
} out;
|
||||
|
||||
Result rc = serviceDispatchInOut(&g_timeTimeZoneService, 100, timestamp, out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||
.buffers = { { rule, sizeof(TimeZoneRule) } },
|
||||
);
|
||||
if (R_SUCCEEDED(rc) && caltime) *caltime = out.caltime;
|
||||
if (R_SUCCEEDED(rc) && info) *info = out.info;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result timeToCalendarTimeWithMyRule(u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 timestamp;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 101;
|
||||
raw->timestamp = timestamp;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
TimeCalendarTime caltime;
|
||||
TimeCalendarAdditionalInfo info;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && caltime) memcpy(caltime, &resp->caltime, sizeof(TimeCalendarTime));
|
||||
if (R_SUCCEEDED(rc) && info) memcpy(info, &resp->info, sizeof(TimeCalendarAdditionalInfo));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result timeToPosixTime(const TimeZoneRule *rule, const TimeCalendarTime *caltime, u64 *timestamp_list, size_t timestamp_list_count, u32 *timestamp_count) {
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendBuffer(&c, rule, sizeof(TimeZoneRule), BufferType_Normal);
|
||||
ipcAddRecvStatic(&c, timestamp_list, sizeof(u64)*timestamp_list_count, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
TimeCalendarTime caltime;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 201;
|
||||
raw->caltime = *caltime;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 timestamp_count;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && timestamp_count) *timestamp_count = resp->timestamp_count;
|
||||
}
|
||||
TimeCalendarAdditionalInfo info;
|
||||
} out;
|
||||
|
||||
Result rc = serviceDispatchInOut(&g_timeTimeZoneService, 101, timestamp, out);
|
||||
if (R_SUCCEEDED(rc) && caltime) *caltime = out.caltime;
|
||||
if (R_SUCCEEDED(rc) && info) *info = out.info;
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result timeToPosixTimeWithMyRule(const TimeCalendarTime *caltime, u64 *timestamp_list, size_t timestamp_list_count, u32 *timestamp_count) {
|
||||
Result timeToPosixTime(const TimeZoneRule *rule, const TimeCalendarTime *caltime, u64 *timestamp_list, s32 timestamp_list_count, s32 *timestamp_count) {
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvStatic(&c, timestamp_list, sizeof(u64)*timestamp_list_count, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
TimeCalendarTime caltime;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 202;
|
||||
raw->caltime = *caltime;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 timestamp_count;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && timestamp_count) *timestamp_count = resp->timestamp_count;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return serviceDispatchInOut(&g_timeTimeZoneService, 201, *caltime, *timestamp_count,
|
||||
.buffer_attrs = {
|
||||
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
||||
SfBufferAttr_HipcPointer | SfBufferAttr_Out,
|
||||
},
|
||||
.buffers = {
|
||||
{ rule, sizeof(TimeZoneRule) },
|
||||
{ timestamp_list, sizeof(u64)*timestamp_list_count },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Result timeToPosixTimeWithMyRule(const TimeCalendarTime *caltime, u64 *timestamp_list, s32 timestamp_list_count, s32 *timestamp_count) {
|
||||
if (!serviceIsActive(&g_timeTimeZoneService))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return serviceDispatchInOut(&g_timeTimeZoneService, 202, *caltime, *timestamp_count,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { { timestamp_list, sizeof(u64)*timestamp_list_count } },
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user