Dostęp do urządzenia HID – przeniesienie kodu do Qt

0

Witam,
W projekcie który robię chciałem wykorzystać czytnik kart NFC. Czytnik którego używam w systemie operacyjnym zgłasza się jako urządzenie HID. Chciałbym mieć dostęp do tego urządzenia "na wyłączność".

Znalazłem i uruchomiłem przykładowy kod w C++, który działa zgodnie z moimi założeniami.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>

int main(int argc, char* argv[])
{
    struct input_event ev[64];
    int fevdev = -1;
    int result = 0;
    int size = sizeof(struct input_event);
    int rd;
    int value;
    char name[256] = "Unknown";
    char *device = "/dev/input/event3";


    fevdev = open(device, O_RDONLY);
    if (fevdev == -1) {
        printf("Failed to open event device.\n");
        exit(1);
    }

    result = ioctl(fevdev, EVIOCGNAME(sizeof(name)), name);
    printf ("Reading From : %s (%s)\n", device, name);

    printf("Getting exclusive access: ");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");

    while (1)
    {
        if ((rd = read(fevdev, ev, size * 64)) < size) {
            break;
        }

        value = ev[0].value;

        if (value != ' ' && ev[1].value == 1 && ev[1].type == 1) {
            printf ("Code[%d]\n", (ev[1].code));
        }
    }

    printf("Exiting.\n");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    close(fevdev);
    return 0;
}

Mam jednak problem z przeniesieniem tego kody do Qt. Po wprowadzeniu odpowiednich modyfikacji nadal mam błędy przy kompilacji. Dotyczą one definicji struktury:

struct input_event ev[64];
input_event have incomplete type
storage size of 'ev' isn't know

oraz metody dostępu do pliku urządzenia:

result = ioctl(fevdev, EVIOCGNAME(sizeof(name)), name);
printf ("Reading From : %s (%s)\n", device, name);

printf("Getting exclusive access: ");
result = ioctl(fevdev, EVIOCGRAB, 1);
EVIOCGNAME is not declared in this scope
EVIOCGRAB is not decalred in this scope

Nie moge sobie z tym poradzić. Może ktoś podpowie, naprowadzi...?

0

Brzmi jak byś nie dodał nagłówków.

0

kod wyjściowy ma undefined behavior, jeśli ilość przeczytanych danych jest równa size.
Podawanie w pytaniu kodu innego niż tego, którego bezpośrednio dotyczy problem, to jakiś absurd, szczególnie gdy problemem jest błąd kompilacji!
W oczywisty sposób zapomniałeś przekopiować wszystkie wymagane pliki nagłówkowe.

1

To powinno wyglądać tak (mniej więcej).
Nie testowałem, więc może nie działać.

#include<QObject>
#include<QString>

QT_FORWARD_DECLARE_CLASS(QFile);

class NFCEventReader : QObject {
    Q_OBJECT
public:
    ~NFCEventReader();
    explicit NFCEventReader(QObject *parent);
    explicit NFCEventReader(const QString fileName, QObject *parent);

    bool open(const QString fileName);
    void close();

public signals:
   void opened();
   void closed();
   void eventReceived(const NFCEvent& event);

private:
    void connectFile();
public slots:
    void handleReadyRead();

private:
    QFile *mFile;
    int mFd = -1;
};
#include<QFile>

#include <sys/ioctl.h>
#include <sys/stat.h> 
#include <linux/input.h>

NFCEventReader::~NFCEventReader()
{
    if (mFd != -1) {
         close();
    }
}

NFCEventReader::NFCEventReader(QObject *parent = nullptr)
    : QObject(parent)
    , mFile(new QFile(this))
{
    connectFile();
}

NFCEventReader::NFCEventReader(const QString fileName, QObject *parent = nullptr)
    : QObject(parent)
    , mFile(new QFile(this))
{
    connectFile();
    open(fileName);
}

NFCEventReader::connectFile()
{
    connect(mFile, &QIODevice::readyRead,
            this, &NFCEventReader::readyRead)
}

bool NFCEventReader::open(const QString fileName)
{
    mFd = ::open(fileName.toLocal8Bit().data(), O_RDONLY);
    if (mFd == -1) {
         qWarning() << "Failed to open event device:" << fileName;
         return false;
    }
    static const char name[256] = "Unknown";
    int result = ioctl(mFd, EVIOCGNAME(sizeof(name)), name);
    qDebug() << "Reading From: " << fileName << "(" << name << ")";
 
    qDebug("Getting exclusive access: ");
    result = ioctl(mFd, EVIOCGRAB, 1);
    qDebug("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");

    bool returnValue =  mFile->open(mFd, QIODevice::ReadOnly);
    if (returnValue) {
         emit opened();
    } else {
         close();
    }
    return returnValue;
}

void NFCEventReader::close()
{
     if (mFd == -1) {
          qWarning() << "File descriptor not opened";
          return;
     }
     int result = ioctl(fevdev, EVIOCGRAB, 1);
     qDebug() << "Closing: " << result;
     mFile->close();
     ::close(mFd);
     mFd = -1;
     emit closed();
}

void NFCEventReader::handleReadyRead()
{
    while (mFile->bytesAvailable() >= sizeof(struct input_event)) {
          struct input_event data;
          mFile->read((char *)&data, sizeof(struct input_event));
          NFCEvent event = convertFromInputEvent(data); // convertFromInputEvent napisz sam
          emit eventReceived(event);
    }
}
0

Bardzo dziękuję za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1