diff 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 diff
--- a/rcctl.c	Thu Dec 16 20:30:11 2010 +0900
+++ b/rcctl.c	Fri Dec 24 15:28:04 2010 +0900
@@ -1,207 +1,229 @@
 /* rcctl.c ---------------------------------------------
-$Id: rcctl.c,v 1.1 2002/12/21 01:13:28 tosy Exp $
+   $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 の履歴も参照のこと】
-------------------------------------------------------*/
-
+   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 <sys/ioctl.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
 
-/* #define VERBOSE */
-/* #define NOCTSCHK */
+#include <linux/types.h>
+
+#define BITS_PER_LONG 32
 
-#ifndef SDEV
-#define SDEV "/dev/cuaa0"
+#include <asm/types.h>
+#include <errno.h>
+#include <string.h>
+
+
+#ifndef S_VERS
+#define S_VERS "0.41"
 #endif
 
-#ifndef UDEV
-#define UDEV "/dev/uhid0"
-#endif
+/* globals */
+HIDInterface *hidif;
+extern int errno;
 
-#ifndef S_VERS
-#define S_VERS "0.40"
-#endif
-
-int fd;
-
+/* prototypes */
 int cdcnv(int buf[], char *mak, char *cod);
 extern char *cverrstr[];
 
-int init_sio(void)
+int init_usb(void)
 {
-#ifndef NOCTSCHK
-  int tcnt = 0;
-#endif
-  struct termios tios;
-  int md;
+    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;
+    }
 
-  if ((fd = open(SDEV, O_RDWR)) == -1) {
-    fprintf(stderr, "Cannot open %s.\n", SDEV);
-    return 255;
-  }
+    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;
+    }
 
-  tcgetattr(fd, &tios);
-  tios.c_iflag = 0;
-  tios.c_oflag = 0;
-  tios.c_cflag = B9600|CS8|CLOCAL;
-  tios.c_lflag = 0;
-/*
-  cfmakeraw(&tios);
-  cfsetspeed(&tios, B9600);
-*/
-  tcsetattr(fd, TCSANOW, &tios);
-  tcflush(fd, TCOFLUSH);
+
+
+#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 */
 
-  md = TIOCM_LE|TIOCM_DTR|TIOCM_RTS;
-  ioctl(fd, TIOCMBIS, &md);
+    /* 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;
+    };
+
 
-  /* wait for CTS: 充電待ち */
-#ifndef NOCTSCHK
-  for(;;) {
-    ioctl(fd, TIOCMGET, &md);
-    if (md & TIOCM_CTS)
-      break;
-    if (tcnt == 0) {
-      fprintf(stderr, "Waiting....");
+// 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;
     }
-    if (tcnt++ >= 30) {
-      fprintf(stderr, "Device timeout.\n");
-      close(fd);
-      return 1;
+    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;
     }
-    sleep(1);
-  }
-#endif /* NOCTSCHK */
+
+    hid_delete_HIDInterface(&hidif);
 
-  md = TIOCM_RTS;
-  ioctl(fd, TIOCMBIC, &md);
-  usleep(10000);	/* 10ms */
-  ioctl(fd, TIOCMBIS, &md);
-  usleep(50000);	/* 50ms */
+    ret = hid_cleanup();
+    if (ret != HID_RET_SUCCESS) {
+        fprintf(stderr, "hid_cleanup failed with return code %d\n", ret);
+        return 1;
+    }
 
-  return 0;
+    return 0;
 }
 
-/* CTS が 0.5 秒以上連続して ON になるまで待つ */
-void charge(void)
-{
-#ifndef NOCTSCHK
-  int i, md;
 
-  for( i=0; i<50; i++ ) {
-    usleep(10000);	/* 10ms */
-    ioctl(fd, TIOCMGET, &md);
-    if (!(md & TIOCM_CTS))
-      i = 0;
-  }
-#endif /* NOCTSCHK */
-}
-
-int init_usb(void)
-{
-  report_desc_t rd;
-  hid_data_t hd;
-  hid_item_t shi;
-
-  hid_init(NULL);
-
-  if((fd = open(UDEV, O_RDWR)) < 0) {
-    fprintf(stderr, "Cannot open %s.\n", UDEV);
-    return 1;
-  }
-
-  /* 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 */
-  if (hid_report_size(rd, hid_output, 0) != 8) {
-    fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV);
-    return 1;
-  };
-
-  hid_dispose_report_desc(rd);
-
-  return 0;
-}
 
 int main(int ac, char *av[])
 {
-  int i, u, buf[16];
-  u_char sbuf[8];
+    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 (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;
-  }
+    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....");
+    printf("Initializing....\n");
 #endif
-  if (init_usb())
-  /* if (init_sio()) */
-    return 255;
+
+    if (init_usb())
+        return 255;
+
 #ifdef VERBOSE
-  printf(" done.\n");
+    printf(" done.\n");
 #endif
 
 #ifdef VERBOSE
-/*  printf("maker %d (%c).\n", maker, mks[maker]); */
-  for(i=0; i<u; i++ ) {
-    printf("%02x ", buf[i]);
-  }
-  printf("\n");
+    for(i=0; i<u; i++ ) {
+        printf("%02x ", buf[i]);
+    }
+    printf("\n");
 #endif
 
-  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))) {
-      write(fd, sbuf, 8);
+    /* 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(" --- got %d chars.\n", read(fd, sbuf, 8));
-#else
-      read(fd, sbuf, 8);
+        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
 
-  /* charge(); */
-  close(fd);
-  return 0;
+    if(fin_usb())
+        return 255;
+
+    return 0;
 }