diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index 9b992dd8..4c332a71 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -1906,18 +1906,17 @@ Result appletApplicationHasSaveDataAccessPermission(AppletApplication *a, u64 ap * @param[in] buffer Input buffer. * @param[in] size Input buffer size. */ -Result appletPushToFriendInvitationStorageChannel(AppletApplication *a, AccountUid uid, const void* buffer, u64 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] uid \ref AccountUid * @param[in] buffer Input buffer. * @param[in] size Input buffer size. */ -Result appletPushToNotificationStorageChannel(AppletApplication *a, const void* buffer, u64 size); +Result appletApplicationPushToNotificationStorageChannel(AppletApplication *a, const void* buffer, u64 size); ///@} @@ -2237,7 +2236,7 @@ Result appletReadThemeStorage(void* buffer, size_t size, u64 offset, u64 *transf Result appletWriteThemeStorage(const void* buffer, size_t size, u64 offset); /** - * @brief PushToAppletBoundChannel + * @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. @@ -2245,7 +2244,7 @@ Result appletWriteThemeStorage(const void* buffer, size_t size, u64 offset); Result appletPushToAppletBoundChannel(AppletStorage *s); /** - * @brief TryPopFromAppletBoundChannel + * @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. */ @@ -2326,6 +2325,70 @@ Result appletRequestLaunchApplicationWithUserAndArgumentForDebug(u64 application */ 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 diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index 4681cd80..6b1f175d 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -766,6 +766,42 @@ static Result _appletCmdInStorage(Service* srv, AppletStorage* s, u32 cmd_id) { return rc; } +static Result _appletCmdInStorageU32(Service* srv, AppletStorage* s, u32 inval, u32 cmd_id) { + if (!serviceIsActive(&s->s)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + serviceAssumeDomain(srv); + Result rc = serviceDispatchIn(srv, cmd_id, inval, + .in_num_objects = 1, + .in_objects = { &s->s }, + ); + appletStorageClose(s); + return rc; +} + +static Result _appletCmdInStorageU64(Service* srv, AppletStorage* s, u64 inval, u32 cmd_id) { + if (!serviceIsActive(&s->s)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + serviceAssumeDomain(srv); + Result rc = serviceDispatchIn(srv, cmd_id, inval, + .in_num_objects = 1, + .in_objects = { &s->s }, + ); + appletStorageClose(s); + return rc; +} + +static Result _appletCmdInU32OutStorage(Service* srv, AppletStorage* s, u32 inval, u32 cmd_id) { + memset(s, 0, sizeof(AppletStorage)); + serviceAssumeDomain(srv); + Result rc = serviceDispatchIn(srv, cmd_id, inval, + .out_num_objects = 1, + .out_objects = &s->s, + ); + return rc; +} + static Result _appletCmdNoInOutStorage(Service* srv, AppletStorage* s, u32 cmd_id) { memset(s, 0, sizeof(AppletStorage)); return _appletCmdGetSession(srv, &s->s, cmd_id); @@ -2406,17 +2442,8 @@ IPC_MAKE_CMD_IMPL_HOSVER(Result appletApplicationGetApplicationId(AppletApplicat Result appletApplicationPushLaunchParameter(AppletApplication *a, AppletLaunchParameterKind kind, AppletStorage* s) { if (!serviceIsActive(&a->s)) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - if (!serviceIsActive(&s->s)) - return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - u32 tmpkind=kind; - serviceAssumeDomain(&a->s); - Result rc = serviceDispatchIn(&a->s, 121, tmpkind, - .in_num_objects = 1, - .in_objects = { &s->s }, - ); - appletStorageClose(s); - return rc; + return _appletCmdInStorageU32(&a->s, s, kind, 121); } IPC_MAKE_CMD_IMPL( Result appletApplicationGetApplicationControlProperty(AppletApplication *a, NacpStruct *nacp), &a->s, 122, _appletCmdNoInRecvBuf, nacp, sizeof(*nacp)) @@ -2478,9 +2505,7 @@ Result appletApplicationHasSaveDataAccessPermission(AppletApplication *a, u64 ap return rc; } -Result appletPushToFriendInvitationStorageChannel(AppletApplication *a, AccountUid uid, const void* buffer, u64 size) { - if (!serviceIsActive(&a->s)) - return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); +static Result _appletPushToFriendInvitationStorageChannel(Service* srv, AccountUid uid, const void* buffer, u64 size, u32 cmd_id) { if (hosversionBefore(9,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -2490,15 +2515,13 @@ Result appletPushToFriendInvitationStorageChannel(AppletApplication *a, AccountU rc = appletCreateStorage(&storage, size+sizeof(uid)); if (R_SUCCEEDED(rc)) rc = appletStorageWrite(&storage, 0, &uid, sizeof(uid)); if (R_SUCCEEDED(rc)) rc = appletStorageWrite(&storage, sizeof(uid), buffer, size); - if (R_SUCCEEDED(rc)) rc = _appletCmdInStorage(&a->s, &storage, 180); + if (R_SUCCEEDED(rc)) rc = _appletCmdInStorage(srv, &storage, cmd_id); appletStorageClose(&storage); return rc; } -Result appletPushToNotificationStorageChannel(AppletApplication *a, const void* buffer, u64 size) { - if (!serviceIsActive(&a->s)) - return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); +static Result _appletPushToNotificationStorageChannel(Service* srv, const void* buffer, u64 size, u32 cmd_id) { if (hosversionBefore(9,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -2507,12 +2530,26 @@ Result appletPushToNotificationStorageChannel(AppletApplication *a, const void* rc = appletCreateStorage(&storage, size); if (R_SUCCEEDED(rc)) rc = appletStorageWrite(&storage, 0, buffer, size); - if (R_SUCCEEDED(rc)) rc = _appletCmdInStorage(&a->s, &storage, 190); + if (R_SUCCEEDED(rc)) rc = _appletCmdInStorage(srv, &storage, cmd_id); appletStorageClose(&storage); return rc; } +Result appletApplicationPushToFriendInvitationStorageChannel(AppletApplication *a, AccountUid uid, const void* buffer, u64 size) { + if (!serviceIsActive(&a->s)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return _appletPushToFriendInvitationStorageChannel(&a->s, uid, buffer, size, 180); +} + +Result appletApplicationPushToNotificationStorageChannel(AppletApplication *a, const void* buffer, u64 size) { + if (!serviceIsActive(&a->s)) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return _appletPushToNotificationStorageChannel(&a->s, buffer, size, 190); +} + // ILibraryAppletSelfAccessor IPC_MAKE_CMD_IMPL_INITEXPR( Result appletPopInData(AppletStorage *s), &g_appletILibraryAppletSelfAccessor, 0, _appletCmdNoInOutStorage, __nx_applet_type != AppletType_LibraryApplet, s) @@ -2715,6 +2752,15 @@ Result appletGetAppletResourceUsageInfo(AppletResourceUsageInfo *info) { return serviceDispatchOut(&g_appletIDebugFunctions, 40, *info); } +IPC_MAKE_CMD_IMPL_HOSVER(Result appletPushToAppletBoundChannelForDebug(AppletStorage *s, s32 channel), &g_appletIDebugFunctions, 110, _appletCmdInStorageU32, (9,0,0), s, channel) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletTryPopFromAppletBoundChannelForDebug(AppletStorage *s, s32 channel), &g_appletIDebugFunctions, 111, _appletCmdInU32OutStorage, (9,0,0), s, channel) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletAlarmSettingNotificationEnableAppEventReserve(AppletStorage *s, u64 application_id), &g_appletIDebugFunctions, 120, _appletCmdInStorageU64, (9,0,0), s, application_id) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletAlarmSettingNotificationDisableAppEventReserve(void), &g_appletIDebugFunctions, 121, _appletCmdNoIO, (9,0,0)) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletAlarmSettingNotificationPushAppEventNotify(const void* buffer, u64 size), &g_appletIDebugFunctions, 122, _appletPushToNotificationStorageChannel, (9,0,0), buffer, size) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletFriendInvitationSetApplicationParameter(AppletStorage *s, u64 application_id), &g_appletIDebugFunctions, 130, _appletCmdInStorageU64, (9,0,0), s, application_id) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletFriendInvitationClearApplicationParameter(void), &g_appletIDebugFunctions, 131, _appletCmdNoIO, (9,0,0)) +IPC_MAKE_CMD_IMPL_HOSVER(Result appletFriendInvitationPushApplicationParameter(AccountUid uid, const void* buffer, u64 size), &g_appletIDebugFunctions, 132, _appletPushToFriendInvitationStorageChannel, (9,0,0), uid, buffer, size) + // Common cmds Result appletSetTerminateResult(Result res) { if (!serviceIsActive(&g_appletSrv) || (!_appletIsApplication() && !serviceIsActive(&g_appletIAppletCommonFunctions)))