• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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