• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2025 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 #include "task_manager.h"
27 #include "critical_handler.h"
28 #include "string_util.h"
29 
30 typedef struct {
31     DevSession *session;
32     int64_t createTime;
33 } SessionInfo;
34 
35 typedef struct {
36     HcTaskBase base;
37     int64_t sessionId;
38 } StartSessionTask;
39 
40 typedef struct {
41     HcTaskBase base;
42     int64_t sessionId;
43     CJson *receivedMsg;
44 } ProcSessionTask;
45 
46 DECLARE_HC_VECTOR(SessionInfoList, SessionInfo)
47 IMPLEMENT_HC_VECTOR(SessionInfoList, SessionInfo, 1)
48 
49 static SessionInfoList g_sessionInfoList;
50 static HcMutex g_sessionMutex;
51 
GetSessionInfo(int64_t sessionId,SessionInfo ** returnObj)52 static int32_t GetSessionInfo(int64_t sessionId, SessionInfo **returnObj)
53 {
54     uint32_t index;
55     SessionInfo *ptr;
56     FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
57         DevSession *session = ptr->session;
58         if (session->id == sessionId) {
59             *returnObj = ptr;
60             return HC_SUCCESS;
61         }
62     }
63     return HC_ERR_SESSION_NOT_EXIST;
64 }
65 
RemoveTimeoutSession(void)66 void RemoveTimeoutSession(void)
67 {
68     uint32_t index = 0;
69     while (index < g_sessionInfoList.size(&(g_sessionInfoList))) {
70         SessionInfo *sessionInfo = g_sessionInfoList.getp(&(g_sessionInfoList), index);
71         int64_t runningTime = HcGetIntervalTime(sessionInfo->createTime);
72         if (runningTime < TIME_OUT_VALUE) {
73             index++;
74             continue;
75         }
76         DevSession *session = sessionInfo->session;
77         LOGI("session timeout. [AppId]: %" LOG_PUB "s, [Id]: %" LOG_PUB PRId64, session->appId, session->id);
78         LOGI("session timeout. [TimeLimit(/s)]: %" LOG_PUB "d, [RunningTime(/s)]: %" LOG_PUB PRId64,
79             TIME_OUT_VALUE, runningTime);
80         ProcessErrorCallback(session->id, session->opCode, HC_ERR_TIME_OUT, NULL, &session->callback);
81         session->destroy(session);
82         g_sessionInfoList.eraseElement(&(g_sessionInfoList), sessionInfo, index);
83     }
84 }
85 
CheckEnvForOpenSession(int64_t sessionId)86 static int32_t CheckEnvForOpenSession(int64_t sessionId)
87 {
88     SessionInfo *sessionInfo;
89     int32_t res = GetSessionInfo(sessionId, &sessionInfo);
90     if (res == HC_SUCCESS) {
91         LOGE("session has existed. [Id]: %" LOG_PUB PRId64, sessionId);
92         return HC_ERR_REQUEST_EXIST;
93     }
94     uint32_t curSessionNum = HC_VECTOR_SIZE(&g_sessionInfoList);
95     if (curSessionNum >= MAX_AUTH_SESSION_COUNT) {
96         LOGE("The number of sessions has reached the maximum limit. [CurNum]: %" LOG_PUB "u, [NumLimit]: %" LOG_PUB "d",
97             curSessionNum, MAX_AUTH_SESSION_COUNT);
98         return HC_ERR_SESSION_IS_FULL;
99     }
100     return HC_SUCCESS;
101 }
102 
AddNewSessionToList(DevSession * session)103 static int32_t AddNewSessionToList(DevSession *session)
104 {
105     SessionInfo newSessionInfo;
106     newSessionInfo.session = session;
107     newSessionInfo.createTime = HcGetCurTime();
108     if (g_sessionInfoList.pushBackT(&g_sessionInfoList, newSessionInfo) == NULL) {
109         LOGE("push session to list fail.");
110         return HC_ERR_MEMORY_COPY;
111     }
112     return HC_SUCCESS;
113 }
114 
InitDevSessionManager(void)115 int32_t InitDevSessionManager(void)
116 {
117     int32_t res = InitHcMutex(&g_sessionMutex, false);
118     if (res != HC_SUCCESS) {
119         LOGE("Init session mutex failed.");
120         return res;
121     }
122     g_sessionInfoList = CREATE_HC_VECTOR(SessionInfoList);
123     return HC_SUCCESS;
124 }
125 
DestroyDevSessionManager(void)126 void DestroyDevSessionManager(void)
127 {
128     uint32_t index;
129     SessionInfo *ptr;
130     (void)LockHcMutex(&g_sessionMutex);
131     FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
132         ptr->session->destroy(ptr->session);
133     }
134     DESTROY_HC_VECTOR(SessionInfoList, &g_sessionInfoList);
135     UnlockHcMutex(&g_sessionMutex);
136     DestroyHcMutex(&g_sessionMutex);
137 }
138 
IsSessionExist(int64_t sessionId)139 bool IsSessionExist(int64_t sessionId)
140 {
141     (void)LockHcMutex(&g_sessionMutex);
142     SessionInfo *sessionInfo;
143     int32_t res = GetSessionInfo(sessionId, &sessionInfo);
144     UnlockHcMutex(&g_sessionMutex);
145     return res == HC_SUCCESS;
146 }
147 
OpenDevSession(int64_t sessionId,const char * appId,SessionInitParams * params)148 int32_t OpenDevSession(int64_t sessionId, const char *appId, SessionInitParams *params)
149 {
150     if ((appId == NULL) || (params == NULL)) {
151         LOGE("invalid params.");
152         return HC_ERR_INVALID_PARAMS;
153     }
154     (void)LockHcMutex(&g_sessionMutex);
155     RemoveTimeoutSession();
156     int32_t res = CheckEnvForOpenSession(sessionId);
157     if (res != HC_SUCCESS) {
158         UnlockHcMutex(&g_sessionMutex);
159         return res;
160     }
161     DevSession *session;
162     res = CreateDevSession(sessionId, appId, params, &session);
163     if (res != HC_SUCCESS) {
164         LOGE("create session fail. [AppId]: %" LOG_PUB "s, [Id]: %" LOG_PUB PRId64, appId, sessionId);
165         UnlockHcMutex(&g_sessionMutex);
166         return res;
167     }
168     res = AddNewSessionToList(session);
169     if (res != HC_SUCCESS) {
170         session->destroy(session);
171         UnlockHcMutex(&g_sessionMutex);
172         return res;
173     }
174     LOGI("create session success. [AppId]: %" LOG_PUB "s, [CurNum]: %" LOG_PUB "u, [Id]: %" LOG_PUB PRId64,
175         appId, HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
176     UnlockHcMutex(&g_sessionMutex);
177     return HC_SUCCESS;
178 }
179 
StartDevSession(int64_t sessionId)180 int32_t StartDevSession(int64_t sessionId)
181 {
182     (void)LockHcMutex(&g_sessionMutex);
183     RemoveTimeoutSession();
184     SessionInfo *sessionInfo;
185     int32_t res = GetSessionInfo(sessionId, &sessionInfo);
186     if (res != HC_SUCCESS) {
187         LOGE("session not found. [Id]: %" LOG_PUB PRId64, sessionId);
188         UnlockHcMutex(&g_sessionMutex);
189         return res;
190     }
191     DevSession *session = sessionInfo->session;
192     res = session->start(session);
193     UnlockHcMutex(&g_sessionMutex);
194     return res;
195 }
196 
ProcessDevSession(int64_t sessionId,const CJson * receviedMsg,bool * isFinish)197 int32_t ProcessDevSession(int64_t sessionId, const CJson *receviedMsg, bool *isFinish)
198 {
199     if ((receviedMsg == NULL) || (isFinish == NULL)) {
200         LOGE("invalid params.");
201         return HC_ERR_INVALID_PARAMS;
202     }
203     (void)LockHcMutex(&g_sessionMutex);
204     RemoveTimeoutSession();
205     SessionInfo *sessionInfo;
206     int32_t res = GetSessionInfo(sessionId, &sessionInfo);
207     if (res != HC_SUCCESS) {
208         LOGE("session not found. [Id]: %" LOG_PUB PRId64, sessionId);
209         UnlockHcMutex(&g_sessionMutex);
210         return res;
211     }
212     DevSession *session = sessionInfo->session;
213     res = session->process(session, receviedMsg, isFinish);
214     UnlockHcMutex(&g_sessionMutex);
215     return res;
216 }
217 
CloseDevSession(int64_t sessionId)218 void CloseDevSession(int64_t sessionId)
219 {
220     (void)LockHcMutex(&g_sessionMutex);
221     RemoveTimeoutSession();
222     uint32_t index;
223     SessionInfo *ptr;
224     FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
225         DevSession *session = ptr->session;
226         if (session->id == sessionId) {
227             session->destroy(session);
228             HC_VECTOR_POPELEMENT(&g_sessionInfoList, ptr, index);
229             LOGI("close session success. [CurNum]: %" LOG_PUB "u, [Id]: %" LOG_PUB PRId64,
230                 HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
231             UnlockHcMutex(&g_sessionMutex);
232             return;
233         }
234     }
235     LOGI("session not exist. [Id]: %" LOG_PUB PRId64, sessionId);
236     UnlockHcMutex(&g_sessionMutex);
237 }
238 
CancelDevSession(int64_t sessionId,const char * appId)239 void CancelDevSession(int64_t sessionId, const char *appId)
240 {
241     if (appId == NULL) {
242         LOGE("appId is NULL.");
243         return;
244     }
245     (void)LockHcMutex(&g_sessionMutex);
246     RemoveTimeoutSession();
247     uint32_t index;
248     SessionInfo *ptr;
249     FOR_EACH_HC_VECTOR(g_sessionInfoList, index, ptr) {
250         DevSession *session = ptr->session;
251         if (session->id == sessionId && IsStrEqual(session->appId, appId)) {
252             session->destroy(session);
253             HC_VECTOR_POPELEMENT(&g_sessionInfoList, ptr, index);
254             LOGI("cancel session success. [CurNum]: %" LOG_PUB "u, [Id]: %" LOG_PUB PRId64,
255                 HC_VECTOR_SIZE(&g_sessionInfoList), sessionId);
256             UnlockHcMutex(&g_sessionMutex);
257             return;
258         }
259     }
260     LOGI("session not exist. [Id]: %" LOG_PUB PRId64, sessionId);
261     UnlockHcMutex(&g_sessionMutex);
262 }
263 
DoStartSession(HcTaskBase * task)264 static void DoStartSession(HcTaskBase *task)
265 {
266     LOGI("start session task begin.");
267     if (task == NULL) {
268         LOGE("The input task is NULL, can't start session!");
269         DecreaseCriticalCnt();
270         return;
271     }
272     StartSessionTask *realTask = (StartSessionTask *)task;
273     SET_LOG_MODE(TRACE_MODE);
274     SET_TRACE_ID(realTask->sessionId);
275     int32_t res = StartDevSession(realTask->sessionId);
276     if (res != HC_SUCCESS) {
277         LOGE("start session fail.[Res]: %" LOG_PUB "d", res);
278         CloseDevSession(realTask->sessionId);
279     }
280     DecreaseCriticalCnt();
281 }
282 
DoProcSession(HcTaskBase * task)283 static void DoProcSession(HcTaskBase *task)
284 {
285     LOGI("proc session task begin.");
286     if (task == NULL) {
287         LOGE("The input task is NULL, can't start session!");
288         DecreaseCriticalCnt();
289         return;
290     }
291     ProcSessionTask *realTask = (ProcSessionTask *)task;
292     SET_LOG_MODE(TRACE_MODE);
293     SET_TRACE_ID(realTask->sessionId);
294     bool isFinish = false;
295     int32_t res = ProcessDevSession(realTask->sessionId, realTask->receivedMsg, &isFinish);
296     if (res != HC_SUCCESS) {
297         LOGE("ProcessDevSession fail. [Res]: %" LOG_PUB "d", res);
298         CloseDevSession(realTask->sessionId);
299         DecreaseCriticalCnt();
300         return;
301     }
302     LOGI("ProcessDevSession success. [State]: %" LOG_PUB "s", isFinish ? "FINISH" : "CONTINUE");
303     if (isFinish) {
304         CloseDevSession(realTask->sessionId);
305     }
306     DecreaseCriticalCnt();
307 }
308 
InitStartSessionTask(StartSessionTask * task,int64_t sessionId)309 static void InitStartSessionTask(StartSessionTask *task, int64_t sessionId)
310 {
311     task->base.doAction = DoStartSession;
312     task->base.destroy = NULL;
313     task->sessionId = sessionId;
314 }
315 
DestroyProcSessionTask(HcTaskBase * task)316 static void DestroyProcSessionTask(HcTaskBase *task)
317 {
318     ProcSessionTask *realTask = (ProcSessionTask *)task;
319     FreeJson(realTask->receivedMsg);
320     DecreaseCriticalCnt();
321 }
322 
InitProcSessionTask(ProcSessionTask * task,int64_t sessionId,CJson * receivedMsg)323 static void InitProcSessionTask(ProcSessionTask *task, int64_t sessionId, CJson *receivedMsg)
324 {
325     task->base.doAction = DoProcSession;
326     task->base.destroy = DestroyProcSessionTask;
327     task->sessionId = sessionId;
328     task->receivedMsg = receivedMsg;
329 }
330 
PushStartSessionTask(int64_t sessionId)331 int32_t PushStartSessionTask(int64_t sessionId)
332 {
333     StartSessionTask *task = (StartSessionTask *)HcMalloc(sizeof(StartSessionTask), 0);
334     if (task == NULL) {
335         LOGE("Failed to allocate memory for task!");
336         return HC_ERR_ALLOC_MEMORY;
337     }
338     InitStartSessionTask(task, sessionId);
339     if (PushTask((HcTaskBase*)task) != HC_SUCCESS) {
340         LOGE("push start session task fail.");
341         HcFree(task);
342         return HC_ERR_INIT_TASK_FAIL;
343     }
344     IncreaseCriticalCnt(ADD_ONE);
345     LOGI("push start session task success.");
346     return HC_SUCCESS;
347 }
348 
PushProcSessionTask(int64_t sessionId,CJson * receivedMsg)349 int32_t PushProcSessionTask(int64_t sessionId, CJson *receivedMsg)
350 {
351     ProcSessionTask *task = (ProcSessionTask *)HcMalloc(sizeof(ProcSessionTask), 0);
352     if (task == NULL) {
353         LOGE("Failed to allocate memory for task!");
354         return HC_ERR_ALLOC_MEMORY;
355     }
356     InitProcSessionTask(task, sessionId, receivedMsg);
357     if (PushTask((HcTaskBase*)task) != HC_SUCCESS) {
358         LOGE("push start session task fail.");
359         HcFree(task);
360         return HC_ERR_INIT_TASK_FAIL;
361     }
362     IncreaseCriticalCnt(ADD_TWO);
363     LOGI("push start session task success.");
364     return HC_SUCCESS;
365 }