• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_socket.h"
16 
17 #include <thread>
18 #include "socket.h"
19 #include "session.h"
20 #include "distributed_server.h"
21 #include "distributed_client.h"
22 #include "distributed_const_define.h"
23 
24 namespace OHOS {
25 namespace Notification {
26 
27 static const int32_t BIND_SERVICE_MAX_RETRY_TIMES = 1;
28 static const int32_t BIND_SERVICE_SLEEP_TIMES_MS = 10000;  // 0.1s
29 static const uint32_t SOCKET_NAME_MAX_LEN = 256;
30 static const int32_t QOS_NUM = 5;
31 
OnServerBind(int32_t socket,PeerSocketInfo info)32 static void OnServerBind(int32_t socket, PeerSocketInfo info)
33 {
34     ANS_LOGI("Socket fd is %{public}d.", socket);
35     if (socket <= 0) {
36         ANS_LOGE("Socket fd invalid.");
37         return;
38     }
39     DistributedServer::GetInstance().OnBind(socket, info);
40 }
41 
OnServerShutdown(int32_t socket,ShutdownReason reason)42 static void OnServerShutdown(int32_t socket, ShutdownReason reason)
43 {
44     ANS_LOGI("Socket fd %{public}d shutdown because %{public}d.", socket, (int32_t)(reason));
45     if (socket <= 0) {
46         ANS_LOGE("Socket fd invalid.");
47         return;
48     }
49     DistributedServer::GetInstance().OnShutdown(socket, reason);
50 }
51 
OnServerBytes(int32_t socket,const void * data,uint32_t dataLen)52 static void OnServerBytes(int32_t socket, const void *data, uint32_t dataLen)
53 {
54     ANS_LOGI("Socket byte fd %{public}d, recv len %{public}d.", socket, dataLen);
55     if ((socket <= 0) || (data == nullptr) || (dataLen == 0)) {
56         ANS_LOGW("Socket byte invalid data.");
57         return;
58     }
59     DistributedServer::GetInstance().OnBytes(socket, data, dataLen);
60 }
61 
OnServerMessage(int32_t socket,const void * data,uint32_t dataLen)62 static void OnServerMessage(int32_t socket, const void *data, uint32_t dataLen)
63 {
64     ANS_LOGI("Socket byte fd %{public}d, recv len %{public}d.", socket, dataLen);
65     if ((socket <= 0) || (data == nullptr) || (dataLen == 0)) {
66         ANS_LOGW("Socket byte invalid data.");
67         return;
68     }
69     DistributedServer::GetInstance().OnMessage(socket, data, dataLen);
70 }
71 
OnClientBytes(int32_t socket,const void * data,uint32_t dataLen)72 static void OnClientBytes(int32_t socket, const void *data, uint32_t dataLen)
73 {
74     ANS_LOGI("Socket message fd %{public}d, recv len %{public}d.", socket, dataLen);
75     if ((socket <= 0) || (data == nullptr) || (dataLen == 0)) {
76         ANS_LOGW("Socket message invalid data.");
77     }
78     DistributedServer::GetInstance().OnMessage(socket, data, dataLen);
79 }
80 
OnClientShutdown(int32_t socket,ShutdownReason reason)81 static void OnClientShutdown(int32_t socket, ShutdownReason reason)
82 {
83     ANS_LOGI("Socket fd %{public}d shutdown because %{public}d.", socket, (int32_t)(reason));
84     if (socket <= 0) {
85         ANS_LOGE("Socket fd invalid.");
86         return;
87     }
88     DistributedClient::GetInstance().OnShutdown(socket, reason);
89 }
90 
OnQos(int32_t socket,QoSEvent eventId,const QosTV * qos,uint32_t qosCount)91 static void OnQos(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)
92 {
93     ANS_LOGI("OnQos %{public}d %{public}d %{public}d", socket, (int32_t)eventId, (int32_t)(qosCount));
94 }
95 
CloseSocket(int32_t socketId)96 void CloseSocket(int32_t socketId)
97 {
98     ANS_LOGI("Close socket id %{public}d", socketId);
99     ::Shutdown(socketId);
100 }
101 
CheckAndCopyStr(char * dest,uint32_t destLen,const std::string & src)102 bool CheckAndCopyStr(char* dest, uint32_t destLen, const std::string& src)
103 {
104     if (destLen < src.length() + 1) {
105         return false;
106     }
107     if (strcpy_s(dest, destLen, src.c_str()) != EOK) {
108         return false;
109     }
110     return true;
111 }
112 
ServiceListen(const std::string & name,const std::string & pkgName,TransDataType dataType,int32_t & socketId)113 int32_t ServiceListen(const std::string& name, const std::string& pkgName, TransDataType dataType, int32_t& socketId)
114 {
115     char nameStr[SOCKET_NAME_MAX_LEN + 1];
116     if (!CheckAndCopyStr(nameStr, SOCKET_NAME_MAX_LEN, name)) {
117         return DISRTIBUED_ERR;
118     }
119 
120     char pkgNameStr[SOCKET_NAME_MAX_LEN + 1];
121     if (!CheckAndCopyStr(pkgNameStr, SOCKET_NAME_MAX_LEN, pkgName)) {
122         return DISRTIBUED_ERR;
123     }
124 
125     SocketInfo info = { .name = nameStr, .pkgName = pkgNameStr, .dataType = dataType };
126     socketId = ::Socket(info); // create service socket id
127     if (socketId <= 0) {
128         ANS_LOGW("Create socket faild, %{public}s %{public}s %{public}d.", nameStr, pkgNameStr, socketId);
129         return DISRTIBUED_SOCKET_CREATE_ERR;
130     }
131 
132     QosTV serverQos[] = {
133         { .qos = QOS_TYPE_MIN_BW,      .value = 64*1024 },
134         { .qos = QOS_TYPE_MAX_LATENCY, .value = 10000 },
135         { .qos = QOS_TYPE_MIN_LATENCY, .value = 2000 },
136     };
137     ISocketListener listener;
138     listener.OnBind = OnServerBind; // only service may receive OnBind
139     listener.OnQos = OnQos; // only service may receive OnBind
140     listener.OnShutdown = OnServerShutdown;
141     listener.OnBytes = OnServerBytes;
142     listener.OnMessage = OnServerMessage;
143     int32_t ret = ::Listen(socketId, serverQos, 3, &listener);
144     if (ret != ERR_OK) {
145         ::Shutdown(socketId);
146         ANS_LOGW("Create listener failed, ret is %{public}d.", ret);
147         return ret;
148     }
149     ANS_LOGI("Service listen %{public}s %{public}d %{public}d.", name.c_str(), dataType, socketId);
150     return ERR_OK;
151 }
152 
ClientBind(const std::string & name,const std::string & pkgName,const std::string & peerNetWorkId,TransDataType dataType,int32_t & socketId)153 int32_t ClientBind(const std::string& name, const std::string& pkgName,
154     const std::string& peerNetWorkId, TransDataType dataType, int32_t& socketId)
155 {
156     char nameStr[SOCKET_NAME_MAX_LEN + 1];
157     char peerNetWorkIdStr[SOCKET_NAME_MAX_LEN + 1];
158     if (!CheckAndCopyStr(nameStr, SOCKET_NAME_MAX_LEN, name) ||
159         !CheckAndCopyStr(peerNetWorkIdStr, SOCKET_NAME_MAX_LEN, peerNetWorkId)) {
160         return DISRTIBUED_ERR;
161     }
162     char pkgNameStr[SOCKET_NAME_MAX_LEN + 1];
163     char peerNameStr[SOCKET_NAME_MAX_LEN + 1];
164     if (!CheckAndCopyStr(pkgNameStr, SOCKET_NAME_MAX_LEN, pkgName) ||
165         !CheckAndCopyStr(peerNameStr, SOCKET_NAME_MAX_LEN, name)) {
166         return DISRTIBUED_ERR;
167     }
168     SocketInfo info = { .name = nameStr, .peerName = peerNameStr, .peerNetworkId = peerNetWorkIdStr,
169         .pkgName = pkgNameStr, .dataType = dataType };
170     socketId = ::Socket(info); // create client socket id
171     if (socketId <= 0) {
172         ANS_LOGW("Create client socket faild, ret is %{public}d.", socketId);
173         return DISRTIBUED_SOCKET_CREATE_ERR;
174     }
175 
176     QosTV clientQos[] = {
177         { .qos = QOS_TYPE_MIN_BW,      .value = 64*1024 }, { .qos = QOS_TYPE_MAX_LATENCY, .value = 10000 },
178         { .qos = QOS_TYPE_MIN_LATENCY, .value = 2000 }, { .qos = QOS_TYPE_TRANS_CONTINUOUS, .value = 1 },
179         { .qos = QOS_TYPE_MAX_IDLE_TIMEOUT, .value = 600000 },
180     };
181     ISocketListener listener;
182     listener.OnQos = OnQos;
183     listener.OnShutdown = OnClientShutdown;
184     listener.OnBytes = OnClientBytes;
185 
186     // retry 10 times or bind success
187     int32_t result = 0;
188     int32_t retryTimes = 0;
189     auto sleepTime = std::chrono::milliseconds(BIND_SERVICE_SLEEP_TIMES_MS);
190     bool bindSuccess = false;
191     while (retryTimes < BIND_SERVICE_MAX_RETRY_TIMES) {
192         result = ::Bind(socketId, clientQos, QOS_NUM, &listener);
193         if (result != 0) {
194             ANS_LOGE("Bind Server failed, ret is %{public}d.", result);
195             retryTimes++;
196             continue;
197         }
198         bindSuccess = true;
199         break;
200     }
201 
202     if (!bindSuccess) {
203         ::Shutdown(socketId); // close client.
204         return result;
205     }
206     return ERR_OK;
207 }
208 
ClientSendBytes(int32_t socketId,const void * data,uint32_t length)209 int32_t ClientSendBytes(int32_t socketId, const void* data, uint32_t length)
210 {
211     int32_t result = ::SendBytes(socketId, data, length);
212     ANS_LOGI("Socket send byte %{public}d %{public}d %{public}d ", socketId, length, result);
213     return result;
214 }
215 
ClientSendMessage(int32_t socketId,const void * data,uint32_t length)216 int32_t ClientSendMessage(int32_t socketId, const void* data, uint32_t length)
217 {
218     int32_t result = ::SendMessage(socketId, data, length);
219     ANS_LOGI("Socket send message %{public}d %{public}d %{public}d ", socketId, length, result);
220     return result;
221 }
222 
223 }
224 }
225