1 /*
2 * Copyright (c) 2023-2025 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 "socket_client.h"
17
18 #include "event_handler.h"
19
20 #include "devicestatus_define.h"
21 #include "intention_client.h"
22 #include "intention_identity.h"
23 #include "time_cost_chk.h"
24
25 #undef LOG_TAG
26 #define LOG_TAG "SocketClient"
27
28 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace {
32 const std::string THREAD_NAME { "os_ClientEventHandler" };
33 const int32_t INVALID_SOCKT { -1 };
34 }
35
SocketClient()36 SocketClient::SocketClient()
37 {
38 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
39 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
40 }
41
RegisterEvent(MessageId id,std::function<int32_t (const StreamClient &,NetPacket &)> callback)42 bool SocketClient::RegisterEvent(MessageId id, std::function<int32_t(const StreamClient&, NetPacket&)> callback)
43 {
44 std::lock_guard guard(lock_);
45 auto [_, inserted] = callbacks_.emplace(id, callback);
46 return inserted;
47 }
48
Start()49 void SocketClient::Start()
50 {
51 CALL_INFO_TRACE;
52 Reconnect();
53 }
54
Stop()55 void SocketClient::Stop()
56 {}
57
Connect()58 bool SocketClient::Connect()
59 {
60 CALL_DEBUG_ENTER;
61 if (socket_ != nullptr) {
62 return true;
63 }
64 auto socket = SocketConnection::Connect(
65 [this] { return this->Socket(); },
66 [this](NetPacket &pkt) { this->OnPacket(pkt); },
67 [this] { this->OnDisconnected(); });
68 CHKPF(socket);
69 CHKPF(eventHandler_);
70 auto errCode = eventHandler_->AddFileDescriptorListener(socket->GetFd(),
71 AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, socket, "DeviceStatusTask");
72 if (errCode != ERR_OK) {
73 FI_HILOGE("AddFileDescriptorListener(%{public}d) failed (%{public}u)", socket->GetFd(), errCode);
74 return false;
75 }
76 socket_ = socket;
77 FI_HILOGD("SocketClient started successfully");
78 if (funConnected_ != nullptr) {
79 FI_HILOGI("Execute funConnected");
80 funConnected_();
81 }
82 return true;
83 }
84
Socket()85 int32_t SocketClient::Socket()
86 {
87 CALL_DEBUG_ENTER;
88 auto programName = GetProgramName();
89 int32_t socketFd { -1 };
90 int32_t tokenType { -1 };
91 if (int32_t ret = INTENTION_CLIENT->Socket(programName, CONNECT_MODULE_TYPE_FI_CLIENT, socketFd, tokenType);
92 ret != RET_OK) {
93 FI_HILOGE("Socket fail");
94 return INVALID_SOCKT;
95 }
96 return socketFd;
97 }
98
OnPacket(NetPacket & pkt)99 void SocketClient::OnPacket(NetPacket &pkt)
100 {
101 CALL_DEBUG_ENTER;
102 std::lock_guard guard(lock_);
103 OnMsgHandler(*this, pkt);
104 }
105
OnDisconnected()106 void SocketClient::OnDisconnected()
107 {
108 CALL_DEBUG_ENTER;
109 std::lock_guard guard(lock_);
110 if (socket_ != nullptr) {
111 eventHandler_->RemoveFileDescriptorListener(socket_->GetFd());
112 eventHandler_->RemoveAllEvents();
113 socket_.reset();
114 }
115 if (funDisconnected_ != nullptr) {
116 FI_HILOGI("Execute funDisconnected");
117 funDisconnected_();
118 }
119 if (!eventHandler_->PostTask([this] { this->Reconnect(); }, CLIENT_RECONNECT_COOLING_TIME)) {
120 FI_HILOGE("Failed to post reconnection task");
121 }
122 }
123
Reconnect()124 void SocketClient::Reconnect()
125 {
126 std::lock_guard guard(lock_);
127 if (Connect()) {
128 return;
129 }
130 if (!eventHandler_->PostTask([this] { this->Reconnect(); }, CLIENT_RECONNECT_COOLING_TIME)) {
131 FI_HILOGE("Failed to post reconnection task");
132 }
133 }
134
OnMsgHandler(const StreamClient & client,NetPacket & pkt)135 void SocketClient::OnMsgHandler(const StreamClient &client, NetPacket &pkt)
136 {
137 CALL_DEBUG_ENTER;
138 MessageId id = pkt.GetMsgId();
139 TimeCostChk chk("SocketClient::OnMsgHandler", "overtime 300(us)", MAX_OVER_TIME, id);
140 auto iter = callbacks_.find(id);
141 if (iter == callbacks_.end()) {
142 FI_HILOGE("Unknown msg id:%{public}d", id);
143 return;
144 }
145 int32_t ret = iter->second(client, pkt);
146 if (ret < 0) {
147 FI_HILOGE("Msg handling failed, id:%{public}d, ret:%{public}d", id, ret);
148 }
149 }
150
RegisterConnectedFunction(ConnectCallback funConnected)151 void SocketClient::RegisterConnectedFunction(ConnectCallback funConnected)
152 {
153 funConnected_ = funConnected;
154 }
155
RegisterDisconnectedFunction(ConnectCallback funDisconnected)156 void SocketClient::RegisterDisconnectedFunction(ConnectCallback funDisconnected)
157 {
158 funDisconnected_ = funDisconnected;
159 }
160 } // namespace DeviceStatus
161 } // namespace Msdp
162 } // namespace OHOS