altosui: Add low-level Bluetooth APIs
authorKeith Packard <keithp@keithp.com>
Fri, 8 Apr 2011 17:13:55 +0000 (10:13 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 8 Apr 2011 17:13:55 +0000 (10:13 -0700)
Adds the JNI functions to query and connect to arbitrary
bluetooth devices.

Adds Java wrappers to construct a list of proximate bluetooth devices.

Signed-off-by: Keith Packard <keithp@keithp.com>
altosui/AltosBTDevice.java [new file with mode: 0644]
altosui/AltosEepromDownload.java
altosui/Makefile.am
altosui/libaltos/Makefile.am
altosui/libaltos/cjnitest.c
altosui/libaltos/libaltos.c
altosui/libaltos/libaltos.h

diff --git a/altosui/AltosBTDevice.java b/altosui/AltosBTDevice.java
new file mode 100644 (file)
index 0000000..8eb18bb
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package altosui;
+import java.lang.*;
+import java.util.*;
+import libaltosJNI.*;
+
+public class AltosBTDevice extends altos_bt_device {
+
+       static public boolean initialized = false;
+       static public boolean loaded_library = false;
+
+       public static boolean load_library() {
+               if (!initialized) {
+                       try {
+                               System.loadLibrary("altos");
+                               libaltos.altos_init();
+                               loaded_library = true;
+                       } catch (UnsatisfiedLinkError e) {
+                               loaded_library = false;
+                       }
+                       initialized = true;
+               }
+               return loaded_library;
+       }
+
+       static String bt_product_telebt() {
+               if (load_library())
+                       return libaltosConstants.BLUETOOTH_PRODUCT_TELEBT;
+               return "TeleBT";
+       }
+
+       public final static String bt_product_telebt = bt_product_telebt();
+       public final static String bt_product_any = "Any";
+       public final static String bt_product_basestation = "Basestation";
+
+       public String getProduct() {
+               String  name = getName();
+               if (name == null)
+                       return "Altus Metrum";
+               int     dash = name.lastIndexOf("-");
+               if (dash < 0)
+                       return name;
+               return name.substring(0,dash);
+       }
+
+       public int getSerial() {
+               String name = getName();
+               if (name == null)
+                       return 0;
+               int dash = name.lastIndexOf("-");
+               if (dash < 0 || dash >= name.length())
+                       return 0;
+               String sn = name.substring(dash + 1, name.length());
+               try {
+                       return Integer.parseInt(sn);
+               } catch (NumberFormatException ne) {
+                       return 0;
+               }
+       }
+
+       public String toString() {
+               String  name = getName();
+               if (name == null)
+                       name = "Altus Metrum";
+               return String.format("%-20.20s %4d %s",
+                                    getProduct(), getSerial(), getAddr());
+       }
+
+       public String toShortString() {
+               String  name = getName();
+               if (name == null)
+                       name = "Altus Metrum";
+               return String.format("%s %d %s",
+                                    getProduct(), getSerial(), getAddr());
+
+       }
+
+       public boolean isAltusMetrum() {
+               if (getName().startsWith(bt_product_telebt))
+                       return true;
+               return false;
+       }
+
+       public boolean matchProduct(String want_product) {
+
+               if (!isAltusMetrum())
+                       return false;
+
+               if (want_product.equals(bt_product_any))
+                       return true;
+
+               if (want_product.equals(bt_product_basestation))
+                       return matchProduct(bt_product_telebt);
+
+               if (want_product.equals(getProduct()))
+                       return true;
+
+               return false;
+       }
+
+       static AltosBTDevice[] list(String product) {
+               if (!load_library())
+                       return null;
+
+               SWIGTYPE_p_altos_bt_list list = libaltos.altos_bt_list_start();
+
+               ArrayList<AltosBTDevice> device_list = new ArrayList<AltosBTDevice>();
+               if (list != null) {
+                       SWIGTYPE_p_altos_file file;
+
+                       for (;;) {
+                               AltosBTDevice device = new AltosBTDevice();
+                               if (libaltos.altos_bt_list_next(list, device) == 0)
+                                       break;
+                               if (device.matchProduct(product))
+                                       device_list.add(device);
+                       }
+                       libaltos.altos_bt_list_finish(list);
+               }
+
+               AltosBTDevice[] devices = new AltosBTDevice[device_list.size()];
+               for (int i = 0; i < device_list.size(); i++)
+                       devices[i] = device_list.get(i);
+               return devices;
+       }
+}
\ No newline at end of file
index fad1646072e2890604773c14f31ab51594e4f03b..5c7049683008fc8107c0fdd0d1191130b43838e0 100644 (file)
@@ -158,6 +158,7 @@ public class AltosEepromDownload implements Runnable {
                                        r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, s, 0);
                                        if (s == Altos.ao_flight_landed)
                                                done = true;
                                        r = new AltosEepromRecord(Altos.AO_LOG_STATE, tiny_tick, s, 0);
                                        if (s == Altos.ao_flight_landed)
                                                done = true;
+                                       state = s;
                                        any_valid = true;
                                } else {
                                        if (v != 0xffff)
                                        any_valid = true;
                                } else {
                                        if (v != 0xffff)
index 01fe50c8560924d0efab5546892351c15a64b02f..5b11d1b0c2759d7e89ce0fba2769b9ea1259f4f0 100644 (file)
@@ -26,6 +26,7 @@ altosui_JAVA = \
        AltosDescent.java \
        AltosDeviceDialog.java \
        AltosDevice.java \
        AltosDescent.java \
        AltosDeviceDialog.java \
        AltosDevice.java \
+       AltosBTDevice.java \
        AltosDisplayThread.java \
        AltosEepromChunk.java \
        AltosEepromDelete.java \
        AltosDisplayThread.java \
        AltosEepromChunk.java \
        AltosEepromDelete.java \
index 388d21046dc1c655fb66d20ebd89789fccb832ed..3f5f3ee2f07d32559e2e7de2a700741fbc69e086 100644 (file)
@@ -16,7 +16,7 @@ noinst_PROGRAMS=cjnitest
 
 cjnitest_LDADD=libaltos.la
 
 
 cjnitest_LDADD=libaltos.la
 
-LIBS=
+LIBS=-lbluetooth
 
 HFILES=libaltos.h
 
 
 HFILES=libaltos.h
 
index c6d6e069c1f188cd56666292236e5c1f083c7dbb..795616436aa99a7da70c9463b3e431aab7ba0c96 100644 (file)
@@ -14,6 +14,8 @@ main ()
 {
        struct altos_device     device;
        struct altos_list       *list;
 {
        struct altos_device     device;
        struct altos_list       *list;
+       struct altos_bt_device  bt_device;
+       struct altos_bt_list    *bt_list;
 
        altos_init();
        list = altos_list_start();
 
        altos_init();
        list = altos_list_start();
@@ -39,5 +41,29 @@ main ()
                altos_close(file);
        }
        altos_list_finish(list);
                altos_close(file);
        }
        altos_list_finish(list);
+       bt_list = altos_bt_list_start();
+       while (altos_bt_list_next(bt_list, &bt_device)) {
+               printf ("%s %s\n", bt_device.name, bt_device.addr);
+               if (strncmp(bt_device.name, "TeleBT", 6) == 0) {
+                       struct altos_file       *file;
+
+                       int                     c;
+                       file = altos_bt_open(&bt_device);
+                       if (!file) {
+                               printf("altos_bt_open failed\n");
+                               continue;
+                       }
+                       altos_puts(file,"v\nc s\n");
+                       altos_flush(file);
+                       while ((c = altos_getchar(file, 100)) >= 0) {
+                               putchar(c);
+                       }
+                       if (c != LIBALTOS_TIMEOUT)
+                               printf("getchar returns %d\n", c);
+                       altos_close(file);
+               }
+       }
+       altos_bt_list_finish(bt_list);
        altos_fini();
        altos_fini();
+       return 0;
 }
 }
index 465f0ac89475c03d61b1b89067a7b4b05ef67e4a..13635a0da0f2d0b4311112c029926eddd6e91831 100644 (file)
@@ -56,6 +56,230 @@ altos_strndup (const char *s, size_t n)
 #define altos_strndup strndup
 #endif
 
 #define altos_strndup strndup
 #endif
 
+#ifdef POSIX_TTY
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <errno.h>
+
+#define USB_BUF_SIZE   64
+
+struct altos_file {
+       int                             fd;
+#ifdef USE_POLL
+       int                             pipe[2];
+#else
+       int                             out_fd;
+#endif
+       unsigned char                   out_data[USB_BUF_SIZE];
+       int                             out_used;
+       unsigned char                   in_data[USB_BUF_SIZE];
+       int                             in_used;
+       int                             in_read;
+};
+
+PUBLIC struct altos_file *
+altos_open(struct altos_device *device)
+{
+       struct altos_file       *file = calloc (sizeof (struct altos_file), 1);
+       int                     ret;
+       struct termios          term;
+
+       if (!file)
+               return NULL;
+
+       file->fd = open(device->path, O_RDWR | O_NOCTTY);
+       if (file->fd < 0) {
+               perror(device->path);
+               free(file);
+               return NULL;
+       }
+#ifdef USE_POLL
+       pipe(file->pipe);
+#else
+       file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
+       if (file->out_fd < 0) {
+               perror(device->path);
+               close(file->fd);
+               free(file);
+               return NULL;
+       }
+#endif
+       ret = tcgetattr(file->fd, &term);
+       if (ret < 0) {
+               perror("tcgetattr");
+               close(file->fd);
+#ifndef USE_POLL
+               close(file->out_fd);
+#endif
+               free(file);
+               return NULL;
+       }
+       cfmakeraw(&term);
+#ifdef USE_POLL
+       term.c_cc[VMIN] = 1;
+       term.c_cc[VTIME] = 0;
+#else
+       term.c_cc[VMIN] = 0;
+       term.c_cc[VTIME] = 1;
+#endif
+       ret = tcsetattr(file->fd, TCSAFLUSH, &term);
+       if (ret < 0) {
+               perror("tcsetattr");
+               close(file->fd);
+#ifndef USE_POLL
+               close(file->out_fd);
+#endif
+               free(file);
+               return NULL;
+       }
+       return file;
+}
+
+PUBLIC void
+altos_close(struct altos_file *file)
+{
+       if (file->fd != -1) {
+               int     fd = file->fd;
+               file->fd = -1;
+#ifdef USE_POLL
+               write(file->pipe[1], "\r", 1);
+#else
+               close(file->out_fd);
+               file->out_fd = -1;
+#endif
+               close(fd);
+       }
+}
+
+PUBLIC void
+altos_free(struct altos_file *file)
+{
+       altos_close(file);
+       free(file);
+}
+
+PUBLIC int
+altos_flush(struct altos_file *file)
+{
+       if (file->out_used && 0) {
+               printf ("flush \"");
+               fwrite(file->out_data, 1, file->out_used, stdout);
+               printf ("\"\n");
+       }
+       while (file->out_used) {
+               int     ret;
+
+               if (file->fd < 0)
+                       return -EBADF;
+#ifdef USE_POLL
+               ret = write (file->fd, file->out_data, file->out_used);
+#else
+               ret = write (file->out_fd, file->out_data, file->out_used);
+#endif
+               if (ret < 0)
+                       return -errno;
+               if (ret) {
+                       memmove(file->out_data, file->out_data + ret,
+                               file->out_used - ret);
+                       file->out_used -= ret;
+               }
+       }
+       return 0;
+}
+
+PUBLIC int
+altos_putchar(struct altos_file *file, char c)
+{
+       int     ret;
+
+       if (file->out_used == USB_BUF_SIZE) {
+               ret = altos_flush(file);
+               if (ret) {
+                       return ret;
+               }
+       }
+       file->out_data[file->out_used++] = c;
+       ret = 0;
+       if (file->out_used == USB_BUF_SIZE)
+               ret = altos_flush(file);
+       return 0;
+}
+
+#ifdef USE_POLL
+#include <poll.h>
+#endif
+
+static int
+altos_fill(struct altos_file *file, int timeout)
+{
+       int             ret;
+#ifdef USE_POLL
+       struct pollfd   fd[2];
+#endif
+
+       if (timeout == 0)
+               timeout = -1;
+       while (file->in_read == file->in_used) {
+               if (file->fd < 0)
+                       return LIBALTOS_ERROR;
+#ifdef USE_POLL
+               fd[0].fd = file->fd;
+               fd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
+               fd[1].fd = file->pipe[0];
+               fd[1].events = POLLIN;
+               ret = poll(fd, 2, timeout);
+               if (ret < 0) {
+                       perror("altos_getchar");
+                       return LIBALTOS_ERROR;
+               }
+               if (ret == 0)
+                       return LIBALTOS_TIMEOUT;
+
+               if (fd[0].revents & (POLLHUP|POLLERR|POLLNVAL))
+                       return LIBALTOS_ERROR;
+               if (fd[0].revents & POLLIN)
+#endif
+               {
+                       ret = read(file->fd, file->in_data, USB_BUF_SIZE);
+                       if (ret < 0) {
+                               perror("altos_getchar");
+                               return LIBALTOS_ERROR;
+                       }
+                       file->in_read = 0;
+                       file->in_used = ret;
+#ifndef USE_POLL
+                       if (ret == 0 && timeout > 0)
+                               return LIBALTOS_TIMEOUT;
+#endif
+               }
+       }
+       if (file->in_used && 0) {
+               printf ("fill \"");
+               fwrite(file->in_data, 1, file->in_used, stdout);
+               printf ("\"\n");
+       }
+       return 0;
+}
+
+PUBLIC int
+altos_getchar(struct altos_file *file, int timeout)
+{
+       int     ret;
+       while (file->in_read == file->in_used) {
+               if (file->fd < 0)
+                       return LIBALTOS_ERROR;
+               ret = altos_fill(file, timeout);
+               if (ret)
+                       return ret;
+       }
+       return file->in_data[file->in_read++];
+}
+
+#endif /* POSIX_TTY */
+
 /*
  * Scan for Altus Metrum devices by looking through /sys
  */
 /*
  * Scan for Altus Metrum devices by looking through /sys
  */
@@ -68,6 +292,10 @@ altos_strndup (const char *s, size_t n)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/rfcomm.h>
 
 static char *
 cc_fullname (char *dir, char *file)
 
 static char *
 cc_fullname (char *dir, char *file)
@@ -354,6 +582,129 @@ altos_list_finish(struct altos_list *usbdevs)
        free(usbdevs);
 }
 
        free(usbdevs);
 }
 
+struct altos_bt_list {
+       inquiry_info    *ii;
+       int             sock;
+       int             dev_id;
+       int             rsp;
+       int             num_rsp;
+};
+
+#define INQUIRY_MAX_RSP        255
+#define INQUIRY_LEN    8
+
+struct altos_bt_list *
+altos_bt_list_start(void)
+{
+       struct altos_bt_list    *bt_list;
+
+       bt_list = calloc(1, sizeof (struct altos_bt_list));
+       if (!bt_list)
+               goto no_bt_list;
+
+       bt_list->ii = calloc(INQUIRY_MAX_RSP, sizeof (inquiry_info));
+       if (!bt_list->ii)
+               goto no_ii;
+       bt_list->dev_id = hci_get_route(NULL);
+       if (bt_list->dev_id < 0)
+               goto no_dev_id;
+
+       bt_list->sock = hci_open_dev(bt_list->dev_id);
+       if (bt_list->sock < 0)
+               goto no_sock;
+
+       bt_list->num_rsp = hci_inquiry(bt_list->dev_id,
+                                      INQUIRY_LEN,
+                                      INQUIRY_MAX_RSP,
+                                      NULL,
+                                      &bt_list->ii,
+                                      IREQ_CACHE_FLUSH);
+       if (bt_list->num_rsp < 0)
+               goto no_rsp;
+
+       bt_list->rsp = 0;
+       return bt_list;
+
+no_rsp:
+       close(bt_list->sock);
+no_sock:
+no_dev_id:
+       free(bt_list->ii);
+no_ii:
+       free(bt_list);
+no_bt_list:
+       return NULL;
+}
+
+int
+altos_bt_list_next(struct altos_bt_list *bt_list,
+                  struct altos_bt_device *device)
+{
+       inquiry_info    *ii;
+
+       if (bt_list->rsp >= bt_list->num_rsp)
+               return 0;
+
+       ii = &bt_list->ii[bt_list->rsp];
+       ba2str(&ii->bdaddr, device->addr);
+       memset(&device->name, '\0', sizeof (device->name));
+       if (hci_read_remote_name(bt_list->sock, &ii->bdaddr,
+                                sizeof (device->name),
+                                device->name, 0) < 0) {
+               strcpy(device->name, "[unknown]");
+       }
+       bt_list->rsp++;
+       return 1;
+}
+
+void
+altos_bt_list_finish(struct altos_bt_list *bt_list)
+{
+       close(bt_list->sock);
+       free(bt_list->ii);
+       free(bt_list);
+}
+
+struct altos_file *
+altos_bt_open(struct altos_bt_device *device)
+{
+       struct sockaddr_rc addr = { 0 };
+       int     s, status;
+       struct altos_file *file;
+
+       file = calloc(1, sizeof (struct altos_file));
+       if (!file)
+               goto no_file;
+       file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+       if (file->fd < 0)
+               goto no_sock;
+
+       addr.rc_family = AF_BLUETOOTH;
+       addr.rc_channel = 1;
+       str2ba(device->addr, &addr.rc_bdaddr);
+
+       status = connect(file->fd,
+                        (struct sockaddr *)&addr,
+                        sizeof(addr));
+       if (status < 0) {
+               perror("connect");
+               goto no_link;
+       }
+
+#ifdef USE_POLL
+       pipe(file->pipe);
+#else
+       file->out_fd = dup(file->fd);
+#endif
+       return file;
+no_link:
+       close(s);
+no_sock:
+       free(file);
+no_file:
+       return NULL;
+}
+
 #endif
 
 #ifdef DARWIN
 #endif
 
 #ifdef DARWIN
@@ -468,229 +819,6 @@ altos_list_finish(struct altos_list *list)
 
 #endif
 
 
 #endif
 
-#ifdef POSIX_TTY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <errno.h>
-
-#define USB_BUF_SIZE   64
-
-struct altos_file {
-       int                             fd;
-#ifdef USE_POLL
-       int                             pipe[2];
-#else
-       int                             out_fd;
-#endif
-       unsigned char                   out_data[USB_BUF_SIZE];
-       int                             out_used;
-       unsigned char                   in_data[USB_BUF_SIZE];
-       int                             in_used;
-       int                             in_read;
-};
-
-PUBLIC struct altos_file *
-altos_open(struct altos_device *device)
-{
-       struct altos_file       *file = calloc (sizeof (struct altos_file), 1);
-       int                     ret;
-       struct termios          term;
-
-       if (!file)
-               return NULL;
-
-       file->fd = open(device->path, O_RDWR | O_NOCTTY);
-       if (file->fd < 0) {
-               perror(device->path);
-               free(file);
-               return NULL;
-       }
-#ifdef USE_POLL
-       pipe(file->pipe);
-#else
-       file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
-       if (file->out_fd < 0) {
-               perror(device->path);
-               close(file->fd);
-               free(file);
-               return NULL;
-       }
-#endif
-       ret = tcgetattr(file->fd, &term);
-       if (ret < 0) {
-               perror("tcgetattr");
-               close(file->fd);
-#ifndef USE_POLL
-               close(file->out_fd);
-#endif
-               free(file);
-               return NULL;
-       }
-       cfmakeraw(&term);
-#ifdef USE_POLL
-       term.c_cc[VMIN] = 1;
-       term.c_cc[VTIME] = 0;
-#else
-       term.c_cc[VMIN] = 0;
-       term.c_cc[VTIME] = 1;
-#endif
-       ret = tcsetattr(file->fd, TCSAFLUSH, &term);
-       if (ret < 0) {
-               perror("tcsetattr");
-               close(file->fd);
-#ifndef USE_POLL
-               close(file->out_fd);
-#endif
-               free(file);
-               return NULL;
-       }
-       return file;
-}
-
-PUBLIC void
-altos_close(struct altos_file *file)
-{
-       if (file->fd != -1) {
-               int     fd = file->fd;
-               file->fd = -1;
-#ifdef USE_POLL
-               write(file->pipe[1], "\r", 1);
-#else
-               close(file->out_fd);
-               file->out_fd = -1;
-#endif
-               close(fd);
-       }
-}
-
-PUBLIC void
-altos_free(struct altos_file *file)
-{
-       altos_close(file);
-       free(file);
-}
-
-PUBLIC int
-altos_flush(struct altos_file *file)
-{
-       if (file->out_used && 0) {
-               printf ("flush \"");
-               fwrite(file->out_data, 1, file->out_used, stdout);
-               printf ("\"\n");
-       }
-       while (file->out_used) {
-               int     ret;
-
-               if (file->fd < 0)
-                       return -EBADF;
-#ifdef USE_POLL
-               ret = write (file->fd, file->out_data, file->out_used);
-#else
-               ret = write (file->out_fd, file->out_data, file->out_used);
-#endif
-               if (ret < 0)
-                       return -errno;
-               if (ret) {
-                       memmove(file->out_data, file->out_data + ret,
-                               file->out_used - ret);
-                       file->out_used -= ret;
-               }
-       }
-       return 0;
-}
-
-PUBLIC int
-altos_putchar(struct altos_file *file, char c)
-{
-       int     ret;
-
-       if (file->out_used == USB_BUF_SIZE) {
-               ret = altos_flush(file);
-               if (ret) {
-                       return ret;
-               }
-       }
-       file->out_data[file->out_used++] = c;
-       ret = 0;
-       if (file->out_used == USB_BUF_SIZE)
-               ret = altos_flush(file);
-       return 0;
-}
-
-#ifdef USE_POLL
-#include <poll.h>
-#endif
-
-static int
-altos_fill(struct altos_file *file, int timeout)
-{
-       int             ret;
-#ifdef USE_POLL
-       struct pollfd   fd[2];
-#endif
-
-       if (timeout == 0)
-               timeout = -1;
-       while (file->in_read == file->in_used) {
-               if (file->fd < 0)
-                       return LIBALTOS_ERROR;
-#ifdef USE_POLL
-               fd[0].fd = file->fd;
-               fd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
-               fd[1].fd = file->pipe[0];
-               fd[1].events = POLLIN;
-               ret = poll(fd, 2, timeout);
-               if (ret < 0) {
-                       perror("altos_getchar");
-                       return LIBALTOS_ERROR;
-               }
-               if (ret == 0)
-                       return LIBALTOS_TIMEOUT;
-
-               if (fd[0].revents & (POLLHUP|POLLERR|POLLNVAL))
-                       return LIBALTOS_ERROR;
-               if (fd[0].revents & POLLIN)
-#endif
-               {
-                       ret = read(file->fd, file->in_data, USB_BUF_SIZE);
-                       if (ret < 0) {
-                               perror("altos_getchar");
-                               return LIBALTOS_ERROR;
-                       }
-                       file->in_read = 0;
-                       file->in_used = ret;
-#ifndef USE_POLL
-                       if (ret == 0 && timeout > 0)
-                               return LIBALTOS_TIMEOUT;
-#endif
-               }
-       }
-       if (file->in_used && 0) {
-               printf ("fill \"");
-               fwrite(file->in_data, 1, file->in_used, stdout);
-               printf ("\"\n");
-       }
-       return 0;
-}
-
-PUBLIC int
-altos_getchar(struct altos_file *file, int timeout)
-{
-       int     ret;
-       while (file->in_read == file->in_used) {
-               if (file->fd < 0)
-                       return LIBALTOS_ERROR;
-               ret = altos_fill(file, timeout);
-               if (ret)
-                       return ret;
-       }
-       return file->in_data[file->in_read++];
-}
-
-#endif /* POSIX_TTY */
 
 #ifdef WINDOWS
 
 
 #ifdef WINDOWS
 
index 0e5691cb87b8acd6e9649f819f97d4f673387b9e..9c3f965589d754b2a6ee784429c3e1c9c6a20d8f 100644 (file)
@@ -58,6 +58,15 @@ struct altos_device {
        //%mutable;
 };
 
        //%mutable;
 };
 
+#define BLUETOOTH_PRODUCT_TELEBT       "TeleBT"
+
+struct altos_bt_device {
+       //%immutable;
+       char                            name[256];
+       char                            addr[20];
+       //%mutable;
+};
+
 #define LIBALTOS_SUCCESS       0
 #define LIBALTOS_ERROR         -1
 #define LIBALTOS_TIMEOUT       -2
 #define LIBALTOS_SUCCESS       0
 #define LIBALTOS_ERROR         -1
 #define LIBALTOS_TIMEOUT       -2
@@ -100,4 +109,16 @@ altos_flush(struct altos_file *file);
 PUBLIC int
 altos_getchar(struct altos_file *file, int timeout);
 
 PUBLIC int
 altos_getchar(struct altos_file *file, int timeout);
 
+PUBLIC struct altos_bt_list *
+altos_bt_list_start(void);
+
+PUBLIC int
+altos_bt_list_next(struct altos_bt_list *list, struct altos_bt_device *device);
+
+PUBLIC void
+altos_bt_list_finish(struct altos_bt_list *list);
+
+PUBLIC struct altos_file *
+altos_bt_open(struct altos_bt_device *device);
+
 #endif /* _LIBALTOS_H_ */
 #endif /* _LIBALTOS_H_ */