1 /*
2 * Copyright (c) 2022-2023 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 "coordination_softbus_adapter.h"
17
18 #include <chrono>
19 #include <thread>
20
21 #include <netinet/in.h>
22 #include <netinet/tcp.h>
23 #include <sys/socket.h>
24
25 #include "softbus_bus_center.h"
26 #include "softbus_common.h"
27
28 #include "coordination_hisysevent.h"
29 #include "coordination_sm.h"
30 #include "device_coordination_softbus_define.h"
31 #include "devicestatus_define.h"
32 #include "dfs_session.h"
33 #include "json_parser.h"
34
35 namespace OHOS {
36 namespace Msdp {
37 namespace DeviceStatus {
38 namespace {
39 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "CoordinationSoftbusAdapter" };
40 std::shared_ptr<CoordinationSoftbusAdapter> g_instance = nullptr;
41 constexpr uint32_t QOS_LEN { 3 };
42 constexpr int32_t MIN_BW { 80 * 1024 * 1024 };
43 constexpr int32_t LATENCY { 1600 };
44 constexpr int32_t SOCKET_SERVER { 0 };
45 constexpr int32_t SOCKET_CLIENT { 1 };
46
ResponseStartRemoteCoordination(int32_t sessionId,const JsonParser & parser)47 void ResponseStartRemoteCoordination(int32_t sessionId, const JsonParser &parser)
48 {
49 CALL_INFO_TRACE;
50 cJSON* networkId = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_LOCAL_DEVICE_ID);
51 cJSON* buttonIsPressed = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_POINTER_BUTTON_IS_PRESS);
52 if (!cJSON_IsString(networkId) || !cJSON_IsBool(buttonIsPressed)) {
53 FI_HILOGE("The data type of CJSON is incorrect");
54 return;
55 }
56 COOR_SM->StartRemoteCoordination(networkId->valuestring, cJSON_IsTrue(buttonIsPressed));
57 }
58
ResponseStartRemoteCoordinationResult(int32_t sessionId,const JsonParser & parser)59 void ResponseStartRemoteCoordinationResult(int32_t sessionId, const JsonParser &parser)
60 {
61 CALL_INFO_TRACE;
62 cJSON* result = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_RESULT);
63 cJSON* dhid = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_START_DHID);
64 cJSON* x = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_POINTER_X);
65 cJSON* y = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_POINTER_Y);
66 if (!cJSON_IsBool(result) || !cJSON_IsString(dhid) || !cJSON_IsNumber(x) || !cJSON_IsNumber(y)) {
67 FI_HILOGE("The data type of CJSON is incorrect");
68 return;
69 }
70 COOR_SM->StartRemoteCoordinationResult(cJSON_IsTrue(result), dhid->valuestring, x->valueint, y->valueint);
71 }
72
ResponseStopRemoteCoordination(int32_t sessionId,const JsonParser & parser)73 void ResponseStopRemoteCoordination(int32_t sessionId, const JsonParser &parser)
74 {
75 CALL_INFO_TRACE;
76 cJSON* result = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_RESULT);
77
78 if (!cJSON_IsBool(result)) {
79 FI_HILOGE("The data type of CJSON is incorrect");
80 return;
81 }
82 COOR_SM->StopRemoteCoordination(cJSON_IsTrue(result));
83 }
84
ResponseStopRemoteCoordinationResult(int32_t sessionId,const JsonParser & parser)85 void ResponseStopRemoteCoordinationResult(int32_t sessionId, const JsonParser &parser)
86 {
87 CALL_INFO_TRACE;
88 cJSON* result = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_RESULT);
89
90 if (!cJSON_IsBool(result)) {
91 FI_HILOGE("The data type of CJSON is incorrect");
92 return;
93 }
94 COOR_SM->StopRemoteCoordinationResult(cJSON_IsTrue(result));
95 }
96
ResponseNotifyUnchainedResult(int32_t sessionId,const JsonParser & parser)97 void ResponseNotifyUnchainedResult(int32_t sessionId, const JsonParser &parser)
98 {
99 CALL_INFO_TRACE;
100 cJSON* networkId = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_LOCAL_DEVICE_ID);
101 cJSON* result = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_RESULT);
102 if (!cJSON_IsString(networkId) || !cJSON_IsBool(result)) {
103 FI_HILOGE("The data type of CJSON is incorrect");
104 return;
105 }
106 COOR_SM->NotifyUnchainedResult(networkId->valuestring, cJSON_IsTrue(result));
107 }
108
ResponseStartCoordinationOtherResult(int32_t sessionId,const JsonParser & parser)109 void ResponseStartCoordinationOtherResult(int32_t sessionId, const JsonParser &parser)
110 {
111 CALL_INFO_TRACE;
112 cJSON* networkId = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_OTHER_DEVICE_ID);
113
114 if (!cJSON_IsString(networkId)) {
115 FI_HILOGE("The data type of CJSON is incorrect");
116 return;
117 }
118 COOR_SM->StartCoordinationOtherResult(networkId->valuestring);
119 }
120 } // namespace
121
BindLink(int32_t socket,PeerSocketInfo info)122 static void BindLink(int32_t socket, PeerSocketInfo info)
123 {
124 COOR_SOFTBUS_ADAPTER->OnBind(socket, info);
125 }
126
ShutdownLink(int32_t socket,ShutdownReason reason)127 static void ShutdownLink(int32_t socket, ShutdownReason reason)
128 {
129 COOR_SOFTBUS_ADAPTER->OnShutdown(socket, reason);
130 }
131
BytesReceived(int32_t socket,const void * data,uint32_t dataLen)132 static void BytesReceived(int32_t socket, const void *data, uint32_t dataLen)
133 {
134 COOR_SOFTBUS_ADAPTER->OnBytes(socket, data, dataLen);
135 }
136
InitSocket(SocketInfo info,int32_t socketType,int32_t & socket)137 int32_t CoordinationSoftbusAdapter::InitSocket(SocketInfo info, int32_t socketType, int32_t &socket)
138 {
139 CALL_INFO_TRACE;
140 socket = Socket(info);
141 QosTV socketQos[] = {
142 { .qos = QOS_TYPE_MIN_BW, .value = MIN_BW },
143 { .qos = QOS_TYPE_MAX_LATENCY, .value = LATENCY },
144 { .qos = QOS_TYPE_MIN_LATENCY, .value = LATENCY },
145 };
146 ISocketListener listener = {
147 .OnBind = BindLink,
148 .OnShutdown = ShutdownLink,
149 .OnBytes = BytesReceived
150 };
151 FI_HILOGI("The socketType:%{public}d, name:%{public}s, peerName:%{public}s, peerNetworkId:%{public}s",
152 socketType, info.name, info.peerName, info.peerNetworkId);
153 if (socketType == SOCKET_SERVER) {
154 return Listen(socket, socketQos, QOS_LEN, &listener);
155 } else if (socketType == SOCKET_CLIENT) {
156 return Bind(socket, socketQos, QOS_LEN, &listener);
157 }
158 return RET_ERR;
159 }
160
Init()161 int32_t CoordinationSoftbusAdapter::Init()
162 {
163 CALL_INFO_TRACE;
164 std::unique_lock<std::mutex> sessionLock(operationMutex_);
165 const std::string SESS_NAME = "ohos.msdp.device_status.";
166 std::string localNetworkId = COORDINATION::GetLocalNetworkId();
167 if (localNetworkId.empty()) {
168 FI_HILOGE("Local network id is empty");
169 return RET_ERR;
170 }
171 std::string bindName = SESS_NAME + localNetworkId.substr(0, BIND_STRING_LENGTH);
172 std::string sessionName = SESS_NAME + localNetworkId.substr(0, INTERCEPT_STRING_LENGTH);
173 if (bindName == localSessionName_) {
174 FI_HILOGI("Softbus session server has already created");
175 return RET_OK;
176 }
177 localSessionName_ = bindName;
178 char name[DEVICE_NAME_SIZE_MAX] = { 0 };
179 if (ChkAndCpyStr(name, DEVICE_NAME_SIZE_MAX, sessionName.c_str()) != RET_OK) {
180 FI_HILOGE("Invalid name:%{public}s", sessionName.c_str());
181 return RET_ERR;
182 }
183 char pkgName[PKG_NAME_SIZE_MAX] = FI_PKG_NAME;
184 SocketInfo info = {
185 .name = name,
186 .pkgName = pkgName,
187 .dataType = DATA_TYPE_BYTES
188 };
189 int32_t ret = InitSocket(info, SOCKET_SERVER, socketFd_);
190 if (ret == RET_OK && socketFd_ != -1) {
191 FI_HILOGI("Server set ok");
192 } else {
193 FI_HILOGE("Server set failed, ret:%{public}d", ret);
194 Shutdown(socketFd_);
195 }
196 return ret;
197 }
198
~CoordinationSoftbusAdapter()199 CoordinationSoftbusAdapter::~CoordinationSoftbusAdapter()
200 {
201 Release();
202 }
203
Release()204 void CoordinationSoftbusAdapter::Release()
205 {
206 CALL_INFO_TRACE;
207 std::unique_lock<std::mutex> sessionLock(operationMutex_);
208 std::for_each(sessionDevs_.begin(), sessionDevs_.end(), [](auto item) {
209 Shutdown(item.second);
210 FI_HILOGD("Session closed successful");
211 });
212 Shutdown(socketFd_);
213 sessionDevs_.clear();
214 }
215
CheckDeviceSessionState(const std::string & remoteNetworkId)216 bool CoordinationSoftbusAdapter::CheckDeviceSessionState(const std::string &remoteNetworkId)
217 {
218 std::unique_lock<std::mutex> sessionLock(operationMutex_);
219 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
220 FI_HILOGE("Check session state error");
221 return false;
222 }
223 return true;
224 }
225
ChkAndCpyStr(char * dest,uint32_t destLen,const std::string & src)226 int32_t CoordinationSoftbusAdapter::ChkAndCpyStr(char* dest, uint32_t destLen, const std::string &src)
227 {
228 if (destLen < src.length() + 1) {
229 FI_HILOGE("Invalid src length");
230 return RET_ERR;
231 }
232 if (strcpy_s(dest, destLen, src.c_str()) != EOK) {
233 FI_HILOGE("Invalid src");
234 return RET_ERR;
235 }
236 return RET_OK;
237 }
238
OpenInputSoftbus(const std::string & remoteNetworkId)239 int32_t CoordinationSoftbusAdapter::OpenInputSoftbus(const std::string &remoteNetworkId)
240 {
241 CALL_INFO_TRACE;
242 const std::string SESSION_NAME = "ohos.msdp.device_status.";
243 if (CheckDeviceSessionState(remoteNetworkId)) {
244 FI_HILOGD("InputSoftbus session has already opened");
245 return RET_OK;
246 }
247 char name[DEVICE_NAME_SIZE_MAX] = { 0 };
248 if (ChkAndCpyStr(name, DEVICE_NAME_SIZE_MAX, localSessionName_.c_str()) != RET_OK) {
249 FI_HILOGE("Invalid name:%{public}s", localSessionName_.c_str());
250 return RET_ERR;
251 }
252 std::string peerSessionName = SESSION_NAME + remoteNetworkId.substr(0, INTERCEPT_STRING_LENGTH);
253 char peerName[DEVICE_NAME_SIZE_MAX] = { 0 };
254 if (ChkAndCpyStr(peerName, DEVICE_NAME_SIZE_MAX, peerSessionName.c_str()) != RET_OK) {
255 FI_HILOGE("Invalid peerSessionName:%{public}s", peerSessionName.c_str());
256 return RET_ERR;
257 }
258 char peerNetworkId[PKG_NAME_SIZE_MAX] = { 0 };
259 if (ChkAndCpyStr(peerNetworkId, PKG_NAME_SIZE_MAX, remoteNetworkId.c_str()) != RET_OK) {
260 FI_HILOGE("Invalid peerNetworkId:%{public}s", remoteNetworkId.c_str());
261 return RET_ERR;
262 }
263 char pkgName[PKG_NAME_SIZE_MAX] = FI_PKG_NAME;
264 SocketInfo info = {
265 .name = name,
266 .peerName = peerName,
267 .peerNetworkId = peerNetworkId,
268 .pkgName = pkgName,
269 .dataType = DATA_TYPE_BYTES
270 };
271 int32_t socket = -1;
272 int32_t ret = InitSocket(info, SOCKET_CLIENT, socket);
273 if (ret == RET_OK && socket != -1) {
274 sessionDevs_[remoteNetworkId] = socket;
275 ConfigTcpAlive(socket);
276 } else {
277 FI_HILOGE("Bind failed, ret:%{public}d", ret);
278 Shutdown(socket);
279 }
280 return ret;
281 }
282
WaitSessionOpend(const std::string & remoteNetworkId,int32_t sessionId)283 int32_t CoordinationSoftbusAdapter::WaitSessionOpend(const std::string &remoteNetworkId, int32_t sessionId)
284 {
285 CALL_INFO_TRACE;
286 std::unique_lock<std::mutex> waitLock(operationMutex_);
287 sessionDevs_[remoteNetworkId] = sessionId;
288 auto status = openSessionWaitCond_.wait_for(waitLock, std::chrono::seconds(SESSION_WAIT_TIMEOUT_SECOND),
289 [this, remoteNetworkId] () { return false; });
290 if (!status) {
291 CoordinationDFX::WriteOpenSoftbusResult(remoteNetworkId, 0, STATUS_SIGN);
292 FI_HILOGE("Open session timeout");
293 return RET_ERR;
294 }
295 return RET_OK;
296 }
297
CloseInputSoftbus(const std::string & remoteNetworkId)298 void CoordinationSoftbusAdapter::CloseInputSoftbus(const std::string &remoteNetworkId)
299 {
300 CALL_INFO_TRACE;
301 std::unique_lock<std::mutex> sessionLock(operationMutex_);
302 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
303 FI_HILOGI("SessionDevIdMap is not found");
304 return;
305 }
306 int32_t sessionId = sessionDevs_[remoteNetworkId];
307
308 Shutdown(sessionId);
309 sessionDevs_.erase(remoteNetworkId);
310 }
311
GetInstance()312 std::shared_ptr<CoordinationSoftbusAdapter> CoordinationSoftbusAdapter::GetInstance()
313 {
314 static std::once_flag flag;
315 std::call_once(flag, [&]() {
316 g_instance.reset(new (std::nothrow) CoordinationSoftbusAdapter());
317 });
318 return g_instance;
319 }
320
StartRemoteCoordination(const std::string & localNetworkId,const std::string & remoteNetworkId,bool checkButtonDown)321 int32_t CoordinationSoftbusAdapter::StartRemoteCoordination(const std::string &localNetworkId,
322 const std::string &remoteNetworkId, bool checkButtonDown)
323 {
324 CALL_INFO_TRACE;
325 std::unique_lock<std::mutex> sessionLock(operationMutex_);
326 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
327 FI_HILOGE("Failed to discover the remote device");
328 return RET_ERR;
329 }
330 int32_t sessionId = sessionDevs_[remoteNetworkId];
331 auto pointerEvent = COOR_SM->GetLastPointerEvent();
332 bool isPointerButtonPressed = false;
333 if (checkButtonDown && pointerEvent != nullptr) {
334 for (const auto &item : pointerEvent->GetPressedButtons()) {
335 if (item == MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
336 isPointerButtonPressed = true;
337 break;
338 }
339 }
340 }
341 FI_HILOGD("isPointerButtonPressed:%{public}d", isPointerButtonPressed);
342 cJSON *jsonStr = cJSON_CreateObject();
343 CHKPR(jsonStr, RET_ERR);
344 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(REMOTE_COORDINATION_START));
345 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_LOCAL_DEVICE_ID, cJSON_CreateString(localNetworkId.c_str()));
346 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
347 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_POINTER_BUTTON_IS_PRESS, cJSON_CreateBool(isPointerButtonPressed));
348 char *sendMsg = cJSON_Print(jsonStr);
349 cJSON_Delete(jsonStr);
350 int32_t ret = SendMsg(sessionId, sendMsg);
351 cJSON_free(sendMsg);
352 if (ret != RET_OK) {
353 CoordinationDFX::WriteActivate(localNetworkId, remoteNetworkId, sessionDevs_,
354 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
355 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
356 return RET_ERR;
357 }
358 if (isPointerButtonPressed) {
359 FI_HILOGD("Across with button down, waiting");
360 auto status = openSessionWaitCond_.wait_for(sessionLock, std::chrono::seconds(FILTER_WAIT_TIMEOUT_SECOND));
361 if (status == std::cv_status::timeout) {
362 CoordinationDFX::WriteActivate(localNetworkId, remoteNetworkId, sessionDevs_,
363 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
364 FI_HILOGE("Add filter timeout");
365 return RET_ERR;
366 }
367 }
368 return RET_OK;
369 }
370
StartRemoteCoordinationResult(const std::string & remoteNetworkId,bool isSuccess,const std::string & startDeviceDhid,int32_t xPercent,int32_t yPercent)371 int32_t CoordinationSoftbusAdapter::StartRemoteCoordinationResult(const std::string &remoteNetworkId,
372 bool isSuccess, const std::string &startDeviceDhid, int32_t xPercent, int32_t yPercent)
373 {
374 CALL_INFO_TRACE;
375 std::unique_lock<std::mutex> sessionLock(operationMutex_);
376 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
377 FI_HILOGE("Failed to discover the remote device");
378 return RET_ERR;
379 }
380 int32_t sessionId = sessionDevs_[remoteNetworkId];
381 cJSON *jsonStr = cJSON_CreateObject();
382 CHKPR(jsonStr, RET_ERR);
383 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(REMOTE_COORDINATION_START_RES));
384 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_RESULT, cJSON_CreateBool(isSuccess));
385 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_START_DHID, cJSON_CreateString(startDeviceDhid.c_str()));
386 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_POINTER_X, cJSON_CreateNumber(xPercent));
387 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_POINTER_Y, cJSON_CreateNumber(yPercent));
388 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
389 char *sendMsg = cJSON_Print(jsonStr);
390 cJSON_Delete(jsonStr);
391 int32_t ret = SendMsg(sessionId, sendMsg);
392 cJSON_free(sendMsg);
393 if (ret != RET_OK) {
394 CoordinationDFX::WriteActivateResult(remoteNetworkId, isSuccess);
395 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
396 return RET_ERR;
397 }
398 return RET_OK;
399 }
400
StopRemoteCoordination(const std::string & remoteNetworkId,bool isUnchained)401 int32_t CoordinationSoftbusAdapter::StopRemoteCoordination(const std::string &remoteNetworkId, bool isUnchained)
402 {
403 CALL_INFO_TRACE;
404 std::unique_lock<std::mutex> sessionLock(operationMutex_);
405 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
406 FI_HILOGE("Failed to discover the remote device");
407 return RET_ERR;
408 }
409 int32_t sessionId = sessionDevs_[remoteNetworkId];
410 cJSON *jsonStr = cJSON_CreateObject();
411 CHKPR(jsonStr, RET_ERR);
412 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(REMOTE_COORDINATION_STOP));
413 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_RESULT, cJSON_CreateBool(isUnchained));
414 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
415 char *sendMsg = cJSON_Print(jsonStr);
416 cJSON_Delete(jsonStr);
417 int32_t ret = SendMsg(sessionId, sendMsg);
418 cJSON_free(sendMsg);
419 if (ret != RET_OK) {
420 CoordinationDFX::WriteDeactivate(remoteNetworkId, sessionDevs_, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
421 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
422 return RET_ERR;
423 }
424 return RET_OK;
425 }
426
StopRemoteCoordinationResult(const std::string & remoteNetworkId,bool isSuccess)427 int32_t CoordinationSoftbusAdapter::StopRemoteCoordinationResult(const std::string &remoteNetworkId,
428 bool isSuccess)
429 {
430 CALL_INFO_TRACE;
431 std::unique_lock<std::mutex> sessionLock(operationMutex_);
432 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
433 FI_HILOGE("Failed to discover the remote device");
434 return RET_ERR;
435 }
436 int32_t sessionId = sessionDevs_[remoteNetworkId];
437 cJSON *jsonStr = cJSON_CreateObject();
438 CHKPR(jsonStr, RET_ERR);
439 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(REMOTE_COORDINATION_STOP_RES));
440 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_RESULT, cJSON_CreateBool(isSuccess));
441 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
442 char *sendMsg = cJSON_Print(jsonStr);
443 cJSON_Delete(jsonStr);
444 int32_t ret = SendMsg(sessionId, sendMsg);
445 cJSON_free(sendMsg);
446 if (ret != RET_OK) {
447 CoordinationDFX::WriteDeactivateResult(remoteNetworkId, sessionDevs_);
448 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
449 return RET_ERR;
450 }
451 return RET_OK;
452 }
453
NotifyUnchainedResult(const std::string & localNetworkId,const std::string & remoteNetworkId,bool result)454 int32_t CoordinationSoftbusAdapter::NotifyUnchainedResult(const std::string &localNetworkId,
455 const std::string &remoteNetworkId, bool result)
456 {
457 CALL_INFO_TRACE;
458 std::unique_lock<std::mutex> sessionLock(operationMutex_);
459 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
460 FI_HILOGE("Failed to discover the remote device");
461 return RET_ERR;
462 }
463 int32_t sessionId = sessionDevs_[remoteNetworkId];
464 cJSON *jsonStr = cJSON_CreateObject();
465 CHKPR(jsonStr, RET_ERR);
466 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(NOTIFY_UNCHAINED_RES));
467 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_LOCAL_DEVICE_ID, cJSON_CreateString(localNetworkId.c_str()));
468 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_RESULT, cJSON_CreateBool(result));
469 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
470 char *sendmsg = cJSON_Print(jsonStr);
471 cJSON_Delete(jsonStr);
472 CHKPR(sendmsg, RET_ERR);
473 int32_t ret = SendMsg(sessionId, sendmsg);
474 cJSON_free(sendmsg);
475 if (ret != RET_OK) {
476 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
477 return RET_ERR;
478 }
479 return RET_OK;
480 }
481
NotifyFilterAdded(const std::string & remoteNetworkId)482 int32_t CoordinationSoftbusAdapter::NotifyFilterAdded(const std::string &remoteNetworkId)
483 {
484 CALL_DEBUG_ENTER;
485 std::unique_lock<std::mutex> sessionLock(operationMutex_);
486 if (sessionDevs_.find(remoteNetworkId) == sessionDevs_.end()) {
487 FI_HILOGE("Failed to discover the remote device");
488 return RET_ERR;
489 }
490 int32_t sessionId = sessionDevs_[remoteNetworkId];
491 cJSON *jsonStr = cJSON_CreateObject();
492 CHKPR(jsonStr, RET_ERR);
493 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(NOTIFY_FILTER_ADDED));
494 char *sendmsg = cJSON_Print(jsonStr);
495 cJSON_Delete(jsonStr);
496 CHKPR(sendmsg, RET_ERR);
497 int32_t ret = SendMsg(sessionId, sendmsg);
498 cJSON_free(sendmsg);
499 if (ret != RET_OK) {
500 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
501 return RET_ERR;
502 }
503 return RET_OK;
504 }
505
StartCoordinationOtherResult(const std::string & originNetworkId,const std::string & remoteNetworkId)506 int32_t CoordinationSoftbusAdapter::StartCoordinationOtherResult(const std::string &originNetworkId,
507 const std::string &remoteNetworkId)
508 {
509 CALL_DEBUG_ENTER;
510 std::unique_lock<std::mutex> sessionLock(operationMutex_);
511 if (sessionDevs_.find(originNetworkId) == sessionDevs_.end()) {
512 FI_HILOGE("Failed to discover the original device");
513 return RET_ERR;
514 }
515 int32_t sessionId = sessionDevs_[originNetworkId];
516 cJSON *jsonStr = cJSON_CreateObject();
517 CHKPR(jsonStr, RET_ERR);
518 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_CMD_TYPE, cJSON_CreateNumber(REMOTE_COORDINATION_STOP_OTHER_RES));
519 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_OTHER_DEVICE_ID, cJSON_CreateString(remoteNetworkId.c_str()));
520 cJSON_AddItemToObject(jsonStr, FI_SOFTBUS_KEY_SESSION_ID, cJSON_CreateNumber(sessionId));
521 char *sendMsg = cJSON_Print(jsonStr);
522 cJSON_Delete(jsonStr);
523 int32_t ret = SendMsg(sessionId, sendMsg);
524 cJSON_free(sendMsg);
525 if (ret != RET_OK) {
526 FI_HILOGE("Failed to send the sendMsg, ret:%{public}d", ret);
527 return RET_ERR;
528 }
529 return RET_OK;
530 }
531
HandleSessionData(int32_t socket,const std::string & message)532 void CoordinationSoftbusAdapter::HandleSessionData(int32_t socket, const std::string &message)
533 {
534 if (message.empty()) {
535 FI_HILOGE("Handle session data, message is empty");
536 return;
537 }
538 JsonParser parser;
539 parser.json = cJSON_Parse(message.c_str());
540 if (!cJSON_IsObject(parser.json)) {
541 FI_HILOGI("Handle session data, parser json is not object");
542 CHKPV(onRecvDataCallback_);
543 onRecvDataCallback_(reinterpret_cast<void *> (const_cast<char *> (message.c_str())), message.size());
544 return;
545 }
546 HandleCoordinationSessionData(socket, parser);
547 }
548
OnBytes(int32_t socket,const void * data,uint32_t dataLen)549 void CoordinationSoftbusAdapter::OnBytes(int32_t socket, const void *data, uint32_t dataLen)
550 {
551 FI_HILOGD("dataLen:%{public}d", dataLen);
552 if ((socket < 0) || (data == nullptr) || (dataLen <= 0)) {
553 FI_HILOGE("Param check failed");
554 return;
555 }
556 std::string message = std::string(static_cast<const char *>(data), dataLen);
557 HandleSessionData(socket, message);
558 }
559
SendMsg(int32_t socket,const std::string & message)560 int32_t CoordinationSoftbusAdapter::SendMsg(int32_t socket, const std::string &message)
561 {
562 CALL_DEBUG_ENTER;
563 if (message.size() > MSG_MAX_SIZE) {
564 FI_HILOGW("Error:the message size:%{public}zu beyond the maximum limit", message.size());
565 return RET_ERR;
566 }
567 return SendBytes(socket, message.c_str(), strlen(message.c_str()));
568 }
569
FindDevice(int32_t socket)570 std::string CoordinationSoftbusAdapter::FindDevice(int32_t socket)
571 {
572 std::unique_lock<std::mutex> sessionLock(operationMutex_);
573 auto find_item = std::find_if(sessionDevs_.begin(), sessionDevs_.end(),
574 [socket](const std::map<std::string, int32_t>::value_type item) {
575 return item.second == socket;
576 });
577 if (find_item == sessionDevs_.end()) {
578 FI_HILOGE("Find device error");
579 return {};
580 }
581 return find_item->first;
582 }
583
OnBind(int32_t socket,PeerSocketInfo info)584 int32_t CoordinationSoftbusAdapter::OnBind(int32_t socket, PeerSocketInfo info)
585 {
586 CALL_INFO_TRACE;
587 if (socket == -1) {
588 std::string networkId = FindDevice(socket);
589 std::unique_lock<std::mutex> sessionLock(operationMutex_);
590 if (sessionDevs_.find(networkId) != sessionDevs_.end()) {
591 sessionDevs_.erase(networkId);
592 }
593 return RET_OK;
594 }
595 std::unique_lock<std::mutex> sessionLock(operationMutex_);
596 sessionDevs_[info.networkId] = socket;
597 ConfigTcpAlive(socket);
598 return RET_OK;
599 }
600
OnShutdown(int32_t socket,ShutdownReason reason)601 void CoordinationSoftbusAdapter::OnShutdown(int32_t socket, ShutdownReason reason)
602 {
603 CALL_INFO_TRACE;
604 (void)reason;
605 std::string networkId = FindDevice(socket);
606 std::unique_lock<std::mutex> sessionLock(operationMutex_);
607 if (sessionDevs_.find(networkId) != sessionDevs_.end()) {
608 sessionDevs_.erase(networkId);
609 }
610 COOR_SM->OnSoftbusSessionClosed(networkId);
611 socketFd_ = -1;
612 }
613
RegisterRecvFunc(std::function<void (void *,uint32_t)> callback)614 void CoordinationSoftbusAdapter::RegisterRecvFunc(std::function<void(void*, uint32_t)> callback)
615 {
616 CALL_DEBUG_ENTER;
617 CHKPV(callback);
618 onRecvDataCallback_ = callback;
619 }
620
SendData(const std::string & networkId,Parcel & parcel)621 int32_t CoordinationSoftbusAdapter::SendData(const std::string &networkId, Parcel &parcel)
622 {
623 CALL_DEBUG_ENTER;
624 std::unique_lock<std::mutex> sessionLock(operationMutex_);
625 if (SendBytes(sessionDevs_[networkId], reinterpret_cast<void *> (parcel.GetData()),
626 parcel.GetDataSize()) != RET_OK) {
627 FI_HILOGE("Send bytes failed");
628 return RET_ERR;
629 }
630 return RET_OK;
631 }
632
ResponseNotifyFilterAdded()633 void CoordinationSoftbusAdapter::ResponseNotifyFilterAdded()
634 {
635 CALL_INFO_TRACE;
636 std::unique_lock<std::mutex> sessionLock(operationMutex_);
637 openSessionWaitCond_.notify_all();
638 }
639
HandleCoordinationSessionData(int32_t sessionId,const JsonParser & parser)640 void CoordinationSoftbusAdapter::HandleCoordinationSessionData(int32_t sessionId, const JsonParser &parser)
641 {
642 cJSON* comType = cJSON_GetObjectItemCaseSensitive(parser.json, FI_SOFTBUS_KEY_CMD_TYPE);
643 if (!cJSON_IsNumber(comType)) {
644 FI_HILOGE("The data type of CJSON is incorrect");
645 return;
646 }
647 FI_HILOGD("valueint:%{public}d", comType->valueint);
648 switch (comType->valueint) {
649 case REMOTE_COORDINATION_START: {
650 ResponseStartRemoteCoordination(sessionId, parser);
651 break;
652 }
653 case REMOTE_COORDINATION_START_RES: {
654 ResponseStartRemoteCoordinationResult(sessionId, parser);
655 break;
656 }
657 case REMOTE_COORDINATION_STOP: {
658 ResponseStopRemoteCoordination(sessionId, parser);
659 break;
660 }
661 case REMOTE_COORDINATION_STOP_RES: {
662 ResponseStopRemoteCoordinationResult(sessionId, parser);
663 break;
664 }
665 case REMOTE_COORDINATION_STOP_OTHER_RES: {
666 ResponseStartCoordinationOtherResult(sessionId, parser);
667 break;
668 }
669 case NOTIFY_UNCHAINED_RES: {
670 ResponseNotifyUnchainedResult(sessionId, parser);
671 break;
672 }
673 case NOTIFY_FILTER_ADDED: {
674 ResponseNotifyFilterAdded();
675 break;
676 }
677 default: {
678 FI_HILOGE("The cmdType is undefined");
679 break;
680 }
681 }
682 }
683
ConfigTcpAlive(int32_t socket)684 void CoordinationSoftbusAdapter::ConfigTcpAlive(int32_t socket)
685 {
686 CALL_INFO_TRACE;
687 if (socket < 0) {
688 FI_HILOGW("Config tcp alive, invalid sessionId");
689 return;
690 }
691 int32_t handle { -1 };
692 int32_t result = GetSessionHandle(socket, &handle);
693 if (result != RET_OK) {
694 FI_HILOGE("Failed to get the session handle, socketId:%{public}d, handle:%{public}d", socket, handle);
695 return;
696 }
697 int32_t keepAliveTimeout { 10 };
698 result = setsockopt(handle, IPPROTO_TCP, TCP_KEEPIDLE, &keepAliveTimeout, sizeof(keepAliveTimeout));
699 if (result != RET_OK) {
700 FI_HILOGE("Falied to enable setsockopt for ailve-timeout, %{public}d", result);
701 return;
702 }
703 int32_t keepAliveCount { 5 };
704 result = setsockopt(handle, IPPROTO_TCP, TCP_KEEPCNT, &keepAliveCount, sizeof(keepAliveCount));
705 if (result != RET_OK) {
706 FI_HILOGE("Falied to enable setsockopt for ailve-count, %{public}d", result);
707 return;
708 }
709 int32_t interval { 1 };
710 result = setsockopt(handle, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
711 if (result != RET_OK) {
712 FI_HILOGE("Falied to enable setsockopt for interval, %{public}d", result);
713 return;
714 }
715 int32_t enable { 1 };
716 result = setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
717 if (result != RET_OK) {
718 FI_HILOGE("Falied to enable setsockopt for keep-alive, %{public}d", result);
719 return;
720 }
721 int32_t TimeoutMs { 15000 };
722 result = setsockopt(handle, IPPROTO_TCP, TCP_USER_TIMEOUT, &TimeoutMs, sizeof(TimeoutMs));
723 if (result != RET_OK) {
724 FI_HILOGE("Falied to enable setsockopt for timeout, %{public}d", result);
725 return;
726 }
727 }
728 } // namespace DeviceStatus
729 } // namespace Msdp
730 } // namespace OHOS
731