From 475922ce345bb0443cf4fdef00efa86676a1bf62 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 1 Sep 2015 00:41:49 +0100 Subject: fish --- ble.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 ble.c (limited to 'ble.c') diff --git a/ble.c b/ble.c new file mode 100644 index 0000000..9f0b683 --- /dev/null +++ b/ble.c @@ -0,0 +1,147 @@ +#include "project.h" + +static int verbose = 1; + +#define ATT_CID 4 + + + +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 ("btgatt-client: 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; +} + + + +void ble_finish(struct ble *ble) +{ +if (!ble) return; + +if (ble->att) bt_att_unref(ble->att); +if (ble->fd>0) close(ble->fd); + +free(ble); +} + + +struct ble *ble_start (const char *bdaddr) +{ + struct ble *ble; + + ble=xmalloc(sizeof(*ble)); + memset(ble,0,sizeof(*ble)); + + ble->sec = BT_SECURITY_LOW; + ble->dst_type = BDADDR_LE_RANDOM; + bacpy (&ble->src_addr, BDADDR_ANY); + + if (str2ba (bdaddr, &ble->dst_addr) < 0) + { + fprintf (stderr, "Invalid remote address: %s\n", bdaddr); + ble_finish(ble); + return NULL; + } + + + ble->fd = l2cap_le_att_connect (&ble->src_addr, &ble->dst_addr, ble->dst_type, ble->sec); + if (ble->fd < 0) + { + perror ("l2cap_le_att_connect"); + ble_finish(ble); + return NULL; + } + + + ble->att = bt_att_new(ble->fd); + + if (!ble->att) { + fprintf(stderr, "Failed to initialze ATT transport layer\n"); + ble_finish(ble); + return NULL; + } + + if (!bt_att_set_close_on_unref(ble->att, true)) { + fprintf(stderr, "Failed to set up ATT transport layer\n"); + ble_finish(ble); + return NULL; + } + + if (!bt_att_register_disconnect(ble->att, att_disconnect_cb, NULL, + NULL)) { + fprintf(stderr, "Failed to set ATT disconnect handler\n"); + ble_finish(ble); + return NULL; + } + + + + printf ("Connected!\n"); +} -- cgit v1.2.3