On Tue, 9 Jun 2009, Maksim Yevmenkin wrote:

> > Are you still with us?  After some delay (and a tan from last week :) I am
> > about ready with the bt_dev stuff for NetBSD now (latest dump at
> > www.netbsd.org:~plunky/btdev-20090609.tar.gz)
>
> sorry. i'm completely swamped at $real_job :(

sounds like hair loss is imminent, heh :)

> > - bt_devopen(name, flags) flags argument?
>
> i guess its fine, but i still kinda like setopt() call.

my reasoning to set it in devopen is that if you open -> bind -> setopt
then there is a race condition where you could get packets already in the
buffer where you don't get the control messages.

anyway I attach a FreeBSD patch for you that implements some changes -
note I haven't compile tested it, and I don't know if you need to bump
library version but it looks about right

 - spelling fixes in manpage
 - add flags argument to bt_devopen()
 - bt_devopen(NULL, 0) will open for any device
 - change return value of bt_devsend()
 - add name argument to bt_devinfo()

> > - struct bt_devinfo state field needs to be genericalised,
>
> i have not look at the source. i'm guessing its probably fine too :)

I'm still thinking about how best to do that, will look at the linux
sources later to see what might fit.  I'm thinking that either

a) bt_devinfo structure should be completely MI and have the caller get OS
specific information on their own time

b) incompletely specify the bt_devinfo structure in the manpage (as in
"the bt_devinfo structure contains at least the following fields:") so
that callers are not tempted to rely on OS specific data.

regards,
iain
Index: bluetooth.3
===================================================================
RCS file: /home/ncvs/src/lib/libbluetooth/bluetooth.3,v
retrieving revision 1.10
diff -u -r1.10 bluetooth.3
--- bluetooth.3 22 Apr 2009 15:50:03 -0000      1.10
+++ bluetooth.3 10 Jun 2009 08:01:18 -0000
@@ -97,14 +97,14 @@
 .Ft int
 .Fn (bt_devenum_cb_t) "int s" "struct bt_devinfo const *di" "void *arg"
 .Ft int
-.Fn bt_devinfo "struct bt_devinfo *di"
+.Fn bt_devinfo "char const *devname" "struct bt_devinfo *di"
 .Ft int
 .Fn bt_devenum "bt_devenum_cb_t *cb" "void *arg"
 .Ft int
-.Fn bt_devopen "char const *devname"
+.Fn bt_devopen "char const *devname" "int flags"
 .Ft int
 .Fn bt_devclose "int s"
-.Ft int
+.Ft ssize_t
 .Fn bt_devsend "int s" "uint16_t opcode" "void *param" "size_t plen"
 .Ft ssize_t
 .Fn bt_devrecv "int s" "void *buf" "size_t size" "time_t to"
@@ -115,13 +115,13 @@
 .Ft void
 .Fn bt_devfilter_pkt_set "struct bt_devfilter *filter" "uint8_t type"
 .Ft void
-.Fn bt_devfilter_pkt_clt "struct bt_devfilter *filter" "uint8_t type"
+.Fn bt_devfilter_pkt_clr "struct bt_devfilter *filter" "uint8_t type"
 .Ft int
 .Fn bt_devfilter_pkt_tst "struct bt_devfilter const *filter" "uint8_t type"
 .Ft void
 .Fn bt_devfilter_evt_set "struct bt_devfilter *filter" "uint8_t event"
 .Ft void
-.Fn bt_devfilter_evt_clt "struct bt_devfilter *filter" "uint8_t event"
+.Fn bt_devfilter_evt_clr "struct bt_devfilter *filter" "uint8_t event"
 .Ft int
 .Fn bt_devfilter_evt_tst "struct bt_devfilter const *filter" "uint8_t event"
 .Ft int
@@ -272,14 +272,9 @@
 .Pp
 The
 .Fn bt_devinfo
-function populates prodivded
+function populates provided
 .Vt bt_devinfo
 structure with the information about given Bluetooth device.
-The caller is expected to pass Bluetooth device name in the
-.Fa devname
-field of the passed
-.Vt bt_devinfo
-structure.
 The function returns 0 when successful,
 otherwise -1.
 The
@@ -360,6 +355,20 @@
 and returns a connected and bound
 .Dv HCI
 socket handle.
+If the
+.Fa devname
+is
+.Dv NULL
+the socket will receive messages from all devices.
+Any combination of the following
+.Fa flags
+may be used to pre-set the socket options:
+.Bl -tag -width ".Dv BTOPT_DIRECTION"
+.It Dv BTOPT_DIRECTION
+Enable control messages on each packet indicating the direction of travel.
+.It Dv BTOPT_TIMESTAMP
+Enable control messages providing packet timestamps.
+.El
 The function returns -1 if an error has occurred.
 .Pp
 The
@@ -383,7 +392,7 @@
 .Xr bt_devopen 3 .
 The
 .Fa opcode
-parameter is exppected to be in the host byte order.
+parameter is expected to be in the host byte order.
 The
 .Fa param
 and
@@ -395,7 +404,7 @@
 .Dv HCI
 filter on the provided socket
 .Fa s .
-The function returns 0 on success,
+The function returns the number of characters successfully written,
 or -1 if an error occurred.
 .Pp
 The
Index: bluetooth.h
===================================================================
RCS file: /home/ncvs/src/lib/libbluetooth/bluetooth.h,v
retrieving revision 1.5
diff -u -r1.5 bluetooth.h
--- bluetooth.h 22 Apr 2009 15:50:03 -0000      1.5
+++ bluetooth.h 10 Jun 2009 08:01:18 -0000
@@ -158,9 +158,9 @@
 
 typedef int    (bt_devenum_cb_t)(int, struct bt_devinfo const *, void *);
 
-int            bt_devopen (char const *devname);
+int            bt_devopen (char const *devname, int flags);
 int            bt_devclose(int s);
-int            bt_devsend (int s, uint16_t opcode, void *param, size_t plen);
+ssize_t                bt_devsend (int s, uint16_t opcode, void *param, size_t 
plen);
 ssize_t                bt_devrecv (int s, void *buf, size_t size, time_t to);
 int            bt_devreq  (int s, struct bt_devreq *r, time_t to);
 int            bt_devfilter(int s, struct bt_devfilter const *new,
@@ -173,10 +173,17 @@
 int            bt_devfilter_evt_tst(struct bt_devfilter const *filter, uint8_t 
event);
 int            bt_devinquiry(char const *devname, time_t length, int num_rsp,
                              struct bt_devinquiry **ii);
-int            bt_devinfo (struct bt_devinfo *di);
+int            bt_devinfo (char const *devname, struct bt_devinfo *di);
 int            bt_devenum (bt_devenum_cb_t *cb, void *arg);
 
 /*
+ * bt_devopen flags
+ */
+
+#define        BTOPT_DIRECTION         (1 << 0)
+#define        BTOPT_TIMESTAMP         (1 << 1)
+
+/*
  * bdaddr utility functions (from NetBSD)
  */
 
Index: hci.c
===================================================================
RCS file: /home/ncvs/src/lib/libbluetooth/hci.c,v
retrieving revision 1.3
diff -u -r1.3 hci.c
--- hci.c       14 May 2009 17:10:19 -0000      1.3
+++ hci.c       10 Jun 2009 08:01:18 -0000
@@ -45,40 +45,53 @@
 static char * bt_dev2node (char const *devname, char *nodename, int nnlen);
 
 int
-bt_devopen(char const *devname)
+bt_devopen(char const *devname, int flags)
 {
        struct sockaddr_hci     ha;
        bdaddr_t                ba;
-       int                     s;
+       int                     opt, s;
 
-       if (devname == NULL) {
-               errno = EINVAL;
-               return (-1);
-       }
-
-       memset(&ha, 0, sizeof(ha));
-       ha.hci_len = sizeof(ha);
-       ha.hci_family = AF_BLUETOOTH;
-
-       if (bt_aton(devname, &ba)) {
-               if (!bt_devname(ha.hci_node, &ba))
-                       return (-1);
-       } else if (bt_dev2node(devname, ha.hci_node,
+       if (devname != NULL) {
+               memset(&ha, 0, sizeof(ha));
+               ha.hci_len = sizeof(ha);
+               ha.hci_family = AF_BLUETOOTH;
+
+               if (bt_aton(devname, &ba)) {
+                       if (!bt_devname(ha.hci_node, &ba))
+                               return (-1);
+               } else if (bt_dev2node(devname, ha.hci_node,
                                        sizeof(ha.hci_node)) == NULL) {
-               errno = ENXIO;
-               return (-1);
+                       errno = ENXIO;
+                       return (-1);
+               }
        }
 
        s = socket(PF_BLUETOOTH, SOCK_RAW, BLUETOOTH_PROTO_HCI);
        if (s < 0)
                return (-1);
 
-       if (bind(s, (struct sockaddr *) &ha, sizeof(ha)) < 0 ||
-           connect(s, (struct sockaddr *) &ha, sizeof(ha)) < 0) {
+       opt = 1;
+       if ((flags & BTOPT_DIRECTION) && setsockopt(s, SOL_HCI_RAW,
+           SO_HCI_RAW_DIRECTION, &opt, sizeof(opt)) < 0) {
                close(s);
                return (-1);
        }
 
+       opt = 1;
+       if ((flags & BTOPT_TIMESTAMP) && setsockopt(s, SOL_SOCKET,
+           SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
+               close(s);
+               return (-1);
+       }
+
+       if (devname != NULL) {
+               if (bind(s, (struct sockaddr *) &ha, sizeof(ha)) < 0 ||
+                   connect(s, (struct sockaddr *) &ha, sizeof(ha)) < 0) {
+                       close(s);
+                       return (-1);
+               }
+       }
+
        return (s);
 }
 
@@ -88,12 +101,13 @@
        return (close(s));
 }
 
-int
+ssize_t
 bt_devsend(int s, uint16_t opcode, void *param, size_t plen)
 {
        ng_hci_cmd_pkt_t        h;
        struct iovec            iv[2];
        int                     ivn;
+       ssize_t                 n;
 
        if ((plen == 0 && param != NULL) ||
            (plen > 0 && param == NULL) ||
@@ -117,14 +131,14 @@
        } else
                h.length = 0;
 
-       while (writev(s, iv, ivn) < 0) {
+       while ((n = writev(s, iv, ivn)) < 0) {
                if (errno == EAGAIN || errno == EINTR)
                        continue;
 
                return (-1);
        }
 
-       return (0);
+       return (n);
 }
 
 ssize_t
@@ -532,7 +546,7 @@
 }
 
 int
-bt_devinfo(struct bt_devinfo *di)
+bt_devinfo(char const *devname, struct bt_devinfo *di)
 {
        union {
                struct ng_btsocket_hci_raw_node_state           r0;
@@ -554,7 +568,7 @@
                return (-1);
        }
 
-       s = bt_devopen(di->devname);
+       s = bt_devopen(devname);
        if (s < 0)
                return (-1);
 
@@ -662,8 +676,7 @@
        }
 
        for (count = 0, i = 0; i < rp.num_names; i ++) {
-               strlcpy(di.devname, rp.names[i].name, sizeof(di.devname));
-               if (bt_devinfo(&di) < 0)
+               if (bt_devinfo(rp.names[i].name, &di) < 0)
                        continue;
 
                count ++;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "[email protected]"

Reply via email to