view rcctl.c @ 1:05cc06e88a57

modified to make use of libhid to access the device
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Fri, 24 Dec 2010 15:28:04 +0900
parents e1a1a181c0d7
children b16b82dbfe87
line wrap: on
line source

/* rcctl.c ---------------------------------------------
   $Id: rcctl.c,v 1.1 2002/12/21 01:13:28 tosy Exp $

   v0.10  97.08.15  初期版(コミケット52)
   v0.11  97.08.27  通信タイミング修正
   v0.12  97.09.12  U-kara-2サポート
   v0.12a 97.09.15  返り値設定
   v0.12b 97.09.20  Bug fix (JOY:[SP])
   v0.20  97.10.01  FreeBSD版
   v0.20a 97.10.18  Bug fix (X2k:[SP],[ST])
   v0.21  97.12.10  ALISA-3シーケンス修正
   v0.30  97.12.13  コード変換部(cdcnv.c)分離
   v0.40  02.12.16  USB版対応
   【cdcnv.c の履歴も参照のこと】
   ------------------------------------------------------*/
#define __LINUX__
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define HID_MAX_USAGES 16
typedef unsigned int __u32;
typedef unsigned int kernel_ulong_t;

#include <hid.h>
#include <libusb.h>

#include <linux/types.h>

#define BITS_PER_LONG 32

#include <asm/types.h>
#include <errno.h>
#include <string.h>


#ifndef S_VERS
#define S_VERS "0.41"
#endif

/* globals */
HIDInterface *hidif;
extern int errno;

/* prototypes */
int cdcnv(int buf[], char *mak, char *cod);
extern char *cverrstr[];

int init_usb(void)
{
    hid_return ret;

//    unsigned int report_id;
//    unsigned int report_type;
//    unsigned int size;

    /* vendor id and product id of okecon */
    HIDInterfaceMatcher matcher = { 0x0bfe, 0x2022, NULL, NULL, 0 };

    /* see include/debug.h for possible values */
    hid_set_debug(HID_DEBUG_ALL);
    hid_set_debug_stream(stderr);
    /* passed directly to libusb */
    hid_set_usb_debug(0);

    ret = hid_init();
    if (ret != HID_RET_SUCCESS) {
        fprintf(stderr, "hid_init failed with return code %d\n", ret);
        return 1;
    }

    hidif = hid_new_HIDInterface();
    if (hidif == 0) {
        fprintf(stderr, "hid_new_HIDInterface() failed, out of memory?\n");
        return 1;
    }

    ret = hid_force_open(hidif, 0, &matcher, 3);
    if (ret != HID_RET_SUCCESS) {
        fprintf(stderr, "hid_force_open failed with return code %d\n", ret);
        return 1;
    }



#if 0
    /* read feature */
    ret = hid_get_feature_report(hidif, path, depth, buffer, size);
    if(ret != HID_RET_SUCCESS) {
        fprintf(stderr, "hid_get_feature_report failed with return code %d\n", ret);
        return 1;
    }

    /* parse */

    /* prepare buffers */
    hid_get_report_size(hidif, report_id, report_type, &size);
    if(size != 8) {
        fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV);
        return 1;
    };


// BSD
    /* read header */
    if ((rd = hid_get_report_desc(fd)) == 0) {
        fprintf(stderr, "Failed on USB_GET_REPORT_DESC.\n");
        return 1;
    }

    /* parse */
    hd = hid_start_parse(rd, 1<<hid_output);
    while ( hid_get_item(hd, &shi) ) {
        if(shi.kind == hid_output)
            break;
    }
    hid_end_parse(hd);

    /* prepare buffers */
    hid_get_report_size(&hidif, report_id, report_type, &size);
    if(size != 8) {
        fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV);
        return 1;
    };

    hid_dispose_report_desc(rd);
#endif

    return 0;
} /* end of init_usb() */


int fin_usb()
{
    hid_return ret;

    ret = hid_close(hidif);
    if (ret != HID_RET_SUCCESS) {
        fprintf(stderr, "hid_close failed with return code %d\n", ret);
        return 1;
    }

    hid_delete_HIDInterface(&hidif);

    ret = hid_cleanup();
    if (ret != HID_RET_SUCCESS) {
        fprintf(stderr, "hid_cleanup failed with return code %d\n", ret);
        return 1;
    }

    return 0;
}



int main(int ac, char *av[])
{
    int i, u, buf[16];
    unsigned char sbuf[8];
    hid_return ret;

    if (ac < 3) {
        printf("'Oke-Con' controller, version " S_VERS ".\n");
        printf("Copyright (C) 1997-2002 by Tosy / W341IG.\n");
        printf("Usage: rcctl <maker> <code>\n");
        return 255;
    }

    if ((u = cdcnv(buf, av[1], av[2])) < 0) {
        fprintf(stderr, "%s: %s\n", av[0], cverrstr[~u]);
        return 1;
    }
    printf("cdcnv %d\n", u);

#ifdef VERBOSE
    printf("Initializing....\n");
#endif

    if (init_usb())
        return 255;

#ifdef VERBOSE
    printf(" done.\n");
#endif

#ifdef VERBOSE
    for(i=0; i<u; i++ ) {
        printf("%02x ", buf[i]);
    }
    printf("\n");
#endif

    /* xxx */
	const int PATH_IN[1] = { 0xffa10004 };
//    const int PATH_OUT[1] = { 0xffa10008 };

    /* u is the total length of the packet to send */
    for(i=1; i<u; i++ ) {
        sbuf[(i-1)%8] = buf[i] & 0x00ff;
#ifdef VERBOSE
        printf("%02x ", sbuf[(i-1)%8]);
#endif
        if ((i == 8)||(i == (u-1))) {
            ret = hid_set_output_report(hidif, PATH_IN, 2, (char *)sbuf, 8);
            fprintf(stderr, "**WRITE**\n");
            if (ret != HID_RET_SUCCESS) {
                fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret);
            }

#if 0
            char packet[8];
            ret = hid_get_input_report(hidif, PATH_OUT, 2, packet, 8);
            if (ret != HID_RET_SUCCESS) {
                fprintf(stderr, "hid_get_input_report failed with return code %d\n", ret);
            }
#endif
        }
    }
#ifdef VERBOSE
    printf("\n");
#endif

    if(fin_usb())
        return 255;

    return 0;
}