bt_dev API

View: New views
5 Messages — Rating Filter:   Alert me  

bt_dev API

by Iain Hibbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Max,

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)

some questions re API still to be resolved though

- bt_devopen(name, flags) flags argument?
                                  BTOPT_DIRECTION
                                  BTOPT_TIMESTAMP

- bt_devclose(s) should not be required?

- ssize_t bt_devsend() return number of bytes sent?

- bt_devinfo(name, info) add name argument?

- struct bt_devinfo state field needs to be genericalised,

regards,
iain
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Re: bt_dev API

by Maksim Yevmenkin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Iain,

> 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 :(

> some questions re API still to be resolved though
>
> - bt_devopen(name, flags)       flags argument?
>                                  BTOPT_DIRECTION
>                                  BTOPT_TIMESTAMP

i guess its fine, but i still kinda like setopt() call.

> - bt_devclose(s)                should not be required?

i'd like to just keep it for clarity. we can turn it into #define if needed

> - ssize_t bt_devsend()          return number of bytes sent?

sure

> - bt_devinfo(name, info)        add name argument?

no problem

> - struct bt_devinfo             state field needs to be genericalised,

i have not look at the source. i'm guessing its probably fine too :)

thanks,
max
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Re: bt_dev API

by Iain Hibbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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 ++;

_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Re: bt_dev API

by Iain Hibbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 10 Jun 2009, Iain Hibbert wrote:

> > > - 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

Ok, BlueZ has a HCI_UP flag that they use to mean device enabled, NetBSD
has BTF_UP and FreeBSD has 'state == connected' to mean the same thing (?)

So, I propose the simplified 'publicly documented' interface as follows

--

Obtain information from a Bluetooth device present in the system.
The
.Fa info
argument is a pointer to a
.Ft bt_devinfo
structure into which information about device
.Fa name
is placed.
The
.Ft bt_devinfo
structure contains at least the following fields:
.Bd -literal
        char        devname[HCI_DEVNAME_SIZE];
        int         enabled;    /* device is enabled */

        /* device information */
        bdaddr_t    bdaddr;
        uint8_t     features[HCI_FEATURES_SIZE];
        uint16_t    acl_size;
        uint16_t    sco_size;

        /* flow control */
        uint16_t    cmd_free;
        uint16_t    acl_free;
        uint16_t    sco_free;

        /* statistics */
        uint32_t    cmd_sent;
        uint32_t    evnt_recv;
        uint32_t    acl_recv;
        uint32_t    acl_sent;
        uint32_t    sco_recv;
        uint32_t    sco_sent;
        uint32_t    bytes_recv;
        uint32_t    bytes_sent;

        /* device settings */
        uint16_t    link_policy_info;
        uint16_t    packet_type_info;
        uint16_t    role_switch_info;
.Ed
.Lp
Because a Bluetooth device must be enabled in order to retrieve
information, the
.Fa enabled
flag should be tested to be non-zero before relying on further data.

--

So, I dropped all the struct padding as no caller needs to care about it,
plus acl_pkts and sco_pkts as from what I can see, they are not properly
available (only FreeBSD provides such a 'max' value but its not really
part of the HCI spec, devices will only ever provide 'current' value)

thoughts?

iain
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."

Re: bt_dev API

by Iain Hibbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 10 Jun 2009, Iain Hibbert wrote:

> plus acl_pkts and sco_pkts as from what I can see, they are not properly
> available (only FreeBSD provides such a 'max' value but its not really
> part of the HCI spec, devices will only ever provide 'current' value)

sigh, that is wrong, they come from HCI_CMD_READ_BUFFER_SIZE of course..

iain
_______________________________________________
freebsd-bluetooth@... mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
To unsubscribe, send any mail to "freebsd-bluetooth-unsubscribe@..."