summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ao-tools/libaltos/Makefile53
-rw-r--r--ao-tools/libaltos/cjnitest.c21
-rw-r--r--ao-tools/libaltos/libaltos.c501
-rw-r--r--ao-tools/libaltos/libaltos.h68
4 files changed, 383 insertions, 260 deletions
diff --git a/ao-tools/libaltos/Makefile b/ao-tools/libaltos/Makefile
index fa5127eb..a251e54e 100644
--- a/ao-tools/libaltos/Makefile
+++ b/ao-tools/libaltos/Makefile
@@ -1,27 +1,56 @@
OS:=$(shell uname)
+#
+# Linux
+#
ifeq ($(OS),Linux)
JAVA_CFLAGS=-I/usr/lib/jvm/java-6-openjdk/include
OS_CFLAGS=-DLINUX -DPOSIX_TTY $(JAVA_CFLAGS)
-LIBEXT=so
+OS_LDFLAGS=
+
+LIBNAME=libaltos.so
+EXEEXT=
endif
+#
+# Darwin (Mac OS X)
+#
ifeq ($(OS),Darwin)
-DARWIN_CFLAGS=\
+OS_CFLAGS=\
+ -DDARWIN -DPOSIX_TTY -arch i386 -arch x86_64 \
--sysroot=/Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 \
-iwithsysroot /System/Library/Frameworks/JavaVM.framework/Headers \
-iwithsysroot /System/Library/Frameworks/IOKit.framework/Headers \
-iwithsysroot /System/Library/Frameworks/CoreFoundation.framework/Headers
-DARWIN_LIBS=\
+
+OS_LDFLAGS =\
-framework IOKit -framework CoreFoundation
-OS_CFLAGS = $(DARWIN_CFLAGS) -DDARWIN -DPOSIX_TTY -arch i386 -arch x86_64
-LIBEXT=dylib
+LIBNAME=libaltos.dylib
+EXEEXT=
+
+endif
+
+#
+# Windows
+#
+ifneq (,$(findstring MINGW,$(OS)))
+
+CC=gcc
+
+OS_CFLAGS = -DWINDOWS -mconsole
+
+OS_LDFLAGS = -lgdi32 -luser32 -lcfgmgr32 -lsetupapi -lole32 \
+ -ladvapi32 -lcomctl32 -mconsole -Wl,--add-stdcall-alias
+
+LIBNAME=altos.dll
+
+EXEEXT=.exe
endif
@@ -48,26 +77,30 @@ CLASSFILES = $(JAVAFILES:%.java=%.class)
JAVAFLAGS=-Xlint:unchecked
-all: libaltos.$(LIBEXT) cjnitest $(CLASSFILES)
+CJNITEST=cjnitest$(EXEEXT)
+
+all: $(LIBNAME) $(CJNITEST) $(CLASSFILES)
.java.class:
javac -encoding UTF8 -classpath "$(CLASSPATH)" $(JAVAFLAGS) $*.java
CFLAGS=$(OS_CFLAGS) -O0 -g -I.
+LDFLAGS=$(OS_LDFLAGS)
+
HEADERS=libaltos.h
SRCS = libaltos.c $(SWIG_WRAP)
OBJS = $(SRCS:%.c=%.o)
LIBS = $(DARWIN_LIBS)
-cjnitest: cjnitest.o $(OBJS)
+$(CJNITEST): cjnitest.o $(OBJS)
cc -o $@ $(CFLAGS) cjnitest.o $(OBJS) $(LIBS)
-libaltos.$(LIBEXT): $(OBJS)
- gcc -shared $(CFLAGS) -o $@ $(OBJS) $(LIBS)
+$(LIBNAME): $(OBJS)
+ gcc -shared $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
clean:
- rm -f $(CLASSFILES) $(OBJS) libaltos.$(LIBEXT) cjnitest cjnitest.o
+ rm -f $(CLASSFILES) $(OBJS) $(LIBNAME) $(CJNITEST) cjnitest.o
rm -rf swig_bindings libaltosJNI
$(JNI_FILE): libaltos.i0 $(HEADERS)
diff --git a/ao-tools/libaltos/cjnitest.c b/ao-tools/libaltos/cjnitest.c
index cd3898ed..93d1f376 100644
--- a/ao-tools/libaltos/cjnitest.c
+++ b/ao-tools/libaltos/cjnitest.c
@@ -1,6 +1,15 @@
#include <stdio.h>
#include "libaltos.h"
+static void
+altos_puts(struct altos_file *file, char *string)
+{
+ char c;
+
+ while ((c = *string++))
+ altos_putchar(file, c);
+}
+
main ()
{
struct altos_device device;
@@ -12,12 +21,20 @@ main ()
struct altos_file *file;
int c;
+ printf ("%04x:%04x %-20s %4d %s\n", device.vendor, device.product,
+ device.name, device.serial, device.path);
+
file = altos_open(&device);
- altos_putchar(file, '?'); altos_putchar(file, '\n'); altos_flush(file);
+ if (!file) {
+ printf("altos_open failed\n");
+ continue;
+ }
+ altos_puts(file,"v\nc s\n");
while ((c = altos_getchar(file, 100)) >= 0) {
putchar (c);
}
- printf ("getchar returns %d\n", c);
+ if (c != LIBALTOS_TIMEOUT)
+ printf ("getchar returns %d\n", c);
altos_close(file);
}
altos_list_finish(list);
diff --git a/ao-tools/libaltos/libaltos.c b/ao-tools/libaltos/libaltos.c
index 00fb2125..3e8485e4 100644
--- a/ao-tools/libaltos/libaltos.c
+++ b/ao-tools/libaltos/libaltos.c
@@ -15,29 +15,21 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
+#define BUILD_DLL
#include "libaltos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-static int
-match_dev(char *product, int serial, struct altos_device *device)
+PUBLIC int
+altos_init(void)
{
- struct altos_list *list;
- int i;
+ return LIBALTOS_SUCCESS;
+}
- list = altos_list_start();
- if (!list)
- return 0;
- while ((i = altos_list_next(list, device)) != 0) {
- if (product && strncmp (product, device->product, strlen(product)) != 0)
- continue;
- if (serial && serial != device->serial)
- continue;
- break;
- }
- altos_list_finish(list);
- return i;
+PUBLIC void
+altos_fini(void)
+{
}
#ifdef DARWIN
@@ -60,48 +52,9 @@ altos_strndup (const char *s, size_t n)
#define altos_strndup strndup
#endif
-int
-altos_find_by_arg(char *arg, char *default_product, struct altos_device *device)
-{
- char *product;
- int serial;
- char *end;
- char *colon;
- int ret;
-
- if (arg)
- {
- /* check for <serial> */
- serial = strtol(arg, &end, 0);
- if (end != arg) {
- if (*end != '\0')
- return 0;
- product = NULL;
- } else {
- /* check for <product>:<serial> */
- colon = strchr(arg, ':');
- if (colon) {
- product = altos_strndup(arg, colon - arg);
- serial = strtol(colon + 1, &end, 0);
- if (*end != '\0')
- return 0;
- } else {
- product = arg;
- serial = 0;
- }
- }
- } else {
- product = NULL;
- serial = 0;
- }
- if (!product && default_product)
- ret = match_dev(default_product, serial, device);
- if (!ret)
- ret = match_dev(product, serial, device);
- if (product && product != arg)
- free(product);
- return ret;
-}
+/*
+ * Scan for Altus Metrum devices by looking through /sys
+ */
#ifdef LINUX
@@ -216,7 +169,7 @@ struct altos_usbdev {
char *sys;
char *tty;
char *manufacturer;
- char *product;
+ char *product_name;
int serial; /* AltOS always uses simple integer serial numbers */
int idProduct;
int idVendor;
@@ -286,7 +239,7 @@ usb_scan_device(char *sys)
return NULL;
usbdev->sys = strdup(sys);
usbdev->manufacturer = load_string(sys, "manufacturer");
- usbdev->product = load_string(sys, "product");
+ usbdev->product_name = load_string(sys, "product");
usbdev->serial = load_dec(sys, "serial");
usbdev->idProduct = load_hex(sys, "idProduct");
usbdev->idVendor = load_hex(sys, "idVendor");
@@ -299,7 +252,7 @@ usbdev_free(struct altos_usbdev *usbdev)
{
free(usbdev->sys);
free(usbdev->manufacturer);
- free(usbdev->product);
+ free(usbdev->product_name);
/* this can get used as a return value */
if (usbdev->tty)
free(usbdev->tty);
@@ -332,17 +285,6 @@ struct altos_list {
int ndev;
};
-int
-altos_init(void)
-{
- return 1;
-}
-
-void
-altos_fini(void)
-{
-}
-
struct altos_list *
altos_list_start(void)
{
@@ -366,7 +308,7 @@ altos_list_start(void)
dir = cc_fullname(USB_DEVICES, ents[e]->d_name);
dev = usb_scan_device(dir);
free(dir);
- if (dev->idVendor == 0xfffe && dev->tty) {
+ if (USB_IS_ALTUSMETRUM(dev->idVendor, dev->idProduct)) {
if (devs->dev)
devs->dev = realloc(devs->dev,
devs->ndev + 1 * sizeof (struct usbdev *));
@@ -387,7 +329,9 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
if (list->current >= list->ndev)
return 0;
dev = list->dev[list->current];
- strcpy(device->product, dev->product);
+ strcpy(device->name, dev->product_name);
+ device->vendor = dev->idVendor;
+ device->product = dev->idProduct;
strcpy(device->path, dev->tty);
device->serial = dev->serial;
list->current++;
@@ -447,17 +391,6 @@ get_string(io_object_t object, CFStringRef entry, char *result, int result_len)
return 0;
}
-int
-altos_init(void)
-{
- return 1;
-}
-
-void
-altos_fini(void)
-{
-}
-
struct altos_list *
altos_list_start(void)
{
@@ -566,15 +499,16 @@ altos_open(struct altos_device *device)
void
altos_close(struct altos_file *file)
{
- close(file->fd);
- file->fd = -1;
+ if (file->fd != -1) {
+ close(file->fd);
+ file->fd = -1;
+ }
}
void
altos_free(struct altos_file *file)
{
- if (file->fd != -1)
- close(file->fd);
+ altos_close(file);
free(file);
}
@@ -613,6 +547,8 @@ altos_flush(struct altos_file *file)
}
}
+#include <poll.h>
+
int
altos_getchar(struct altos_file *file, int timeout)
{
@@ -622,9 +558,18 @@ altos_getchar(struct altos_file *file, int timeout)
altos_flush(file);
if (file->fd < 0)
return -EBADF;
+ if (timeout) {
+ struct pollfd fd;
+ int ret;
+ fd.fd = file->fd;
+ fd.events = POLLIN;
+ ret = poll(&fd, 1, timeout);
+ if (ret == 0)
+ return LIBALTOS_TIMEOUT;
+ }
ret = read(file->fd, file->in_data, USB_BUF_SIZE);
if (ret < 0)
- return -errno;
+ return LIBALTOS_ERROR;
file->in_read = 0;
file->in_used = ret;
}
@@ -633,143 +578,255 @@ altos_getchar(struct altos_file *file, int timeout)
#endif /* POSIX_TTY */
-#ifdef USE_LIBUSB
-#include <libusb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#ifdef WINDOWS
-libusb_context *usb_context;
+#include <windows.h>
+#include <setupapi.h>
-int altos_init(void)
-{
- int ret;
- ret = libusb_init(&usb_context);
- if (ret)
- return ret;
- libusb_set_debug(usb_context, 3);
- return 0;
-}
+struct altos_list {
+ HDEVINFO dev_info;
+ int index;
+};
-void altos_fini(void)
-{
- libusb_exit(usb_context);
- usb_context = NULL;
-}
+#define USB_BUF_SIZE 64
-static libusb_device **list;
-static ssize_t num, current;
+struct altos_file {
+ HANDLE handle;
+ unsigned char out_data[USB_BUF_SIZE];
+ int out_used;
+ unsigned char in_data[USB_BUF_SIZE];
+ int in_used;
+ int in_read;
+};
-int altos_list_start(void)
+
+PUBLIC struct altos_list *
+altos_list_start(void)
{
- if (list)
- altos_list_finish();
- current = 0;
- num = libusb_get_device_list(usb_context, &list);
- if (num == 0) {
- current = num = 0;
- list = NULL;
- return 0;
+ struct altos_list *list = calloc(1, sizeof (struct altos_list));
+
+ if (!list)
+ return NULL;
+ list->dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
+ DIGCF_ALLCLASSES|DIGCF_PRESENT);
+ if (list->dev_info == INVALID_HANDLE_VALUE) {
+ printf("SetupDiGetClassDevs failed %d\n", GetLastError());
+ free(list);
+ return NULL;
}
- return 1;
+ list->index = 0;
+ return list;
}
-int altos_list_next(struct altos_device *device)
-{
- while (current < num) {
- struct libusb_device_descriptor descriptor;
- libusb_device *usb_device = list[current++];
-
- if (libusb_get_device_descriptor(usb_device, &descriptor) == 0) {
- if (descriptor.idVendor == 0xfffe)
- {
- libusb_device_handle *handle;
- if (libusb_open(usb_device, &handle) == 0) {
- char serial_number[256];
- libusb_get_string_descriptor_ascii(handle, descriptor.iProduct,
- device->product,
- sizeof(device->product));
- libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber,
- serial_number,
- sizeof (serial_number));
- libusb_close(handle);
- device->serial = atoi(serial_number);
- device->device = usb_device;
- return 1;
- }
- }
+PUBLIC int
+altos_list_next(struct altos_list *list, struct altos_device *device)
+{
+ SP_DEVINFO_DATA dev_info_data;
+ char port[128];
+ DWORD port_len;
+ char location[256];
+ char symbolic[256];
+ DWORD symbolic_len;
+ HKEY dev_key;
+ int vid, pid;
+ int serial;
+ HRESULT result;
+ DWORD location_type;
+ DWORD location_len;
+
+ dev_info_data.cbSize = sizeof (SP_DEVINFO_DATA);
+ while(SetupDiEnumDeviceInfo(list->dev_info, list->index,
+ &dev_info_data))
+ {
+ list->index++;
+
+ dev_key = SetupDiOpenDevRegKey(list->dev_info, &dev_info_data,
+ DICS_FLAG_GLOBAL, 0, DIREG_DEV,
+ KEY_READ);
+ if (dev_key == INVALID_HANDLE_VALUE) {
+ printf("cannot open device registry key\n");
+ continue;
}
+
+ /* Fetch symbolic name for this device and parse out
+ * the vid/pid/serial info */
+ symbolic_len = sizeof(symbolic);
+ result = RegQueryValueEx(dev_key, "SymbolicName", NULL, NULL,
+ symbolic, &symbolic_len);
+ if (result != 0) {
+ printf("cannot find SymbolicName value\n");
+ RegCloseKey(dev_key);
+ continue;
+ }
+ vid = pid = serial = 0;
+ sscanf(symbolic + sizeof("\\??\\USB#VID_") - 1,
+ "%04X", &vid);
+ sscanf(symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
+ "%04X", &pid);
+ sscanf(symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
+ "%d", &serial);
+ if (!USB_IS_ALTUSMETRUM(vid, pid)) {
+ printf("Not Altus Metrum symbolic name: %s\n",
+ symbolic);
+ RegCloseKey(dev_key);
+ continue;
+ }
+
+ /* Fetch the com port name */
+ port_len = sizeof (port);
+ result = RegQueryValueEx(dev_key, "PortName", NULL, NULL,
+ port, &port_len);
+ RegCloseKey(dev_key);
+ if (result != 0) {
+ printf("failed to get PortName\n");
+ continue;
+ }
+
+ /* Fetch the 'location information' which is the device name,
+ * at least on XP */
+ location_len = sizeof (location);
+ if(!SetupDiGetDeviceRegistryProperty(list->dev_info,
+ &dev_info_data,
+ SPDRP_LOCATION_INFORMATION,
+ &location_type,
+ (BYTE *)location,
+ sizeof(location),
+ &location_len))
+ {
+ printf("Failed to get location\n");
+ continue;
+ }
+ device->vendor = vid;
+ device->product = pid;
+ device->serial = serial;
+
+ if (strcasestr(location, "tele"))
+ strcpy(device->name, location);
+ else
+ strcpy(device->name, "");
+
+ strcpy(device->path, port);
+ printf ("product: %04x:%04x (%s) path: %s serial %d\n",
+ device->vendor, device->product, device->name,
+ device->path, device->serial);
+ return 1;
}
+ result = GetLastError();
+ if (result != ERROR_NO_MORE_ITEMS)
+ printf ("SetupDiEnumDeviceInfo failed error %d\n", result);
return 0;
}
-void altos_list_finish(void)
+PUBLIC void
+altos_list_finish(struct altos_list *list)
+{
+ SetupDiDestroyDeviceInfoList(list->dev_info);
+ free(list);
+}
+
+static int
+altos_fill(struct altos_file *file, int timeout)
{
- if (list) {
- libusb_free_device_list(list, 1);
- list = NULL;
+ DWORD result;
+ DWORD got;
+ COMMTIMEOUTS timeouts;
+
+ if (file->in_read < file->in_used)
+ return LIBALTOS_SUCCESS;
+ file->in_read = file->in_used = 0;
+
+ if (timeout) {
+ timeouts.ReadIntervalTimeout = MAXDWORD;
+ timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
+ timeouts.ReadTotalTimeoutConstant = timeout;
+ } else {
+ timeouts.ReadIntervalTimeout = 0;
+ timeouts.ReadTotalTimeoutMultiplier = 0;
+ timeouts.ReadTotalTimeoutConstant = 0;
+ }
+ timeouts.WriteTotalTimeoutMultiplier = 0;
+ timeouts.WriteTotalTimeoutConstant = 0;
+
+ if (!SetCommTimeouts(file->handle, &timeouts)) {
+ printf("SetCommTimeouts failed %d\n", GetLastError());
}
+
+ if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, NULL)) {
+ result = GetLastError();
+ printf ("read failed %d\n", result);
+ return LIBALTOS_ERROR;
+ got = 0;
+ }
+ if (got)
+ return LIBALTOS_SUCCESS;
+ return LIBALTOS_TIMEOUT;
}
-#define USB_BUF_SIZE 64
+PUBLIC int
+altos_flush(struct altos_file *file)
+{
+ DWORD put;
+ char *data = file->out_data;
+ char used = file->out_used;
+ DWORD result;
-struct altos_file {
- struct libusb_device *device;
- struct libusb_device_handle *handle;
- int out_ep;
- int out_size;
- int in_ep;
- int in_size;
- unsigned char out_data[USB_BUF_SIZE];
- int out_used;
- unsigned char in_data[USB_BUF_SIZE];
- int in_used;
- int in_read;
-};
+ while (used) {
+ if (!WriteFile(file->handle, data, used, &put, NULL)) {
+ result = GetLastError();
+ printf ("write failed %d\n", result);
+ return LIBALTOS_ERROR;
+ }
+ data += put;
+ used -= put;
+ }
+ file->out_used = 0;
+ return LIBALTOS_SUCCESS;
+}
-struct altos_file *
+PUBLIC struct altos_file *
altos_open(struct altos_device *device)
{
- struct altos_file *file;
- struct libusb_device_handle *handle;
- if (libusb_open(device->device, &handle) == 0) {
- int ret;
+ struct altos_file *file = calloc (sizeof (struct altos_file), 1);
+ char full_name[64];
- ret = libusb_claim_interface(handle, 1);
-#if 0
- if (ret) {
- libusb_close(handle);
- return NULL;
- }
-#endif
- ret = libusb_detach_kernel_driver(handle, 1);
-#if 0
- if (ret) {
- libusb_close(handle);
- return NULL;
- }
-#endif
+ if (!file)
+ return NULL;
- file = calloc(sizeof (struct altos_file), 1);
- file->device = libusb_ref_device(device->device);
- file->handle = handle;
- /* XXX should get these from the endpoint descriptors */
- file->out_ep = 4 | LIBUSB_ENDPOINT_OUT;
- file->out_size = 64;
- file->in_ep = 5 | LIBUSB_ENDPOINT_IN;
- file->in_size = 64;
+ strcpy(full_name, "\\\\.\\");
+ strcat(full_name, device->path);
+ file->handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file->handle == INVALID_HANDLE_VALUE) {
+ free(file);
+ return NULL;
+ }
- return file;
+ timeouts.ReadIntervalTimeout = MAXDWORD;
+ timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
+ timeouts.ReadTotalTimeoutConstant = 100;
+ timeouts.WriteTotalTimeoutMultiplier = 0;
+ timeouts.WriteTotalTimeoutConstant = 10000;
+ if (!SetCommTimeouts(file->handle, &timeouts)) {
+ printf("SetCommTimeouts failed %d\n", GetLastError());
}
- return NULL;
+
+ return file;
}
-void
+PUBLIC void
altos_close(struct altos_file *file)
{
- libusb_close(file->handle);
- libusb_unref_device(file->device);
- file->handle = NULL;
+ if (file->handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(file->handle);
+ file->handle = INVALID_HANDLE_VALUE;
+ }
+}
+
+PUBLIC void
+altos_free(struct altos_file *file)
+{
+ altos_close(file);
free(file);
}
@@ -778,60 +835,32 @@ altos_putchar(struct altos_file *file, char c)
{
int ret;
- if (file->out_used == file->out_size) {
+ if (file->out_used == USB_BUF_SIZE) {
ret = altos_flush(file);
if (ret)
return ret;
}
file->out_data[file->out_used++] = c;
- if (file->out_used == file->out_size)
+ if (file->out_used == USB_BUF_SIZE)
return altos_flush(file);
- return 0;
-}
-
-int
-altos_flush(struct altos_file *file)
-{
- while (file->out_used) {
- int transferred;
- int ret;
-
- ret = libusb_bulk_transfer(file->handle,
- file->out_ep,
- file->out_data,
- file->out_used,
- &transferred,
- 0);
- if (ret)
- return ret;
- if (transferred) {
- memmove(file->out_data, file->out_data + transferred,
- file->out_used - transferred);
- file->out_used -= transferred;
- }
- }
+ return LIBALTOS_SUCCESS;
}
int
altos_getchar(struct altos_file *file, int timeout)
{
+ int ret;
while (file->in_read == file->in_used) {
- int ret;
- int transferred;
-
- altos_flush(file);
- ret = libusb_bulk_transfer(file->handle,
- file->in_ep,
- file->in_data,
- file->in_size,
- &transferred,
- (unsigned int) timeout);
+ ret = altos_flush(file);
+ if (ret)
+ return ret;
+ if (file->handle == INVALID_HANDLE_VALUE)
+ return LIBALTOS_ERROR;
+ ret = altos_fill(file, timeout);
if (ret)
return ret;
- file->in_read = 0;
- file->in_used = transferred;
}
return file->in_data[file->in_read++];
}
-#endif /* USE_LIBUSB */
+#endif
diff --git a/ao-tools/libaltos/libaltos.h b/ao-tools/libaltos/libaltos.h
index 53026e0a..fe2c483c 100644
--- a/ao-tools/libaltos/libaltos.h
+++ b/ao-tools/libaltos/libaltos.h
@@ -18,39 +18,83 @@
#ifndef _LIBALTOS_H_
#define _LIBALTOS_H_
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# ifndef BUILD_STATIC
+# ifdef BUILD_DLL
+# define PUBLIC __declspec(dllexport)
+# else
+# define PUBLIC __declspec(dllimport)
+# endif
+# endif /* BUILD_STATIC */
+#endif
+
+#ifndef PUBLIC
+# define PUBLIC
+#endif
+
+#define USB_VENDOR_FSF 0xfffe
+#define USB_VENDOR_ALTUSMETRUM USB_VENDOR_FSF
+#define USB_PRODUCT_ALTUSMETRUM 0x000a
+#define USB_PRODUCT_TELEMETRUM 0x000b
+#define USB_PRODUCT_TELEDONGLE 0x000c
+#define USB_PRODUCT_TELETERRA 0x000d
+#define USB_PRODUCT_ALTUSMETRUM_MIN 0x000a
+#define USB_PRODUCT_ALTUSMETRUM_MAX 0x0013
+
+#define USB_IS_ALTUSMETRUM(v,p) ((v) == USB_VENDOR_ALTUSMETRUM && \
+ (USB_PRODUCT_ALTUSMETRUM_MIN <= (p) && \
+ (p) <= USB_PRODUCT_ALTUSMETRUM_MAX))
+
struct altos_device {
//%immutable;
- char product[256];
+ int vendor;
+ int product;
int serial;
+ char name[256];
char path[256];
//%mutable;
};
-int altos_init(void);
+#define LIBALTOS_SUCCESS 0
+#define LIBALTOS_ERROR -1
+#define LIBALTOS_TIMEOUT -2
+
+/* Returns 0 for success, < 0 on error */
+PUBLIC int
+altos_init(void);
-void altos_fini(void);
+PUBLIC void
+altos_fini(void);
-struct altos_list *
+PUBLIC struct altos_list *
altos_list_start(void);
-int altos_list_next(struct altos_list *list, struct altos_device *device);
+/* Returns 1 for success, zero on end of list */
+PUBLIC int
+altos_list_next(struct altos_list *list, struct altos_device *device);
-void altos_list_finish(struct altos_list *list);
+PUBLIC void
+altos_list_finish(struct altos_list *list);
-struct altos_file *
+PUBLIC struct altos_file *
altos_open(struct altos_device *device);
-void altos_close(struct altos_file *file);
+PUBLIC void
+altos_close(struct altos_file *file);
-void altos_free(struct altos_file *file);
+PUBLIC void
+altos_free(struct altos_file *file);
-int
+/* Returns < 0 for error */
+PUBLIC int
altos_putchar(struct altos_file *file, char c);
-int
+/* Returns < 0 for error */
+PUBLIC int
altos_flush(struct altos_file *file);
-int
+/* Returns < 0 for error or timeout. timeout of 0 == wait forever */
+PUBLIC int
altos_getchar(struct altos_file *file, int timeout);
#endif /* _LIBALTOS_H_ */