ioctl for HID Power devices (UPS) always returning 0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

For quite some time, upower is not properly displaying the information from my Eaton UPS, looking at this it seems that the kernel is not returning the correct information.

I've attached a test program (that is heavily inspired by apcupsd hid-ups example) that displays:

UPS HID device name: "EATON Ellipse ECO"
Battery Chemistry: "" (0)
Battery Capacity: (null)

As you can see, the values are set to 0.

Any idea what's wrong here?

Kind regards,

Laurent Bigonville

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

#include <errno.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/ioctl.h>
#include <linux/hiddev.h>

#define BAT_CHEMISTRY           0x850089
#define UPS_CAPACITY_MODE       0x85002c

static const char *get_string(int fd, int sindex) {
    static struct hiddev_string_descriptor sdesc;
    static char buf[200];

    if (sindex == 0) {
       return "";
    }
    sdesc.index = sindex;
    if (ioctl(fd, HIDIOCGSTRING, &sdesc) < 0) {
        sprintf(buf, "String index %d returned ERR=%s\n", sindex,
            strerror(errno));
        return buf;
    }
    return sdesc.value;
}

int main(void) {
    int fd;
    char name[256] = "Unknown";
    struct hiddev_usage_ref uref;

    if ((fd = open("/dev/usb/hiddev4", O_RDONLY)) < 0) {
        perror("open");
        exit(1);
    }

    ioctl(fd, HIDIOCINITREPORT, 0);
    ioctl(fd, HIDIOCGNAME(sizeof(name)), name);
    printf("UPS HID device name: \"%s\"\n", name);

    memset(&uref, 0, sizeof(uref));
    uref.report_type = HID_REPORT_TYPE_FEATURE;
    uref.report_id = HID_REPORT_ID_UNKNOWN;
    uref.usage_code = BAT_CHEMISTRY;
    if (ioctl(fd, HIDIOCGUSAGE, &uref) == 0) {
        printf("Battery Chemistry: \"%s\" (%d)\n", get_string(fd, uref.value),
            uref.value);
    }

    memset(&uref, 0, sizeof(uref));
    uref.report_type = HID_REPORT_TYPE_FEATURE;
    uref.report_id = HID_REPORT_ID_UNKNOWN;
    uref.usage_code = UPS_CAPACITY_MODE;
    if (ioctl(fd, HIDIOCGUSAGE, &uref) == 0) {
        printf("Battery Capacity: %s\n", uref.value);
    }

    close(fd);
    return 0;
}

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux