1 /*
2 * Copyright (c) 2022 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 #include "messenger_device_session_manager.h"
16
17 #include <stdlib.h>
18
19 #include "securec.h"
20 #include "session.h"
21
22 #include "messenger_device_status_manager.h"
23 #include "messenger_utils.h"
24 #include "utils_dslm_list.h"
25 #include "utils_log.h"
26 #include "utils_mem.h"
27 #include "utils_mutex.h"
28
29 #define IS_SERVER 0
30 #define MSG_BUFF_MAX_LENGTH (81920 * 4)
31
32 static int MessengerOnSessionOpened(int sessionId, int result);
33 static void MessengerOnSessionClosed(int sessionId);
34 static void MessengerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen);
35 static void MessengerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen);
36
37 typedef struct DeviceSessionManager {
38 const ISessionListener listener;
39 ListHead pendingSendList;
40 ListHead openedSessionList;
41 DeviceMessageReceiver messageReceiver;
42 MessageSendResultNotifier sendResultNotifier;
43 const char *pkgName;
44 const char *primarySessName;
45 const char *secondarySessName;
46 WorkQueue *queue;
47 Mutex mutex;
48 } DeviceSessionManager;
49
50 typedef struct PendingMsgData {
51 ListNode link;
52 uint32_t transNo;
53 DeviceIdentify destIdentity;
54 uint32_t msgLen;
55 uint8_t msgData[1];
56 } PendingMsgData;
57
58 typedef struct SessionInfo {
59 ListNode link;
60 int32_t sessionId;
61 uint32_t maskId;
62 DeviceIdentify identity;
63 } SessionInfo;
64
GetDeviceSessionManagerInstance(void)65 static DeviceSessionManager *GetDeviceSessionManagerInstance(void)
66 {
67 static DeviceSessionManager manager = {
68 {
69 .OnSessionOpened = MessengerOnSessionOpened,
70 .OnSessionClosed = MessengerOnSessionClosed,
71 .OnBytesReceived = MessengerOnBytesReceived,
72 .OnMessageReceived = MessengerOnMessageReceived,
73 },
74 .pendingSendList = INIT_LIST(manager.pendingSendList),
75 .openedSessionList = INIT_LIST(manager.openedSessionList),
76 .messageReceiver = NULL,
77 .sendResultNotifier = NULL,
78 .queue = NULL,
79 .mutex = INITED_MUTEX,
80 };
81 return &manager;
82 }
83
ProcessSessionMessageReceived(const uint8_t * data,uint32_t len)84 static void ProcessSessionMessageReceived(const uint8_t *data, uint32_t len)
85 {
86 if (data == NULL || len == 0) {
87 return;
88 }
89 QueueMsgData *queueData = (QueueMsgData *)data;
90 if (queueData->msgLen + sizeof(QueueMsgData) != len) {
91 SECURITY_LOG_ERROR("invalid input");
92 return;
93 }
94
95 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
96 DeviceMessageReceiver messageReceiver = instance->messageReceiver;
97 if (messageReceiver == NULL) {
98 SECURITY_LOG_ERROR("messageReceiver is null");
99 return;
100 }
101 messageReceiver(&queueData->srcIdentity, queueData->msgData, queueData->msgLen);
102 FREE(queueData);
103 }
104
OnSessionMessageReceived(const DeviceIdentify * devId,const uint8_t * msg,uint32_t msgLen)105 static void OnSessionMessageReceived(const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen)
106 {
107 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
108 WorkQueue *queue = instance->queue;
109 if (queue == NULL) {
110 SECURITY_LOG_ERROR("queue is null");
111 return;
112 }
113 DeviceMessageReceiver messageReceiver = instance->messageReceiver;
114 if (messageReceiver == NULL) {
115 SECURITY_LOG_ERROR("messageReceiver is null");
116 return;
117 }
118 uint32_t queueDataLen = 0;
119 QueueMsgData *queueData = CreateQueueMsgData(devId, msg, msgLen, &queueDataLen);
120 if (queueData == NULL) {
121 return;
122 }
123 uint32_t ret = QueueWork(queue, ProcessSessionMessageReceived, (uint8_t *)queueData, queueDataLen);
124 if (ret != WORK_QUEUE_OK) {
125 SECURITY_LOG_ERROR("QueueWork failed, ret is %{public}u", ret);
126 FREE(queueData);
127 return;
128 }
129 }
130
GetDeviceIdentityFromSessionId(int sessionId,DeviceIdentify * identity,uint32_t * maskId)131 static bool GetDeviceIdentityFromSessionId(int sessionId, DeviceIdentify *identity, uint32_t *maskId)
132 {
133 if (identity == NULL || maskId == NULL) {
134 return false;
135 }
136 char networkId[DEVICE_ID_MAX_LEN + 1] = {0};
137 int ret = GetPeerDeviceId(sessionId, networkId, DEVICE_ID_MAX_LEN + 1);
138 if (ret != 0) {
139 SECURITY_LOG_INFO("GetPeerDeviceId failed, sessionId is %{public}d, result is %{public}d", sessionId, ret);
140 return false;
141 }
142
143 if (!MessengerGetDeviceIdentifyByNetworkId(networkId, identity)) {
144 SECURITY_LOG_ERROR("MessengerGetDeviceIdentifyByNetworkId failed");
145 return false;
146 }
147
148 *maskId = MaskDeviceIdentity((const char *)identity->identity, DEVICE_ID_MAX_LEN);
149
150 return true;
151 }
152
153 #ifdef L0_MINI
MessengerOnSessionOpened(int sessionId,int result)154 static int MessengerOnSessionOpened(int sessionId, int result)
155 {
156 int side = GetSessionSide(sessionId);
157 SECURITY_LOG_INFO("sessionId=%{public}d, side=%{public}s, result=%{public}d", sessionId,
158 (side == IS_SERVER) ? "server" : "client", result);
159 if (side != IS_SERVER) {
160 return 0;
161 }
162 if (result != 0) {
163 return 0;
164 }
165
166 DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
167 uint32_t maskId;
168 bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId);
169 if (ret == false) {
170 SECURITY_LOG_ERROR("GetDeviceIdentityFromSessionId failed");
171 return 0;
172 }
173
174 SessionInfo *sessionInfo = MALLOC(sizeof(SessionInfo));
175 if (sessionInfo == NULL) {
176 SECURITY_LOG_ERROR("malloc failed, sessionInfo is null");
177 return 0;
178 }
179 sessionInfo->sessionId = sessionId;
180 sessionInfo->maskId = maskId;
181 (void)memcpy_s(&sessionInfo->identity, sizeof(DeviceIdentify), &identity, sizeof(DeviceIdentify));
182
183 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
184 LockMutex(&instance->mutex);
185 AddListNodeBefore(&sessionInfo->link, &instance->openedSessionList);
186 UnlockMutex(&instance->mutex);
187 return 0;
188 }
189 #else
MessengerOnSessionOpened(int sessionId,int result)190 static int MessengerOnSessionOpened(int sessionId, int result)
191 {
192 int side = GetSessionSide(sessionId);
193 SECURITY_LOG_INFO("sessionId=%{public}d, side=%{public}s, result=%{public}d", sessionId,
194 (side == IS_SERVER) ? "server" : "client", result);
195
196 if (side == IS_SERVER) {
197 return 0;
198 }
199 if (result != 0) {
200 return 0;
201 }
202
203 DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
204 uint32_t maskId;
205 bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId);
206 if (ret == false) {
207 SECURITY_LOG_ERROR("GetDeviceIdentityFromSessionId failed");
208 return 0;
209 }
210
211 SessionInfo *sessionInfo = MALLOC(sizeof(SessionInfo));
212 if (sessionInfo == NULL) {
213 SECURITY_LOG_ERROR("malloc failed, sessionInfo is null");
214 return 0;
215 }
216 sessionInfo->sessionId = sessionId;
217 sessionInfo->maskId = maskId;
218 (void)memcpy_s(&sessionInfo->identity, sizeof(DeviceIdentify), &identity, sizeof(DeviceIdentify));
219
220 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
221 LockMutex(&instance->mutex);
222 AddListNodeBefore(&sessionInfo->link, &instance->openedSessionList);
223
224 ListNode *node = NULL;
225 ListNode *temp = NULL;
226
227 FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) {
228 PendingMsgData *msgData = LIST_ENTRY(node, PendingMsgData, link);
229 if (!IsSameDevice(&msgData->destIdentity, &identity)) {
230 continue;
231 }
232
233 RemoveListNode(node);
234 int sent = SendBytes(sessionId, msgData->msgData, msgData->msgLen);
235 if (sent != 0) {
236 SECURITY_LOG_ERROR("SendBytes error code = %{public}d", ret);
237 }
238 FREE(msgData);
239 }
240
241 UnlockMutex(&instance->mutex);
242 return 0;
243 }
244 #endif /* L0_MINI */
245
MessengerOnSessionClosed(int sessionId)246 static void MessengerOnSessionClosed(int sessionId)
247 {
248 int side = GetSessionSide(sessionId);
249 SECURITY_LOG_INFO("sessionId=%{public}d, side=%{public}s", sessionId, (side == IS_SERVER) ? "server" : "client");
250
251 #ifndef L0_MINI
252 if (side == IS_SERVER) {
253 return;
254 }
255 #endif
256
257 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
258 LockMutex(&instance->mutex);
259 ListNode *node = NULL;
260 ListNode *temp = NULL;
261 FOREACH_LIST_NODE_SAFE (node, &instance->openedSessionList, temp) {
262 SessionInfo *info = LIST_ENTRY(node, SessionInfo, link);
263 if (info->sessionId == sessionId) {
264 SECURITY_LOG_INFO("device=%{public}x", info->maskId);
265 RemoveListNode(node);
266 FREE(info);
267 }
268 }
269 UnlockMutex(&instance->mutex);
270 }
271
MessengerOnBytesReceived(int sessionId,const void * data,unsigned int dataLen)272 static void MessengerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
273 {
274 if (data == NULL || dataLen == 0 || dataLen > MSG_BUFF_MAX_LENGTH) {
275 SECURITY_LOG_ERROR("invalid msg received");
276 return;
277 }
278
279 DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
280 uint32_t maskId;
281 bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId);
282 if (ret == false) {
283 return;
284 }
285 SECURITY_LOG_INFO("device=%{public}x***, data length is %{public}u", maskId, dataLen);
286 OnSessionMessageReceived(&identity, (const uint8_t *)data, (uint32_t)dataLen);
287 }
288
MessengerOnMessageReceived(int sessionId,const void * data,unsigned int dataLen)289 static void MessengerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen)
290 {
291 return MessengerOnBytesReceived(sessionId, data, dataLen);
292 }
293
TryToCreateSessionServer(const char * pkgName,const char * sessionName,const ISessionListener * listener)294 static bool TryToCreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener)
295 {
296 int try = 0;
297 int ret = CreateSessionServer(pkgName, sessionName, listener);
298 while (ret != 0 && try < MAX_TRY_TIMES) {
299 MessengerSleep(1); // sleep 1 second and try again
300 ret = CreateSessionServer(pkgName, sessionName, listener);
301 try++;
302 }
303
304 if (ret != 0) {
305 SECURITY_LOG_ERROR("CreateSessionServer failed = %{public}d", ret);
306 return false;
307 }
308 return true;
309 }
310
InitDeviceSessionManager(WorkQueue * queue,const MessengerConfig * config)311 bool InitDeviceSessionManager(WorkQueue *queue, const MessengerConfig *config)
312 {
313 if ((queue == NULL) || (config == NULL)) {
314 return false;
315 }
316 DeviceSessionManager *inst = GetDeviceSessionManagerInstance();
317 inst->pkgName = config->pkgName;
318 inst->primarySessName = config->primarySessName;
319 inst->secondarySessName = config->secondarySessName;
320 inst->messageReceiver = config->messageReceiver;
321 inst->sendResultNotifier = config->sendResultNotifier;
322 inst->queue = queue;
323
324 bool succ = TryToCreateSessionServer(inst->pkgName, inst->primarySessName, &inst->listener);
325 SECURITY_LOG_INFO("CreateSessionServer %{public}s = %{public}s", inst->primarySessName, succ ? "succ" : "fail");
326
327 if (inst->secondarySessName == NULL) {
328 return succ;
329 }
330
331 succ = TryToCreateSessionServer(inst->pkgName, inst->secondarySessName, &inst->listener);
332 SECURITY_LOG_INFO("CreateSessionServer %{public}s = %{public}s", inst->secondarySessName, succ ? "succ" : "fail");
333 return succ;
334 }
335
DeInitDeviceSessionManager(void)336 bool DeInitDeviceSessionManager(void)
337 {
338 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
339 int ret = RemoveSessionServer(instance->pkgName, instance->primarySessName);
340 if (ret != 0) {
341 SECURITY_LOG_ERROR("RemoveSessionServer %{public}s failed = %{public}d", instance->primarySessName, ret);
342 }
343
344 if (instance->secondarySessName) {
345 ret = RemoveSessionServer(instance->pkgName, instance->primarySessName);
346 if (ret != 0) {
347 SECURITY_LOG_ERROR("RemoveSessionServer %{public}s failed = %{public}d", instance->primarySessName, ret);
348 }
349 }
350
351 LockMutex(&instance->mutex);
352 instance->pkgName = NULL;
353 instance->primarySessName = NULL;
354 instance->secondarySessName = NULL;
355 instance->messageReceiver = NULL;
356 instance->sendResultNotifier = NULL;
357 instance->queue = NULL;
358
359 ListNode *node = NULL;
360 ListNode *temp = NULL;
361
362 FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) {
363 PendingMsgData *msgData = LIST_ENTRY(node, PendingMsgData, link);
364 RemoveListNode(node);
365 FREE(msgData);
366 }
367
368 FOREACH_LIST_NODE_SAFE (node, &instance->openedSessionList, temp) {
369 SessionInfo *info = LIST_ENTRY(node, SessionInfo, link);
370 RemoveListNode(node);
371 FREE(info);
372 }
373
374 DestroyWorkQueue(instance->queue);
375 UnlockMutex(&instance->mutex);
376
377 SECURITY_LOG_INFO("RemoveSessionServer success");
378 return true;
379 }
380
GetOpenedSessionId(const DeviceIdentify * devId,int32_t * sessionId)381 static bool GetOpenedSessionId(const DeviceIdentify *devId, int32_t *sessionId)
382 {
383 if (devId == NULL || sessionId == NULL) {
384 return false;
385 }
386 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
387
388 bool find = false;
389 LockMutex(&instance->mutex);
390 ListNode *node = NULL;
391 uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length);
392
393 FOREACH_LIST_NODE (node, &instance->openedSessionList) {
394 SessionInfo *sessionInfo = LIST_ENTRY(node, SessionInfo, link);
395 if (IsSameDevice(&sessionInfo->identity, devId)) {
396 *sessionId = sessionInfo->sessionId;
397 find = true;
398 break;
399 }
400 }
401 UnlockMutex(&instance->mutex);
402 SECURITY_LOG_DEBUG("device %{public}x %{public}s", mask, find ? "exist" : "no exist");
403 return find;
404 }
405
PushMsgDataToPendingList(uint32_t transNo,const DeviceIdentify * devId,const uint8_t * msg,uint32_t msgLen)406 static void PushMsgDataToPendingList(uint32_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen)
407 {
408 PendingMsgData *data = MALLOC(sizeof(PendingMsgData) + msgLen);
409 if (data == NULL) {
410 SECURITY_LOG_ERROR("malloc failed, data is null");
411 return;
412 }
413 data->transNo = transNo;
414 data->msgLen = msgLen;
415 (void)memcpy_s(&data->destIdentity, sizeof(DeviceIdentify), devId, sizeof(DeviceIdentify));
416 (void)memcpy_s(data->msgData, msgLen, msg, msgLen);
417 DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
418 LockMutex(&instance->mutex);
419 AddListNodeBefore(&data->link, &instance->pendingSendList);
420 UnlockMutex(&instance->mutex);
421 }
422
CreateNewDeviceSession(const DeviceIdentify * devId)423 static void CreateNewDeviceSession(const DeviceIdentify *devId)
424 {
425 uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length);
426 char deviceName[DEVICE_ID_MAX_LEN + 1] = {0};
427 bool succ = MessengerGetNetworkIdByDeviceIdentify(devId, deviceName, DEVICE_ID_MAX_LEN + 1);
428 if (!succ) {
429 SECURITY_LOG_ERROR("get network id failed");
430 return;
431 }
432
433 const SessionAttribute attr = {
434 .dataType = TYPE_BYTES,
435 };
436
437 const char *primary = GetDeviceSessionManagerInstance()->primarySessName;
438 const char *secondary = GetDeviceSessionManagerInstance()->secondarySessName;
439
440 int ret = OpenSession(primary, primary, deviceName, "", &attr);
441 if (ret <= 0) {
442 // open failed, need to try again.
443 ret = OpenSession(primary, primary, deviceName, "", &attr);
444 }
445 SECURITY_LOG_INFO("open 1st session %{public}s device %{public}x ret is %{public}d", primary, mask, ret);
446
447 if (secondary == NULL || ret) {
448 return;
449 }
450
451 ret = OpenSession(primary, secondary, deviceName, "", &attr);
452 if (ret <= 0) {
453 // open failed, need to try again.
454 ret = OpenSession(primary, secondary, deviceName, "", &attr);
455 }
456 SECURITY_LOG_INFO("open 2nd session %{public}s device %{public}x ret is %{public}d", secondary, mask, ret);
457 }
458
MessengerSendMsgTo(uint64_t transNo,const DeviceIdentify * devId,const uint8_t * msg,uint32_t msgLen)459 void MessengerSendMsgTo(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen)
460 {
461 if (devId == NULL || msg == NULL || msgLen == 0 || msgLen > MSG_BUFF_MAX_LENGTH) {
462 SECURITY_LOG_ERROR("invalid params");
463 return;
464 }
465
466 static DeviceIdentify self = {0, {0}};
467 int32_t level;
468 MessengerGetSelfDeviceIdentify(&self, &level);
469
470 if (IsSameDevice(&self, devId)) {
471 SECURITY_LOG_DEBUG("loopback msg");
472 OnSessionMessageReceived(devId, msg, msgLen);
473 return;
474 }
475
476 int32_t sessionId;
477 bool find = GetOpenedSessionId(devId, &sessionId);
478 if (find) {
479 int ret = SendBytes(sessionId, msg, msgLen);
480 if (ret != 0) {
481 SECURITY_LOG_ERROR("SendBytes error code = %{public}d", ret);
482 }
483 return;
484 }
485
486 PushMsgDataToPendingList(transNo, devId, msg, msgLen);
487 #ifndef L0_MINI
488 CreateNewDeviceSession(devId);
489 #endif
490 }