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 }