1f16e0440Sopenharmony_ci/* 2f16e0440Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3f16e0440Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f16e0440Sopenharmony_ci * you may not use this file except in compliance with the License. 5f16e0440Sopenharmony_ci * You may obtain a copy of the License at 6f16e0440Sopenharmony_ci * 7f16e0440Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f16e0440Sopenharmony_ci * 9f16e0440Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f16e0440Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f16e0440Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f16e0440Sopenharmony_ci * See the License for the specific language governing permissions and 13f16e0440Sopenharmony_ci * limitations under the License. 14f16e0440Sopenharmony_ci */ 15f16e0440Sopenharmony_ci 16f16e0440Sopenharmony_ci#include "battery_thread.h" 17f16e0440Sopenharmony_ci#include <cerrno> 18f16e0440Sopenharmony_ci#include <sys/epoll.h> 19f16e0440Sopenharmony_ci#include <sys/socket.h> 20f16e0440Sopenharmony_ci#include <sys/timerfd.h> 21f16e0440Sopenharmony_ci#include <unistd.h> 22f16e0440Sopenharmony_ci#include <linux/netlink.h> 23f16e0440Sopenharmony_ci#include "hdf_base.h" 24f16e0440Sopenharmony_ci#include "charger_log.h" 25f16e0440Sopenharmony_ci 26f16e0440Sopenharmony_cinamespace OHOS { 27f16e0440Sopenharmony_cinamespace PowerMgr { 28f16e0440Sopenharmony_cinamespace { 29f16e0440Sopenharmony_ciconstexpr int32_t UEVENT_BUFF_SIZE = (64 * 1024); 30f16e0440Sopenharmony_ciconstexpr int32_t UEVENT_RESERVED_SIZE = 2; 31f16e0440Sopenharmony_ciconstexpr int32_t UEVENT_MSG_LEN = (2 * 1024); 32f16e0440Sopenharmony_ciconstexpr int32_t TIMER_FAST_SEC = 2; 33f16e0440Sopenharmony_ciconstexpr int32_t SEC_TO_MSEC = 1000; 34f16e0440Sopenharmony_ciconst std::string POWER_SUPPLY = "SUBSYSTEM=power_supply"; 35f16e0440Sopenharmony_ci} 36f16e0440Sopenharmony_ci 37f16e0440Sopenharmony_ciint32_t BatteryThread::OpenUeventSocket() 38f16e0440Sopenharmony_ci{ 39f16e0440Sopenharmony_ci int32_t bufferSize = UEVENT_BUFF_SIZE; 40f16e0440Sopenharmony_ci struct sockaddr_nl address = { 41f16e0440Sopenharmony_ci .nl_family = AF_NETLINK, 42f16e0440Sopenharmony_ci .nl_pid = getpid(), 43f16e0440Sopenharmony_ci .nl_groups = 0xffffffff 44f16e0440Sopenharmony_ci }; 45f16e0440Sopenharmony_ci 46f16e0440Sopenharmony_ci int32_t fd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT); 47f16e0440Sopenharmony_ci if (fd == INVALID_FD) { 48f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "open uevent socket failed, fd is invalid"); 49f16e0440Sopenharmony_ci return INVALID_FD; 50f16e0440Sopenharmony_ci } 51f16e0440Sopenharmony_ci 52f16e0440Sopenharmony_ci int32_t ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); 53f16e0440Sopenharmony_ci if (ret < 0) { 54f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "set socket opt failed, ret: %{public}d", ret); 55f16e0440Sopenharmony_ci close(fd); 56f16e0440Sopenharmony_ci return INVALID_FD; 57f16e0440Sopenharmony_ci } 58f16e0440Sopenharmony_ci 59f16e0440Sopenharmony_ci ret = bind(fd, reinterpret_cast<const struct sockaddr*>(&address), sizeof(struct sockaddr_nl)); 60f16e0440Sopenharmony_ci if (ret < 0) { 61f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "bind socket address failed, ret: %{public}d", ret); 62f16e0440Sopenharmony_ci close(fd); 63f16e0440Sopenharmony_ci return INVALID_FD; 64f16e0440Sopenharmony_ci } 65f16e0440Sopenharmony_ci return fd; 66f16e0440Sopenharmony_ci} 67f16e0440Sopenharmony_ci 68f16e0440Sopenharmony_ciint32_t BatteryThread::RegisterCallback(int32_t fd, EventType et) 69f16e0440Sopenharmony_ci{ 70f16e0440Sopenharmony_ci struct epoll_event ev = {0}; 71f16e0440Sopenharmony_ci 72f16e0440Sopenharmony_ci ev.events = EPOLLIN; 73f16e0440Sopenharmony_ci if (et == EVENT_TIMER_FD) { 74f16e0440Sopenharmony_ci ev.events |= EPOLLWAKEUP; 75f16e0440Sopenharmony_ci } 76f16e0440Sopenharmony_ci 77f16e0440Sopenharmony_ci ev.data.ptr = reinterpret_cast<void*>(this); 78f16e0440Sopenharmony_ci ev.data.fd = fd; 79f16e0440Sopenharmony_ci if (epoll_ctl(epFd_, EPOLL_CTL_ADD, fd, &ev) == -1) { 80f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "epoll_ctl failed, error num =%{public}d", errno); 81f16e0440Sopenharmony_ci return HDF_FAILURE; 82f16e0440Sopenharmony_ci } 83f16e0440Sopenharmony_ci return HDF_SUCCESS; 84f16e0440Sopenharmony_ci} 85f16e0440Sopenharmony_ci 86f16e0440Sopenharmony_civoid BatteryThread::UpdateEpollInterval(const int32_t chargeState) 87f16e0440Sopenharmony_ci{ 88f16e0440Sopenharmony_ci if ((chargeState != PowerSupplyProvider::CHARGE_STATE_NONE) && 89f16e0440Sopenharmony_ci (chargeState != PowerSupplyProvider::CHARGE_STATE_RESERVED)) { 90f16e0440Sopenharmony_ci epollInterval_ = TIMER_FAST_SEC * SEC_TO_MSEC; 91f16e0440Sopenharmony_ci } else { 92f16e0440Sopenharmony_ci epollInterval_ = -1; 93f16e0440Sopenharmony_ci } 94f16e0440Sopenharmony_ci} 95f16e0440Sopenharmony_ci 96f16e0440Sopenharmony_ciint32_t BatteryThread::InitUevent() 97f16e0440Sopenharmony_ci{ 98f16e0440Sopenharmony_ci ueventFd_ = OpenUeventSocket(); 99f16e0440Sopenharmony_ci if (ueventFd_ == INVALID_FD) { 100f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "open uevent socket failed, fd is invalid"); 101f16e0440Sopenharmony_ci return HDF_ERR_BAD_FD; 102f16e0440Sopenharmony_ci } 103f16e0440Sopenharmony_ci 104f16e0440Sopenharmony_ci fcntl(ueventFd_, F_SETFL, O_NONBLOCK); 105f16e0440Sopenharmony_ci callbacks_.insert(std::make_pair(ueventFd_, &BatteryThread::UeventCallback)); 106f16e0440Sopenharmony_ci 107f16e0440Sopenharmony_ci if (RegisterCallback(ueventFd_, EVENT_UEVENT_FD)) { 108f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "register Uevent event failed"); 109f16e0440Sopenharmony_ci return HDF_ERR_BAD_FD; 110f16e0440Sopenharmony_ci } 111f16e0440Sopenharmony_ci return HDF_SUCCESS; 112f16e0440Sopenharmony_ci} 113f16e0440Sopenharmony_ci 114f16e0440Sopenharmony_ciint32_t BatteryThread::Init([[maybe_unused]] void* service) 115f16e0440Sopenharmony_ci{ 116f16e0440Sopenharmony_ci provider_ = std::make_unique<PowerSupplyProvider>(); 117f16e0440Sopenharmony_ci if (provider_ != nullptr) { 118f16e0440Sopenharmony_ci provider_->InitBatteryPath(); 119f16e0440Sopenharmony_ci provider_->InitPowerSupplySysfs(); 120f16e0440Sopenharmony_ci } 121f16e0440Sopenharmony_ci 122f16e0440Sopenharmony_ci epFd_ = epoll_create1(EPOLL_CLOEXEC); 123f16e0440Sopenharmony_ci if (epFd_ == INVALID_FD) { 124f16e0440Sopenharmony_ci BATTERY_HILOGE(FEATURE_CHARGING, "epoll create failed, epFd_ is invalid"); 125f16e0440Sopenharmony_ci return HDF_ERR_BAD_FD; 126f16e0440Sopenharmony_ci } 127f16e0440Sopenharmony_ci 128f16e0440Sopenharmony_ci InitUevent(); 129f16e0440Sopenharmony_ci 130f16e0440Sopenharmony_ci return HDF_SUCCESS; 131f16e0440Sopenharmony_ci} 132f16e0440Sopenharmony_ci 133f16e0440Sopenharmony_ciint32_t BatteryThread::UpdateWaitInterval() 134f16e0440Sopenharmony_ci{ 135f16e0440Sopenharmony_ci return HDF_FAILURE; 136f16e0440Sopenharmony_ci} 137f16e0440Sopenharmony_ci 138f16e0440Sopenharmony_civoid BatteryThread::UeventCallback(void* service) 139f16e0440Sopenharmony_ci{ 140f16e0440Sopenharmony_ci char msg[UEVENT_MSG_LEN + UEVENT_RESERVED_SIZE] = { 0 }; 141f16e0440Sopenharmony_ci 142f16e0440Sopenharmony_ci ssize_t len = recv(ueventFd_, msg, UEVENT_MSG_LEN, 0); 143f16e0440Sopenharmony_ci if (len < 0 || len >= UEVENT_MSG_LEN) { 144f16e0440Sopenharmony_ci BATTERY_HILOGI(FEATURE_CHARGING, "recv return msg is invalid, len: %{public}zd", len); 145f16e0440Sopenharmony_ci return; 146f16e0440Sopenharmony_ci } 147f16e0440Sopenharmony_ci 148f16e0440Sopenharmony_ci // msg separator 149f16e0440Sopenharmony_ci msg[len] = '\0'; 150f16e0440Sopenharmony_ci msg[len + 1] = '\0'; 151f16e0440Sopenharmony_ci if (!IsPowerSupplyEvent(msg)) { 152f16e0440Sopenharmony_ci return; 153f16e0440Sopenharmony_ci } 154f16e0440Sopenharmony_ci UpdateBatteryInfo(service); 155f16e0440Sopenharmony_ci} 156f16e0440Sopenharmony_ci 157f16e0440Sopenharmony_civoid BatteryThread::UpdateBatteryInfo(void* service) {} 158f16e0440Sopenharmony_ci 159f16e0440Sopenharmony_cibool BatteryThread::IsPowerSupplyEvent(const char* msg) 160f16e0440Sopenharmony_ci{ 161f16e0440Sopenharmony_ci while (*msg) { 162f16e0440Sopenharmony_ci if (!strcmp(msg, POWER_SUPPLY.c_str())) { 163f16e0440Sopenharmony_ci return true; 164f16e0440Sopenharmony_ci } 165f16e0440Sopenharmony_ci while (*msg++) {} // move to next 166f16e0440Sopenharmony_ci } 167f16e0440Sopenharmony_ci 168f16e0440Sopenharmony_ci return false; 169f16e0440Sopenharmony_ci} 170f16e0440Sopenharmony_ci 171f16e0440Sopenharmony_ciint32_t BatteryThread::LoopingThreadEntry(void* arg) 172f16e0440Sopenharmony_ci{ 173f16e0440Sopenharmony_ci int32_t nevents = 0; 174f16e0440Sopenharmony_ci size_t size = callbacks_.size(); 175f16e0440Sopenharmony_ci struct epoll_event events[size]; 176f16e0440Sopenharmony_ci 177f16e0440Sopenharmony_ci while (true) { 178f16e0440Sopenharmony_ci if (!nevents) { 179f16e0440Sopenharmony_ci CycleMatters(); 180f16e0440Sopenharmony_ci } 181f16e0440Sopenharmony_ci 182f16e0440Sopenharmony_ci HandleStates(); 183f16e0440Sopenharmony_ci 184f16e0440Sopenharmony_ci int32_t timeout = epollInterval_; 185f16e0440Sopenharmony_ci int32_t waitTimeout = UpdateWaitInterval(); 186f16e0440Sopenharmony_ci if ((timeout < 0) || (waitTimeout > 0 && waitTimeout < timeout)) { 187f16e0440Sopenharmony_ci timeout = waitTimeout; 188f16e0440Sopenharmony_ci } 189f16e0440Sopenharmony_ci 190f16e0440Sopenharmony_ci nevents = epoll_wait(epFd_, events, static_cast<int32_t>(size), timeout); 191f16e0440Sopenharmony_ci if (nevents <= 0) { 192f16e0440Sopenharmony_ci continue; 193f16e0440Sopenharmony_ci } 194f16e0440Sopenharmony_ci 195f16e0440Sopenharmony_ci for (int32_t n = 0; n < nevents; ++n) { 196f16e0440Sopenharmony_ci if (events[n].data.ptr) { 197f16e0440Sopenharmony_ci auto* func = const_cast<BatteryThread*>(this); 198f16e0440Sopenharmony_ci (callbacks_.find(events[n].data.fd)->second)(func, arg); 199f16e0440Sopenharmony_ci } 200f16e0440Sopenharmony_ci } 201f16e0440Sopenharmony_ci } 202f16e0440Sopenharmony_ci} 203f16e0440Sopenharmony_ci 204f16e0440Sopenharmony_civoid BatteryThread::StartThread(void* service) 205f16e0440Sopenharmony_ci{ 206f16e0440Sopenharmony_ci Init(service); 207f16e0440Sopenharmony_ci Run(service); 208f16e0440Sopenharmony_ci} 209f16e0440Sopenharmony_ci 210f16e0440Sopenharmony_civoid BatteryThread::Run(void* service) {} 211f16e0440Sopenharmony_ci} // namespace PowerMgr 212f16e0440Sopenharmony_ci} // namespace OHOS 213