diff options
| -rw-r--r-- | ao-tools/libaltos/Makefile | 53 | ||||
| -rw-r--r-- | ao-tools/libaltos/cjnitest.c | 21 | ||||
| -rw-r--r-- | ao-tools/libaltos/libaltos.c | 501 | ||||
| -rw-r--r-- | ao-tools/libaltos/libaltos.h | 68 | 
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_ */  | 
