Added PsmSession, which is now an additional param for: psmBindStateChangeEvent, psmWaitStateChangeEvent, and psmUnbindStateChangeEvent. Hence, the psm session is now handled with this object instead of libnx automatically handling it internally. psmBindStateChangeEvent no longer calls psmUnbindStateChangeEvent. Other adjustments.

This commit is contained in:
yellows8 2018-12-31 19:36:07 -05:00
parent 2c89aed2b9
commit e59036d4c8
2 changed files with 50 additions and 58 deletions

View File

@ -6,6 +6,8 @@
*/ */
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../services/sm.h"
#include "../kernel/event.h"
typedef enum { typedef enum {
ChargerType_None = 0, ///< No charger ChargerType_None = 0, ///< No charger
@ -20,6 +22,12 @@ typedef enum {
PsmBatteryVoltageState_Normal = 3, ///< Everything is normal PsmBatteryVoltageState_Normal = 3, ///< Everything is normal
} PsmBatteryVoltageState; } PsmBatteryVoltageState;
/// IPsmSession
typedef struct {
Service s;
Event StateChangeEvent; ///< autoclear=false
} PsmSession;
Result psmInitialize(void); Result psmInitialize(void);
void psmExit(void); void psmExit(void);
@ -28,17 +36,17 @@ Result psmGetChargerType(ChargerType *out);
Result psmGetBatteryVoltageState(PsmBatteryVoltageState *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 Uses the actual BindStateChangeEvent cmd internally.
* @note The event is not signalled on BatteryChargePercentage changes. * @note The event is not signalled on BatteryChargePercentage changes.
* @param[in] ChargerType Passed to SetChargerTypeChangeEventEnabled. * @param[in] ChargerType Passed to SetChargerTypeChangeEventEnabled.
* @param[in] PowerSupply Passed to SetPowerSupplyChangeEventEnabled. * @param[in] PowerSupply Passed to SetPowerSupplyChangeEventEnabled.
* @param[in] BatteryVoltage Passed to SetBatteryVoltageStateChangeEventEnabled. * @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. /// Wait on the Event setup by \ref psmBindStateChangeEvent.
Result psmWaitStateChangeEvent(u64 timeout); Result psmWaitStateChangeEvent(PsmSession* s, u64 timeout);
/// Cleanup version of psmBindStateChangeEvent. Called automatically by \ref psmExit and \ref psmBindStateChangeEvent, if already initialized. /// Cleanup version of \ref psmBindStateChangeEvent. Must be called by the user once the PsmSession is done being used.
Result psmUnbindStateChangeEvent(void); Result psmUnbindStateChangeEvent(PsmSession* s);

View File

@ -8,17 +8,14 @@
#include "services/sm.h" #include "services/sm.h"
static Service g_psmSrv; static Service g_psmSrv;
static Service g_psmSession;
static Event g_psmStateChangeEvent;
static bool g_psmStateChangeEventInitialized;
static u64 g_refCnt; static u64 g_refCnt;
static Result _psmOpenSession(Service* out); 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 _psmSetChargerTypeChangeEventEnabled(PsmSession* s, bool flag);
static Result _psmSetPowerSupplyChangeEventEnabled(bool flag); static Result _psmSetPowerSupplyChangeEventEnabled(PsmSession* s, bool flag);
static Result _psmSetBatteryVoltageStateChangeEventEnabled(bool flag); static Result _psmSetBatteryVoltageStateChangeEventEnabled(PsmSession* s, bool flag);
Result psmInitialize(void) { Result psmInitialize(void) {
Result rc = 0; Result rc = 0;
@ -28,14 +25,8 @@ Result psmInitialize(void) {
if (serviceIsActive(&g_psmSrv)) if (serviceIsActive(&g_psmSrv))
return 0; return 0;
g_psmStateChangeEventInitialized = 0;
rc = smGetService(&g_psmSrv, "psm"); rc = smGetService(&g_psmSrv, "psm");
if (R_SUCCEEDED(rc)) {
rc = _psmOpenSession(&g_psmSession);
}
if (R_FAILED(rc)) psmExit(); if (R_FAILED(rc)) psmExit();
return rc; return rc;
@ -43,8 +34,6 @@ Result psmInitialize(void) {
void psmExit(void) { void psmExit(void) {
if (atomicDecrement64(&g_refCnt) == 0) { if (atomicDecrement64(&g_refCnt) == 0) {
if (g_psmStateChangeEventInitialized) psmUnbindStateChangeEvent();
serviceClose(&g_psmSession);
serviceClose(&g_psmSrv); serviceClose(&g_psmSrv);
} }
} }
@ -140,39 +129,36 @@ static Result _psmOpenSession(Service* out) {
return rc; return rc;
} }
Result psmBindStateChangeEvent(bool ChargerType, bool PowerSupply, bool BatteryVoltage) { Result psmBindStateChangeEvent(PsmSession* s, bool ChargerType, bool PowerSupply, bool BatteryVoltage) {
Result rc=0; Result rc=0;
if (g_psmStateChangeEventInitialized) { rc = _psmOpenSession(&s->s);
rc = psmUnbindStateChangeEvent();
if (R_FAILED(rc)) return rc;
}
rc = _psmSetChargerTypeChangeEventEnabled(ChargerType);
if (R_FAILED(rc)) return rc; if (R_FAILED(rc)) return rc;
rc = _psmSetPowerSupplyChangeEventEnabled(PowerSupply); rc = _psmSetChargerTypeChangeEventEnabled(s, ChargerType);
if (R_FAILED(rc)) return rc; if (R_FAILED(rc)) return rc;
rc = _psmSetBatteryVoltageStateChangeEventEnabled(BatteryVoltage); rc = _psmSetPowerSupplyChangeEventEnabled(s, PowerSupply);
if (R_FAILED(rc)) return rc; 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; return rc;
} }
Result psmWaitStateChangeEvent(u64 timeout) { Result psmWaitStateChangeEvent(PsmSession* s, u64 timeout) {
Result rc = 0; Result rc = 0;
rc = eventWait(&g_psmStateChangeEvent, timeout); rc = eventWait(&s->StateChangeEvent, timeout);
if (R_SUCCEEDED(rc)) rc = eventClear(&g_psmStateChangeEvent); if (R_SUCCEEDED(rc)) rc = eventClear(&s->StateChangeEvent);
return rc; return rc;
} }
static Result _psmBindStateChangeEvent(Event *event_out) { static Result _psmBindStateChangeEvent(PsmSession* s, Event *event_out) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
@ -181,12 +167,12 @@ static Result _psmBindStateChangeEvent(Event *event_out) {
u64 cmd_id; u64 cmd_id;
} *raw; } *raw;
raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC; raw->magic = SFCI_MAGIC;
raw->cmd_id = 0; raw->cmd_id = 0;
Result rc = serviceIpcDispatch(&g_psmSession); Result rc = serviceIpcDispatch(&s->s);
if(R_SUCCEEDED(rc)) { if(R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -196,7 +182,7 @@ static Result _psmBindStateChangeEvent(Event *event_out) {
u64 result; u64 result;
} *resp; } *resp;
serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); serviceIpcParse(&s->s, &r, sizeof(*resp));
resp = r.Raw; resp = r.Raw;
rc = resp->result; rc = resp->result;
@ -209,26 +195,21 @@ static Result _psmBindStateChangeEvent(Event *event_out) {
return rc; return rc;
} }
Result psmUnbindStateChangeEvent(void) { Result psmUnbindStateChangeEvent(PsmSession* s) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
if (g_psmStateChangeEventInitialized) {
g_psmStateChangeEventInitialized = 0;
eventClose(&g_psmStateChangeEvent);
}
struct { struct {
u64 magic; u64 magic;
u64 cmd_id; u64 cmd_id;
} *raw; } *raw;
raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC; raw->magic = SFCI_MAGIC;
raw->cmd_id = 1; raw->cmd_id = 1;
Result rc = serviceIpcDispatch(&g_psmSession); Result rc = serviceIpcDispatch(&s->s);
if(R_SUCCEEDED(rc)) { if(R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -238,16 +219,19 @@ Result psmUnbindStateChangeEvent(void) {
u64 result; u64 result;
} *resp; } *resp;
serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); serviceIpcParse(&s->s, &r, sizeof(*resp));
resp = r.Raw; resp = r.Raw;
rc = resp->result; rc = resp->result;
} }
eventClose(&s->StateChangeEvent);
serviceClose(&s->s);
return rc; return rc;
} }
static Result _psmSetEventEnabled(u64 cmd_id, bool flag) { static Result _psmSetEventEnabled(PsmSession* s, u64 cmd_id, bool flag) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
@ -257,13 +241,13 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) {
u8 flag; u8 flag;
} *raw; } *raw;
raw = serviceIpcPrepareHeader(&g_psmSession, &c, sizeof(*raw)); raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC; raw->magic = SFCI_MAGIC;
raw->cmd_id = cmd_id; raw->cmd_id = cmd_id;
raw->flag = (flag != 0); raw->flag = (flag != 0);
Result rc = serviceIpcDispatch(&g_psmSession); Result rc = serviceIpcDispatch(&s->s);
if(R_SUCCEEDED(rc)) { if(R_SUCCEEDED(rc)) {
IpcParsedCommand r; IpcParsedCommand r;
@ -273,7 +257,7 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) {
u64 result; u64 result;
} *resp; } *resp;
serviceIpcParse(&g_psmSession, &r, sizeof(*resp)); serviceIpcParse(&s->s, &r, sizeof(*resp));
resp = r.Raw; resp = r.Raw;
rc = resp->result; rc = resp->result;
@ -282,14 +266,14 @@ static Result _psmSetEventEnabled(u64 cmd_id, bool flag) {
return rc; return rc;
} }
static Result _psmSetChargerTypeChangeEventEnabled(bool flag) { static Result _psmSetChargerTypeChangeEventEnabled(PsmSession* s, bool flag) {
return _psmSetEventEnabled(2, flag); return _psmSetEventEnabled(s, 2, flag);
} }
static Result _psmSetPowerSupplyChangeEventEnabled(bool flag) { static Result _psmSetPowerSupplyChangeEventEnabled(PsmSession* s, bool flag) {
return _psmSetEventEnabled(3, flag); return _psmSetEventEnabled(s, 3, flag);
} }
static Result _psmSetBatteryVoltageStateChangeEventEnabled(bool flag) { static Result _psmSetBatteryVoltageStateChangeEventEnabled(PsmSession* s, bool flag) {
return _psmSetEventEnabled(4, flag); return _psmSetEventEnabled(s, 4, flag);
} }