218 lines
4.4 KiB
Text
218 lines
4.4 KiB
Text
$NetBSD: patch-aj,v 1.2 2009/07/20 05:56:03 hasso Exp $
|
|
|
|
--- apps/bt_discovery.c.orig 2006-01-11 17:27:35.000000000 +0000
|
|
+++ apps/bt_discovery.c
|
|
@@ -10,6 +10,205 @@
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
|
|
+#if defined(__NetBSD__) || defined(__DragonFly__)
|
|
+#include <bluetooth.h>
|
|
+#include <err.h>
|
|
+#include <errno.h>
|
|
+#include <sdp.h>
|
|
+
|
|
+#include "bt_discovery.h"
|
|
+
|
|
+/*
|
|
+ * Parse protocol descriptor list for the RFCOMM channel
|
|
+ *
|
|
+ * seq8 len8 2
|
|
+ * seq8 len8 2
|
|
+ * uuid16 value16 3 L2CAP
|
|
+ * seq8 len8 2
|
|
+ * uuid16 value16 3 RFCOMM
|
|
+ * uint8 value8 2 channel
|
|
+ * ===
|
|
+ * 14
|
|
+ */
|
|
+
|
|
+static int32_t
|
|
+parse_rfcomm_channel(sdp_attr_t *a)
|
|
+{
|
|
+ uint8_t *ptr = a->value;
|
|
+ uint8_t *end = a->value + a->vlen;
|
|
+ int32_t type, len, uuid, channel;
|
|
+
|
|
+ if (end - ptr < 14)
|
|
+ return (-1);
|
|
+
|
|
+ SDP_GET8(type, ptr);
|
|
+ switch (type) {
|
|
+ case SDP_DATA_SEQ8:
|
|
+ SDP_GET8(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ16:
|
|
+ SDP_GET16(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ32:
|
|
+ SDP_GET32(len, ptr);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return (-1);
|
|
+ }
|
|
+ if (ptr + len > end)
|
|
+ return (-1);
|
|
+
|
|
+ /* Protocol */
|
|
+ SDP_GET8(type, ptr);
|
|
+ switch (type) {
|
|
+ case SDP_DATA_SEQ8:
|
|
+ SDP_GET8(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ16:
|
|
+ SDP_GET16(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ32:
|
|
+ SDP_GET32(len, ptr);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return (-1);
|
|
+ }
|
|
+ if (ptr + len > end)
|
|
+ return (-1);
|
|
+
|
|
+ /* UUID */
|
|
+ if (ptr + 3 > end)
|
|
+ return (-1);
|
|
+ SDP_GET8(type, ptr);
|
|
+ switch (type) {
|
|
+ case SDP_DATA_UUID16:
|
|
+ SDP_GET16(uuid, ptr);
|
|
+ if (uuid != SDP_UUID_PROTOCOL_L2CAP)
|
|
+ return (-1);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */
|
|
+ case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */
|
|
+ default:
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ /* Protocol */
|
|
+ SDP_GET8(type, ptr);
|
|
+ switch (type) {
|
|
+ case SDP_DATA_SEQ8:
|
|
+ SDP_GET8(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ16:
|
|
+ SDP_GET16(len, ptr);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_SEQ32:
|
|
+ SDP_GET32(len, ptr);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return (-1);
|
|
+ }
|
|
+ if (ptr + len > end)
|
|
+ return (-1);
|
|
+
|
|
+ /* UUID */
|
|
+ if (ptr + 3 > end)
|
|
+ return (-1);
|
|
+ SDP_GET8(type, ptr);
|
|
+ switch (type) {
|
|
+ case SDP_DATA_UUID16:
|
|
+ SDP_GET16(uuid, ptr);
|
|
+ if (uuid != SDP_UUID_PROTOCOL_RFCOMM)
|
|
+ return (-1);
|
|
+ break;
|
|
+
|
|
+ case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */
|
|
+ case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */
|
|
+ default:
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ /* channel */
|
|
+ if (ptr + 2 > end)
|
|
+ return (-1);
|
|
+
|
|
+ SDP_GET8(type, ptr);
|
|
+ if (type != SDP_DATA_UINT8)
|
|
+ return (-1);
|
|
+
|
|
+ SDP_GET8(channel, ptr);
|
|
+
|
|
+ return (channel);
|
|
+}
|
|
+
|
|
+int
|
|
+discover_bt(char *addr, char **res_bdaddr, int *res_channel)
|
|
+{
|
|
+ bdaddr_t laddr, raddr;
|
|
+ uint8_t buffer[256];
|
|
+ sdp_attr_t proto = { SDP_ATTR_INVALID, 0, sizeof(buffer), buffer };
|
|
+ uint16_t serv = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER;
|
|
+ uint32_t attr = SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
|
|
+ SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
|
|
+ void *ss;
|
|
+
|
|
+ /*
|
|
+ * Convert given address to bdaddr. If not bdaddr,
|
|
+ * look it up in hosts database.
|
|
+ *
|
|
+ * XXX original does an inquiry if no name is given,
|
|
+ * XXX and matches against the name given or uses
|
|
+ * XXX the first device found. Consider that.
|
|
+ */
|
|
+ if (addr == NULL)
|
|
+ errx(1, "must have address");
|
|
+
|
|
+ if (!bt_aton(addr, &raddr)) {
|
|
+ struct hostent *he = NULL;
|
|
+
|
|
+ if ((he = bt_gethostbyname(addr)) == NULL)
|
|
+ errx(1, "%s: %s",
|
|
+ addr, hstrerror(h_errno));
|
|
+
|
|
+ bdaddr_copy(&raddr, (bdaddr_t *)he->h_addr);
|
|
+ }
|
|
+
|
|
+ *res_bdaddr = strdup(bt_ntoa(&raddr, NULL));
|
|
+ fprintf(stderr, "Browsing %s ...\n", *res_bdaddr);
|
|
+
|
|
+ /*
|
|
+ * Connect to remote SDP server to find the channel
|
|
+ * number to use for the OBEX_FILE_TRANSFER service
|
|
+ */
|
|
+ bdaddr_copy(&laddr, BDADDR_ANY);
|
|
+ ss = sdp_open(&laddr, &raddr);
|
|
+ if (ss == NULL || (errno = sdp_error(ss)) != 0)
|
|
+ err(1, "%s", addr);
|
|
+
|
|
+ if (sdp_search(ss, 1, &serv, 1, &attr, 1, &proto) != 0)
|
|
+ errx(1, "sdp_search", strerror(sdp_error(ss)));
|
|
+
|
|
+ if (proto.flags != SDP_ATTR_OK)
|
|
+ errx(1, "sdp_search: File Transfer not available");
|
|
+
|
|
+ sdp_close(ss);
|
|
+
|
|
+ *res_channel = parse_rfcomm_channel(&proto);
|
|
+ if (*res_channel == -1)
|
|
+ errx(1, "sdp_search: No Channel #");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#else
|
|
#include <bluetooth/bluetooth.h>
|
|
#include <bluetooth/hci.h>
|
|
#include <bluetooth/hci_lib.h>
|
|
@@ -146,6 +345,7 @@ int discover_bt(char *addr, char **res_b
|
|
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
#else
|
|
#include "bt_discovery.h"
|