Question

According to https://github.com/signal11/hidapi/issues/72 HIDAPI ought to be thread safe on Linux machines. However, I can't get it working at all. This is what I do:

#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>

#include "hidapi.h"
hid_device *handle;

static void *TaskCode(void *argument)
{
    int res;
    //hid_device *handle;
    unsigned char buf[64];

//     res = hid_init();
//     if( res == -1 )
//     {
//         return (void*)1;
//     }
//
//     handle = hid_open(0x0911, 0x251c, NULL);
//     if( handle == NULL )
//     {
//         return (void*)2;
//     }

    printf( "while 2\n");

    while( 1 )
    {
        memset( buf, 64, 0 );
        res = hid_read(handle, buf, 0);
        if( res == -1 )
        {
            return (void*)3;
        }

        printf( "received %d bytes\n", res);

        for (int i = 0; i < res; i++)
            printf("Byte %d: %02x ", i+1, buf[i]);
        //printf( "%02x ", buf[0]);
        fflush(stdout);
    }

    return (void*)0;
}


int main(int argc, char* argv[])
{
    int res;
    //hid_device *handle;
    unsigned char buf[65];

    res = hid_init();
    if( res == -1 )
    {
        return 1;
    }

    handle = hid_open(0x0911, 0x251c, NULL);
    if( handle == NULL )
    {
        return 2;
    }

    hid_set_nonblocking( handle, 0 );

    pthread_t thread;
    int rc = pthread_create(&thread, NULL, TaskCode, NULL);

    printf( "while 1\n");

    while(1)
    {
        int a = getchar();
        if( a == 'a')
        {
            // Get Device Type (cmd 0x82). The first byte is the report number (0x0).
            buf[0] = 0x0;
            buf[1] = 0x82;
            res = hid_write(handle, buf, 65);
            if( res != -1 )
                printf( "write ok, transferred %d bytes\n", res );
            else
            {
                printf( "write error\n" );
                char* str = hid_error(handle);
                printf( "error: %s\n", str );
                return 1;
            }
        }
        else if( a== 'b')
            break;
    }

    void* trc;
    rc = pthread_join(thread, &trc);

    printf( "rc code: %d\n", (int)trc );

    // Finalize the hidapi library
    res = hid_exit();

    return 0;
}

If I don't use the global handle, I get 'write error' every time. If I do, as in the example, formally everything works but hid_read always returns 0 bytes... Of course, if I do simple hid_write() followed by hid_read(), I'll get the correct reply to the command 0x82 as intended. I'm really lost here, am I overlooking something?

EDIT: to clarify, zero bytes return also for everything, incl. buttons on mouse etc. So it seems to work but the data buffer is always zero bytes.

Was it helpful?

Solution

Shame on me, a dumb mistake. The code should be:

memset( buf, 0, 64 );
res = hid_read(handle, buf, 64);

and then it works. Should sleep more and write less!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top