1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci* Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci* you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci* You may obtain a copy of the License at 6d9f0492fSopenharmony_ci* 7d9f0492fSopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci* 9d9f0492fSopenharmony_ci* Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci* See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci* limitations under the License. 14d9f0492fSopenharmony_ci*/ 15d9f0492fSopenharmony_ci#include "service_watcher.h" 16d9f0492fSopenharmony_ci 17d9f0492fSopenharmony_ci#include <errno.h> 18d9f0492fSopenharmony_ci#include <stdio.h> 19d9f0492fSopenharmony_ci#include <string.h> 20d9f0492fSopenharmony_ci 21d9f0492fSopenharmony_ci#include "beget_ext.h" 22d9f0492fSopenharmony_ci#include "init_utils.h" 23d9f0492fSopenharmony_ci#include "parameter.h" 24d9f0492fSopenharmony_ci#include "securec.h" 25d9f0492fSopenharmony_ci#include "service_control.h" 26d9f0492fSopenharmony_ci#include "sysparam_errno.h" 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_cistatic void ServiceStateChange(const char *key, const char *value, void *context) 29d9f0492fSopenharmony_ci{ 30d9f0492fSopenharmony_ci ServiceStatusChangePtr callback = (ServiceStatusChangePtr)context; 31d9f0492fSopenharmony_ci uint32_t v = 0; 32d9f0492fSopenharmony_ci int ret = StringToUint(value, &v); 33d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return, "Failed to get value from %s", value); 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_ci // get pid 36d9f0492fSopenharmony_ci char paramName[PARAM_NAME_LEN_MAX] = { 0 }; 37d9f0492fSopenharmony_ci ret = snprintf_s(paramName, sizeof(paramName), sizeof(paramName) - 1, "%s.pid", key); 38d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret != -1, return, "Failed to get format pid ret %d for %s ", ret, key); 39d9f0492fSopenharmony_ci 40d9f0492fSopenharmony_ci ServiceInfo info = {0}; 41d9f0492fSopenharmony_ci info.status = (ServiceStatus)v; 42d9f0492fSopenharmony_ci info.pid = (pid_t)GetUintParameter(paramName, INVALID_PID); 43d9f0492fSopenharmony_ci if (strlen(key) > strlen(STARTUP_SERVICE_CTL)) { 44d9f0492fSopenharmony_ci callback(key + strlen(STARTUP_SERVICE_CTL) + 1, &info); 45d9f0492fSopenharmony_ci } else { 46d9f0492fSopenharmony_ci BEGET_LOGE("Invalid service name %s %s", key, value); 47d9f0492fSopenharmony_ci } 48d9f0492fSopenharmony_ci} 49d9f0492fSopenharmony_ci 50d9f0492fSopenharmony_ciint ServiceWatchForStatus(const char *serviceName, ServiceStatusChangePtr changeCallback) 51d9f0492fSopenharmony_ci{ 52d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(serviceName != NULL, return EC_INVALID, "Service watch failed, service is null."); 53d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(changeCallback != NULL, return EC_INVALID, "Service watch failed, callback is null."); 54d9f0492fSopenharmony_ci 55d9f0492fSopenharmony_ci char paramName[PARAM_NAME_LEN_MAX] = {0}; 56d9f0492fSopenharmony_ci BEGET_LOGI("Watcher service %s status", serviceName); 57d9f0492fSopenharmony_ci if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, 58d9f0492fSopenharmony_ci "%s.%s", STARTUP_SERVICE_CTL, serviceName) == -1) { 59d9f0492fSopenharmony_ci BEGET_LOGE("Failed snprintf_s err=%d", errno); 60d9f0492fSopenharmony_ci return EC_SYSTEM_ERR; 61d9f0492fSopenharmony_ci } 62d9f0492fSopenharmony_ci int ret = SystemWatchParameter(paramName, ServiceStateChange, (void *)changeCallback); 63d9f0492fSopenharmony_ci if (ret != 0) { 64d9f0492fSopenharmony_ci BEGET_LOGE("Failed to watcher service %s ret %d.", serviceName, ret); 65d9f0492fSopenharmony_ci if (ret == DAC_RESULT_FORBIDED) { 66d9f0492fSopenharmony_ci return SYSPARAM_PERMISSION_DENIED; 67d9f0492fSopenharmony_ci } 68d9f0492fSopenharmony_ci return EC_SYSTEM_ERR; 69d9f0492fSopenharmony_ci } 70d9f0492fSopenharmony_ci return 0; 71d9f0492fSopenharmony_ci} 72d9f0492fSopenharmony_ci 73d9f0492fSopenharmony_ciint WatchParameter(const char *keyprefix, ParameterChgPtr callback, void *context) 74d9f0492fSopenharmony_ci{ 75d9f0492fSopenharmony_ci if (keyprefix == NULL) { 76d9f0492fSopenharmony_ci return EC_INVALID; 77d9f0492fSopenharmony_ci } 78d9f0492fSopenharmony_ci#ifdef NO_PARAM_WATCHER 79d9f0492fSopenharmony_ci printf("ParameterWatcher is disabled."); 80d9f0492fSopenharmony_ci return EC_INVALID; 81d9f0492fSopenharmony_ci#else 82d9f0492fSopenharmony_ci int ret = SystemWatchParameter(keyprefix, callback, context); 83d9f0492fSopenharmony_ci BEGET_CHECK_ONLY_ELOG(ret == 0, "WatchParameter failed! the errNum is %d", ret); 84d9f0492fSopenharmony_ci return ret; 85d9f0492fSopenharmony_ci#endif 86d9f0492fSopenharmony_ci}