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
16 #include "soft_bus_client_socket.h"
17
18 #include "relative_timer.h"
19 #include "remote_connect_listener_manager.h"
20 #include "remote_connect_manager.h"
21 #include "remote_message.h"
22 #include "thread_handler_manager.h"
23
24 #define LOG_TAG "USER_AUTH_SA"
25 namespace OHOS {
26 namespace UserIam {
27 namespace UserAuth {
28 namespace {
29 const uint32_t KEEP_ALIVE_INTERVAL = 1000; // 1s
30 }
ClientSocket(const int32_t socketId)31 ClientSocket::ClientSocket(const int32_t socketId)
32 : BaseSocket(socketId)
33 {
34 IAM_LOGI("client socket id is %{public}d.", socketId);
35 }
36
~ClientSocket()37 ClientSocket::~ClientSocket()
38 {
39 if (keepAliveTimerId_.has_value()) {
40 RelativeTimer::GetInstance().Unregister(keepAliveTimerId_.value());
41 }
42 }
43
SendMessage(const std::string & connectionName,const std::string & srcEndPoint,const std::string & destEndPoint,const std::shared_ptr<Attributes> & attributes,MsgCallback & callback)44 ResultCode ClientSocket::SendMessage(const std::string &connectionName, const std::string &srcEndPoint,
45 const std::string &destEndPoint, const std::shared_ptr<Attributes> &attributes, MsgCallback &callback)
46 {
47 IAM_LOGD("start.");
48 int32_t socketId = GetSocketId();
49 if (socketId == INVALID_SOCKET_ID) {
50 IAM_LOGE("socket id is invalid");
51 return GENERAL_ERROR;
52 }
53
54 RefreshKeepAliveTimer();
55 return SendRequest(socketId, connectionName, srcEndPoint, destEndPoint, attributes, callback);
56 }
57
OnQos(int32_t socketId,QoSEvent eventId,const QosTV * qos,uint32_t qosCount)58 void ClientSocket::OnQos(int32_t socketId, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)
59 {
60 IAM_LOGI("start, socket id is %{public}d", socketId);
61 }
62
OnShutdown(int32_t socketId,ShutdownReason reason)63 void ClientSocket::OnShutdown(int32_t socketId, ShutdownReason reason)
64 {
65 IAM_LOGI("start, socket id is %{public}d", socketId);
66 std::string connectionName = GetConnectionName();
67 if (!connectionName.empty()) {
68 RemoteConnectListenerManager::GetInstance().OnConnectionDown(connectionName);
69 }
70 }
71
OnBytes(int32_t socketId,const void * data,uint32_t dataLen)72 void ClientSocket::OnBytes(int32_t socketId, const void *data, uint32_t dataLen)
73 {
74 IAM_LOGD("start, socket id is %{public}d", socketId);
75 IF_FALSE_LOGE_AND_RETURN(data != nullptr);
76 IF_FALSE_LOGE_AND_RETURN(dataLen != 0);
77
78 std::string networkId = GetNetworkId();
79 if (networkId.empty()) {
80 IAM_LOGE("networkId id is null, socketId:%{public}d.", socketId);
81 return;
82 }
83
84 std::shared_ptr<SoftBusMessage> softBusMessage = ParseMessage(networkId, const_cast<void *>(data), dataLen);
85 if (softBusMessage == nullptr) {
86 IAM_LOGE("serverSocket parse message fail.");
87 return;
88 }
89
90 ResultCode ret = ProcDataReceive(socketId, softBusMessage);
91 if (ret != SUCCESS) {
92 IAM_LOGE("HandleDataReceive fail, socketId:%{public}d.", socketId);
93 return;
94 }
95 }
96
OnBind(int32_t socketId,PeerSocketInfo info)97 void ClientSocket::OnBind(int32_t socketId, PeerSocketInfo info)
98 {
99 IAM_LOGI("start, socket id is %{public}d", socketId);
100 }
101
GetConnectionName()102 std::string ClientSocket::GetConnectionName()
103 {
104 return connectionName_;
105 }
106
GetNetworkId()107 std::string ClientSocket::GetNetworkId()
108 {
109 return networkId_;
110 }
111
SetConnectionName(const std::string & connectionName)112 void ClientSocket::SetConnectionName(const std::string &connectionName)
113 {
114 connectionName_ = connectionName;
115 }
116
SetNetworkId(const std::string & networkId)117 void ClientSocket::SetNetworkId(const std::string &networkId)
118 {
119 networkId_ = networkId;
120 }
121
RefreshKeepAliveTimer()122 void ClientSocket::RefreshKeepAliveTimer()
123 {
124 if (keepAliveTimerId_.has_value()) {
125 RelativeTimer::GetInstance().Unregister(keepAliveTimerId_.value());
126 }
127 keepAliveTimerId_ = RelativeTimer::GetInstance().Register([weakThis = weak_from_this(), this]() {
128 auto sharedThis = weakThis.lock();
129 IF_FALSE_LOGE_AND_RETURN(sharedThis != nullptr);
130 SendKeepAliveMessage();
131 }, KEEP_ALIVE_INTERVAL);
132 IAM_LOGI("ConnectionName: %{public}s, keep alive timer is refreshed", connectionName_.c_str());
133 }
134
SendKeepAliveMessage()135 void ClientSocket::SendKeepAliveMessage()
136 {
137 IAM_LOGI("ConnectionName: %{public}s, send keep alive message begin", connectionName_.c_str());
138 std::shared_ptr<Attributes> request = Common::MakeShared<Attributes>();
139 IF_FALSE_LOGE_AND_RETURN(request != nullptr);
140
141 bool setMsgTypeRet = request->SetInt32Value(Attributes::ATTR_MSG_TYPE, MessageType::KEEP_ALIVE);
142 IF_FALSE_LOGE_AND_RETURN(setMsgTypeRet);
143
144 MsgCallback sendKeepAliveCallback = [connectionName = connectionName_](const std::shared_ptr<Attributes> &) {
145 IAM_LOGI("ConnectionName: %{public}s, receive keep alive message ack", connectionName.c_str());
146 };
147 ResultCode ret = RemoteConnectionManager::GetInstance().SendMessage(connectionName_, CLIENT_SOCKET_ENDPOINT_NAME,
148 REMOTE_SERVICE_ENDPOINT_NAME, request, sendKeepAliveCallback);
149 if (ret != SUCCESS) {
150 IAM_LOGE("ConnectionName: %{public}s, send keep alive message failed, connection down",
151 connectionName_.c_str());
152 auto threadHandler = ThreadHandlerManager::GetInstance().GetThreadHandler(SINGLETON_THREAD_NAME);
153 if (threadHandler == nullptr) {
154 IAM_LOGE("ConnectionName: %{public}s, threadHandler is nullptr", connectionName_.c_str());
155 return;
156 }
157 threadHandler->PostTask(
158 [connectionName = connectionName_]() {
159 RemoteConnectListenerManager::GetInstance().OnConnectionDown(connectionName);
160 IAM_LOGE("ConnectionName: %{public}s, set connection down", connectionName.c_str());
161 });
162 return;
163 }
164 IAM_LOGI("ConnectionName: %{public}s, send keep alive message success", connectionName_.c_str());
165 }
166 } // namespace UserAuth
167 } // namespace UserIam
168 } // namespace OHOS