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