• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }