1f857971dSopenharmony_ci/* 2f857971dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f857971dSopenharmony_ci * you may not use this file except in compliance with the License. 5f857971dSopenharmony_ci * You may obtain a copy of the License at 6f857971dSopenharmony_ci * 7f857971dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f857971dSopenharmony_ci * 9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f857971dSopenharmony_ci * See the License for the specific language governing permissions and 13f857971dSopenharmony_ci * limitations under the License. 14f857971dSopenharmony_ci */ 15f857971dSopenharmony_ci 16f857971dSopenharmony_ci#include "socket_client.h" 17f857971dSopenharmony_ci 18f857971dSopenharmony_ci#include "event_handler.h" 19f857971dSopenharmony_ci 20f857971dSopenharmony_ci#include "devicestatus_define.h" 21f857971dSopenharmony_ci#include "intention_identity.h" 22f857971dSopenharmony_ci#include "socket_params.h" 23f857971dSopenharmony_ci#include "time_cost_chk.h" 24f857971dSopenharmony_ci 25f857971dSopenharmony_ci#undef LOG_TAG 26f857971dSopenharmony_ci#define LOG_TAG "SocketClient" 27f857971dSopenharmony_ci 28f857971dSopenharmony_cinamespace OHOS { 29f857971dSopenharmony_cinamespace Msdp { 30f857971dSopenharmony_cinamespace DeviceStatus { 31f857971dSopenharmony_cinamespace { 32f857971dSopenharmony_ciconst std::string THREAD_NAME { "os_ClientEventHandler" }; 33f857971dSopenharmony_ci} 34f857971dSopenharmony_ci 35f857971dSopenharmony_ciSocketClient::SocketClient(std::shared_ptr<ITunnelClient> tunnel) 36f857971dSopenharmony_ci : tunnel_(tunnel) 37f857971dSopenharmony_ci{ 38f857971dSopenharmony_ci auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME); 39f857971dSopenharmony_ci eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner); 40f857971dSopenharmony_ci} 41f857971dSopenharmony_ci 42f857971dSopenharmony_cibool SocketClient::RegisterEvent(MessageId id, std::function<int32_t(const StreamClient&, NetPacket&)> callback) 43f857971dSopenharmony_ci{ 44f857971dSopenharmony_ci std::lock_guard guard(lock_); 45f857971dSopenharmony_ci auto [_, inserted] = callbacks_.emplace(id, callback); 46f857971dSopenharmony_ci return inserted; 47f857971dSopenharmony_ci} 48f857971dSopenharmony_ci 49f857971dSopenharmony_civoid SocketClient::Start() 50f857971dSopenharmony_ci{ 51f857971dSopenharmony_ci CALL_DEBUG_ENTER; 52f857971dSopenharmony_ci Reconnect(); 53f857971dSopenharmony_ci} 54f857971dSopenharmony_ci 55f857971dSopenharmony_civoid SocketClient::Stop() 56f857971dSopenharmony_ci{} 57f857971dSopenharmony_ci 58f857971dSopenharmony_cibool SocketClient::Connect() 59f857971dSopenharmony_ci{ 60f857971dSopenharmony_ci CALL_DEBUG_ENTER; 61f857971dSopenharmony_ci if (socket_ != nullptr) { 62f857971dSopenharmony_ci return true; 63f857971dSopenharmony_ci } 64f857971dSopenharmony_ci auto socket = SocketConnection::Connect( 65f857971dSopenharmony_ci [this] { return this->Socket(); }, 66f857971dSopenharmony_ci [this](NetPacket &pkt) { this->OnPacket(pkt); }, 67f857971dSopenharmony_ci [this] { this->OnDisconnected(); }); 68f857971dSopenharmony_ci CHKPF(socket); 69f857971dSopenharmony_ci CHKPF(eventHandler_); 70f857971dSopenharmony_ci auto errCode = eventHandler_->AddFileDescriptorListener(socket->GetFd(), 71f857971dSopenharmony_ci AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, socket, "DeviceStatusTask"); 72f857971dSopenharmony_ci if (errCode != ERR_OK) { 73f857971dSopenharmony_ci FI_HILOGE("AddFileDescriptorListener(%{public}d) failed (%{public}u)", socket->GetFd(), errCode); 74f857971dSopenharmony_ci return false; 75f857971dSopenharmony_ci } 76f857971dSopenharmony_ci socket_ = socket; 77f857971dSopenharmony_ci FI_HILOGD("SocketClient started successfully"); 78f857971dSopenharmony_ci if (funConnected_ != nullptr) { 79f857971dSopenharmony_ci FI_HILOGI("Execute funConnected"); 80f857971dSopenharmony_ci funConnected_(); 81f857971dSopenharmony_ci } 82f857971dSopenharmony_ci return true; 83f857971dSopenharmony_ci} 84f857971dSopenharmony_ci 85f857971dSopenharmony_ciint32_t SocketClient::Socket() 86f857971dSopenharmony_ci{ 87f857971dSopenharmony_ci CALL_DEBUG_ENTER; 88f857971dSopenharmony_ci std::shared_ptr<ITunnelClient> tunnel = tunnel_.lock(); 89f857971dSopenharmony_ci CHKPR(tunnel, RET_ERR); 90f857971dSopenharmony_ci AllocSocketPairParam param { GetProgramName(), CONNECT_MODULE_TYPE_FI_CLIENT }; 91f857971dSopenharmony_ci AllocSocketPairReply reply; 92f857971dSopenharmony_ci 93f857971dSopenharmony_ci int32_t ret = tunnel->Control(Intention::SOCKET, SocketAction::SOCKET_ACTION_CONNECT, param, reply); 94f857971dSopenharmony_ci if (ret != RET_OK) { 95f857971dSopenharmony_ci FI_HILOGE("ITunnelClient::Control fail"); 96f857971dSopenharmony_ci return -1; 97f857971dSopenharmony_ci } 98f857971dSopenharmony_ci FI_HILOGD("Connected to intention service (%{public}d)", reply.socketFd); 99f857971dSopenharmony_ci return reply.socketFd; 100f857971dSopenharmony_ci} 101f857971dSopenharmony_ci 102f857971dSopenharmony_civoid SocketClient::OnPacket(NetPacket &pkt) 103f857971dSopenharmony_ci{ 104f857971dSopenharmony_ci CALL_DEBUG_ENTER; 105f857971dSopenharmony_ci std::lock_guard guard(lock_); 106f857971dSopenharmony_ci OnMsgHandler(*this, pkt); 107f857971dSopenharmony_ci} 108f857971dSopenharmony_ci 109f857971dSopenharmony_civoid SocketClient::OnDisconnected() 110f857971dSopenharmony_ci{ 111f857971dSopenharmony_ci CALL_DEBUG_ENTER; 112f857971dSopenharmony_ci std::lock_guard guard(lock_); 113f857971dSopenharmony_ci if (socket_ != nullptr) { 114f857971dSopenharmony_ci eventHandler_->RemoveFileDescriptorListener(socket_->GetFd()); 115f857971dSopenharmony_ci eventHandler_->RemoveAllEvents(); 116f857971dSopenharmony_ci socket_.reset(); 117f857971dSopenharmony_ci } 118f857971dSopenharmony_ci if (funDisconnected_ != nullptr) { 119f857971dSopenharmony_ci FI_HILOGI("Execute funDisconnected"); 120f857971dSopenharmony_ci funDisconnected_(); 121f857971dSopenharmony_ci } 122f857971dSopenharmony_ci if (!eventHandler_->PostTask([this] { this->Reconnect(); }, CLIENT_RECONNECT_COOLING_TIME)) { 123f857971dSopenharmony_ci FI_HILOGE("Failed to post reconnection task"); 124f857971dSopenharmony_ci } 125f857971dSopenharmony_ci} 126f857971dSopenharmony_ci 127f857971dSopenharmony_civoid SocketClient::Reconnect() 128f857971dSopenharmony_ci{ 129f857971dSopenharmony_ci std::lock_guard guard(lock_); 130f857971dSopenharmony_ci if (Connect()) { 131f857971dSopenharmony_ci return; 132f857971dSopenharmony_ci } 133f857971dSopenharmony_ci if (!eventHandler_->PostTask([this] { this->Reconnect(); }, CLIENT_RECONNECT_COOLING_TIME)) { 134f857971dSopenharmony_ci FI_HILOGE("Failed to post reconnection task"); 135f857971dSopenharmony_ci } 136f857971dSopenharmony_ci} 137f857971dSopenharmony_ci 138f857971dSopenharmony_civoid SocketClient::OnMsgHandler(const StreamClient &client, NetPacket &pkt) 139f857971dSopenharmony_ci{ 140f857971dSopenharmony_ci CALL_DEBUG_ENTER; 141f857971dSopenharmony_ci MessageId id = pkt.GetMsgId(); 142f857971dSopenharmony_ci TimeCostChk chk("SocketClient::OnMsgHandler", "overtime 300(us)", MAX_OVER_TIME, id); 143f857971dSopenharmony_ci auto iter = callbacks_.find(id); 144f857971dSopenharmony_ci if (iter == callbacks_.end()) { 145f857971dSopenharmony_ci FI_HILOGE("Unknown msg id:%{public}d", id); 146f857971dSopenharmony_ci return; 147f857971dSopenharmony_ci } 148f857971dSopenharmony_ci int32_t ret = iter->second(client, pkt); 149f857971dSopenharmony_ci if (ret < 0) { 150f857971dSopenharmony_ci FI_HILOGE("Msg handling failed, id:%{public}d, ret:%{public}d", id, ret); 151f857971dSopenharmony_ci } 152f857971dSopenharmony_ci} 153f857971dSopenharmony_ci 154f857971dSopenharmony_civoid SocketClient::RegisterConnectedFunction(ConnectCallback funConnected) 155f857971dSopenharmony_ci{ 156f857971dSopenharmony_ci funConnected_ = funConnected; 157f857971dSopenharmony_ci} 158f857971dSopenharmony_ci 159f857971dSopenharmony_civoid SocketClient::RegisterDisconnectedFunction(ConnectCallback funDisconnected) 160f857971dSopenharmony_ci{ 161f857971dSopenharmony_ci funDisconnected_ = funDisconnected; 162f857971dSopenharmony_ci} 163f857971dSopenharmony_ci} // namespace DeviceStatus 164f857971dSopenharmony_ci} // namespace Msdp 165f857971dSopenharmony_ci} // namespace OHOS