#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_TELEBT 0x000e
#define USB_PRODUCT_ALTUSMETRUM_MIN 0x000a
-#define USB_PRODUCT_ALTUSMETRUM_MAX 0x0013
+#define USB_PRODUCT_ALTUSMETRUM_MAX 0x00ff
#define USB_IS_ALTUSMETRUM(v,p) ((v) == USB_VENDOR_ALTUSMETRUM && \
(USB_PRODUCT_ALTUSMETRUM_MIN <= (p) && \
{
}
+static struct altos_error last_error;
+
+static void
+altos_set_last_error(int code, char *string)
+{
+ last_error.code = code;
+ strncpy(last_error.string, string, sizeof (last_error.string) -1);
+ last_error.string[sizeof(last_error.string)-1] = '\0';
+}
+
+PUBLIC void
+altos_get_last_error(struct altos_error *error)
+{
+ *error = last_error;
+}
+
#ifdef DARWIN
#undef USE_POLL
int in_read;
};
+static void
+altos_set_last_posix_error(void)
+{
+ altos_set_last_error(errno, strerror(errno));
+}
+
PUBLIC struct altos_file *
altos_open(struct altos_device *device)
{
int ret;
struct termios term;
- if (!file)
+ if (!file) {
+ altos_set_last_posix_error();
return NULL;
+ }
+
+// altos_set_last_error(12, "yeah yeah, failed again");
+// free(file);
+// return NULL;
file->fd = open(device->path, O_RDWR | O_NOCTTY);
if (file->fd < 0) {
- perror(device->path);
+ altos_set_last_posix_error();
free(file);
return NULL;
}
#else
file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
if (file->out_fd < 0) {
- perror(device->path);
+ altos_set_last_posix_error();
close(file->fd);
free(file);
return NULL;
#endif
ret = tcgetattr(file->fd, &term);
if (ret < 0) {
- perror("tcgetattr");
+ altos_set_last_posix_error();
close(file->fd);
#ifndef USE_POLL
close(file->out_fd);
#endif
ret = tcsetattr(file->fd, TCSAFLUSH, &term);
if (ret < 0) {
- perror("tcsetattr");
+ altos_set_last_posix_error();
close(file->fd);
#ifndef USE_POLL
close(file->out_fd);
#else
ret = write (file->out_fd, file->out_data, file->out_used);
#endif
- if (ret < 0)
- return -errno;
+ if (ret < 0) {
+ altos_set_last_posix_error();
+ return -last_error.code;
+ }
if (ret) {
memmove(file->out_data, file->out_data + ret,
file->out_used - ret);
ret = 0;
if (file->out_used == USB_BUF_SIZE)
ret = altos_flush(file);
- return 0;
+ return ret;
}
#ifdef USE_POLL
fd[1].events = POLLIN;
ret = poll(fd, 2, timeout);
if (ret < 0) {
- perror("altos_getchar");
+ altos_set_last_posix_error();
return LIBALTOS_ERROR;
}
if (ret == 0)
{
ret = read(file->fd, file->in_data, USB_BUF_SIZE);
if (ret < 0) {
- perror("altos_getchar");
+ altos_set_last_posix_error();
return LIBALTOS_ERROR;
}
file->in_read = 0;
free(usbdevs);
}
-#if HAS_BLUETOOTH
struct altos_bt_list {
inquiry_info *ii;
int sock;
if (!file)
goto no_file;
file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (file->fd < 0)
+ if (file->fd < 0) {
+ altos_set_last_posix_error();
goto no_sock;
+ }
addr.rc_family = AF_BLUETOOTH;
addr.rc_channel = 1;
(struct sockaddr *)&addr,
sizeof(addr));
if (status < 0) {
- perror("connect");
+ altos_set_last_posix_error();
goto no_link;
}
sleep(1);
no_file:
return NULL;
}
-#endif /* HAS_BLUETOOTH */
#endif
return 0;
}
-struct altos_list *
-altos_list_start(int time)
+PUBLIC struct altos_list *
+altos_list_start(void)
{
struct altos_list *list = calloc (sizeof (struct altos_list), 1);
CFMutableDictionaryRef matching_dictionary = IOServiceMatching("IOUSBDevice");
return list;
}
-int
+PUBLIC int
altos_list_next(struct altos_list *list, struct altos_device *device)
{
io_object_t object;
}
}
-void
+PUBLIC void
altos_list_finish(struct altos_list *list)
{
IOObjectRelease (list->iterator);
free(list);
}
+struct altos_bt_list {
+ int sock;
+ int dev_id;
+ int rsp;
+ int num_rsp;
+};
+
+#define INQUIRY_MAX_RSP 255
+
+struct altos_bt_list *
+altos_bt_list_start(int inquiry_time)
+{
+ return NULL;
+}
+
+int
+altos_bt_list_next(struct altos_bt_list *bt_list,
+ struct altos_bt_device *device)
+{
+ return 0;
+}
+
+void
+altos_bt_list_finish(struct altos_bt_list *bt_list)
+{
+}
+
+void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
+{
+ strncpy(device->name, name, sizeof (device->name));
+ device->name[sizeof(device->name)-1] = '\0';
+ strncpy(device->addr, addr, sizeof (device->addr));
+ device->addr[sizeof(device->addr)-1] = '\0';
+}
+
+struct altos_file *
+altos_bt_open(struct altos_bt_device *device)
+{
+ return NULL;
+}
+
#endif
OVERLAPPED ov_write;
};
+static void
+altos_set_last_windows_error(void)
+{
+ DWORD error = GetLastError();
+ TCHAR message[1024];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ error,
+ 0,
+ message,
+ sizeof (message) / sizeof (TCHAR),
+ NULL);
+ altos_set_last_error(error, message);
+}
+
PUBLIC struct altos_list *
altos_list_start(void)
{
list->dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
DIGCF_ALLCLASSES|DIGCF_PRESENT);
if (list->dev_info == INVALID_HANDLE_VALUE) {
- printf("SetupDiGetClassDevs failed %d\n", GetLastError());
+ altos_set_last_windows_error();
free(list);
return NULL;
}
altos_list_next(struct altos_list *list, struct altos_device *device)
{
SP_DEVINFO_DATA dev_info_data;
- char port[128];
+ BYTE port[128];
DWORD port_len;
char friendlyname[256];
- char symbolic[256];
+ BYTE symbolic[256];
DWORD symbolic_len;
HKEY dev_key;
- int vid, pid;
+ unsigned int vid, pid;
int serial;
HRESULT result;
DWORD friendlyname_type;
DICS_FLAG_GLOBAL, 0, DIREG_DEV,
KEY_READ);
if (dev_key == INVALID_HANDLE_VALUE) {
+ altos_set_last_windows_error();
printf("cannot open device registry key\n");
continue;
}
result = RegQueryValueEx(dev_key, "SymbolicName", NULL, NULL,
symbolic, &symbolic_len);
if (result != 0) {
+ altos_set_last_windows_error();
printf("cannot find SymbolicName value\n");
RegCloseKey(dev_key);
continue;
}
vid = pid = serial = 0;
- sscanf(symbolic + sizeof("\\??\\USB#VID_") - 1,
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
"%04X", &vid);
- sscanf(symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
"%04X", &pid);
- sscanf(symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
+ sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
"%d", &serial);
if (!USB_IS_ALTUSMETRUM(vid, pid)) {
RegCloseKey(dev_key);
port, &port_len);
RegCloseKey(dev_key);
if (result != 0) {
+ altos_set_last_windows_error();
printf("failed to get PortName\n");
continue;
}
sizeof(friendlyname),
&friendlyname_len))
{
+ altos_set_last_windows_error();
printf("Failed to get friendlyname\n");
continue;
}
device->serial = serial;
strcpy(device->name, friendlyname);
- strcpy(device->path, port);
+ strcpy(device->path, (char *) port);
return 1;
}
result = GetLastError();
- if (result != ERROR_NO_MORE_ITEMS)
- printf ("SetupDiEnumDeviceInfo failed error %d\n", result);
+ if (result != ERROR_NO_MORE_ITEMS) {
+ altos_set_last_windows_error();
+ printf ("SetupDiEnumDeviceInfo failed error %d\n", (int) result);
+ }
return 0;
}
return LIBALTOS_SUCCESS;
if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, &file->ov_read)) {
- if (GetLastError() != ERROR_IO_PENDING)
+ if (GetLastError() != ERROR_IO_PENDING) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
file->pend_read = TRUE;
} else {
file->pend_read = FALSE;
ret = WaitForSingleObject(file->ov_read.hEvent, timeout);
switch (ret) {
case WAIT_OBJECT_0:
- if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE))
+ if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE)) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
file->pend_read = FALSE;
file->in_read = 0;
file->in_used = got;
PUBLIC int
altos_flush(struct altos_file *file)
{
- DWORD put;
- char *data = file->out_data;
- char used = file->out_used;
- DWORD ret;
+ DWORD put;
+ unsigned char *data = file->out_data;
+ int used = file->out_used;
+ DWORD ret;
while (used) {
if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) {
- if (GetLastError() != ERROR_IO_PENDING)
+ if (GetLastError() != ERROR_IO_PENDING) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE);
switch (ret) {
case WAIT_OBJECT_0:
- if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE))
+ if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
break;
default:
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
}
}
0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (file->handle == INVALID_HANDLE_VALUE) {
+ altos_set_last_windows_error();
free(file);
return NULL;
}
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(file->handle, &dcbSerialParams)) {
+ altos_set_last_windows_error();
CloseHandle(file->handle);
free(file);
return NULL;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(file->handle, &dcbSerialParams)) {
+ altos_set_last_windows_error();
CloseHandle(file->handle);
free(file);
return NULL;
free(file);
}
-int
+PUBLIC int
altos_putchar(struct altos_file *file, char c)
{
int ret;
return LIBALTOS_SUCCESS;
}
-int
+PUBLIC int
altos_getchar(struct altos_file *file, int timeout)
{
int ret;
return file->in_data[file->in_read++];
}
+struct altos_bt_list *
+altos_bt_list_start(int inquiry_time)
+{
+ return NULL;
+}
+
+int
+altos_bt_list_next(struct altos_bt_list *bt_list,
+ struct altos_bt_device *device)
+{
+ return 0;
+}
+
+void
+altos_bt_list_finish(struct altos_bt_list *bt_list)
+{
+ free(bt_list);
+}
+
+void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
+{
+ strncpy(device->name, name, sizeof (device->name));
+ device->name[sizeof(device->name)-1] = '\0';
+ strncpy(device->addr, addr, sizeof (device->addr));
+ device->addr[sizeof(device->addr)-1] = '\0';
+}
+
+struct altos_file *
+altos_bt_open(struct altos_bt_device *device)
+{
+ return NULL;
+}
+
#endif