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 }