diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/battery/battery_nbsd.c | |
Add the files
Diffstat (limited to 'src/detection/battery/battery_nbsd.c')
| -rw-r--r-- | src/detection/battery/battery_nbsd.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/detection/battery/battery_nbsd.c b/src/detection/battery/battery_nbsd.c new file mode 100644 index 0000000..2e8b426 --- /dev/null +++ b/src/detection/battery/battery_nbsd.c @@ -0,0 +1,109 @@ +#include "battery.h" +#include "common/io.h" +#include "common/FFstrbuf.h" +#include "common/strutil.h" + +#include <prop/prop_array.h> +#include <prop/prop_bool.h> +#include <prop/prop_dictionary.h> +#include <prop/prop_object.h> +#include <sys/envsys.h> +#include <prop/proplib.h> +#include <paths.h> +#include <time.h> +#include <unistd.h> +#include <fcntl.h> + +const char* ffDetectBattery(FF_A_UNUSED FFBatteryOptions* options, FFlist* results) { + FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed"; + } + + prop_dictionary_t root = NULL; + if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) { + return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed"; + } + + 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); + } + } + + 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_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; + } + + 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); + } + } + + if (max > 0) { + FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results); + battery->temperature = FF_BATTERY_TEMP_UNSET; + battery->cycleCount = 0; + ffStrbufInit(&battery->manufacturer); + ffStrbufInit(&battery->modelName); + ffStrbufInit(&battery->technology); + ffStrbufInit(&battery->serial); + ffStrbufInit(&battery->manufactureDate); + battery->status = FF_BATTERY_STATUS_NONE; + battery->timeRemaining = -1; + + battery->capacity = (double) curr / (double) max * 100.; + if (charging) { + battery->status |= FF_BATTERY_STATUS_CHARGING; + } else if (dischargeRate) { + battery->status |= FF_BATTERY_STATUS_DISCHARGING; + battery->timeRemaining = (int32_t) ((double) curr / dischargeRate * 3600); + } + if (critical) { + battery->status |= FF_BATTERY_STATUS_CRITICAL; + } + if (acConnected) { + battery->status |= FF_BATTERY_STATUS_AC_CONNECTED; + } + } + + prop_object_iterator_release(iter); + } + prop_object_iterator_release(itKey); + prop_object_release(root); + + return NULL; +} |