summaryrefslogtreecommitdiff
path: root/usr.bin/sdpquery/command.c
diff options
context:
space:
mode:
authorplunky <plunky@NetBSD.org>2009-05-12 18:37:50 +0000
committerplunky <plunky@NetBSD.org>2009-05-12 18:37:50 +0000
commit384153c15add471f372ea7eeab726d9afe1fd790 (patch)
tree1d79b16938ccb7ae7a6694300dcf91ce27fe7d46 /usr.bin/sdpquery/command.c
parent04b1ea702b993c562cbd027e89877d1b4c7ff08f (diff)
update sdpquery with a newer version that fetches the whole service
record and displays it in a human readable fashion.
Diffstat (limited to 'usr.bin/sdpquery/command.c')
-rw-r--r--usr.bin/sdpquery/command.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/usr.bin/sdpquery/command.c b/usr.bin/sdpquery/command.c
new file mode 100644
index 00000000000..8e44307fcae
--- /dev/null
+++ b/usr.bin/sdpquery/command.c
@@ -0,0 +1,240 @@
+/* $NetBSD: command.c,v 1.1 2009/05/12 18:37:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: command.c,v 1.1 2009/05/12 18:37:50 plunky Exp $");
+
+#include <bluetooth.h>
+#include <err.h>
+#include <sdp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sdpquery.h"
+
+static sdp_session_t open_session(void);
+static void build_ssp(sdp_data_t *, int, const char **);
+
+static struct alias {
+ uint16_t uuid;
+ const char * name;
+ const char * desc;
+} aliases[] = {
+ { SDP_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION,
+ "A2DP", "Advanced Audio Distribution Profile" },
+ { SDP_UUID_PROTOCOL_BNEP,
+ "BNEP", "Bluetooth Network Encapsulation Protocol" },
+ { SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS,
+ "CIP", "Common ISDN Access Service" },
+ { SDP_SERVICE_CLASS_CORDLESS_TELEPHONY,
+ "CTP", "Cordless Telephony Service" },
+ { SDP_SERVICE_CLASS_DIALUP_NETWORKING,
+ "DUN", "Dial Up Networking Service" },
+ { SDP_SERVICE_CLASS_FAX,
+ "FAX", "Fax Service" },
+ { SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER,
+ "FTRN", "File Transfer Service" },
+ { SDP_SERVICE_CLASS_GN,
+ "GN", "Group ad-hoc Network Service" },
+ { SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE,
+ "HID", "Human Interface Device Service" },
+ { SDP_SERVICE_CLASS_HANDSFREE,
+ "HF", "Handsfree Service" },
+ { SDP_SERVICE_CLASS_HEADSET,
+ "HSET", "Headset Service" },
+ { SDP_UUID_PROTOCOL_L2CAP,
+ "L2CAP", "Logical Link Control and Adapatation Protocol" },
+ { SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP,
+ "LAN", "Lan access using PPP Service" },
+ { SDP_SERVICE_CLASS_NAP,
+ "NAP", "Network Access Point Service" },
+ { SDP_UUID_PROTOCOL_OBEX,
+ "OBEX", "Object Exchange Protocol" },
+ { SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH,
+ "OPUSH", "Object Push Service" },
+ { SDP_SERVICE_CLASS_PANU,
+ "PANU", "Personal Area Networking User Service" },
+ { SDP_UUID_PROTOCOL_RFCOMM,
+ "RFCOMM", "RFCOMM Protocol" },
+ { SDP_UUID_PROTOCOL_SDP,
+ "SDP", "Service Discovery Protocol" },
+ { SDP_SERVICE_CLASS_SERIAL_PORT,
+ "SP", "Serial Port Service" },
+ { SDP_SERVICE_CLASS_IR_MC_SYNC,
+ "SYNC", "IrMC Sync Client Service" },
+};
+
+int
+do_sdp_browse(int argc, const char **argv)
+{
+#define STR(x) __STRING(x)
+ const char *av = STR(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
+#undef STR
+
+ if (argc > 1)
+ errx(EXIT_FAILURE, "Too many arguments");
+
+ if (argc == 0) {
+ argc = 1;
+ argv = &av;
+ }
+
+ return do_sdp_search(argc, argv);
+}
+
+int
+do_sdp_record(int argc, const char **argv)
+{
+ sdp_session_t ss;
+ sdp_data_t rsp;
+ char * ep;
+ unsigned long handle;
+ bool rv;
+
+ if (argc == 0)
+ errx(EXIT_FAILURE, "Record handle required");
+
+ ss = open_session();
+
+ for (; argc-- > 0; argv++) {
+ handle = strtoul(*argv, &ep, 0);
+ if (*argv[0] == '\0' || *ep != '\0' || handle > UINT32_MAX)
+ errx(EXIT_FAILURE, "Invalid handle: %s\n", *argv);
+
+ rv = sdp_service_attribute(ss, handle, NULL, &rsp);
+ if (!rv)
+ warn("%s", *argv);
+ else
+ print_record(&rsp);
+
+ if (argc > 0)
+ printf("\n\n");
+ }
+
+ sdp_close(ss);
+ return EXIT_SUCCESS;
+}
+
+int
+do_sdp_search(int argc, const char **argv)
+{
+ sdp_session_t ss;
+ sdp_data_t ssp, rec, rsp;
+ bool rv;
+
+ if (argc < 1)
+ errx(EXIT_FAILURE, "UUID required");
+
+ if (argc > 12)
+ errx(EXIT_FAILURE, "Too many UUIDs");
+
+ build_ssp(&ssp, argc, argv);
+
+ ss = open_session();
+
+ rv = sdp_service_search_attribute(ss, &ssp, NULL, &rsp);
+ if (!rv)
+ err(EXIT_FAILURE, "sdp_service_search_attribute");
+
+ while (sdp_get_seq(&rsp, &rec)) {
+ if (!rv)
+ printf("\n\n");
+ else
+ rv = false;
+
+ print_record(&rec);
+ }
+
+ if (rsp.next != rsp.end) {
+ printf("\n\nAdditional Data:\n");
+ sdp_data_print(&rsp, 4);
+ }
+
+ sdp_close(ss);
+
+ return EXIT_SUCCESS;
+}
+
+static sdp_session_t
+open_session(void)
+{
+ sdp_session_t ss;
+
+ if (bdaddr_any(&remote_addr))
+ ss = sdp_open_local(control_socket);
+ else
+ ss = sdp_open(&local_addr, &remote_addr);
+
+ if (ss == NULL)
+ err(EXIT_FAILURE, "sdp_open");
+
+ return ss;
+}
+
+/*
+ * build ServiceSearchPattern from arglist
+ */
+static void
+build_ssp(sdp_data_t *ssp, int argc, const char **argv)
+{
+ static uint8_t data[36]; /* 12 * sizeof(uuid16) */
+ char * ep;
+ unsigned long uuid;
+ int i;
+
+ ssp->next = data;
+ ssp->end = data + sizeof(data);
+
+ for (; argc-- > 0; argv++) {
+ uuid = strtoul(*argv, &ep, 0);
+ if (*argv[0] == '\0' || *ep != '\0') {
+ for (i = 0;; i++) {
+ if (i == __arraycount(aliases))
+ errx(EXIT_FAILURE,
+ "Unknown alias \"%s\"", *argv);
+
+ if (strcasecmp(aliases[i].name, *argv) == 0)
+ break;
+ }
+
+ uuid = aliases[i].uuid;
+ }
+
+ if (uuid > UINT16_MAX)
+ errx(EXIT_FAILURE, "%s: Not 16-bit UUID", *argv);
+
+ sdp_put_uuid16(ssp, uuid);
+ }
+
+ ssp->end = ssp->next;
+ ssp->next = data;
+ return;
+}