diff --git a/nx/include/switch/services/psm.h b/nx/include/switch/services/psm.h index 3062e8c2..79d74803 100644 --- a/nx/include/switch/services/psm.h +++ b/nx/include/switch/services/psm.h @@ -6,6 +6,8 @@ */ #pragma once #include "../types.h" +#include "../services/sm.h" +#include "../kernel/event.h" typedef enum { ChargerType_None = 0, ///< No charger @@ -20,6 +22,12 @@ typedef enum { PsmBatteryVoltageState_Normal = 3, ///< Everything is normal } PsmBatteryVoltageState; +/// IPsmSession +typedef struct { + Service s; + Event StateChangeEvent; ///< autoclear=false +} PsmSession; + Result psmInitialize(void); void psmExit(void); @@ -28,17 +36,17 @@ Result psmGetChargerType(ChargerType *out); Result psmGetBatteryVoltageState(PsmBatteryVoltageState *out); /** - * @brief Wrapper func which handles event setup. + * @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[in] ChargerType Passed to SetChargerTypeChangeEventEnabled. * @param[in] PowerSupply Passed to SetPowerSupplyChangeEventEnabled. * @param[in] BatteryVoltage Passed to SetBatteryVoltageStateChangeEventEnabled. */ -Result psmBindStateChangeEvent(bool ChargerType, bool PowerSupply, bool BatteryVoltage); +Result psmBindStateChangeEvent(PsmSession* s, bool ChargerType, bool PowerSupply, bool BatteryVoltage); -/// Wait on the Event setup by psmBindStateChangeEvent. -Result psmWaitStateChangeEvent(u64 timeout); +/// Wait on the Event setup by \ref psmBindStateChangeEvent. +Result psmWaitStateChangeEvent(PsmSession* s, u64 timeout); -/// Cleanup version of psmBindStateChangeEvent. Called automatically by \ref psmExit and \ref psmBindStateChangeEvent, if already initialized. -Result psmUnbindStateChangeEvent(void); +/// 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/nx/source/services/psm.c b/nx/source/services/psm.c index 24f5679e..38d18203 100644 --- a/nx/source/services/psm.c +++ b/nx/source/services/psm.c @@ -8,17 +8,14 @@ #include "services/sm.h" static Service g_psmSrv; -static Service g_psmSession; -static Event g_psmStateChangeEvent; -static bool g_psmStateChangeEventInitialized; static u64 g_refCnt; static Result _psmOpenSession(Service* out); -static Result _psmBindStateChangeEvent(Event* event_out); +static Result _psmBindStateChangeEvent(PsmSession* s, Event* event_out); -static Result _psmSetChargerTypeChangeEventEnabled(bool flag); -static Result _psmSetPowerSupplyChangeEventEnabled(bool flag); -static Result _psmSetBatteryVoltageStateChangeEventEnabled(bool flag); +static Result _psmSetChargerTypeChangeEventEnabled(PsmSession* s, bool flag); +static Result _psmSetPowerSupplyChangeEventEnabled(PsmSession* s, bool flag); +static Result _psmSetBatteryVoltageStateChangeEventEnabled(PsmSession* s, bool flag); Result psmInitialize(void) { Result rc = 0; @@ -28,14 +25,8 @@ Result psmInitialize(void) { if (serviceIsActive(&g_psmSrv)) return 0; - g_psmStateChangeEventInitialized = 0; - rc = smGetService(&g_psmSrv, "psm"); - if (R_SUCCEEDED(rc)) { - rc = _psmOpenSession(&g_psmSession); - } - if (R_FAILED(rc)) psmExit(); return rc; @@ -43,8 +34,6 @@ Result psmInitialize(void) { void psmExit(void) { if (atomicDecrement64(&g_refCnt) == 0) { - if (g_psmStateChangeEventInitialized) psmUnbindStateChangeEvent(); - serviceClose(&g_psmSession); serviceClose(&g_psmSrv); } } @@ -140,39 +129,36 @@ static Result _psmOpenSession(Service* out) { return rc; } -Result psmBindStateChangeEvent(bool ChargerType, bool PowerSupply, bool BatteryVoltage) { +Result psmBindStateChangeEvent(PsmSession* s, bool ChargerType, bool PowerSupply, bool BatteryVoltage) { Result rc=0; - if (g_psmStateChangeEventInitialized) { - rc = psmUnbindStateChangeEvent(); - if (R_FAILED(rc)) return rc; - } - - rc = _psmSetChargerTypeChangeEventEnabled(ChargerType); + rc = _psmOpenSession(&s->s); if (R_FAILED(rc)) return rc; - rc = _psmSetPowerSupplyChangeEventEnabled(PowerSupply); + rc = _psmSetChargerTypeChangeEventEnabled(s, ChargerType); if (R_FAILED(rc)) return rc; - rc = _psmSetBatteryVoltageStateChangeEventEnabled(BatteryVoltage); + rc = _psmSetPowerSupplyChangeEventEnabled(s, PowerSupply); if (R_FAILED(rc)) return rc; - rc = _psmBindStateChangeEvent(&g_psmStateChangeEvent); + rc = _psmSetBatteryVoltageStateChangeEventEnabled(s, BatteryVoltage); + if (R_FAILED(rc)) return rc; - if (R_SUCCEEDED(rc)) g_psmStateChangeEventInitialized = 1; + rc = _psmBindStateChangeEvent(s, &s->StateChangeEvent); + if (R_FAILED(rc)) serviceClose(&s->s); return rc; } -Result psmWaitStateChangeEvent(u64 timeout) { +Result psmWaitStateChangeEvent(PsmSession* s, u64 timeout) { Result rc = 0; - rc = eventWait(&g_psmStateChangeEvent, timeout); - if (R_SUCCEEDED(rc)) rc = eventClear(&g_psmStateChangeEvent); + rc = eventWait(&s->StateChangeEvent, timeout); + if (R_SUCCEEDED(rc)) rc = eventClear(&s->StateChangeEvent); return rc; } -static Result _psmBindStateChangeEvent(Event *event_out) { +static Result _psmBindStateChangeEvent(PsmSession* s, Event *event_out) { IpcCommand c; ipcInitialize(&c); @@ -181,12 +167,12 @@ static Result _psmBindStateChangeEvent(Event *event_out) { u64 cmd_id; } *raw; - raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 0; - Result rc = serviceIpcDispatch(&g_psmSession); + Result rc = serviceIpcDispatch(&s->s); if(R_SUCCEEDED(rc)) { IpcParsedCommand r; @@ -196,7 +182,7 @@ static Result _psmBindStateChangeEvent(Event *event_out) { u64 result; } *resp; - serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); + serviceIpcParse(&s->s, &r, sizeof(*resp)); resp = r.Raw; rc = resp->result; @@ -209,26 +195,21 @@ static Result _psmBindStateChangeEvent(Event *event_out) { return rc; } -Result psmUnbindStateChangeEvent(void) { +Result psmUnbindStateChangeEvent(PsmSession* s) { IpcCommand c; ipcInitialize(&c); - if (g_psmStateChangeEventInitialized) { - g_psmStateChangeEventInitialized = 0; - eventClose(&g_psmStateChangeEvent); - } - struct { u64 magic; u64 cmd_id; } *raw; - raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 1; - Result rc = serviceIpcDispatch(&g_psmSession); + Result rc = serviceIpcDispatch(&s->s); if(R_SUCCEEDED(rc)) { IpcParsedCommand r; @@ -238,16 +219,19 @@ Result psmUnbindStateChangeEvent(void) { u64 result; } *resp; - serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); + serviceIpcParse(&s->s, &r, sizeof(*resp)); resp = r.Raw; rc = resp->result; } + eventClose(&s->StateChangeEvent); + serviceClose(&s->s); + return rc; } -static Result _psmSetEventEnabled(u64 cmd_id, bool flag) { +static Result _psmSetEventEnabled(PsmSession* s, u64 cmd_id, bool flag) { IpcCommand c; ipcInitialize(&c); @@ -257,13 +241,13 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) { u8 flag; } *raw; - raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = cmd_id; raw->flag = (flag != 0); - Result rc = serviceIpcDispatch(&g_psmSession); + Result rc = serviceIpcDispatch(&s->s); if(R_SUCCEEDED(rc)) { IpcParsedCommand r; @@ -273,7 +257,7 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) { u64 result; } *resp; - serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); + serviceIpcParse(&s->s, &r, sizeof(*resp)); resp = r.Raw; rc = resp->result; @@ -282,14 +266,14 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) { return rc; } -static Result _psmSetChargerTypeChangeEventEnabled(bool flag) { - return _psmSetEventEnabled(2, flag); +static Result _psmSetChargerTypeChangeEventEnabled(PsmSession* s, bool flag) { + return _psmSetEventEnabled(s, 2, flag); } -static Result _psmSetPowerSupplyChangeEventEnabled(bool flag) { - return _psmSetEventEnabled(3, flag); +static Result _psmSetPowerSupplyChangeEventEnabled(PsmSession* s, bool flag) { + return _psmSetEventEnabled(s, 3, flag); } -static Result _psmSetBatteryVoltageStateChangeEventEnabled(bool flag) { - return _psmSetEventEnabled(4, flag); +static Result _psmSetBatteryVoltageStateChangeEventEnabled(PsmSession* s, bool flag) { + return _psmSetEventEnabled(s, 4, flag); }