1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dev_session_mgr.h"
17
18 #include <inttypes.h>
19 #include "callback_manager.h"
20 #include "device_auth_defines.h"
21 #include "hc_dev_info.h"
22 #include "hc_log.h"
23 #include "hc_mutex.h"
24 #include "hc_time.h"
25 #include "hc_vector.h"
26
27 typedef struct {
28 DevSession *session;
29 int64_t createTime;
30 } SessionInfo;
31
32 DECLARE_HC_VECTOR(SessionInfoList, SessionInfo)
33 IMPLEMENT_HC_VECTOR(SessionInfoList, SessionInfo, 1)
34
35 static SessionInfoList g_sessionInfoList;
36 static HcMutex g_sessionMutex;
37
GetSessionInfo(int64_t sessionId,SessionInfo ** returnObj)38 static int32_t GetSessionInfo(int64_t sessionId, SessionInfo **returnObj)
39 {
40 uint32_t index;
41 SessionInfo *ptr;
42 FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
43 DevSession *session = ptr->session;
44 if (session->id == sessionId) {
45 *returnObj = ptr;
46 return HC_SUCCESS;
47 }
48 }
49 return HC_ERR_SESSION_NOT_EXIST;
50 }
51
RemoveTimeoutSession(void)52 static void RemoveTimeoutSession(void)
53 {
54 uint32_t index = 0;
55 while (index < g_sessionInfoList.size(&(g_sessionInfoList))) {
56 SessionInfo *sessionInfo = g_sessionInfoList.getp(&(g_sessionInfoList), index);
57 int64_t runningTime = HcGetIntervalTime(sessionInfo->createTime);
58 if (runningTime < TIME_OUT_VALUE) {
59 index++;
60 continue;
61 }
62 DevSession *session = sessionInfo->session;
63 LOGI("session timeout. [AppId]: %s, [Id]: %" PRId64, session->appId, session->id);
64 LOGI("session timeout. [TimeLimit(/s)]: %d, [RunningTime(/s)]: %" PRId64, TIME_OUT_VALUE, runningTime);
65 ProcessErrorCallback(session->id, session->opCode, HC_ERR_TIME_OUT, NULL, &session->callback);
66 session->destroy(session);
67 g_sessionInfoList.eraseElement(&(g_sessionInfoList), sessionInfo, index);
68 }
69 }
70
CheckEnvForOpenSession(int64_t sessionId)71 static int32_t CheckEnvForOpenSession(int64_t sessionId)
72 {
73 SessionInfo *sessionInfo;
74 int32_t res = GetSessionInfo(sessionId, &sessionInfo);
75 if (res == HC_SUCCESS) {
76 LOGE("session has existed. [Id]: %" PRId64, sessionId);
77 return HC_ERR_REQUEST_EXIST;
78 }
79 uint32_t curSessionNum = HC_VECTOR_SIZE(&g_sessionInfoList);
80 if (curSessionNum >= MAX_SESSION_COUNT) {
81 LOGE("The number of sessions has reached the maximum limit. [CurNum]: %u, [NumLimit]: %d",
82 curSessionNum, MAX_SESSION_COUNT);
83 return HC_ERR_SESSION_IS_FULL;
84 }
85 return HC_SUCCESS;
86 }
87
AddNewSessionToList(DevSession * session)88 static int32_t AddNewSessionToList(DevSession *session)
89 {
90 SessionInfo newSessionInfo;
91 newSessionInfo.session = session;
92 newSessionInfo.createTime = HcGetCurTime();
93 if (g_sessionInfoList.pushBackT(&g_sessionInfoList, newSessionInfo) == NULL) {
94 LOGE("push session to list fail.");
95 return HC_ERR_MEMORY_COPY;
96 }
97 return HC_SUCCESS;
98 }
99
InitDevSessionManager(void)100 int32_t InitDevSessionManager(void)
101 {
102 int32_t res = InitHcMutex(&g_sessionMutex);
103 if (res != HC_SUCCESS) {
104 LOGE("Init session mutex failed.");
105 return res;
106 }
107 g_sessionInfoList = CREATE_HC_VECTOR(SessionInfoList);
108 return HC_SUCCESS;
109 }
110
DestroyDevSessionManager(void)111 void DestroyDevSessionManager(void)
112 {
113 uint32_t index;
114 SessionInfo *ptr;
115 g_sessionMutex.lock(&g_sessionMutex);
116 FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
117 ptr->session->destroy(ptr->session);
118 }
119 DESTROY_HC_VECTOR(SessionInfoList, &g_sessionInfoList);
120 g_sessionMutex.unlock(&g_sessionMutex);
121 DestroyHcMutex(&g_sessionMutex);
122 }
123
IsSessionExist(int64_t sessionId)124 bool IsSessionExist(int64_t sessionId)
125 {
126 g_sessionMutex.lock(&g_sessionMutex);
127 SessionInfo *sessionInfo;
128 int32_t res = GetSessionInfo(sessionId, &sessionInfo);
129 g_sessionMutex.unlock(&g_sessionMutex);
130 return res == HC_SUCCESS;
131 }
132
OpenDevSession(int64_t sessionId,const char * appId,SessionInitParams * params)133 int32_t OpenDevSession(int64_t sessionId, const char *appId, SessionInitParams *params)
134 {
135 if ((appId == NULL) || (params == NULL)) {
136 LOGE("invalid params.");
137 return HC_ERR_INVALID_PARAMS;
138 }
139 g_sessionMutex.lock(&g_sessionMutex);
140 RemoveTimeoutSession();
141 int32_t res = CheckEnvForOpenSession(sessionId);
142 if (res != HC_SUCCESS) {
143 g_sessionMutex.unlock(&g_sessionMutex);
144 return res;
145 }
146 DevSession *session;
147 res = CreateDevSession(sessionId, appId, params, &session);
148 if (res != HC_SUCCESS) {
149 LOGE("create session fail. [AppId]: %s, [Id]: %" PRId64, appId, sessionId);
150 g_sessionMutex.unlock(&g_sessionMutex);
151 return res;
152 }
153 res = AddNewSessionToList(session);
154 if (res != HC_SUCCESS) {
155 session->destroy(session);
156 g_sessionMutex.unlock(&g_sessionMutex);
157 return res;
158 }
159 LOGI("create session success. [AppId]: %s, [CurNum]: %u, [Id]: %" PRId64,
160 appId, HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
161 g_sessionMutex.unlock(&g_sessionMutex);
162 return HC_SUCCESS;
163 }
164
StartDevSession(int64_t sessionId)165 int32_t StartDevSession(int64_t sessionId)
166 {
167 g_sessionMutex.lock(&g_sessionMutex);
168 RemoveTimeoutSession();
169 SessionInfo *sessionInfo;
170 int32_t res = GetSessionInfo(sessionId, &sessionInfo);
171 if (res != HC_SUCCESS) {
172 LOGE("session not found. [Id]: %" PRId64, sessionId);
173 g_sessionMutex.unlock(&g_sessionMutex);
174 return res;
175 }
176 DevSession *session = sessionInfo->session;
177 res = session->start(session);
178 g_sessionMutex.unlock(&g_sessionMutex);
179 return res;
180 }
181
ProcessDevSession(int64_t sessionId,const CJson * receviedMsg,bool * isFinish)182 int32_t ProcessDevSession(int64_t sessionId, const CJson *receviedMsg, bool *isFinish)
183 {
184 if ((receviedMsg == NULL) || (isFinish == NULL)) {
185 LOGE("invalid params.");
186 return HC_ERR_INVALID_PARAMS;
187 }
188 g_sessionMutex.lock(&g_sessionMutex);
189 RemoveTimeoutSession();
190 SessionInfo *sessionInfo;
191 int32_t res = GetSessionInfo(sessionId, &sessionInfo);
192 if (res != HC_SUCCESS) {
193 LOGE("session not found. [Id]: %" PRId64, sessionId);
194 g_sessionMutex.unlock(&g_sessionMutex);
195 return res;
196 }
197 DevSession *session = sessionInfo->session;
198 res = session->process(session, receviedMsg, isFinish);
199 g_sessionMutex.unlock(&g_sessionMutex);
200 return res;
201 }
202
CloseDevSession(int64_t sessionId)203 void CloseDevSession(int64_t sessionId)
204 {
205 g_sessionMutex.lock(&g_sessionMutex);
206 RemoveTimeoutSession();
207 uint32_t index;
208 SessionInfo *ptr;
209 FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
210 DevSession *session = ptr->session;
211 if (session->id == sessionId) {
212 session->destroy(session);
213 HC_VECTOR_POPELEMENT(&g_sessionInfoList, ptr, index);
214 LOGI("close session success. [CurNum]: %u, [Id]: %" PRId64, HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
215 g_sessionMutex.unlock(&g_sessionMutex);
216 return;
217 }
218 }
219 LOGI("session not exist. [Id]: %" PRId64, sessionId);
220 g_sessionMutex.unlock(&g_sessionMutex);
221 }
222
CancelDevSession(int64_t sessionId,const char * appId)223 void CancelDevSession(int64_t sessionId, const char *appId)
224 {
225 if (appId == NULL) {
226 LOGE("appId is NULL.");
227 return;
228 }
229 g_sessionMutex.lock(&g_sessionMutex);
230 RemoveTimeoutSession();
231 uint32_t index;
232 SessionInfo *ptr;
233 FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
234 DevSession *session = ptr->session;
235 if (session->id == sessionId && strcmp(session->appId, appId) == 0) {
236 session->destroy(session);
237 HC_VECTOR_POPELEMENT(&g_sessionInfoList, ptr, index);
238 LOGI("cancel session success. [CurNum]: %u, [Id]: %" PRId64, HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
239 g_sessionMutex.unlock(&g_sessionMutex);
240 return;
241 }
242 }
243 LOGI("session not exist. [Id]: %" PRId64, sessionId);
244 g_sessionMutex.unlock(&g_sessionMutex);
245 }
246