* Copyright (c) 2024-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include "sle_svc.h"
#include "iotc_svc.h"
#include "iotc_svc_sle.h"
#include "service_proxy.h"
#include "iotc_errcode.h"
#include "sle_svc_ctx.h"
#include "securec.h"
#include "sle_ssap_data_svc.h"
#include "sle_profile.h"
#include "sle_session_mngr.h"
#include "utils_common.h"
#include "sle_svc_report.h"
#include "utils_assert.h"
#include "sle_ssap_mgt.h"
#include "iotc_sle_host.h"
#include "iotc_sle_server.h"
#include "sle_linklayer.h"
#include "sle_common.h"
#include "sle_svc_netcfg_status.h"
#include "iotc_mem.h"
#include "sle_ssap_service.h"
static const char *SLE_SERVICE_NAME = "SLE";
static void SleStackDeinit(void)
{
SleSsapDisconnectAll();
SleSsapMgtDestroy();
}
static int32_t SleStackInit(void)
{
int32_t ret = SetSleConnectParam();
if (ret != IOTC_OK) {
IOTC_LOGE("set connect param error %d", ret);
return ret;
}
ret = IotcInitSleHostService();
IOTC_LOGI("IotcInitSleHostService %d", ret);
ret = IotcSleEnable();
IOTC_LOGI("IotcSleEnable %d", ret);
ret = IotcSleRegisterHostCallbacks();
IOTC_LOGI("IotcSleRegisterHostCallbacks %d", ret);
if (ret != IOTC_OK) {
IOTC_LOGE("init stack error %d", ret);
return ret;
}
return IOTC_OK;
}
static void SleSsapDeinit(void)
{
SleSsapMgtDestroy();
}
static int32_t SleSsapInit(void)
{
int32_t ret = SleSsapDataSvcInit();
if (ret != IOTC_OK) {
IOTC_LOGE("sle ssap svc init err ret=%d", ret);
return ret;
}
ret = SleSsapMgtInit();
if (ret != IOTC_OK) {
IOTC_LOGE("start ssap service err ret=%d", ret);
return ret;
}
return IOTC_OK;
}
static void SleServiceStopInner(void)
{
SleSsapDeinit();
SleSvcNetCfgDeinit();
SleSvcReportDeinit();
DestroySleSess();
SleProfileDeinit();
SleStackDeinit();
SleLinkLayerClearAllCachePkg();
SleSvcCtx *ctx = GetSleSvcCtx();
if (ctx->onFinish != NULL) {
ctx->onFinish(ctx->instanceId);
}
}
static int32_t SleServiceInit(SleSvcCtx *ctx)
{
int32_t ret = SleStackInit();
if (ret != IOTC_OK) {
IOTC_LOGW("sle stack init error %d", ret);
return ret;
}
ret = SleScheduleEventInit();
if (ret != IOTC_OK) {
IOTC_LOGW("sle event init error %d", ret);
return ret;
}
ret = SleSsapInit();
if (ret != IOTC_OK) {
IOTC_LOGW("ssap init error %d", ret);
return ret;
}
ret = SleSsapServiceSvcInit(ctx);
if (ret != IOTC_OK) {
IOTC_LOGE("SleSsapServiceSvcInit err %d", ret);
return ret;
}
ret = SleProfileInit();
if (ret != IOTC_OK) {
IOTC_LOGW("profile init error %d", ret);
return ret;
}
ret = SleSessInit();
if (ret != IOTC_OK) {
IOTC_LOGW("profile init error %d", ret);
return ret;
}
ret = SleSvcReportInit();
if (ret != IOTC_OK) {
IOTC_LOGW("report init error %d", ret);
return ret;
}
ret = SleSvcNetCfgInit();
if (ret != IOTC_OK) {
IOTC_LOGW("report status init error %d", ret);
return ret;
}
return IOTC_OK;
}
static int32_t SleServiceStart(int32_t instanceId, ServiceFinishCallback onFinish, void *param)
{
CHECK_RETURN_LOGW(onFinish != NULL, IOTC_ERR_PARAM_INVALID, "param invalid");
int32_t ret = SleSvcCtxInit();
if (ret != IOTC_OK) {
IOTC_LOGW("ctx init error %d", ret);
return ret;
}
SleSvcCtx *ctx = GetSleSvcCtx();
ctx->instanceId = instanceId;
ctx->onFinish = onFinish;
const SleSvcInitParam *initParam = param;
ret = memcpy_s(&ctx->initParam, sizeof(SleSvcInitParam), initParam, sizeof(SleSvcInitParam));
if (ret != EOK) {
return IOTC_ERR_SECUREC_MEMCPY;
}
ret = SleServiceInit(ctx);
if (ret != IOTC_OK) {
SleServiceStopInner();
}
return ret;
}
static int32_t SleServiceStop(int32_t instanceId, void *param)
{
NOT_USED(param);
SleSvcCtx *ctx = GetSleSvcCtx();
if (ctx->instanceId != instanceId) {
IOTC_LOGW("invalid instance id %d/%d", instanceId, ctx->instanceId);
return IOTC_ERR_PARAM_INVALID;
}
SleServiceStopInner();
(void)SleSvcCtxInit();
return IOTC_OK;
}
int32_t SleConnectServiceInit(void)
{
static const ServiceHandler SLE_SERVICE_HANDLER = {
.onStart = SleServiceStart,
.onStop = SleServiceStop,
.onReset = NULL,
};
int32_t msgs[SLE_SERVICE_MSG_ID_MAX] = {0};
for (uint32_t i = 0 ; i < SLE_SERVICE_MSG_ID_MAX; ++i) {
msgs[i] = i;
}
static const SleSvcApi SLE_SERVICE_API = {
.onStartAdv = SleAdvServiceStart,
.onStopAdv = SleAdvServiceStop,
.onStartScan = SleScanServiceStart,
.onStopScan = SleScanServiceStop,
.onSetAdvType = SleAdvSetType,
.onSendCustomSecData = SleSendCustomSecDataService,
.onSendIndicateData = IotcSleSendIndicateData,
.onFindDeviceInfo = IotcOhSleFindDeviceInfoService,
.onFindDeviceInfoByName = IotcOhSleFindDeviceInfoByNameService,
};
ServiceInstance instance = {
.serviceId = IOTC_SERVICE_ID_SLE,
.name = SLE_SERVICE_NAME,
.handler = &SLE_SERVICE_HANDLER,
.msgNum = SLE_SERVICE_MSG_ID_MAX,
.msgIds = msgs,
.apiHandler = &SLE_SERVICE_API,
};
int32_t ret = ServiceManagerRegisterInstance(&instance);
if (ret != IOTC_OK) {
IOTC_LOGE("reg device service instance error %d", ret);
return ret;
}
return IOTC_OK;
}
void SleConnectServiceDeinit(void)
{
SleServiceStopInner();
ServiceManagerUnregisterInstance(IOTC_SERVICE_ID_SLE);
}