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