1 /*
2 * Copyright (c) 2020 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
16 #include "dmslite_session.h"
17
18 #include <pthread.h>
19 #include <sys/time.h>
20 #include <unistd.h>
21
22 #include "dmsfwk_interface.h"
23 #include "dmslite_feature.h"
24 #include "dmslite_log.h"
25 #include "dmslite_packet.h"
26 #include "dmslite_parser.h"
27 #include "dmslite_utils.h"
28
29 #include "securec.h"
30 #include "session.h"
31 #include "softbus_common.h"
32
33 #define DMS_SESSION_NAME "ohos.distributedschedule.dms.proxymanager"
34 #define DMS_MODULE_NAME "dms"
35
36 #define INVALID_SESSION_ID (-1)
37 #define MAX_DATA_SIZE 1024
38 #define TIMEOUT 60
39
40 static int32_t g_curSessionId = INVALID_SESSION_ID;
41 static bool g_curBusy = false;
42 static time_t g_begin;
43 static IDmsListener *g_listener = NULL;
44
45 /* session callback */
46 static void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen);
47 static void OnSessionClosed(int32_t sessionId);
48 static int32_t OnSessionOpened(int32_t sessionId, int result);
49 static void OnMessageReceived(int sessionId, const void *data, unsigned int len);
50
51 static bool IsTimeout();
52 static void OnStartAbilityDone(int8_t errCode);
53
54 static ISessionListener g_sessionCallback = {
55 .OnBytesReceived = OnBytesReceived,
56 .OnSessionOpened = OnSessionOpened,
57 .OnSessionClosed = OnSessionClosed,
58 .OnMessageReceived = OnMessageReceived
59 };
60
61 static IDmsFeatureCallback g_dmsFeatureCallback = {
62 /* in non-test mode, there is no need set a TlvParseCallback */
63 .onTlvParseDone = NULL,
64 .onStartAbilityDone = OnStartAbilityDone,
65 };
66
OnStartAbilityDone(int8_t errCode)67 void OnStartAbilityDone(int8_t errCode)
68 {
69 HILOGD("[onStartAbilityDone errCode = %d]", errCode);
70 }
71
OnBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)72 void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
73 {
74 HILOGD("[OnBytesReceived dataLen = %d]", dataLen);
75 if (data == NULL || dataLen > MAX_DATA_SIZE) {
76 HILOGE("[OnBytesReceived param error");
77 InvokeCallback(NULL, DMS_EC_INVALID_PARAMETER);
78 return;
79 }
80 char *message = (char *)DMS_ALLOC(dataLen);
81 if (message == NULL) {
82 InvokeCallback(NULL, DMS_EC_FAILURE);
83 return;
84 }
85 if (memcpy_s(message, dataLen, (char *)data, dataLen) != EOK) {
86 DMS_FREE(message);
87 InvokeCallback(NULL, DMS_EC_FAILURE);
88 return;
89 }
90 Request request = {
91 .msgId = BYTES_RECEIVED,
92 .len = dataLen,
93 .data = message,
94 .msgValue = sessionId
95 };
96 int32_t result = SAMGR_SendRequest((const Identity*)&(GetDmsLiteFeature()->identity), &request, NULL);
97 if (result != EC_SUCCESS) {
98 DMS_FREE(message);
99 InvokeCallback(NULL, DMS_EC_FAILURE);
100 HILOGD("[OnBytesReceived errCode = %d]", result);
101 }
102 }
103
HandleBytesReceived(int32_t sessionId,const void * data,uint32_t dataLen)104 void HandleBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen)
105 {
106 CommuMessage commuMessage;
107 commuMessage.payloadLength = dataLen;
108 commuMessage.payload = (uint8_t *)data;
109 int32_t errCode = ProcessCommuMsg(&commuMessage, &g_dmsFeatureCallback);
110 HILOGI("[ProcessCommuMsg errCode = %d]", errCode);
111 }
112
OnSessionClosed(int32_t sessionId)113 void OnSessionClosed(int32_t sessionId)
114 {
115 Request request = {
116 .msgId = SESSION_CLOSE,
117 .len = 0,
118 .data = NULL,
119 .msgValue = sessionId
120 };
121 int32_t result = SAMGR_SendRequest((const Identity*)&(GetDmsLiteFeature()->identity), &request, NULL);
122 if (result != EC_SUCCESS) {
123 InvokeCallback(NULL, DMS_EC_FAILURE);
124 HILOGD("[OnSessionClosed SendRequest errCode = %d]", result);
125 }
126 }
127
HandleSessionClosed(int32_t sessionId)128 void HandleSessionClosed(int32_t sessionId)
129 {
130 if (g_curSessionId == sessionId && !g_curBusy) {
131 g_curSessionId = INVALID_SESSION_ID;
132 g_listener = NULL;
133 g_curBusy = false;
134 }
135 }
136
OnSessionOpened(int32_t sessionId,int32_t result)137 int32_t OnSessionOpened(int32_t sessionId, int32_t result)
138 {
139 HILOGD("[OnSessionOpened result = %d]", result);
140 if (sessionId < 0 || result != 0) {
141 InvokeCallback(NULL, DMS_EC_INVALID_PARAMETER);
142 HILOGD("[OnSessionOpened errCode = %d]", result);
143 return result;
144 }
145
146 Request request = {
147 .msgId = SESSION_OPEN,
148 .len = 0,
149 .data = NULL,
150 .msgValue = sessionId
151 };
152 int32_t ret = SAMGR_SendRequest((const Identity*)&(GetDmsLiteFeature()->identity), &request, NULL);
153 if (ret != EC_SUCCESS) {
154 InvokeCallback(NULL, DMS_EC_FAILURE);
155 HILOGD("[OnSessionOpened SendRequest errCode = %d]", ret);
156 }
157 return ret;
158 }
159
HandleSessionOpened(int32_t sessionId)160 int32_t HandleSessionOpened(int32_t sessionId)
161 {
162 if (g_curSessionId != sessionId) {
163 InvokeCallback(NULL, DMS_EC_INVALID_PARAMETER);
164 return EC_SUCCESS;
165 }
166 int32_t ret = SendBytes(g_curSessionId, GetPacketBufPtr(), GetPacketSize());
167 if (ret != 0) {
168 InvokeCallback(NULL, DMS_EC_FAILURE);
169 HILOGD("[OnSessionOpened SendBytes errCode = %d]", ret);
170 CloseDMSSession();
171 }
172 CleanBuild();
173 return ret;
174 }
175
OnMessageReceived(int32_t sessionId,const void * data,uint32_t len)176 void OnMessageReceived(int32_t sessionId, const void *data, uint32_t len)
177 {
178 return;
179 }
180
CreateDMSSessionServer()181 int32_t CreateDMSSessionServer()
182 {
183 return CreateSessionServer(DMS_MODULE_NAME, DMS_SESSION_NAME, &g_sessionCallback);
184 }
185
CloseDMSSessionServer()186 int32_t CloseDMSSessionServer()
187 {
188 return RemoveSessionServer(DMS_MODULE_NAME, DMS_SESSION_NAME);
189 }
190
SendDmsMessage(const char * data,int32_t len,const char * deviceId,IDmsListener * callback)191 int32_t SendDmsMessage(const char *data, int32_t len, const char *deviceId, IDmsListener *callback)
192 {
193 HILOGI("[SendMessage]");
194 if (data == NULL || len > MAX_DATA_SIZE) {
195 HILOGE("[SendMessage params error]");
196 return EC_FAILURE;
197 }
198
199 if (CreateDMSSessionServer() != EC_SUCCESS) {
200 HILOGE("[CreateDMSSessionServer error]");
201 return EC_FAILURE;
202 }
203
204 g_curBusy = true;
205 g_listener = callback;
206 g_begin = time(NULL);
207
208 SessionAttribute attr = {
209 .dataType = TYPE_BYTES
210 };
211 g_curSessionId = OpenSession(DMS_SESSION_NAME, DMS_SESSION_NAME, deviceId, DMS_MODULE_NAME, &attr);
212 if (g_curSessionId < 0) {
213 g_curSessionId = INVALID_SESSION_ID;
214 g_listener = NULL;
215 g_curBusy = false;
216 return EC_FAILURE;
217 }
218 return EC_SUCCESS;
219 }
220
CloseDMSSession()221 void CloseDMSSession()
222 {
223 CloseSession(g_curSessionId);
224 g_curSessionId = INVALID_SESSION_ID;
225 g_listener = NULL;
226 g_curBusy = false;
227 }
228
InvokeCallback(const void * data,int32_t result)229 void InvokeCallback(const void *data, int32_t result)
230 {
231 g_curBusy = false;
232 if (g_listener == NULL) {
233 return;
234 }
235 if (g_listener->OnResultCallback == NULL) {
236 return;
237 }
238 g_listener->OnResultCallback(data, result);
239 }
240
IsTimeout()241 static bool IsTimeout()
242 {
243 time_t now = time(NULL);
244 HILOGI("[IsTimeout diff %f]", difftime(now, g_begin));
245 return ((int)difftime(now, g_begin)) - TIMEOUT >= 0;
246 }
247
IsDmsBusy()248 bool IsDmsBusy()
249 {
250 if (g_curBusy && IsTimeout() && g_curSessionId >= 0) {
251 CloseDMSSession();
252 }
253
254 return g_curBusy;
255 }