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