[PATCH BlueZ v2 2/7] tools/btgatt-client: Added L2CAP LE ATT connection.

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

 



This patch adds support for connection establishment with different security
levels. Currently, only LE connections are supported.
---
 tools/btgatt-client.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index a5ce70b..30e8e50 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
@@ -28,15 +28,20 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <getopt.h>
 #include <limits.h>
+#include <errno.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
+#include <bluetooth/l2cap.h>
 
 #include "monitor/mainloop.h"
 
+#define ATT_CID 4
+
 static bool verbose = false;
 
 static void print_prompt(void)
@@ -65,6 +70,74 @@ static void prompt_read_cb(int fd, uint32_t events, void *user_data)
 	free(line);
 }
 
+static int l2cap_le_att_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t dst_type,
+									int sec)
+{
+	int sock;
+	struct sockaddr_l2 srcaddr, dstaddr;
+	struct bt_security btsec;
+
+	if (verbose) {
+		char srcaddr_str[18], dstaddr_str[18];
+
+		ba2str(src, srcaddr_str);
+		ba2str(dst, dstaddr_str);
+
+		printf("Opening L2CAP LE connection on ATT channel:\n"
+						"\t src: %s\n\tdest: %s\n",
+						srcaddr_str, dstaddr_str);
+	}
+
+	sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+	if (sock < 0) {
+		perror("Failed to create L2CAP socket");
+		return -1;
+	}
+
+	/* Set up source address */
+	memset(&srcaddr, 0, sizeof(srcaddr));
+	srcaddr.l2_family = AF_BLUETOOTH;
+	srcaddr.l2_cid = htobs(ATT_CID);
+	srcaddr.l2_bdaddr_type = 0;
+	bacpy(&srcaddr.l2_bdaddr, src);
+
+	if (bind(sock, (struct sockaddr *)&srcaddr, sizeof(srcaddr)) < 0) {
+		perror("Failed to bind L2CAP socket");
+		close(sock);
+		return -1;
+	}
+
+	/* Set the security level */
+	memset(&btsec, 0, sizeof(btsec));
+	btsec.level = sec;
+	if (setsockopt(sock, SOL_BLUETOOTH, BT_SECURITY, &btsec,
+							sizeof(btsec)) != 0) {
+		fprintf(stderr, "Failed to set L2CAP security level\n");
+		close(sock);
+		return -1;
+	}
+
+	/* Set up destination address */
+	memset(&dstaddr, 0, sizeof(dstaddr));
+	dstaddr.l2_family = AF_BLUETOOTH;
+	dstaddr.l2_cid = htobs(ATT_CID);
+	dstaddr.l2_bdaddr_type = dst_type;
+	bacpy(&dstaddr.l2_bdaddr, dst);
+
+	printf("Connecting to device...");
+	fflush(stdout);
+
+	if (connect(sock, (struct sockaddr *) &dstaddr, sizeof(dstaddr)) < 0) {
+		perror(" Failed to connect");
+		close(sock);
+		return -1;
+	}
+
+	printf(" Done\n");
+
+	return sock;
+}
+
 static void usage(void)
 {
 	printf("btgatt-client\n");
@@ -95,12 +168,13 @@ static struct option main_options[] = {
 int main(int argc, char *argv[])
 {
 	int opt;
-	int sec;
+	int sec = BT_SECURITY_LOW;
 	uint16_t mtu = 0;
 	uint8_t dst_type = BDADDR_LE_PUBLIC;
 	bool dst_addr_given = false;
 	bdaddr_t src_addr, dst_addr;
 	int dev_id = -1;
+	int fd;
 
 	while ((opt = getopt_long(argc, argv, "+hvs:m:t:d:i:",
 						main_options, NULL)) != -1) {
@@ -203,6 +277,10 @@ int main(int argc, char *argv[])
 
 	mainloop_init();
 
+	fd = l2cap_le_att_connect(&src_addr, &dst_addr, dst_type, sec);
+	if (fd < 0)
+		return EXIT_FAILURE;
+
 	if (mainloop_add_fd(fileno(stdin),
 				EPOLLIN | EPOLLRDHUP | EPOLLHUP | EPOLLERR,
 				prompt_read_cb, NULL, NULL) < 0) {
-- 
2.1.0.rc2.206.gedb03e5

--
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