• 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_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 
MessengerOnSessionOpened(int sessionId,int result)173 static int MessengerOnSessionOpened(int sessionId, int result)
174 {
175     int side = GetSessionSide(sessionId);
176     SECURITY_LOG_INFO("sessionId=%{public}d, side=%{public}s, result=%{public}d", sessionId,
177         (side == IS_SERVER) ? "server" : "client", result);
178 
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 
207     ListNode *node = NULL;
208     ListNode *temp = NULL;
209 
210     FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) {
211         PendingMsgData *msgData = LIST_ENTRY(node, PendingMsgData, link);
212         if (!IsSameDevice(&msgData->destIdentity, &identity)) {
213             continue;
214         }
215 
216         RemoveListNode(node);
217         int sent = SendBytes(sessionId, msgData->msgData, msgData->msgLen);
218         if (sent != 0) {
219             SECURITY_LOG_ERROR("SendBytes error code = %{public}d", ret);
220         }
221         FREE(msgData);
222     }
223 
224     UnlockMutex(&instance->mutex);
225     return 0;
226 }
227 
MessengerOnSessionClosed(int sessionId)228 static void MessengerOnSessionClosed(int sessionId)
229 {
230     int side = GetSessionSide(sessionId);
231     SECURITY_LOG_INFO("sessionId=%{public}d, side=%{public}s", sessionId, (side == IS_SERVER) ? "server" : "client");
232 
233     if (side == IS_SERVER) {
234         return;
235     }
236 
237     DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
238     LockMutex(&instance->mutex);
239     ListNode *node = NULL;
240     ListNode *temp = NULL;
241     FOREACH_LIST_NODE_SAFE (node, &instance->openedSessionList, temp) {
242         SessionInfo *info = LIST_ENTRY(node, SessionInfo, link);
243         if (info->sessionId == sessionId) {
244             SECURITY_LOG_INFO("device=%{public}x", info->maskId);
245             RemoveListNode(node);
246             FREE(info);
247         }
248     }
249     UnlockMutex(&instance->mutex);
250 }
251 
MessengerOnBytesReceived(int sessionId,const void * data,unsigned int dataLen)252 static void MessengerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
253 {
254     if (data == NULL || dataLen == 0 || dataLen > MSG_BUFF_MAX_LENGTH) {
255         SECURITY_LOG_ERROR("invalid msg received");
256         return;
257     }
258 
259     DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}};
260     uint32_t maskId;
261     bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId);
262     if (ret == false) {
263         return;
264     }
265     SECURITY_LOG_INFO("device=%{public}x***, data length is %{public}u", maskId, dataLen);
266     OnSessionMessageReceived(&identity, (const uint8_t *)data, (uint32_t)dataLen);
267 }
268 
MessengerOnMessageReceived(int sessionId,const void * data,unsigned int dataLen)269 static void MessengerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen)
270 {
271     return MessengerOnBytesReceived(sessionId, data, dataLen);
272 }
273 
TryToCreateSessionServer(const char * pkgName,const char * sessionName,const ISessionListener * listener)274 static bool TryToCreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener)
275 {
276     int try = 0;
277     int ret = CreateSessionServer(pkgName, sessionName, listener);
278     while (ret != 0 && try < MAX_TRY_TIMES) {
279         MessengerSleep(1); // sleep 1 second and try again
280         ret = CreateSessionServer(pkgName, sessionName, listener);
281         try++;
282     }
283 
284     if (ret != 0) {
285         SECURITY_LOG_ERROR("CreateSessionServer failed = %{public}d", ret);
286         return false;
287     }
288     return true;
289 }
290 
InitDeviceSessionManager(WorkQueue * queue,const MessengerConfig * config)291 bool InitDeviceSessionManager(WorkQueue *queue, const MessengerConfig *config)
292 {
293     if ((queue == NULL) || (config == NULL)) {
294         return false;
295     }
296     DeviceSessionManager *inst = GetDeviceSessionManagerInstance();
297     inst->pkgName = config->pkgName;
298     inst->primarySessName = config->primarySessName;
299     inst->secondarySessName = config->secondarySessName;
300     inst->messageReceiver = config->messageReceiver;
301     inst->sendResultNotifier = config->sendResultNotifier;
302     inst->queue = queue;
303 
304     bool succ = TryToCreateSessionServer(inst->pkgName, inst->primarySessName, &inst->listener);
305     SECURITY_LOG_INFO("CreateSessionServer %{public}s = %{public}s", inst->primarySessName, succ ? "succ" : "fail");
306 
307     if (inst->secondarySessName == NULL) {
308         return succ;
309     }
310 
311     succ = TryToCreateSessionServer(inst->pkgName, inst->secondarySessName, &inst->listener);
312     SECURITY_LOG_INFO("CreateSessionServer %{public}s = %{public}s", inst->secondarySessName, succ ? "succ" : "fail");
313     return succ;
314 }
315 
DeInitDeviceSessionManager(void)316 bool DeInitDeviceSessionManager(void)
317 {
318     DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
319     int ret = RemoveSessionServer(instance->pkgName, instance->primarySessName);
320     if (ret != 0) {
321         SECURITY_LOG_ERROR("RemoveSessionServer %{public}s failed = %{public}d", instance->primarySessName, ret);
322     }
323 
324     if (instance->secondarySessName) {
325         ret = RemoveSessionServer(instance->pkgName, instance->primarySessName);
326         if (ret != 0) {
327             SECURITY_LOG_ERROR("RemoveSessionServer %{public}s failed = %{public}d", instance->primarySessName, ret);
328         }
329     }
330 
331     LockMutex(&instance->mutex);
332     instance->pkgName = NULL;
333     instance->primarySessName = NULL;
334     instance->secondarySessName = NULL;
335     instance->messageReceiver = NULL;
336     instance->sendResultNotifier = NULL;
337     instance->queue = NULL;
338 
339     ListNode *node = NULL;
340     ListNode *temp = NULL;
341 
342     FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) {
343         PendingMsgData *msgData = LIST_ENTRY(node, PendingMsgData, link);
344         RemoveListNode(node);
345         FREE(msgData);
346     }
347 
348     FOREACH_LIST_NODE_SAFE (node, &instance->openedSessionList, temp) {
349         SessionInfo *info = LIST_ENTRY(node, SessionInfo, link);
350         RemoveListNode(node);
351         FREE(info);
352     }
353 
354     DestroyWorkQueue(instance->queue);
355     UnlockMutex(&instance->mutex);
356 
357     SECURITY_LOG_INFO("RemoveSessionServer success");
358     return true;
359 }
360 
GetOpenedSessionId(const DeviceIdentify * devId,int32_t * sessionId)361 static bool GetOpenedSessionId(const DeviceIdentify *devId, int32_t *sessionId)
362 {
363     if (devId == NULL || sessionId == NULL) {
364         return false;
365     }
366     DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
367 
368     bool find = false;
369     LockMutex(&instance->mutex);
370     ListNode *node = NULL;
371     uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length);
372 
373     FOREACH_LIST_NODE (node, &instance->openedSessionList) {
374         SessionInfo *sessionInfo = LIST_ENTRY(node, SessionInfo, link);
375         if (IsSameDevice(&sessionInfo->identity, devId)) {
376             *sessionId = sessionInfo->sessionId;
377             find = true;
378             break;
379         }
380     }
381     UnlockMutex(&instance->mutex);
382     SECURITY_LOG_DEBUG("device %{public}x %{public}s", mask, find ? "exist" : "no exist");
383     return find;
384 }
385 
PushMsgDataToPendingList(uint32_t transNo,const DeviceIdentify * devId,const uint8_t * msg,uint32_t msgLen)386 static void PushMsgDataToPendingList(uint32_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen)
387 {
388     PendingMsgData *data = MALLOC(sizeof(PendingMsgData) + msgLen);
389     if (data == NULL) {
390         SECURITY_LOG_ERROR("malloc failed, data is null");
391         return;
392     }
393     data->transNo = transNo;
394     data->msgLen = msgLen;
395     (void)memcpy_s(&data->destIdentity, sizeof(DeviceIdentify), devId, sizeof(DeviceIdentify));
396     (void)memcpy_s(data->msgData, msgLen, msg, msgLen);
397     DeviceSessionManager *instance = GetDeviceSessionManagerInstance();
398     LockMutex(&instance->mutex);
399     AddListNodeBefore(&data->link, &instance->pendingSendList);
400     UnlockMutex(&instance->mutex);
401 }
402 
CreateNewDeviceSession(const DeviceIdentify * devId)403 static void CreateNewDeviceSession(const DeviceIdentify *devId)
404 {
405     uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length);
406     char deviceName[DEVICE_ID_MAX_LEN + 1] = {0};
407     bool succ = MessengerGetNetworkIdByDeviceIdentify(devId, deviceName, DEVICE_ID_MAX_LEN + 1);
408     if (!succ) {
409         SECURITY_LOG_ERROR("get network id failed");
410         return;
411     }
412 
413     const SessionAttribute attr = {
414         .dataType = TYPE_BYTES,
415     };
416 
417     const char *primary = GetDeviceSessionManagerInstance()->primarySessName;
418     const char *secondary = GetDeviceSessionManagerInstance()->secondarySessName;
419 
420     int ret = OpenSession(primary, primary, deviceName, "", &attr);
421     if (ret <= 0) {
422         // open failed, need to try again.
423         ret = OpenSession(primary, primary, deviceName, "", &attr);
424     }
425     SECURITY_LOG_INFO("open 1st session %{public}s device %{public}x ret is %{public}d", primary, mask, ret);
426 
427     if (secondary == NULL || ret) {
428         return;
429     }
430 
431     ret = OpenSession(primary, secondary, deviceName, "", &attr);
432     if (ret <= 0) {
433         // open failed, need to try again.
434         ret = OpenSession(primary, secondary, deviceName, "", &attr);
435     }
436     SECURITY_LOG_INFO("open 2nd session %{public}s device %{public}x ret is %{public}d", secondary, mask, ret);
437 }
438 
MessengerSendMsgTo(uint64_t transNo,const DeviceIdentify * devId,const uint8_t * msg,uint32_t msgLen)439 void MessengerSendMsgTo(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen)
440 {
441     if (devId == NULL || msg == NULL || msgLen == 0 || msgLen > MSG_BUFF_MAX_LENGTH) {
442         SECURITY_LOG_ERROR("invalid params");
443         return;
444     }
445 
446     static DeviceIdentify self = {0, {0}};
447     uint32_t devType;
448     MessengerGetSelfDeviceIdentify(&self, &devType);
449 
450     if (IsSameDevice(&self, devId)) {
451         SECURITY_LOG_DEBUG("loopback msg");
452         OnSessionMessageReceived(devId, msg, msgLen);
453         return;
454     }
455 
456     int32_t sessionId;
457     bool find = GetOpenedSessionId(devId, &sessionId);
458     if (find) {
459         int ret = SendBytes(sessionId, msg, msgLen);
460         if (ret != 0) {
461             SECURITY_LOG_ERROR("SendBytes error code = %{public}d", ret);
462         }
463         return;
464     }
465 
466     PushMsgDataToPendingList(transNo, devId, msg, msgLen);
467     CreateNewDeviceSession(devId);
468 }