From 7c1991c2e3f9fb17a2abefb3f170c6ccfa6407c4 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 21 Dec 2024 22:29:41 +0800 Subject: [PATCH] Battery (NetBSD): add support --- src/detection/battery/battery_nbsd.c | 101 ++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 18 deletions(-) diff --git a/src/detection/battery/battery_nbsd.c b/src/detection/battery/battery_nbsd.c index 49f63755..682bfbfd 100644 --- a/src/detection/battery/battery_nbsd.c +++ b/src/detection/battery/battery_nbsd.c @@ -1,7 +1,12 @@ -#include "fastfetch.h" #include "battery.h" #include "common/io/io.h" +#include "util/FFstrbuf.h" +#include "util/stringUtils.h" +#include +#include +#include +#include #include #include #include @@ -9,7 +14,7 @@ #include #include -const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) +const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results) { FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY); if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed"; @@ -18,25 +23,85 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed"; - prop_array_t array = prop_dictionary_get(root, "acpiacad0"); - if (!array) - return "No key `acpibat0` in root dictionary"; + bool acConnected = false; + { + prop_array_t acad = prop_dictionary_get(root, "acpiacad0"); + if (acad) + { + prop_dictionary_t dict = prop_array_get(acad, 0); + prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &acConnected); + } + } - if (prop_array_count(array) != 2) - return "Unexpect `acpibat0` data"; + prop_object_iterator_t itKey = prop_dictionary_iterator(root); + for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL; ) + { + if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) continue; - prop_dictionary_t dict = prop_array_get(array, 0); - if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) - return "Unexpect `acpibat0[0]`"; + prop_array_t bat = prop_dictionary_get_keysym(root, key); + uint32_t max = 0, curr = 0, dischargeRate = 0; + bool charging = false, critical = false; + prop_object_iterator_t iter = prop_array_iterator(bat); + for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;) + { + if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) + continue; + + const char* desc = NULL; + if (!prop_dictionary_get_string(dict, "description", &desc)) + continue; - //prop_array_t keys = prop_dictionary_all_keys(dict); - //for (uint32_t i = 0; i < prop_array_count(keys); ++i) - // puts(prop_dictionary_keysym_value(prop_array_get(keys, i))); + if (ffStrEquals(desc, "present")) + { + int value = 0; + if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0) + continue; + } + else if (ffStrEquals(desc, "charging")) + { + prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &charging); + } + else if (ffStrEquals(desc, "charge")) + { + prop_dictionary_get_uint32(dict, "max-value", &max); + prop_dictionary_get_uint32(dict, "cur-value", &curr); + const char* state = NULL; + if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical")) + critical = true; + } + else if (ffStrEquals(desc, "discharge rate")) + { + prop_dictionary_get_uint(dict, "cur-value", &dischargeRate); + } + } - int acConnected = false; - prop_dictionary_get_int(dict, "cur-value", &acConnected); + if (max > 0) + { + FFBatteryResult* battery = ffListAdd(results); + battery->temperature = FF_BATTERY_TEMP_UNSET; + battery->cycleCount = 0; + ffStrbufInit(&battery->manufacturer); + ffStrbufInit(&battery->modelName); + ffStrbufInit(&battery->status); + ffStrbufInit(&battery->technology); + ffStrbufInit(&battery->serial); + ffStrbufInit(&battery->manufactureDate); + battery->timeRemaining = -1; - // TODO: actually use acpibat0 - - return acConnected ? "AC Connected" : "Discharging"; + battery->capacity = (double) curr / max; + if (charging) + ffStrbufAppendS(&battery->status, "Charging, "); + else if (dischargeRate) + ffStrbufAppendS(&battery->status, "Discharging, "); + if (critical) + ffStrbufAppendS(&battery->status, "Critical, "); + if (acConnected) + ffStrbufAppendS(&battery->status, "AC Connected"); + ffStrbufTrimRight(&battery->status, ' '); + ffStrbufTrimRight(&battery->status, ','); + } + } + prop_object_iterator_release(itKey); + + return NULL; }