mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-05 16:09:24 +02:00
ldn: Use sessionmgr.
This commit is contained in:
parent
eb780c49ac
commit
f6e45096aa
@ -1,6 +1,6 @@
|
||||
#define NX_SERVICE_ASSUME_NON_DOMAIN
|
||||
#include <string.h>
|
||||
#include "service_guard.h"
|
||||
#include "sf/sessionmgr.h"
|
||||
#include "services/ldn.h"
|
||||
#include "runtime/hosversion.h"
|
||||
|
||||
@ -8,11 +8,14 @@ static LdnServiceType g_ldnServiceType;
|
||||
|
||||
__attribute__((weak)) s32 __nx_ldn_priority = LDN_PRIORITY_SYSTEM;
|
||||
|
||||
static Service g_ldnSrvCreator;
|
||||
static Service g_ldnSrv;
|
||||
static Service g_ldnmSrv;
|
||||
|
||||
static Service g_ldnIClientProcessMonitor;
|
||||
|
||||
static SessionMgr g_ldnSessionMgr;
|
||||
|
||||
static Result _ldnGetSession(Service* srv, Service* srv_out, u32 cmd_id);
|
||||
|
||||
static Result _ldnCmdNoIO(Service* srv, u32 cmd_id);
|
||||
@ -30,6 +33,60 @@ static Result _ldnGetIpv4Address(Service* srv, LdnIpv4Address *addr, LdnSubnetMa
|
||||
static Result _ldnGetSecurityParameter(Service* srv, LdnSecurityParameter *out);
|
||||
static Result _ldnGetNetworkConfig(Service* srv, LdnNetworkConfig *out);
|
||||
|
||||
NX_INLINE bool _ldnObjectIsChild(Service* s)
|
||||
{
|
||||
return s->session == g_ldnSrvCreator.session;
|
||||
}
|
||||
|
||||
static void _ldnObjectClose(Service* s) {
|
||||
if (!_ldnObjectIsChild(s)) {
|
||||
serviceClose(s);
|
||||
}
|
||||
else {
|
||||
int slot = sessionmgrAttachClient(&g_ldnSessionMgr);
|
||||
uint32_t object_id = serviceGetObjectId(s);
|
||||
serviceAssumeDomain(s);
|
||||
cmifMakeCloseRequest(armGetTls(), object_id);
|
||||
svcSendSyncRequest(sessionmgrGetClientSession(&g_ldnSessionMgr, slot));
|
||||
sessionmgrDetachClient(&g_ldnSessionMgr, slot);
|
||||
}
|
||||
}
|
||||
|
||||
NX_INLINE Result _ldnObjectDispatchImpl(
|
||||
Service* s, u32 request_id,
|
||||
const void* in_data, u32 in_data_size,
|
||||
void* out_data, u32 out_data_size,
|
||||
SfDispatchParams disp
|
||||
) {
|
||||
int slot = -1;
|
||||
if (_ldnObjectIsChild(s)) {
|
||||
slot = sessionmgrAttachClient(&g_ldnSessionMgr);
|
||||
if (slot < 0) __builtin_unreachable();
|
||||
disp.target_session = sessionmgrGetClientSession(&g_ldnSessionMgr, slot);
|
||||
serviceAssumeDomain(s);
|
||||
}
|
||||
|
||||
Result rc = serviceDispatchImpl(s, request_id, in_data, in_data_size, out_data, out_data_size, disp);
|
||||
|
||||
if (slot >= 0) {
|
||||
sessionmgrDetachClient(&g_ldnSessionMgr, slot);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define _ldnObjectDispatch(_s,_rid,...) \
|
||||
_ldnObjectDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||
|
||||
#define _ldnObjectDispatchIn(_s,_rid,_in,...) \
|
||||
_ldnObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||
|
||||
#define _ldnObjectDispatchOut(_s,_rid,_out,...) \
|
||||
_ldnObjectDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||
|
||||
#define _ldnObjectDispatchInOut(_s,_rid,_in,_out,...) \
|
||||
_ldnObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||
|
||||
// ldn:m
|
||||
|
||||
NX_GENERATE_SERVICE_GUARD(ldnm);
|
||||
@ -83,20 +140,25 @@ Result ldnmGetNetworkConfig(LdnNetworkConfig *out) {
|
||||
NX_GENERATE_SERVICE_GUARD_PARAMS(ldn, (LdnServiceType service_type), (service_type));
|
||||
|
||||
Result _ldnInitialize(LdnServiceType service_type) {
|
||||
Service srv_creator={0};
|
||||
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
s32 version=0;
|
||||
g_ldnServiceType = service_type;
|
||||
switch (g_ldnServiceType) {
|
||||
case LdnServiceType_User:
|
||||
rc = smGetService(&srv_creator, "ldn:u");
|
||||
rc = smGetService(&g_ldnSrvCreator, "ldn:u");
|
||||
break;
|
||||
case LdnServiceType_System:
|
||||
rc = smGetService(&srv_creator, "ldn:s");
|
||||
rc = smGetService(&g_ldnSrvCreator, "ldn:s");
|
||||
break;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _ldnGetSession(&srv_creator, &g_ldnSrv, 0); // CreateSystemLocalCommunicationService/CreateUserLocalCommunicationService
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = serviceConvertToDomain(&g_ldnSrvCreator);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = sessionmgrCreate(&g_ldnSessionMgr, g_ldnSrvCreator.session, 0x3);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _ldnGetSession(&g_ldnSrvCreator, &g_ldnSrv, 0); // CreateSystemLocalCommunicationService/CreateUserLocalCommunicationService
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (hosversionAtLeast(7,0,0)) {
|
||||
@ -122,20 +184,27 @@ Result _ldnInitialize(LdnServiceType service_type) {
|
||||
rc = ldnSetProtocol(LdnProtocol_NX);
|
||||
|
||||
if (R_SUCCEEDED(rc) && hosversionAtLeast(18,0,0)) {
|
||||
rc = _ldnGetSession(&srv_creator, &g_ldnIClientProcessMonitor, 1); // CreateClientProcessMonitor
|
||||
rc = _ldnGetSession(&g_ldnSrvCreator, &g_ldnIClientProcessMonitor, 1); // CreateClientProcessMonitor
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = _ldnCmdInitialize(&g_ldnIClientProcessMonitor, 0); // RegisterClient
|
||||
}
|
||||
|
||||
serviceClose(&srv_creator);
|
||||
_ldnObjectClose(&g_ldnSrvCreator); // Close just the creator object.
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void _ldnCleanup(void) {
|
||||
if (serviceIsActive(&g_ldnSrv)) _ldnCmdNoIO(&g_ldnSrv, 401); // Finalize(System)
|
||||
serviceClose(&g_ldnSrv);
|
||||
serviceClose(&g_ldnIClientProcessMonitor);
|
||||
|
||||
_ldnObjectClose(&g_ldnSrv);
|
||||
_ldnObjectClose(&g_ldnIClientProcessMonitor);
|
||||
|
||||
// Close extra sessions
|
||||
sessionmgrClose(&g_ldnSessionMgr);
|
||||
|
||||
// We can't assume g_ldnSrvCreator is a domain here because serviceConvertToDomain might have failed
|
||||
serviceClose(&g_ldnSrvCreator);
|
||||
}
|
||||
|
||||
Service* ldnGetServiceSession_LocalCommunicationService(void) {
|
||||
@ -147,7 +216,7 @@ Service* ldnGetServiceSession_IClientProcessMonitor(void) {
|
||||
}
|
||||
|
||||
static Result _ldnGetSession(Service* srv, Service* srv_out, u32 cmd_id) {
|
||||
return serviceDispatch(srv, cmd_id,
|
||||
return _ldnObjectDispatch(srv, cmd_id,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = srv_out,
|
||||
);
|
||||
@ -155,7 +224,7 @@ static Result _ldnGetSession(Service* srv, Service* srv_out, u32 cmd_id) {
|
||||
|
||||
static Result _ldnCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 cmd_id) {
|
||||
Handle event = INVALID_HANDLE;
|
||||
Result rc = serviceDispatch(srv, cmd_id,
|
||||
Result rc = _ldnObjectDispatch(srv, cmd_id,
|
||||
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
|
||||
.out_handles = &event,
|
||||
);
|
||||
@ -167,24 +236,24 @@ static Result _ldnCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u3
|
||||
}
|
||||
|
||||
static Result _ldnCmdNoIO(Service* srv, u32 cmd_id) {
|
||||
return serviceDispatch(srv, cmd_id);
|
||||
return _ldnObjectDispatch(srv, cmd_id);
|
||||
}
|
||||
|
||||
static Result _ldnCmdInU32NoOut(Service* srv, u32 in, u32 cmd_id) {
|
||||
return serviceDispatchIn(srv, cmd_id, in);
|
||||
return _ldnObjectDispatchIn(srv, cmd_id, in);
|
||||
}
|
||||
|
||||
static Result _ldnCmdInU16NoOut(Service* srv, u16 in, u32 cmd_id) {
|
||||
return serviceDispatchIn(srv, cmd_id, in);
|
||||
return _ldnObjectDispatchIn(srv, cmd_id, in);
|
||||
}
|
||||
|
||||
static Result _ldnCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) {
|
||||
return serviceDispatchOut(srv, cmd_id, *out);
|
||||
return _ldnObjectDispatchOut(srv, cmd_id, *out);
|
||||
}
|
||||
|
||||
static Result _ldnCmdInitialize(Service* srv, u32 cmd_id) {
|
||||
u64 reserved=0;
|
||||
return serviceDispatchIn(srv, cmd_id, reserved,
|
||||
return _ldnObjectDispatchIn(srv, cmd_id, reserved,
|
||||
.in_send_pid = true,
|
||||
);
|
||||
}
|
||||
@ -197,7 +266,7 @@ static Result _ldnCmdInitializeWithVersion(s32 version) {
|
||||
} in = { version, 0, 0};
|
||||
|
||||
u32 cmd_id = g_ldnServiceType == LdnServiceType_User ? 402 : 403;
|
||||
return serviceDispatchIn(&g_ldnSrv, cmd_id, in,
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, cmd_id, in,
|
||||
.in_send_pid = true,
|
||||
);
|
||||
}
|
||||
@ -209,13 +278,13 @@ static Result _ldnCmdInitializeWithPriority(s32 version, s32 priority) {
|
||||
u64 reserved;
|
||||
} in = { version, priority, 0};
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 404, in,
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 404, in,
|
||||
.in_send_pid = true,
|
||||
);
|
||||
}
|
||||
|
||||
static Result _ldnGetNetworkInfo(Service* srv, LdnNetworkInfo *out) {
|
||||
return serviceDispatch(srv, 1,
|
||||
return _ldnObjectDispatch(srv, 1,
|
||||
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
|
||||
.buffers = { { out, sizeof(*out) } },
|
||||
);
|
||||
@ -227,7 +296,7 @@ static Result _ldnGetIpv4Address(Service* srv, LdnIpv4Address *addr, LdnSubnetMa
|
||||
LdnSubnetMask mask;
|
||||
} out;
|
||||
|
||||
Result rc = serviceDispatchOut(srv, 2, out);
|
||||
Result rc = _ldnObjectDispatchOut(srv, 2, out);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (addr) *addr = out.addr;
|
||||
if (mask) *mask = out.mask;
|
||||
@ -237,17 +306,17 @@ static Result _ldnGetIpv4Address(Service* srv, LdnIpv4Address *addr, LdnSubnetMa
|
||||
|
||||
static Result _ldnGetDisconnectReason(Service* srv, LdnDisconnectReason *out) {
|
||||
s16 tmp=0;
|
||||
Result rc = serviceDispatchOut(srv, 3, tmp);
|
||||
Result rc = _ldnObjectDispatchOut(srv, 3, tmp);
|
||||
if (R_SUCCEEDED(rc) && out) *out = tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _ldnGetSecurityParameter(Service* srv, LdnSecurityParameter *out) {
|
||||
return serviceDispatchOut(srv, 4, *out);
|
||||
return _ldnObjectDispatchOut(srv, 4, *out);
|
||||
}
|
||||
|
||||
static Result _ldnGetNetworkConfig(Service* srv, LdnNetworkConfig *out) {
|
||||
return serviceDispatchOut(srv, 5, *out);
|
||||
return _ldnObjectDispatchOut(srv, 5, *out);
|
||||
}
|
||||
|
||||
static Result _ldnScan(s32 channel, const LdnScanFilter *filter, LdnNetworkInfo *network_info, s32 count, s32 *total_out, u32 cmd_id) {
|
||||
@ -258,7 +327,7 @@ static Result _ldnScan(s32 channel, const LdnScanFilter *filter, LdnNetworkInfo
|
||||
} in = { channel, {0}, *filter};
|
||||
|
||||
s16 out=0;
|
||||
Result rc = serviceDispatchInOut(&g_ldnSrv, cmd_id, in, out,
|
||||
Result rc = _ldnObjectDispatchInOut(&g_ldnSrv, cmd_id, in, out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
|
||||
.buffers = { { network_info, count*sizeof(LdnNetworkInfo) } },
|
||||
);
|
||||
@ -328,7 +397,7 @@ Result ldnGetStateChangeEvent(Event* out_event) {
|
||||
}
|
||||
|
||||
Result ldnGetNetworkInfoAndHistory(LdnNetworkInfo *network_info, LdnNodeLatestUpdate *nodes, s32 count) {
|
||||
return serviceDispatch(&g_ldnSrv, 101,
|
||||
return _ldnObjectDispatch(&g_ldnSrv, 101,
|
||||
.buffer_attrs = {
|
||||
SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out,
|
||||
SfBufferAttr_HipcPointer | SfBufferAttr_Out,
|
||||
@ -387,7 +456,7 @@ Result ldnCreateNetwork(const LdnSecurityConfig *sec_config, const LdnUserConfig
|
||||
LdnNetworkConfig network_config;
|
||||
} in = { *sec_config, tmp_user, 0, tmp_network_config };
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 202, in);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 202, in);
|
||||
}
|
||||
|
||||
Result ldnCreateNetworkPrivate(const LdnSecurityConfig *sec_config, const LdnSecurityParameter *sec_param, const LdnUserConfig *user_config, const LdnNetworkConfig *network_config, const LdnAddressEntry *addrs, s32 count) {
|
||||
@ -404,7 +473,7 @@ Result ldnCreateNetworkPrivate(const LdnSecurityConfig *sec_config, const LdnSec
|
||||
LdnNetworkConfig network_config;
|
||||
} in = { *sec_config, *sec_param, tmp_user, 0, tmp_network_config };
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 203, in,
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 203, in,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
|
||||
.buffers = { { addrs, count*sizeof(LdnAddressEntry) } },
|
||||
);
|
||||
@ -415,11 +484,11 @@ Result ldnDestroyNetwork(void) {
|
||||
}
|
||||
|
||||
Result ldnReject(LdnIpv4Address addr) {
|
||||
return serviceDispatchIn(&g_ldnSrv, 205, addr);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 205, addr);
|
||||
}
|
||||
|
||||
Result ldnSetAdvertiseData(const void* buffer, size_t size) {
|
||||
return serviceDispatch(&g_ldnSrv, 206,
|
||||
return _ldnObjectDispatch(&g_ldnSrv, 206,
|
||||
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In },
|
||||
.buffers = { { buffer, size } },
|
||||
);
|
||||
@ -427,11 +496,11 @@ Result ldnSetAdvertiseData(const void* buffer, size_t size) {
|
||||
|
||||
Result ldnSetStationAcceptPolicy(LdnAcceptPolicy policy) {
|
||||
u8 tmp=policy;
|
||||
return serviceDispatchIn(&g_ldnSrv, 207, tmp);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 207, tmp);
|
||||
}
|
||||
|
||||
Result ldnAddAcceptFilterEntry(LdnMacAddress addr) {
|
||||
return serviceDispatchIn(&g_ldnSrv, 208, addr);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 208, addr);
|
||||
}
|
||||
|
||||
Result ldnClearAcceptFilter(void) {
|
||||
@ -457,7 +526,7 @@ Result ldnConnect(const LdnSecurityConfig *sec_config, const LdnUserConfig *user
|
||||
u32 option;
|
||||
} in = { *sec_config, tmp_user, version, option };
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 302, in,
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 302, in,
|
||||
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_In },
|
||||
.buffers = { { network_info, sizeof(*network_info) } },
|
||||
);
|
||||
@ -479,7 +548,7 @@ Result ldnConnectPrivate(const LdnSecurityConfig *sec_config, const LdnSecurityP
|
||||
LdnNetworkConfig network_config;
|
||||
} in = { *sec_config, *sec_param, tmp_user, version, option, 0, tmp_network_config };
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 303, in);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 303, in);
|
||||
}
|
||||
|
||||
Result ldnDisconnect(void) {
|
||||
@ -503,7 +572,7 @@ Result ldnEnableActionFrame(const LdnActionFrameSettings *settings) {
|
||||
if (hosversionBefore(18,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 500, *settings);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 500, *settings);
|
||||
}
|
||||
|
||||
Result ldnDisableActionFrame(void) {
|
||||
@ -539,7 +608,7 @@ Result ldnSendActionFrame(const void* data, size_t size, LdnMacAddress destinati
|
||||
u32 flags;
|
||||
} in = { destination, bssid, tmp_band, tmp_channel, flags};
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 502, in,
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 502, in,
|
||||
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In },
|
||||
.buffers = { { data, size } },
|
||||
);
|
||||
@ -561,7 +630,7 @@ Result ldnRecvActionFrame(void* data, size_t size, LdnMacAddress *addr0, LdnMacA
|
||||
s32 link_level;
|
||||
} out;
|
||||
|
||||
Result rc = serviceDispatchInOut(&g_ldnSrv, 503, flags, out,
|
||||
Result rc = _ldnObjectDispatchInOut(&g_ldnSrv, 503, flags, out,
|
||||
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
|
||||
.buffers = { { data, size } },
|
||||
);
|
||||
@ -597,7 +666,7 @@ Result ldnSetHomeChannel(s16 channel) {
|
||||
s16 channel;
|
||||
} in = { tmp_band, tmp_channel };
|
||||
|
||||
return serviceDispatchIn(&g_ldnSrv, 505, in);
|
||||
return _ldnObjectDispatchIn(&g_ldnSrv, 505, in);
|
||||
}
|
||||
else
|
||||
tmp_band = _ldnChannelToChannelBand(channel);
|
||||
|
Loading…
Reference in New Issue
Block a user