aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCNLohr <lohr85@gmail.com>2017-03-15 00:14:37 -0400
committerCNLohr <lohr85@gmail.com>2017-03-15 00:14:37 -0400
commite15459cd9efab607e95f720bd971d0e73615f437 (patch)
tree15e04f94b93b743c40ed914588480e334b536c81 /src
parent99b615ba75f24e48b713e9b23ae596d7ddf1c59b (diff)
downloadlibsurvive-e15459cd9efab607e95f720bd971d0e73615f437.tar.gz
libsurvive-e15459cd9efab607e95f720bd971d0e73615f437.tar.bz2
Getting very close to a Windows port.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/survive.c7
-rwxr-xr-xsrc/survive_vive.c202
2 files changed, 187 insertions, 22 deletions
diff --git a/src/survive.c b/src/survive.c
index 0e567ad..1b5bed1 100755
--- a/src/survive.c
+++ b/src/survive.c
@@ -14,7 +14,6 @@
static int did_runtime_symnum;
int SymnumCheck( const char * path, const char * name, void * location, long size )
{
- printf( "--->%s\n", name );
if( strncmp( name, "REGISTER", 8 ) == 0 )
{
typedef void (*sf)();
@@ -41,7 +40,11 @@ static void survivenote( struct SurviveContext * ctx, const char * fault )
SurviveContext * survive_init( int headless )
{
#ifdef RUNTIME_SYMNUM
- EnumerateSymbols( SymnumCheck );
+ if( !did_runtime_symnum )
+ {
+ EnumerateSymbols( SymnumCheck );
+ did_runtime_symnum = 1;
+ }
#endif
int r = 0;
diff --git a/src/survive_vive.c b/src/survive_vive.c
index 0cae6f0..003dd5e 100755
--- a/src/survive_vive.c
+++ b/src/survive_vive.c
@@ -12,14 +12,24 @@
#include <survive.h>
#include <jsmn.h>
-#include <libusb-1.0/libusb.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
+
+#ifdef HIDAPI
+#include <os_generic.h>
+#if defined(WINDOWS) || defined(WIN32)
+#include <windows.h>
+#undef WCHAR_MAX
+#endif
+#include <hidapi.h>
+#else
+#include <libusb-1.0/libusb.h>
+#endif
+
struct SurviveViveData;
const short vidpids[] = {
@@ -60,12 +70,20 @@ typedef struct SurviveViveData SurviveViveData;
typedef void (*usb_callback)( SurviveUSBInterface * ti );
+#ifdef HIDAPI
+#define USBHANDLE hid_device *
+#else
+#define USBHANDLE libusb_device_handle *
+#endif
+
struct SurviveUSBInterface
{
SurviveViveData * sv;
SurviveContext * ctx;
+#ifndef HIDAPI
struct libusb_transfer * transfer;
+#endif
SurviveObject * assoc_obj;
int actual_len;
uint8_t buffer[INTBUFFSIZE];
@@ -78,14 +96,20 @@ struct SurviveViveData
{
SurviveContext * ctx;
- //XXX TODO: UN-STATICIFY THIS.
SurviveUSBInterface uiface[MAX_INTERFACES];
- //USB Subsystem
- struct libusb_context* usbctx;
- struct libusb_device_handle * udev[MAX_USB_DEVS];
+ USBHANDLE udev[MAX_USB_DEVS];
+#ifdef HIDAPI
+ og_thread_t servicethread[MAX_USB_DEVS];
+#else
+ struct libusb_context* usbctx;
+#endif
};
+#ifdef HIDAPI
+og_mutex_t GlobalRXUSBMutx;
+#endif
+
void survive_data_cb( SurviveUSBInterface * si );
//USB Subsystem
@@ -95,7 +119,25 @@ int survive_usb_poll( SurviveContext * ctx );
int survive_get_config( char ** config, SurviveViveData * ctx, int devno, int interface, int send_extra_magic );
int survive_vive_send_magic(struct SurviveContext * ctx, void * drv, int magic_code, void * data, int datalen );
+#ifdef HIDAPI
+void * HAPIReceiver( void * v )
+{
+ char buf[65];
+ int res;
+ SurviveUSBInterface * iface = v;
+ USBHANDLE * hp = &iface->sv->udev[iface->which_interface_am_i];
+ while( iface->actual_len = hid_read( *hp, iface->buffer, sizeof( iface->buffer ) ) > 0 )
+ {
+ OGLockMutex( GlobalRXUSBMutx );
+ survive_data_cb( iface );
+ OGUnlockMutex( GlobalRXUSBMutx );
+ }
+ //XXX TODO: Mark device as failed.
+ *hp = 0;
+ return 0;
+}
+#else
static void handle_transfer(struct libusb_transfer* transfer)
{
struct SurviveUSBInterface * iface = transfer->user_data;
@@ -117,10 +159,10 @@ static void handle_transfer(struct libusb_transfer* transfer)
SV_KILL();
}
}
+#endif
-
-static int AttachInterface( SurviveViveData * sv, SurviveObject * assocobj, int which_interface_am_i, libusb_device_handle * devh, int endpoint, usb_callback cb, const char * hname )
+static int AttachInterface( SurviveViveData * sv, SurviveObject * assocobj, int which_interface_am_i, USBHANDLE devh, int endpoint, usb_callback cb, const char * hname )
{
SurviveContext * ctx = sv->ctx;
SurviveUSBInterface * iface = &sv->uiface[which_interface_am_i];
@@ -129,8 +171,13 @@ static int AttachInterface( SurviveViveData * sv, SurviveObject * assocobj, int
iface->which_interface_am_i = which_interface_am_i;
iface->assoc_obj = assocobj;
iface->hname = hname;
- struct libusb_transfer * tx = iface->transfer = libusb_alloc_transfer(0);
iface->cb = cb;
+
+#ifdef HIDAPI
+ //What do here?
+ sv->servicethread[which_interface_am_i] = OGCreateThread( HAPIReceiver, iface );
+#else
+ struct libusb_transfer * tx = iface->transfer = libusb_alloc_transfer(0);
//printf( "%p %d %p %p\n", iface, which_interface_am_i, tx, devh );
if (!iface->transfer)
@@ -147,7 +194,7 @@ static int AttachInterface( SurviveViveData * sv, SurviveObject * assocobj, int
SV_ERROR( "Error: Could not submit transfer for %s (Code %d)", hname, rc );
return 6;
}
-
+#endif
return 0;
}
@@ -166,6 +213,31 @@ static void debug_cb( struct SurviveUSBInterface * si )
//XXX TODO: Redo this subsystem for setting/updating feature reports.
+
+#ifdef HIDAPI
+static inline int update_feature_report(USBHANDLE dev, uint16_t interface, uint8_t * data, int datalen )
+{
+ uint8_t rrb[65];
+ if( datalen > 64 ) datalen = 64;
+ memcpy( rrb+1, data, datalen );
+ rrb[0] = interface;
+ int r = hid_send_feature_report( dev, rrb, datalen+1 );
+ printf( "HUR: (%p) %d (%d) [%d]\n", dev, r, datalen, rrb[0] );
+ return r;
+}
+static inline int getupdate_feature_report(USBHANDLE dev, uint16_t interface, uint8_t * data, int datalen )
+{
+ uint8_t rrb[65];
+ if( datalen > 64 ) datalen = 64;
+ rrb[0] = interface;
+ int r = hid_get_feature_report( dev, rrb, datalen+1 );
+ printf( "HGR: (%p) %d (%d) (%d)\n", dev, r, datalen, rrb[0] );
+ memcpy( data, rrb+1, datalen );
+ return r;
+}
+
+#else
+
static inline int update_feature_report(libusb_device_handle* dev, uint16_t interface, uint8_t * data, int datalen ) {
// int xfer;
// int r = libusb_interrupt_transfer(dev, 0x01, data, datalen, &xfer, 1000);
@@ -186,9 +258,9 @@ static inline int getupdate_feature_report(libusb_device_handle* dev, uint16_t i
return ret;
}
+#endif
-
-static inline int hid_get_feature_report_timeout(libusb_device_handle* device, uint16_t interface, unsigned char *buf, size_t len )
+static inline int hid_get_feature_report_timeout(USBHANDLE device, uint16_t interface, unsigned char *buf, size_t len )
{
int ret;
uint8_t i = 0;
@@ -196,16 +268,74 @@ static inline int hid_get_feature_report_timeout(libusb_device_handle* device, u
{
ret = getupdate_feature_report(device, interface, buf, len);
if( ret != -9 && ( ret != -1 || errno != EPIPE ) ) return ret;
- usleep( 1000 );
+ OGUSleep( 1000 );
}
return -1;
}
-
int survive_usb_init( struct SurviveViveData * sv, struct SurviveObject * hmd, struct SurviveObject *wm0, struct SurviveObject * wm1, struct SurviveObject * tr0 )
{
struct SurviveContext * ctx = sv->ctx;
+#ifdef HIDAPI
+ int res, i;
+ res = hid_init();
+ if( res )
+ {
+ SV_ERROR( "Could not setup hidapi." );
+ return res;
+ }
+
+ for( i = 0; i < MAX_USB_DEVS; i++ )
+ {
+ int enumid = vidpids[i*3+2];
+ int vendor_id = vidpids[i*3+0];
+ int product_id = vidpids[i*3+1];
+ struct hid_device_info * devs = hid_enumerate(vendor_id, product_id);
+ struct hid_device_info * cur_dev = devs;
+ const char *path_to_open = NULL;
+ hid_device *handle = NULL;
+ int menum = 0;
+
+ cur_dev = devs;
+ while (cur_dev) {
+ if (cur_dev->vendor_id == vendor_id &&
+ cur_dev->product_id == product_id)
+ {
+ if( menum == enumid )
+ {
+ path_to_open = cur_dev->path;
+ break;
+ }
+ menum++;
+ }
+ cur_dev = cur_dev->next;
+ }
+
+ if (path_to_open) {
+ handle = hid_open_path(path_to_open);
+ }
+
+ hid_free_enumeration(devs);
+
+ if( !handle )
+ {
+ SV_INFO( "Warning: Could not find vive device %04x:%04x\n", vendor_id, product_id );
+ continue;
+ }
+
+ // Read the Serial Number String
+ wchar_t wstr[255];
+
+ res = hid_get_serial_number_string(handle, wstr, 255);
+ wprintf(L"Serial Number String: (%d) %s for %04x:%04x\n", wstr[0], wstr,vendor_id, product_id);
+
+ sv->udev[i] = handle;
+
+ }
+
+
+#else
int r = libusb_init( &sv->usbctx );
if( r )
{
@@ -294,7 +424,10 @@ int survive_usb_init( struct SurviveViveData * sv, struct SurviveObject * hmd, s
SV_INFO( "Successfully enumerated %s (%d, %d)", devnames[i], did, conf->bNumInterfaces );
}
+
libusb_free_device_list( devs, 1 );
+#endif
+
if( sv->udev[USB_DEV_HMD] && AttachInterface( sv, hmd, USB_IF_HMD, sv->udev[USB_DEV_HMD], 0x81, survive_data_cb, "Mainboard" ) ) { return -6; }
if( sv->udev[USB_DEV_LIGHTHOUSE] && AttachInterface( sv, hmd, USB_IF_LIGHTHOUSE, sv->udev[USB_DEV_LIGHTHOUSE], 0x81, survive_data_cb, "Lighthouse" ) ) { return -7; }
@@ -362,7 +495,7 @@ int survive_vive_send_magic(struct SurviveContext * ctx, void * drv, int magic_c
r = update_feature_report( sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof( vive_controller_haptic_pulse ) );
SV_INFO( "UCR: %d", r );
if( r != sizeof( vive_controller_haptic_pulse ) ) return 5;
- usleep( 1000 );
+ OGUSleep( 1000 );
}
#endif
SV_INFO( "Powered unit on." );
@@ -403,15 +536,35 @@ int survive_vive_send_magic(struct SurviveContext * ctx, void * drv, int magic_c
void survive_vive_usb_close( struct SurviveViveData * sv )
{
int i;
+#ifdef HIDAPI
+ for( i = 0; i < MAX_USB_DEVS; i++ )
+ {
+ if( sv->udev[i] )
+ hid_close( sv->udev[i] );
+ }
+ for( i = 0; i < MAX_USB_DEVS; i++ )
+ {
+ OGJoinThread( sv->servicethread[i] );
+ }
+ //This is global, don't do it on account of other tasks.
+ //hid_exit();
+
+#else
for( i = 0; i < MAX_USB_DEVS; i++ )
{
libusb_close( sv->udev[i] );
}
libusb_exit(sv->usbctx);
+#endif
}
int survive_vive_usb_poll( struct SurviveContext * ctx, void * v )
{
+#ifdef HIDAPI
+ OGUnlockMutex( GlobalRXUSBMutx );
+ OGUSleep( 100 );
+ OGUnlockMutex( GlobalRXUSBMutx );
+#else
struct SurviveViveData * sv = v;
int r = libusb_handle_events( sv->usbctx );
if( r )
@@ -420,6 +573,7 @@ int survive_vive_usb_poll( struct SurviveContext * ctx, void * v )
SV_ERROR( "Libusb poll failed." );
}
return r;
+#endif
}
@@ -430,7 +584,7 @@ int survive_get_config( char ** config, struct SurviveViveData * sv, int devno,
uint8_t cfgbuff[64];
uint8_t compressed_data[8192];
uint8_t uncompressed_data[65536];
- struct libusb_device_handle * dev = sv->udev[devno];
+ USBHANDLE dev = sv->udev[devno];
if( send_extra_magic )
{
@@ -439,10 +593,14 @@ int survive_get_config( char ** config, struct SurviveViveData * sv, int devno,
memset( cfgbuffwide, 0, sizeof( cfgbuff ) );
cfgbuffwide[0] = 0x01;
ret = hid_get_feature_report_timeout( dev, iface, cfgbuffwide, sizeof( cfgbuffwide ) );
- usleep(1000);
+ OGUSleep(1000);
int k;
+ #ifdef HIDAPI
+ //XXX TODO WRITEME
+ SV_INFO( "XXX TODO WRITEME" );
+ #else
//Switch mode to pull config?
for( k = 0; k < 10; k++ )
{
@@ -459,12 +617,13 @@ int survive_get_config( char ** config, struct SurviveViveData * sv, int devno,
int rk = libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_OUT,
0x09, 0x300 | cfgbuff_send[0], iface, cfgbuff_send, 64, 1000 );
- usleep(1000);
+ OGUSleep(1000);
}
+ #endif
cfgbuffwide[0] = 0xff;
ret = hid_get_feature_report_timeout( dev, iface, cfgbuffwide, sizeof( cfgbuffwide ) );
- usleep(1000);
+ OGUSleep(1000);
}
memset( cfgbuff, 0, sizeof( cfgbuff ) );
@@ -1022,8 +1181,11 @@ static int LoadConfig( SurviveViveData * sv, SurviveObject * so, int devno, int
}
char fname[20];
+#ifdef WINDOWS
+ mkdir( "calinfo" );
+#else
mkdir( "calinfo", 0755 );
-
+#endif
sprintf( fname, "calinfo/%s_points.csv", so->codename );
FILE * f = fopen( fname, "w" );
int j;