Diff between 064ede0856a17e3433ac54bc07dddcc835e0c9cb and 34264e193cd688f27487eb501dfc2c1b0275ac5e

Changed Files

File Additions Deletions Status
mgmt/main.c +105 -0 modified

Full Patch

diff --git a/mgmt/main.c b/mgmt/main.c
index 183711d..e1e9c20 100644
--- a/mgmt/main.c
+++ b/mgmt/main.c
@@ -23,7 +23,112 @@
 #include <config.h>
 #endif
 
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <poll.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/mgmt.h>
+
+static int mgmt_open(void)
+{
+	struct sockaddr_hci addr;
+	int sk;
+
+	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+	if (sk < 0) {
+		fprintf(stderr, "socket: %s\n", strerror(errno));
+		return sk;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.hci_family = AF_BLUETOOTH;
+	addr.hci_dev = HCI_DEV_NONE;
+	addr.hci_channel = HCI_CHANNEL_CONTROL;
+
+	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		fprintf(stderr, "bind: %s\n", strerror(errno));
+		close(sk);
+		return -1;
+	}
+
+	return sk;
+}
+
+static int mgmt_handle_event(int mgmt_sk, uint16_t ev, uint16_t index,
+						void *data, uint16_t len)
+{
+	return 0;
+}
+
+static int mgmt_process_data(int mgmt_sk)
+{
+	char buf[1024];
+	struct mgmt_hdr *hdr = (void *) buf;
+	uint16_t len, ev, index;
+	ssize_t ret;
+
+	ret = read(mgmt_sk, buf, sizeof(buf));
+	if (ret < 0) {
+		fprintf(stderr, "read: %s\n", strerror(errno));
+		return len;
+	}
+
+	if (ret < MGMT_HDR_SIZE) {
+		fprintf(stderr, "Too small mgmt packet (%zd bytes)\n", ret);
+		return 0;
+	}
+
+	ev = bt_get_le16(&hdr->opcode);
+	index = bt_get_le16(&hdr->index);
+	len = bt_get_le16(&hdr->len);
+
+	printf("event 0x%04x len 0x%04x index 0x%04x\n", ev, len, index);
+
+	if (ret != MGMT_HDR_SIZE + len) {
+		fprintf(stderr, "Packet length mismatch. ret %zd len %u",
+								ret, len);
+		return 0;
+	}
+
+	mgmt_handle_event(mgmt_sk, ev, index, buf + MGMT_HDR_SIZE, len);
+
+	return 0;
+}
+
 int main(int argc, char *argv[])
 {
+	int mgmt_sk;
+	struct pollfd pollfd;
+
+	mgmt_sk = mgmt_open();
+	if (mgmt_sk < 0) {
+		fprintf(stderr, "Unable to open mgmt socket\n");
+		return -1;
+	}
+
+	printf("mgmt socket successfully opened\n");
+
+	pollfd.fd = mgmt_sk;
+	pollfd.events = POLLIN;
+	pollfd.revents = 0;
+
+	while (poll(&pollfd, 1, -1) >= 0) {
+		if (pollfd.revents & (POLLHUP | POLLERR | POLLNVAL))
+			break;
+
+		if (pollfd.revents & POLLIN)
+			mgmt_process_data(mgmt_sk);
+
+		pollfd.revents = 0;
+	}
+
+	close(mgmt_sk);
+
 	return 0;
 }