bt_dev API
Iain Hibbert
plunky at rya-online.net
Wed Jun 10 08:17:09 UTC 2009
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
-------------- next part --------------
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 ++;
More information about the freebsd-bluetooth
mailing list