/****************************************************************
 * This is a reverse engineered version of tjapi.o from         *
 * http://www.tjnet.com/software/ip_phone/hardwaresdk.htm#linux *
 * It produces the same assembler and bytecode when compiled    *
 * on Fedora Core 3 (That is the distribution Tigerjet used).   *
 * I created this to compile the driver on x86_64 gnu/linux.    *
 ****************************************************************/

#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include "hiddev.h"

#define TIGERJET_VENDOR_ID 0x06E6
#define UCHAR unsigned char

int delay = 5;

int WriteTjRegs(int hid_fd, int *err, UCHAR uRegAdd, UCHAR *pData, UCHAR uLen) {
    struct hiddev_report_info report_info;
    char unused[32];
    struct hiddev_usage_ref_multi uref_multi;
    int ret = 0;
    int i = 0;

    memset(&report_info, 0, sizeof(struct hiddev_report_info));
    memset(&uref_multi, 0, sizeof(struct hiddev_usage_ref_multi));

    report_info.report_type = 3;
    report_info.report_id = 256;

    uref_multi.uref.report_type = 3;
    uref_multi.uref.report_id = 256;
    uref_multi.uref.field_index = 0;
    uref_multi.uref.usage_index = 0;
    uref_multi.num_values = 4 + uLen;

    uref_multi.values[0] = 2;
    uref_multi.values[1] = uRegAdd;
    uref_multi.values[2] = 0;
    uref_multi.values[3] = uLen;

    for(i=4;i<uLen+4;i++){
        uref_multi.values[i] = pData[i-4];
    };

    ioctl(hid_fd, HIDIOCSUSAGES, &uref_multi);

    ret = ioctl(hid_fd, HIDIOCSREPORT, &report_info);

    if (ret != 0){
        memcpy(err, &errno, sizeof(int));
        return -1;
    }

    usleep(delay);

    return 0;
}


int ReadTjRegs(int hid_fd, int *err, UCHAR uRegAdd, UCHAR *pData, UCHAR uLen){
    struct hiddev_report_info report_info;
    char unused[32];
    struct hiddev_usage_ref_multi uref_multi;
    int ret = 0;
    int i = 0;

    memset(err, 0, sizeof(int));
    memset(&report_info, 0, sizeof(struct hiddev_report_info));
    memset(&uref_multi, 0, sizeof(struct hiddev_usage_ref_multi));

    report_info.report_type = 3;
    report_info.report_id = 256;

    uref_multi.uref.report_type = 3;
    uref_multi.uref.report_id = 256;
    uref_multi.uref.field_index = 0;
    uref_multi.uref.usage_index = 0;
    uref_multi.num_values = 4;

    uref_multi.values[0] = 2;
    uref_multi.values[2] = uRegAdd;
    uref_multi.values[3] = 0;

    ioctl(hid_fd, HIDIOCSUSAGES, &uref_multi);

    ret = ioctl(hid_fd, HIDIOCSREPORT, &report_info);
    if (ret != 0){
        memcpy(err, &errno, sizeof(int));
        return -1;
    }

    usleep(delay);

    ret = ioctl(hid_fd, HIDIOCGREPORT, &report_info);
    if (ret != 0){
        memcpy(err, &errno, sizeof(int));
        return -1;
    }

    if (uLen > 28) uLen = 28;

    uref_multi.num_values = uLen; 

    /* BUG: Have they forgotten to assign ret?? */
    ioctl(hid_fd, HIDIOCGUSAGES, &uref_multi);
    if (ret != 0){
        memcpy(err, &errno, sizeof(int));
        return -1;
    }

    for(i=0; i<uLen; i++){
	pData[i] = uref_multi.values[i];
    }
    return 0;
}

int IsTjDevice(int hid_fd, int *err, int *pid) {
    struct hiddev_devinfo devinfo;
    int ret = 0;

    memset(err, 0, sizeof(int));
    memset(&devinfo, 0, sizeof(devinfo));

    ret = ioctl(hid_fd, HIDIOCGDEVINFO, &devinfo);
    if(ret != 0) {
        memcpy(err, &errno, sizeof(int));
        return -1;
    }
    if(devinfo.vendor == TIGERJET_VENDOR_ID) {
        memcpy(pid, &devinfo.product, sizeof(devinfo.product));
        return 0;
    }
    /* This seems to be another error in the original code:
     * the documentation tells us 0x1234 will be returned */
    return 1234;
}
© 2011 Môshe van der Sterre