Module Name:    src
Committed By:   plunky
Date:           Thu Oct  8 19:25:24 UTC 2009

Modified Files:
        src/usr.sbin/btconfig: btconfig.c

Log Message:
fiddle with printing of "Class of Device" information
  - pass the octet stream pointer to the function
  - only print where the format is known (we only know format #0)
  - use language from the Baseband Assigned numbers document
  - use bit numbers from the Baseband Assigned numbers document
  - add Health device major class


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/usr.sbin/btconfig/btconfig.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/btconfig/btconfig.c
diff -u src/usr.sbin/btconfig/btconfig.c:1.17 src/usr.sbin/btconfig/btconfig.c:1.18
--- src/usr.sbin/btconfig/btconfig.c:1.17	Fri Sep 11 19:22:15 2009
+++ src/usr.sbin/btconfig/btconfig.c	Thu Oct  8 19:25:24 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: btconfig.c,v 1.17 2009/09/11 19:22:15 plunky Exp $ */
+/* $NetBSD: btconfig.c,v 1.18 2009/10/08 19:25:24 plunky Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc.  All rights reserved.");
-__RCSID("$NetBSD: btconfig.c,v 1.17 2009/09/11 19:22:15 plunky Exp $");
+__RCSID("$NetBSD: btconfig.c,v 1.18 2009/10/08 19:25:24 plunky Exp $");
 
 #include <sys/ioctl.h>
 #include <sys/param.h>
@@ -48,15 +48,6 @@
 #include <unistd.h>
 #include <util.h>
 
-/* inquiry results storage */
-struct result {
-	bdaddr_t	bdaddr;
-	uint8_t		page_scan_rep_mode;
-	uint8_t		uclass[HCI_CLASS_SIZE];
-	uint16_t	clock_offset;
-	int8_t		rssi;
-};
-
 int main(int, char *[]);
 void badarg(const char *);
 void badparam(const char *);
@@ -67,19 +58,19 @@
 void print_val(const char *, const char **, int);
 void print_info(int);
 void print_stats(void);
-void print_class(const char *);
+void print_class(const char *, uint8_t *);
+void print_class0(void);
 void print_voice(int);
 void tag(const char *);
 void print_features(const char *, uint8_t, uint8_t *);
 void print_features0(uint8_t *);
 void print_features1(uint8_t *);
+void print_result(int, struct bt_devinquiry *);
 void do_inquiry(void);
-void print_result(int, struct result *, int);
 
 void hci_req(uint16_t, uint8_t , void *, size_t, void *, size_t);
-#define save_value(opcode, cbuf, clen)	hci_req(opcode, 0, cbuf, clen, NULL, 0)
-#define load_value(opcode, rbuf, rlen)	hci_req(opcode, 0, NULL, 0, rbuf, rlen)
-#define hci_cmd(opcode, cbuf, clen)	hci_req(opcode, 0, cbuf, clen, NULL, 0)
+void save_value(uint16_t, void *, size_t);
+void load_value(uint16_t, void *, size_t);
 
 #define MAX_STR_SIZE	0xff
 
@@ -151,7 +142,7 @@
 int opt_rssi = 0;			/* inquiry_with_rssi (obsolete flag) */
 int opt_imode = 0;			/* inquiry mode */
 int opt_inquiry = 0;
-#define INQUIRY_LENGTH		10	/* about 12 seconds */
+#define INQUIRY_LENGTH		10	/* seconds */
 #define INQUIRY_MAX_RESPONSES	10
 const char *imodes[] = { "std", "rssi", "ext", NULL };
 
@@ -390,88 +381,53 @@
 }
 
 /*
- * basic HCI cmd request function with argument return.
- *
- * Normally, this will return on COMMAND_STATUS or COMMAND_COMPLETE for the given
- * opcode, but if event is given then it will ignore COMMAND_STATUS (unless error)
- * and wait for the specified event.
- *
- * if rbuf/rlen is given, results will be copied into the result buffer for
- * COMMAND_COMPLETE/event responses.
+ * basic HCI request wrapper with error check
  */
 void
-hci_req(uint16_t opcode, uint8_t event, void *cbuf, size_t clen, void *rbuf, size_t rlen)
+hci_req(uint16_t opcode, uint8_t event, void *cbuf, size_t clen,
+    void *rbuf, size_t rlen)
 {
-	uint8_t msg[sizeof(hci_cmd_hdr_t) + HCI_CMD_PKT_SIZE];
-	hci_event_hdr_t *ep;
-	hci_cmd_hdr_t *cp;
-
-	cp = (hci_cmd_hdr_t *)msg;
-	cp->type = HCI_CMD_PKT;
-	cp->opcode = opcode = htole16(opcode);
-	cp->length = clen = MIN(clen, sizeof(msg) - sizeof(hci_cmd_hdr_t));
-
-	if (clen) memcpy((cp + 1), cbuf, clen);
-
-	if (send(hci, msg, sizeof(hci_cmd_hdr_t) + clen, 0) < 0)
-		err(EXIT_FAILURE, "HCI Send");
-
-	ep = (hci_event_hdr_t *)msg;
-	for(;;) {
-		if (recv(hci, msg, sizeof(msg), 0) < 0) {
-			if (errno == EAGAIN || errno == EINTR)
-				continue;
-
-			err(EXIT_FAILURE, "HCI Recv");
-		}
-
-		if (ep->event == HCI_EVENT_COMMAND_STATUS) {
-			hci_command_status_ep *cs;
-
-			cs = (hci_command_status_ep *)(ep + 1);
-			if (cs->opcode != opcode)
-				continue;
-
-			if (cs->status)
-				errx(EXIT_FAILURE,
-				    "HCI cmd (%4.4x) failed (status %d)",
-				    opcode, cs->status);
-
-			if (event == 0)
-				break;
-
-			continue;
-		}
-
-		if (ep->event == HCI_EVENT_COMMAND_COMPL) {
-			hci_command_compl_ep *cc;
-			uint8_t *ptr;
-
-			cc = (hci_command_compl_ep *)(ep + 1);
-			if (cc->opcode != opcode)
-				continue;
+	struct bt_devreq req;
 
-			if (rbuf == NULL)
-				break;
+	req.opcode = opcode;
+	req.event = event;
+	req.cparam = cbuf;
+	req.clen = clen;
+	req.rparam = rbuf;
+	req.rlen = rlen;
+
+	if (bt_devreq(hci, &req, 10) == -1)
+		err(EXIT_FAILURE, "cmd (%02x|%03x)",
+		    HCI_OGF(opcode), HCI_OCF(opcode));
+
+	if (event == 0 && rlen > 0 && ((uint8_t *)rbuf)[0] != 0)
+		errx(EXIT_FAILURE, "cmd (%02x|%03x): status 0x%02x",
+		    HCI_OGF(opcode), HCI_OCF(opcode), ((uint8_t *)rbuf)[0]);
+}
 
-			ptr = (uint8_t *)(cc + 1);
-			if (*ptr)
-				errx(EXIT_FAILURE,
-				    "HCI cmd (%4.4x) failed (status %d)",
-				    opcode, *ptr);
+/*
+ * write value to device with opcode.
+ * provide a small response buffer so that the status can be checked
+ */
+void
+save_value(uint16_t opcode, void *cbuf, size_t clen)
+{
+	uint8_t buf[1];
 
-			memcpy(rbuf, ++ptr, rlen);
-			break;
-		}
+	hci_req(opcode, 0, cbuf, clen, buf, sizeof(buf));
+}
 
-		if (ep->event == event) {
-			if (rbuf == NULL)
-				break;
+/*
+ * read value from device with opcode.
+ * use our own buffer and only return the value from the response packet
+ */
+void
+load_value(uint16_t opcode, void *rbuf, size_t rlen)
+{
+	uint8_t buf[UINT8_MAX];
 
-			memcpy(rbuf, (ep + 1), rlen);
-			break;
-		}
-	}
+	hci_req(opcode, 0, NULL, 0, buf, sizeof(buf));
+	memcpy(rbuf, buf + 1, rlen);
 }
 
 int
@@ -505,11 +461,8 @@
 config_unit(void)
 {
 
-	if (opt_enable) {
-		if (opt_enable > 0)
-			btr.btr_flags |= BTF_UP;
-		else
-			btr.btr_flags &= ~BTF_UP;
+	if (opt_enable < 0 || opt_reset) {
+		btr.btr_flags &= ~BTF_UP;
 
 		if (ioctl(hci, SIOCSBTFLAGS, &btr) < 0)
 			err(EXIT_FAILURE, "SIOCSBTFLAGS");
@@ -518,22 +471,12 @@
 			err(EXIT_FAILURE, "%s", btr.btr_name);
 	}
 
-	if (opt_reset) {
-		hci_cmd(HCI_CMD_RESET, NULL, 0);
+	if (opt_enable > 0 || opt_reset) {
+		btr.btr_flags |= BTF_UP;
 
-		btr.btr_flags |= BTF_INIT;
 		if (ioctl(hci, SIOCSBTFLAGS, &btr) < 0)
 			err(EXIT_FAILURE, "SIOCSBTFLAGS");
 
-		/*
-		 * although the reset command will automatically
-		 * carry out these commands, we do them manually
-		 * just so we can wait for completion.
-		 */
-		hci_cmd(HCI_CMD_READ_BDADDR, NULL, 0);
-		hci_cmd(HCI_CMD_READ_BUFFER_SIZE, NULL, 0);
-		hci_cmd(HCI_CMD_READ_LOCAL_FEATURES, NULL, 0);
-
 		if (set_unit(SIOCGBTINFO) < 0)
 			err(EXIT_FAILURE, "%s", btr.btr_name);
 	}
@@ -713,8 +656,7 @@
 	}
 
 	load_value(HCI_CMD_READ_UNIT_CLASS, buf, HCI_CLASS_SIZE);
-	class = (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
-	print_class("\t");
+	print_class("\tclass:", buf);
 
 	load_value(HCI_CMD_READ_LOCAL_NAME, buf, HCI_UNIT_NAME_SIZE);
 	printf("\tname: \"%s\"\n", buf);
@@ -790,15 +732,17 @@
 	if ((buf[7] & HCI_LMP_EXTENDED_FEATURES) == 0) {
 		print_features("\tfeatures:", 0, buf);
 	} else {
-		buf[0] = 0;
+		hci_read_local_extended_features_rp rp;
+
+		rp.page = 0;
 
 		do {
 			hci_req(HCI_CMD_READ_LOCAL_EXTENDED_FEATURES, 0,
-				buf, 1,
-				buf, HCI_FEATURES_SIZE + 2);
+			    &rp.page, sizeof(rp.page), &rp, sizeof(rp));
 
-			print_features("\tfeatures page#%d:", buf[0], buf + 2);
-		} while (buf[0]++ < buf[1]);
+			print_features("\tfeatures (page %d):",
+			    rp.page, rp.features);
+		} while (rp.page++ < rp.max_page);
 	}
 }
 
@@ -934,30 +878,39 @@
 }
 
 void
-print_class(const char *str)
+print_class(const char *str, uint8_t *uclass)
 {
-	int major, minor;
 
-	major = (class & 0x1f00) >> 8;
-	minor = (class & 0x00fc) >> 2;
+	class = (uclass[2] << 16) | (uclass[1] << 8) | uclass[0];
+	width = printf("%s [0x%06x]", str, class);
 
-	width = printf("%sclass: [0x%6.6x]", str, class);
+	switch(__SHIFTOUT(class, __BITS(0, 1))) {
+	case 0:	print_class0();		break;
+	default:			break;
+	}
 
-	switch (major) {
+	tag(NULL);
+}
+
+void
+print_class0(void)
+{
+
+	switch (__SHIFTOUT(class, __BITS(8, 12))) {
 	case 1:	/* Computer */
-		switch (minor) {
-		case 1: tag("Desktop");				break;
-		case 2: tag("Server");				break;
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
+		case 1: tag("Desktop workstation");		break;
+		case 2: tag("Server-class computer");		break;
 		case 3: tag("Laptop");				break;
-		case 4: tag("Handheld");			break;
-		case 5: tag("Palm Sized");			break;
-		case 6: tag("Wearable");			break;
+		case 4: tag("Handheld PC/PDA");			break;
+		case 5: tag("Palm Sized PC/PDA");		break;
+		case 6: tag("Wearable computer");		break;
+		default: tag("Computer");			break;
 		}
-		tag("Computer");
 		break;
 
 	case 2:	/* Phone */
-		switch (minor) {
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
 		case 1: tag("Cellular Phone");			break;
 		case 2: tag("Cordless Phone");			break;
 		case 3: tag("Smart Phone");			break;
@@ -969,7 +922,7 @@
 
 	case 3:	/* LAN */
 		tag("LAN");
-		switch ((minor & 0x38) >> 3) {
+		switch (__SHIFTOUT(class, __BITS(5, 7))) {
 		case 0: tag("[Fully available]");		break;
 		case 1: tag("[1-17% utilised]");		break;
 		case 2: tag("[17-33% utilised]");		break;
@@ -982,7 +935,7 @@
 		break;
 
 	case 4:	/* Audio/Visual */
-		switch (minor) {
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
 		case 1: tag("Wearable Headset");		break;
 		case 2: tag("Hands-free Audio");		break;
 		case 4: tag("Microphone");			break;
@@ -1004,7 +957,7 @@
 		break;
 
 	case 5:	/* Peripheral */
-		switch (minor & 0x0f) {
+		switch (__SHIFTOUT(class, __BITS(2, 5))) {
 		case 1: tag("Joystick");			break;
 		case 2: tag("Gamepad");				break;
 		case 3: tag("Remote Control");			break;
@@ -1014,20 +967,20 @@
 		default: tag("Peripheral");			break;
 		}
 
-		if (minor & 0x10) tag("Keyboard");
-		if (minor & 0x20) tag("Mouse");
+		if (class & __BIT(6)) tag("Keyboard");
+		if (class & __BIT(7)) tag("Mouse");
 		break;
 
 	case 6:	/* Imaging */
-		if (minor & 0x20) tag("Printer");
-		if (minor & 0x10) tag("Scanner");
-		if (minor & 0x08) tag("Camera");
-		if (minor & 0x04) tag("Display");
-		if ((minor & 0x3c) == 0) tag("Imaging");
+		if (class & __BIT(4)) tag("Display");
+		if (class & __BIT(5)) tag("Camera");
+		if (class & __BIT(6)) tag("Scanner");
+		if (class & __BIT(7)) tag("Printer");
+		if ((class & __BITS(4, 7)) == 0) tag("Imaging");
 		break;
 
 	case 7:	/* Wearable */
-		switch (minor) {
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
 		case 1: tag("Wrist Watch");			break;
 		case 2: tag("Pager");				break;
 		case 3: tag("Jacket");				break;
@@ -1038,7 +991,7 @@
 		break;
 
 	case 8:	/* Toy */
-		switch (minor) {
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
 		case 1: tag("Robot");				break;
 		case 2: tag("Vehicle");				break;
 		case 3: tag("Doll / Action Figure");		break;
@@ -1048,26 +1001,39 @@
 		}
 		break;
 
+	case 9: /* Health */
+		switch (__SHIFTOUT(class, __BITS(2, 7))) {
+		case 1:	tag("Blood Pressure Monitor");		break;
+		case 2:	tag("Thermometer");			break;
+		case 3:	tag("Weighing Scale");			break;
+		case 4:	tag("Glucose Meter");			break;
+		case 5:	tag("Pulse Oximeter");			break;
+		case 6:	tag("Heart/Pulse Rate Monitor");	break;
+		case 7:	tag("Health Data Display");		break;
+		default: tag("Health");				break;
+		}
+		break;
+
 	default:
 		break;
 	}
 
-	if (class & 0x002000)	tag("<Limited Discoverable>");
-	if (class & 0x010000)	tag("<Positioning>");
-	if (class & 0x020000)	tag("<Networking>");
-	if (class & 0x040000)	tag("<Rendering>");
-	if (class & 0x080000)	tag("<Capturing>");
-	if (class & 0x100000)	tag("<Object Transfer>");
-	if (class & 0x200000)	tag("<Audio>");
-	if (class & 0x400000)	tag("<Telephony>");
-	if (class & 0x800000)	tag("<Information>");
-	tag(NULL);
+	if (class & __BIT(13))	tag("<Limited Discoverable>");
+	if (class & __BIT(16))	tag("<Positioning>");
+	if (class & __BIT(17))	tag("<Networking>");
+	if (class & __BIT(18))	tag("<Rendering>");
+	if (class & __BIT(19))	tag("<Capturing>");
+	if (class & __BIT(20))	tag("<Object Transfer>");
+	if (class & __BIT(21))	tag("<Audio>");
+	if (class & __BIT(22))	tag("<Telephony>");
+	if (class & __BIT(23))	tag("<Information>");
 }
 
 void
 print_voice(int level)
 {
-	printf("\tvoice: [0x%4.4x]\n", voice);
+
+	printf("\tvoice: [0x%04x]\n", voice);
 
 	if (level == 0)
 		return;
@@ -1075,8 +1041,8 @@
 	printf("\t\tInput Coding: ");
 	switch ((voice & 0x0300) >> 8) {
 	case 0x00:	printf("Linear PCM [%d-bit, pos %d]",
-			(voice & 0x0020 ? 16 : 8),
-			(voice & 0x001c) >> 2);		break;
+			    (voice & 0x0020 ? 16 : 8),
+			    (voice & 0x001c) >> 2);	break;
 	case 0x01:	printf("u-Law");		break;
 	case 0x02:	printf("A-Law");		break;
 	case 0x03:	printf("unknown");		break;
@@ -1101,15 +1067,13 @@
 }
 
 void
-print_result(int num, struct result *r, int rssi)
+print_result(int num, struct bt_devinquiry *r)
 {
 	hci_remote_name_req_cp ncp;
 	hci_remote_name_req_compl_ep nep;
 	struct hostent *hp;
 
-	printf("%3d: bdaddr %s",
-			num,
-			bt_ntoa(&r->bdaddr, NULL));
+	printf("%3d: bdaddr %s", num, bt_ntoa(&r->bdaddr, NULL));
 
 	hp = bt_gethostbyaddr((const char *)&r->bdaddr, sizeof(bdaddr_t), AF_BLUETOOTH);
 	if (hp != NULL)
@@ -1119,7 +1083,7 @@
 
 	memset(&ncp, 0, sizeof(ncp));
 	bdaddr_copy(&ncp.bdaddr, &r->bdaddr);
-	ncp.page_scan_rep_mode = r->page_scan_rep_mode;
+	ncp.page_scan_rep_mode = r->pscan_rep_mode;
 	ncp.clock_offset = r->clock_offset;
 
 	hci_req(HCI_CMD_REMOTE_NAME_REQ,
@@ -1128,28 +1092,18 @@
 		&nep, sizeof(nep));
 
 	printf("   : name \"%s\"\n", nep.name);
-
-	class = (r->uclass[2] << 16) | (r->uclass[1] << 8) | (r->uclass[0]);
-	print_class("   : ");
-
-	printf("   : page scan rep mode 0x%02x\n", r->page_scan_rep_mode);
+	print_class("   : class", r->dev_class);
+	printf("   : page scan rep mode 0x%02x\n", r->pscan_rep_mode);
 	printf("   : clock offset %d\n", le16toh(r->clock_offset));
-
-	if (rssi)
-		printf("   : rssi %d\n", r->rssi);
-
+	printf("   : rssi %d\n", r->rssi);
 	printf("\n");
 }
 
 void
 do_inquiry(void)
 {
-	uint8_t buf[HCI_EVENT_PKT_SIZE];
-	struct result result[INQUIRY_MAX_RESPONSES];
-	hci_inquiry_cp inq;
-	struct hci_filter f;
-	hci_event_hdr_t *hh;
-	int i, j, num, rssi;
+	struct bt_devinquiry *result;
+	int i, num;
 
 	if (opt_inquiry == 0)
 		return;
@@ -1157,97 +1111,18 @@
 	printf("Device Discovery from device: %s ...", btr.btr_name);
 	fflush(stdout);
 
-	memset(&f, 0, sizeof(f));
-	hci_filter_set(HCI_EVENT_COMMAND_STATUS, &f);
-	hci_filter_set(HCI_EVENT_COMMAND_COMPL, &f);
-	hci_filter_set(HCI_EVENT_INQUIRY_RESULT, &f);
-	hci_filter_set(HCI_EVENT_RSSI_RESULT, &f);
-	hci_filter_set(HCI_EVENT_INQUIRY_COMPL, &f);
-	hci_filter_set(HCI_EVENT_REMOTE_NAME_REQ_COMPL, &f);
-	hci_filter_set(HCI_EVENT_READ_REMOTE_FEATURES_COMPL, &f);
-	if (setsockopt(hci, BTPROTO_HCI, SO_HCI_EVT_FILTER, &f, sizeof(f)) < 0)
-		err(EXIT_FAILURE, "Can't set event filter");
-
-	/* General Inquiry LAP is 0x9e8b33 */
-	inq.lap[0] = 0x33;
-	inq.lap[1] = 0x8b;
-	inq.lap[2] = 0x9e;
-	inq.inquiry_length = INQUIRY_LENGTH;
-	inq.num_responses = INQUIRY_MAX_RESPONSES;
-
-	hci_cmd(HCI_CMD_INQUIRY, &inq, sizeof(inq));
-
-	num = 0;
-	rssi = 0;
-	hh = (hci_event_hdr_t *)buf;
-
-	for (;;) {
-		if (recv(hci, buf, sizeof(buf), 0) <= 0)
-			err(EXIT_FAILURE, "recv");
-
-		if (hh->event == HCI_EVENT_INQUIRY_COMPL)
-			break;
+	num = bt_devinquiry(btr.btr_name, INQUIRY_LENGTH,
+	    INQUIRY_MAX_RESPONSES, &result);
 
-		if (hh->event == HCI_EVENT_INQUIRY_RESULT) {
-			hci_inquiry_result_ep *ep = (hci_inquiry_result_ep *)(hh + 1);
-			hci_inquiry_response *ir = (hci_inquiry_response *)(ep + 1);
-
-			for (i = 0 ; i < ep->num_responses ; i++) {
-				if (num == INQUIRY_MAX_RESPONSES)
-					break;
-
-				/* some devices keep responding, ignore dupes */
-				for (j = 0 ; j < num ; j++)
-					if (bdaddr_same(&result[j].bdaddr, &ir[i].bdaddr))
-						break;
-
-				if (j < num)
-					continue;
-
-				bdaddr_copy(&result[num].bdaddr, &ir[i].bdaddr);
-				memcpy(&result[num].uclass, &ir[i].uclass, HCI_CLASS_SIZE);
-				result[num].page_scan_rep_mode = ir[i].page_scan_rep_mode;
-				result[num].clock_offset = ir[i].clock_offset;
-				result[num].rssi = 0;
-				num++;
-				printf(".");
-				fflush(stdout);
-			}
-			continue;
-		}
-
-		if (hh->event == HCI_EVENT_RSSI_RESULT) {
-			hci_rssi_result_ep *ep = (hci_rssi_result_ep *)(hh + 1);
-			hci_rssi_response *rr = (hci_rssi_response *)(ep + 1);
-
-			for (i = 0 ; i < ep->num_responses ; i++) {
-				if (num == INQUIRY_MAX_RESPONSES)
-					break;
-
-				/* some devices keep responding, ignore dupes */
-				for (j = 0 ; j < num ; j++)
-					if (bdaddr_same(&result[j].bdaddr, &rr[i].bdaddr))
-						break;
-
-				if (j < num)
-					continue;
-
-				bdaddr_copy(&result[num].bdaddr, &rr[i].bdaddr);
-				memcpy(&result[num].uclass, &rr[i].uclass, HCI_CLASS_SIZE);
-				result[num].page_scan_rep_mode = rr[i].page_scan_rep_mode;
-				result[num].clock_offset = rr[i].clock_offset;
-				result[num].rssi = rr[i].rssi;
-				rssi = 1;
-				num++;
-				printf(".");
-				fflush(stdout);
-			}
-			continue;
-		}
+	if (num == -1) {
+		printf("failed\n");
+		err(EXIT_FAILURE, "%s", btr.btr_name);
 	}
 
 	printf(" %d response%s\n", num, (num == 1 ? "" : "s"));
 
 	for (i = 0 ; i < num ; i++)
-		print_result(i + 1, &result[i], rssi);
+		print_result(i + 1, &result[i]);
+
+	free(result);
 }

Reply via email to