1 /*
2 * Copyright (C) 2024 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 "distributed_client.h"
16
17 #include "socket.h"
18 #include "session.h"
19 #include "distributed_socket.h"
20 #include "distributed_server.h"
21 #include "analytics_util.h"
22
23 namespace OHOS {
24 namespace Notification {
25
GetInstance()26 DistributedClient& DistributedClient::GetInstance()
27 {
28 static DistributedClient distributedClient;
29 return distributedClient;
30 }
31
ReleaseClient()32 void DistributedClient::ReleaseClient()
33 {
34 std::lock_guard<ffrt::mutex> lock(clientLock_);
35 ANS_LOGI("Release client socket %{public}d.", (int32_t)(socketsId_.size()));
36 for (auto& socketItem : socketsId_) {
37 CloseSocket(socketItem.second);
38 }
39 socketsId_.clear();
40 }
41
OnShutdown(int32_t socket,ShutdownReason reason)42 void DistributedClient::OnShutdown(int32_t socket, ShutdownReason reason)
43 {
44 std::lock_guard<ffrt::mutex> lock(clientLock_);
45 for (auto& socketItem : socketsId_) {
46 if (socketItem.second == socket) {
47 socketItem.second = -1;
48 std::string message = "socketID: " + std::to_string(socket) + " ; ShutdownReason: " +
49 ShutdownReasonToString(reason);
50 AnalyticsUtil::GetInstance().SendHaReport(MODIFY_ERROR_EVENT_CODE, 0,
51 BRANCH4_ID, message, PUBLISH_ERROR_EVENT_CODE);
52 }
53 }
54 }
55
AddDevice(DistributedDeviceInfo peerDevice)56 void DistributedClient::AddDevice(DistributedDeviceInfo peerDevice)
57 {
58 std::lock_guard<ffrt::mutex> lock(clientLock_);
59 ANS_LOGI("Distributed client AddDevice %{public}s %{public}s", StringAnonymous(peerDevice.deviceId_).c_str(),
60 StringAnonymous(peerDevice.networkId_).c_str());
61 networksId_[peerDevice.deviceId_] = peerDevice.networkId_;
62 std::string message = "AddnetworkId: " + StringAnonymous(peerDevice.deviceId_) + " id: " +
63 StringAnonymous(peerDevice.networkId_);
64 AnalyticsUtil::GetInstance().SendHaReport(MODIFY_ERROR_EVENT_CODE, 0,
65 BRANCH6_ID, message, PUBLISH_ERROR_EVENT_CODE);
66 }
67
ReleaseDevice(const std::string & deviceId,uint16_t deviceType,bool releaseNetwork)68 void DistributedClient::ReleaseDevice(const std::string &deviceId, uint16_t deviceType, bool releaseNetwork)
69 {
70 std::string messageKey = deviceId + '_' + std::to_string(TransDataType::DATA_TYPE_MESSAGE);
71 std::string byteKey = deviceId + '_' + std::to_string(TransDataType::DATA_TYPE_BYTES);
72 std::lock_guard<ffrt::mutex> lock(clientLock_);
73 auto socket = socketsId_.find(messageKey);
74 if (socket != socketsId_.end()) {
75 CloseSocket(socket->second);
76 socketsId_.erase(socket);
77 }
78 socket = socketsId_.find(byteKey);
79 if (socket != socketsId_.end()) {
80 CloseSocket(socket->second);
81 socketsId_.erase(socket);
82 }
83 if (releaseNetwork) {
84 networksId_.erase(deviceId);
85 }
86 std::string message = "ReleasenetworkId: " + StringAnonymous(deviceId);
87 AnalyticsUtil::GetInstance().SendHaReport(MODIFY_ERROR_EVENT_CODE, 0,
88 BRANCH7_ID, message, PUBLISH_ERROR_EVENT_CODE);
89 }
90
RefreshDevice(const std::string & deviceId,uint16_t deviceType,const std::string & networkId)91 void DistributedClient::RefreshDevice(const std::string &deviceId, uint16_t deviceType,
92 const std::string &networkId)
93 {
94 ReleaseDevice(deviceId, deviceType);
95 std::lock_guard<ffrt::mutex> lock(clientLock_);
96 networksId_[deviceId] = networkId;
97 ANS_LOGI("Distributed refresh device %{public}s %{public}s", StringAnonymous(deviceId).c_str(),
98 StringAnonymous(networkId).c_str());
99 std::string message = "RefreshnetworkId: " + StringAnonymous(deviceId) + " id: " +
100 StringAnonymous(networkId);
101 AnalyticsUtil::GetInstance().SendHaReport(MODIFY_ERROR_EVENT_CODE, 0,
102 BRANCH8_ID, message, PUBLISH_ERROR_EVENT_CODE);
103 }
104
GetSocketId(const std::string & deviceId,TransDataType dataType,int32_t & socketId)105 int32_t DistributedClient::GetSocketId(const std::string &deviceId, TransDataType dataType, int32_t& socketId)
106 {
107 std::string key = deviceId + '_' + std::to_string(dataType);
108 {
109 std::lock_guard<ffrt::mutex> lock(clientLock_);
110 auto socketItem = socketsId_.find(key);
111 if (socketItem != socketsId_.end() && socketItem->second != -1) {
112 socketId = socketItem->second;
113 return ERR_OK;
114 }
115 }
116
117 std::string networkId;
118 auto networkIdItem = networksId_.find(deviceId);
119 if (networkIdItem != networksId_.end()) {
120 networkId = networkIdItem->second;
121 }
122 std::string name = (dataType == TransDataType::DATA_TYPE_MESSAGE) ? ANS_SOCKET_CMD : ANS_SOCKET_MSG;
123 int32_t result = ClientBind(name, ANS_SOCKET_PKG, networkId, dataType, socketId);
124 if (result != ERR_OK) {
125 ANS_LOGW("Get socketid failed %{public}s %{public}s %{public}d", StringAnonymous(deviceId).c_str(),
126 StringAnonymous(networkId).c_str(), dataType);
127 std::string message = "Get socketid failed: " + StringAnonymous(deviceId) + " id: " +
128 StringAnonymous(networkId);
129 AnalyticsUtil::GetInstance().SendHaReport(OPERATION_DELETE_BRANCH, result,
130 BRANCH8_ID, message, PUBLISH_ERROR_EVENT_CODE);
131 return result;
132 }
133 {
134 std::lock_guard<ffrt::mutex> lock(clientLock_);
135 socketsId_[key] = socketId;
136 ANS_LOGI("Get socketid insert %{public}s %{public}d", StringAnonymous(key).c_str(), socketId);
137 }
138 return ERR_OK;
139 }
140
SendMessage(const std::shared_ptr<BoxBase> & boxPtr,TransDataType dataType,const std::string & deviceId,int32_t eventType)141 int32_t DistributedClient::SendMessage(const std::shared_ptr<BoxBase>& boxPtr, TransDataType dataType,
142 const std::string &deviceId, int32_t eventType)
143 {
144 int32_t type = -1;
145 int32_t socketId = 0;
146 DistributedServer::GetInstance().CheckServer();
147 int32_t result = GetSocketId(deviceId, dataType, socketId);
148 if (boxPtr == nullptr || boxPtr->box_ == nullptr) {
149 ANS_LOGW("Dans send message failed %{public}s", StringAnonymous(deviceId).c_str());
150 return -1;
151 }
152 boxPtr->box_->GetMessageType(type);
153 if (result != ERR_OK) {
154 ANS_LOGW("Get SocketId failed %{public}s %{public}d", StringAnonymous(deviceId).c_str(), dataType);
155 std::string errorReason = "Bind failed type: " + std::to_string(type) + " , id: " + StringAnonymous(deviceId);
156 AnalyticsUtil::GetInstance().SendEventReport(0, result, errorReason);
157 AnalyticsUtil::GetInstance().SendHaReport(eventType, result, BRANCH1_ID, errorReason);
158 return result;
159 }
160
161 if (dataType == TransDataType::DATA_TYPE_MESSAGE) {
162 result = ClientSendMessage(socketId, boxPtr->GetByteBuffer(), boxPtr->GetByteLength());
163 if (result != ERR_OK) {
164 std::string errorReason = "Send failed type: " + std::to_string(type) + " , id: " +
165 StringAnonymous(deviceId);
166 AnalyticsUtil::GetInstance().SendEventReport(0, result, errorReason);
167 AnalyticsUtil::GetInstance().SendHaReport(eventType, result, BRANCH2_ID, errorReason);
168 }
169 return result;
170 }
171
172 // async to send byte message
173 std::string errorReason = "Send failed type: " + std::to_string(type) + " , id: " + StringAnonymous(deviceId);
174 result = ClientSendBytes(socketId, boxPtr->GetByteBuffer(), boxPtr->GetByteLength());
175 if (result != ERR_OK) {
176 AnalyticsUtil::GetInstance().SendEventReport(0, result, errorReason);
177 AnalyticsUtil::GetInstance().SendHaReport(eventType, result, BRANCH2_ID, errorReason);
178 }
179 return result;
180 }
181
ShutdownReasonToString(ShutdownReason reason)182 std::string DistributedClient::ShutdownReasonToString(ShutdownReason reason)
183 {
184 switch (reason) {
185 case ShutdownReason::SHUTDOWN_REASON_UNKNOWN:
186 return "SHUTDOWN_REASON_UNKNOWN";
187 case ShutdownReason::SHUTDOWN_REASON_PEER:
188 return "SHUTDOWN_REASON_PEER";
189 case ShutdownReason::SHUTDOWN_REASON_LNN_CHANGED:
190 return "SHUTDOWN_REASON_LNN_CHANGED";
191 case ShutdownReason::SHUTDOWN_REASON_CONN_CHANGED:
192 return "SHUTDOWN_REASON_CONN_CHANGED";
193 case ShutdownReason::SHUTDOWN_REASON_TIMEOUT:
194 return "SHUTDOWN_REASON_TIMEOUT";
195 case ShutdownReason::SHUTDOWN_REASON_SEND_FILE_ERR:
196 return "SHUTDOWN_REASON_SEND_FILE_ERR";
197 case ShutdownReason::SHUTDOWN_REASON_RECV_FILE_ERR:
198 return "SHUTDOWN_REASON_RECV_FILE_ERR";
199 case ShutdownReason::SHUTDOWN_REASON_RECV_DATA_ERR:
200 return "SHUTDOWN_REASON_RECV_DATA_ERR";
201 case ShutdownReason::SHUTDOWN_REASON_UNEXPECTED:
202 return "SHUTDOWN_REASON_UNEXPECTED";
203 default:
204 return "unknown";
205 }
206 }
207
208 }
209 }
210
211