[PATCH 2/3] btmgmt: Implement Add Network Management API command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Send MGMT_OP_ADD_NETWORK Management API command to create a connection
to a remote 6LowPAN device and wait for the command to complete before
printing out a result.

Also listen for MGMT_EV_NETWORK_ADDED events that indicate creation of
other connections not requested by us.
---
 lib/mgmt.h     |  18 ++++++++++
 tools/btmgmt.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 9db853c..8a9178e 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -540,6 +540,16 @@ struct mgmt_rp_network {
 	uint32_t ifindex;
 } __packed;
 
+#define MGMT_OP_ADD_NETWORK		0x0043
+#define MGMT_ADD_NETWORK_SIZE		7
+struct mgmt_cp_add_network {
+	struct mgmt_addr_info dst;
+} __packed;
+struct mgmt_rp_add_network {
+	struct mgmt_addr_info dst;
+	int ifindex;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	uint16_t opcode;
@@ -752,6 +762,12 @@ struct mgmt_ev_advertising_removed {
 	uint8_t instance;
 } __packed;
 
+#define MGMT_EV_NETWORK_ADDED		0x0025
+struct mgmt_ev_network_added {
+	struct mgmt_addr_info dst;
+	int ifindex;
+} __packed;
+
 static const char *mgmt_op[] = {
 	"<0x0000>",
 	"Read Version",
@@ -820,6 +836,7 @@ static const char *mgmt_op[] = {
 	"Get Advertising Size Information",		/* 0x0040 */
 	"Start Limited Discovery",
 	"Get Networks",
+	"Add Network",
 };
 
 static const char *mgmt_ev[] = {
@@ -860,6 +877,7 @@ static const char *mgmt_ev[] = {
 	"Local Out Of Band Extended Data Updated",
 	"Advertising Added",
 	"Advertising Removed",
+	"Network Added",
 };
 
 static const char *mgmt_status[] = {
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index fb6eec3..7bd0943 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -1110,6 +1110,22 @@ static void advertising_removed(uint16_t index, uint16_t len,
 	print("hci%u advertising_removed: instance %u", index, ev->instance);
 }
 
+static void network_added(uint16_t index, uint16_t len,
+					const void *param, void *user_data)
+{
+	const struct mgmt_ev_network_added *ev = param;
+	char addr[18];
+
+	if (len < sizeof(*ev)) {
+		error("Too few parameters returned (%u bytes)", len);
+		return;
+	}
+
+	ba2str(&ev->dst.bdaddr, addr);
+	print("Network Added %s (%s) hci%d interface %d",
+			addr, typestr(ev->dst.type), index, ev->ifindex);
+}
+
 static void version_rsp(uint8_t status, uint16_t len, const void *param,
 							void *user_data)
 {
@@ -4343,6 +4359,93 @@ static void cmd_get_networks(struct mgmt *mgmt, uint16_t index,
 	}
 }
 
+static void network_usage(const char *command)
+{
+	print("Usage: %s [-t type] <remote address>", command);
+}
+
+static struct option network_info_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ "type",	1, 0, 't' },
+	{ 0, 0, 0, 0 }
+};
+
+static void add_network_rsp(uint8_t status, uint16_t len, const void *param,
+							void *user_data)
+{
+	const struct mgmt_rp_add_network *rp = param;
+	char addr[18];
+
+	if (len == 0 && status != 0) {
+		error("Add Network failed, status 0x%02x (%s)",
+						status, mgmt_errstr(status));
+		return noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (len < sizeof(*rp)) {
+		error("Unexpected Add Network len %u", len);
+		return noninteractive_quit(EXIT_FAILURE);
+	}
+
+	ba2str(&rp->dst.bdaddr, addr);
+
+	if (status)
+		error("Add Network %s (%s) failed with status 0x%02x (%s)",
+			addr, typestr(rp->dst.type),
+			status, mgmt_errstr(status));
+	else
+		print("Add Network %s (%s) interface %d", addr,
+			typestr(rp->dst.type), rp->ifindex);
+
+	noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_add_network(struct mgmt *mgmt, uint16_t index,
+			int argc, char **argv)
+{
+	struct mgmt_cp_add_network cp;
+	uint8_t type = BDADDR_LE_PUBLIC;
+	int opt;
+
+	optind = 0;
+	while ((opt = getopt_long(argc, argv, "+t:h", network_info_options,
+								NULL)) != -1) {
+		switch (opt) {
+		case 't':
+			type = strtol(optarg, NULL, 0);
+			break;
+		case 'h':
+			network_usage("add-network");
+			return noninteractive_quit(EXIT_SUCCESS);
+		default:
+			network_usage("add-network");
+			return noninteractive_quit(EXIT_FAILURE);
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+	optind = 0;
+
+	if (argc < 1) {
+		network_usage("add-network");
+		return noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (index == MGMT_INDEX_NONE)
+		index = 0;
+
+	memset(&cp, 0, sizeof(cp));
+	str2ba(argv[0], &cp.dst.bdaddr);
+	cp.dst.type = type;
+
+	if (mgmt_send(mgmt, MGMT_OP_ADD_NETWORK, index, sizeof(cp), &cp,
+				add_network_rsp, NULL, NULL) == 0) {
+		error("Unable to send Add Network cmd");
+		return noninteractive_quit(EXIT_FAILURE);
+	}
+}
+
 struct cmd_info {
 	char *cmd;
 	void (*func)(struct mgmt *mgmt, uint16_t index, int argc, char **argv);
@@ -4412,6 +4515,7 @@ static struct cmd_info all_cmd[] = {
 	{ "rm-adv",	cmd_rm_adv,	"Remove advertising instance"	},
 	{ "clr-adv",	cmd_clr_adv,	"Clear advertising instances"	},
 	{ "get-networks", cmd_get_networks, "Get 6LowPAN networks"      },
+	{ "add-network", cmd_add_network, "Add a 6LowPAN network"       },
 };
 
 static void cmd_quit(struct mgmt *mgmt, uint16_t index,
@@ -4472,6 +4576,8 @@ static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
 						advertising_added, NULL, NULL);
 	mgmt_register(mgmt, MGMT_EV_ADVERTISING_REMOVED, index,
 					advertising_removed, NULL, NULL);
+	mgmt_register(mgmt, MGMT_EV_NETWORK_ADDED, index, network_added,
+					NULL, NULL);
 }
 
 static void cmd_select(struct mgmt *mgmt, uint16_t index,
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux