pkgsrc/comms/obexftp/patches/patch-aj

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"