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 "param_osadp.h"
16d9f0492fSopenharmony_ci
17d9f0492fSopenharmony_ci#include <pthread.h>
18d9f0492fSopenharmony_ci#include <sys/ipc.h>
19d9f0492fSopenharmony_ci#include <sys/mman.h>
20d9f0492fSopenharmony_ci#include <sys/shm.h>
21d9f0492fSopenharmony_ci
22d9f0492fSopenharmony_ci#include "param_message.h"
23d9f0492fSopenharmony_ci#include "param_utils.h"
24d9f0492fSopenharmony_ci#include "securec.h"
25d9f0492fSopenharmony_ci
26d9f0492fSopenharmony_cistatic const uint32_t RECV_BUFFER_MAX = 5 * 1024;
27d9f0492fSopenharmony_ci
28d9f0492fSopenharmony_cistatic RecvMessage g_recvMessage;
29d9f0492fSopenharmony_cistatic void OnReceiveRequest(const TaskHandle task, const uint8_t *buffer, uint32_t nread)
30d9f0492fSopenharmony_ci{
31d9f0492fSopenharmony_ci    if (nread == 0 || buffer == NULL || g_recvMessage == NULL) {
32d9f0492fSopenharmony_ci        return;
33d9f0492fSopenharmony_ci    }
34d9f0492fSopenharmony_ci    uint32_t curr = 0;
35d9f0492fSopenharmony_ci    while (curr < nread) {
36d9f0492fSopenharmony_ci        const ParamMessage *msg = (const ParamMessage *)(buffer + curr);
37d9f0492fSopenharmony_ci        if ((nread - curr < msg->msgSize) ||
38d9f0492fSopenharmony_ci            (nread - curr < sizeof(ParamMessage)) ||
39d9f0492fSopenharmony_ci            (msg->msgSize < sizeof(ParamMessage))) {
40d9f0492fSopenharmony_ci            break;
41d9f0492fSopenharmony_ci        }
42d9f0492fSopenharmony_ci        curr += msg->msgSize;
43d9f0492fSopenharmony_ci        g_recvMessage(task, msg);
44d9f0492fSopenharmony_ci    }
45d9f0492fSopenharmony_ci}
46d9f0492fSopenharmony_ci
47d9f0492fSopenharmony_ciint ParamServerCreate(ParamTaskPtr *stream, const ParamStreamInfo *streamInfo)
48d9f0492fSopenharmony_ci{
49d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL && streamInfo != NULL, return -1, "Invalid param");
50d9f0492fSopenharmony_ci    PARAM_CHECK(streamInfo->incomingConnect != NULL, return -1, "Invalid incomingConnect");
51d9f0492fSopenharmony_ci    LE_StreamServerInfo info = {};
52d9f0492fSopenharmony_ci    info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER | TASK_PUBLIC;
53d9f0492fSopenharmony_ci    info.server = streamInfo->server;
54d9f0492fSopenharmony_ci    info.baseInfo.close = streamInfo->close;
55d9f0492fSopenharmony_ci    info.incommingConnect = streamInfo->incomingConnect;
56d9f0492fSopenharmony_ci    return LE_CreateStreamServer(LE_GetDefaultLoop(), stream, &info);
57d9f0492fSopenharmony_ci}
58d9f0492fSopenharmony_ci
59d9f0492fSopenharmony_ciint ParamStreamCreate(ParamTaskPtr *stream, ParamTaskPtr server,
60d9f0492fSopenharmony_ci    const ParamStreamInfo *streamInfo, uint16_t userDataSize)
61d9f0492fSopenharmony_ci{
62d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL && streamInfo != NULL, return -1, "Invalid stream");
63d9f0492fSopenharmony_ci    PARAM_CHECK(streamInfo->recvMessage != NULL, return -1, "Invalid recvMessage");
64d9f0492fSopenharmony_ci    PARAM_CHECK(streamInfo->close != NULL, return -1, "Invalid close");
65d9f0492fSopenharmony_ci    LE_StreamInfo info = {};
66d9f0492fSopenharmony_ci    info.baseInfo.userDataSize = userDataSize;
67d9f0492fSopenharmony_ci    info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
68d9f0492fSopenharmony_ci    if (streamInfo->flags & PARAM_TEST_FLAGS) {
69d9f0492fSopenharmony_ci        info.baseInfo.flags |= TASK_TEST;
70d9f0492fSopenharmony_ci    }
71d9f0492fSopenharmony_ci    info.baseInfo.close = streamInfo->close;
72d9f0492fSopenharmony_ci    info.disConnectComplete = NULL;
73d9f0492fSopenharmony_ci    info.sendMessageComplete = NULL;
74d9f0492fSopenharmony_ci    info.recvMessage = OnReceiveRequest;
75d9f0492fSopenharmony_ci    g_recvMessage = streamInfo->recvMessage;
76d9f0492fSopenharmony_ci    LE_STATUS status = LE_AcceptStreamClient(LE_GetDefaultLoop(), server, stream, &info);
77d9f0492fSopenharmony_ci    PARAM_CHECK(status == 0, return -1, "Failed to create client");
78d9f0492fSopenharmony_ci    return 0;
79d9f0492fSopenharmony_ci}
80d9f0492fSopenharmony_ci
81d9f0492fSopenharmony_civoid *ParamGetTaskUserData(const ParamTaskPtr stream)
82d9f0492fSopenharmony_ci{
83d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL, return NULL, "Invalid stream");
84d9f0492fSopenharmony_ci    return LE_GetUserData(stream);
85d9f0492fSopenharmony_ci}
86d9f0492fSopenharmony_ci
87d9f0492fSopenharmony_ciint ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg)
88d9f0492fSopenharmony_ci{
89d9f0492fSopenharmony_ci    PARAM_CHECK(msg != NULL, return -1, "Invalid stream");
90d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL, free((void *)msg);
91d9f0492fSopenharmony_ci        return -1, "Invalid stream");
92d9f0492fSopenharmony_ci    uint32_t dataSize = msg->msgSize;
93d9f0492fSopenharmony_ci    BufferHandle bufferHandle = LE_CreateBuffer(LE_GetDefaultLoop(), dataSize);
94d9f0492fSopenharmony_ci    PARAM_CHECK(bufferHandle != NULL, return -1, "Failed to create request");
95d9f0492fSopenharmony_ci    uint8_t *buffer = LE_GetBufferInfo(bufferHandle, NULL, NULL);
96d9f0492fSopenharmony_ci    int ret = memcpy_s(buffer, dataSize, msg, dataSize);
97d9f0492fSopenharmony_ci    free((void *)msg);
98d9f0492fSopenharmony_ci    PARAM_CHECK(ret == EOK, LE_FreeBuffer(LE_GetDefaultLoop(), NULL, bufferHandle);
99d9f0492fSopenharmony_ci        return -1, "Failed to copy message");
100d9f0492fSopenharmony_ci    return LE_Send(LE_GetDefaultLoop(), stream, bufferHandle, dataSize);
101d9f0492fSopenharmony_ci}
102d9f0492fSopenharmony_ci
103d9f0492fSopenharmony_ciint ParamEventTaskCreate(ParamTaskPtr *stream, LE_ProcessAsyncEvent eventProcess)
104d9f0492fSopenharmony_ci{
105d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL && eventProcess != NULL, return -1, "Invalid info or stream");
106d9f0492fSopenharmony_ci    return LE_CreateAsyncTask(LE_GetDefaultLoop(), stream, eventProcess);
107d9f0492fSopenharmony_ci}
108d9f0492fSopenharmony_ci
109d9f0492fSopenharmony_ciint ParamEventSend(const ParamTaskPtr stream, uint64_t eventId, const char *content, uint32_t size)
110d9f0492fSopenharmony_ci{
111d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL, return -1, "Invalid stream");
112d9f0492fSopenharmony_ci    PARAM_CHECK(size <= RECV_BUFFER_MAX, return -1, "Invalid stream");
113d9f0492fSopenharmony_ci    return LE_StartAsyncEvent(LE_GetDefaultLoop(), stream, eventId, (const uint8_t *)content, size);
114d9f0492fSopenharmony_ci}
115d9f0492fSopenharmony_ci
116d9f0492fSopenharmony_ciint ParamTaskClose(const ParamTaskPtr stream)
117d9f0492fSopenharmony_ci{
118d9f0492fSopenharmony_ci    PARAM_CHECK(stream != NULL, return -1, "Invalid param");
119d9f0492fSopenharmony_ci    LE_CloseTask(LE_GetDefaultLoop(), stream);
120d9f0492fSopenharmony_ci    return 0;
121d9f0492fSopenharmony_ci}
122d9f0492fSopenharmony_ci
123d9f0492fSopenharmony_ci
124d9f0492fSopenharmony_ciint ParamTimerCreate(ParamTaskPtr *timer, ProcessTimer process, void *context)
125d9f0492fSopenharmony_ci{
126d9f0492fSopenharmony_ci    PARAM_CHECK(timer != NULL && process != NULL, return -1, "Invalid timer");
127d9f0492fSopenharmony_ci    LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), timer, (LE_ProcessTimer)process, context);
128d9f0492fSopenharmony_ci    return (int)status;
129d9f0492fSopenharmony_ci}
130d9f0492fSopenharmony_ci
131d9f0492fSopenharmony_ciint ParamTimerStart(const ParamTaskPtr timer, uint64_t timeout, uint64_t repeat)
132d9f0492fSopenharmony_ci{
133d9f0492fSopenharmony_ci    PARAM_CHECK(timer != NULL, return -1, "Invalid timer");
134d9f0492fSopenharmony_ci    return LE_StartTimer(LE_GetDefaultLoop(), timer, timeout, repeat);
135d9f0492fSopenharmony_ci}
136d9f0492fSopenharmony_ci
137d9f0492fSopenharmony_civoid ParamTimerClose(ParamTaskPtr timer)
138d9f0492fSopenharmony_ci{
139d9f0492fSopenharmony_ci    PARAM_CHECK(timer != NULL, return, "Invalid param");
140d9f0492fSopenharmony_ci    LE_CloseTask(LE_GetDefaultLoop(), (ParamTaskPtr)timer);
141d9f0492fSopenharmony_ci}
142d9f0492fSopenharmony_ci
143d9f0492fSopenharmony_ciint ParamServiceStart(void)
144d9f0492fSopenharmony_ci{
145d9f0492fSopenharmony_ci    LE_RunLoop(LE_GetDefaultLoop());
146d9f0492fSopenharmony_ci    return 0;
147d9f0492fSopenharmony_ci}
148d9f0492fSopenharmony_ci
149d9f0492fSopenharmony_ciint ParamServiceStop(void)
150d9f0492fSopenharmony_ci{
151d9f0492fSopenharmony_ci    LE_StopLoop(LE_GetDefaultLoop());
152d9f0492fSopenharmony_ci    return 0;
153d9f0492fSopenharmony_ci}