]> rtime.felk.cvut.cz Git - mirosot.git/commitdiff
Added bluez_test applications.
authorNguyen Hoang <nhttu82@yahoo.com>
Wed, 28 Jun 2006 13:36:00 +0000 (13:36 +0000)
committerNguyen Hoang <nhttu82@yahoo.com>
Wed, 28 Jun 2006 13:36:00 +0000 (13:36 +0000)
darcs-hash:20060628133653-5a954-34d4719d6abbd1f04484af02d9c9d86d330f07db.gz

bluez_test/Makefile [new file with mode: 0644]
bluez_test/hcitest.c [new file with mode: 0644]
bluez_test/l2captest.c [new file with mode: 0644]

diff --git a/bluez_test/Makefile b/bluez_test/Makefile
new file mode 100644 (file)
index 0000000..13390e8
--- /dev/null
@@ -0,0 +1,10 @@
+CFLAGS=-Wall -g
+
+all: hcitest l2captest
+
+# Vymaz implicitni pravidlo
+%: %.c
+
+%: %.o
+       gcc -o $@ $^ -lbluetooth
+#      scp $@ steelbar:/home/wsh/bin
diff --git a/bluez_test/hcitest.c b/bluez_test/hcitest.c
new file mode 100644 (file)
index 0000000..ae8cdb8
--- /dev/null
@@ -0,0 +1,305 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+int chosen_dev_id = -1;           /* BB device id*/
+
+static int dev_info(int socket, int dev_id, long arg)
+{
+    struct hci_dev_info di;
+    char addr[18];
+    int err;
+
+    /* Ziskej informace o BT zarizeni */
+    err = hci_devinfo(dev_id, &di);
+
+    if (err)  return err;
+
+    ba2str(&di.bdaddr, addr);
+    printf("\t%s\t%s", di.name, addr);
+    
+    printf(" flags: ");
+
+    if (hci_test_bit(HCI_RAW, &di.flags)) printf("RAW ");
+    else printf("~RAW");
+
+    if (chosen_dev_id == -1)  {
+        /* Uloz prvni nalezene dev_id */
+        chosen_dev_id = dev_id;
+        printf(" default");
+    }
+    printf("\n");
+
+    return err;
+}
+
+
+/* Projed vsechny lokalni BT zarizeni a pro kazde z nich zavolej fci
+ * dev_info() */
+void najdi_zarizeni()
+{
+    int ret;
+
+    printf("Nalezene lokalni BT zarizeni:\n");
+    ret = hci_for_each_dev(HCI_UP, dev_info, 0);
+
+    /* v knihovne je chyba - vraci to -1 i kdyz bylo volani uspesne) */
+    if (ret && chosen_dev_id == -1) {
+        perror("hledani zarizeni");
+        exit(1);
+    }
+}
+
+/* Otevri BT zarizeni */
+int otevri_bt()
+{
+    int dd;                     /* BT device descriptor se kterym
+                                 * budeme pracovat*/
+
+    dd = hci_open_dev(chosen_dev_id);
+    if (dd == -1) {
+        perror("hci_open_dev");
+        exit(1);
+    }
+
+    /* Nasta RAW rezim, aby data nebyly zpracovavany l2cap vrstvou. */
+    if (ioctl(dd, HCISETRAW, 1) < 0) {
+        perror("Can't set RAW mode");
+        exit(1);
+    }
+    return dd;
+}
+
+
+/* Najdi okolni zarizeni */
+void scan(int dd)
+{
+    uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
+    int inq_length = 10;        /* sekund */
+    inquiry_info *info = NULL;  /* informace o zarizenich */
+    int num_rsp;
+    long flags = 0;
+    int i;
+    
+
+    //flags |= IREQ_CACHE_FLUSH;  /* Vycisti cache */
+
+    printf("Scanuji... (%d sekund)\n", inq_length);
+    num_rsp = hci_inquiry(chosen_dev_id, 
+                          (int)(inq_length / 1.28),
+                          0, /* Najdi vsechna zarizeni */
+                          lap,
+                          &info, /* sem uloz ukazatel na nalezena
+                                  * zarizeni */
+                          flags);
+    char addr[18], name[249];
+    
+    /* Zjisti jmena nalezenych zarizeni a vse vypis */
+    for (i = 0; i < num_rsp; i++) {
+        int ret;
+        ba2str(&info[i].bdaddr, addr);
+        
+        ret = hci_read_remote_name(dd,
+                                   &info[i].bdaddr,
+                                   sizeof(name), name, 
+                                   100000); /* timeout v milisekundach*/
+        if (ret < 0)
+            strcpy(name, "n/a"); /* Jmeno neexistuje */
+        
+        printf("\t%s\t%s\n", addr, name);
+    }
+    bt_free(info);              /* uvolni pamet */
+}
+
+
+/* Spoj se s protejskem */
+uint16_t spojse(int dd, bdaddr_t bdaddr)
+{
+    uint8_t allow_role_switch = 0x01;
+    uint16_t ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;
+    uint16_t handle;
+    struct hci_filter flt;
+    int ret;
+
+    /* Nastav filter, aby nam chodily vsechny HCI pakety */
+    hci_filter_clear(&flt);
+    hci_filter_all_ptypes(&flt);
+    hci_filter_all_events(&flt);
+    if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
+        perror("Can't set filter");
+        exit(1);
+    }
+
+
+
+    printf("Navazuji spojeni\n");
+    ret = hci_create_connection(dd,
+                                &bdaddr,
+                                ptype, htobs(0x0000), 
+                                allow_role_switch, 
+                                &handle, 
+                                10000); /* timeout */
+    if (ret < 0) {
+        perror("Spojeni nelze navazat");
+        exit(1);
+    }
+    return handle;
+}
+
+/* Ukazka jak posilat HCI pakety. Paket je slozen ze 3 casti: typ paketu, hlavicka a data */
+int sendstr(int dd, uint16_t handle, char *buf)
+{
+    uint8_t type = HCI_ACLDATA_PKT;
+    hci_acl_hdr acl_hdr;
+    struct iovec iv[3];
+
+    acl_hdr.handle = htobs(handle);
+    acl_hdr.dlen = htobs(strlen(buf));
+
+    /* sloz paket ze tri casti (typ, hlavicka, data) */
+    iv[0].iov_base = &type;
+    iv[0].iov_len  = 1;
+    iv[1].iov_base = &acl_hdr;
+    iv[1].iov_len  = HCI_ACL_HDR_SIZE;
+        
+    iv[2].iov_base = buf;
+    iv[2].iov_len  = acl_hdr.dlen;
+    
+    printf("Sending %d\n", strlen(buf));
+    while (writev(dd, iv, 3) < 0) {
+        if (errno == EAGAIN || errno == EINTR)
+            continue;
+        return -1;
+    }
+    return 0;
+}
+
+static void hex_dump(char *pref, int width, unsigned char *buf, int len)
+{
+    register int i,n;
+
+    for (i = 0, n = 1; i < len; i++, n++) {
+        if (n == 1)
+            printf("%s", pref);
+        printf("%2.2X ", buf[i]);
+        if (n == width) {
+            printf("\n");
+            n = 0;
+        }
+    }
+    if (i && n!=1)
+        printf("\n");
+}
+
+
+
+int recvstr(int dd, uint16_t handle, char *str, int len)
+{
+    unsigned char buf[200];
+    struct hci_acl_hdr *acl_hdr;
+    
+    while ((len = read(dd, buf, sizeof(buf))) < 0) {
+        if (errno == EAGAIN || errno == EINTR)
+            continue;
+        goto failed;
+    }
+
+    switch (buf[0]) {
+        case HCI_ACLDATA_PKT:
+            printf("ACL DATA: ");
+            acl_hdr = (struct hci_acl_hdr *)(buf+1);
+            break;
+        case HCI_SCODATA_PKT:
+            printf("SCO DATA: ");
+            break;
+        case HCI_EVENT_PKT:
+            printf("EVENT: ");
+            break;
+    }
+
+    hex_dump("content: ", 16, &buf[1], len - 1);
+    return 0;
+failed:
+    return -1;
+}
+
+void komunikuj(int dd, uint16_t handle)
+{
+    int end = 0;
+    int ret;
+
+    struct pollfd p[2];
+
+    p[0].fd = fileno(stdin);
+    p[0].events = POLLIN;
+    p[1].fd = dd;
+    p[1].events = POLLIN;
+    
+    while (!end) {
+        ret = poll(p, 2, 1000);
+        if (ret > 0) {
+            char buf[100];
+            
+            if (p[0].revents & POLLIN) {
+                if (fgets(buf, 99, stdin) != NULL)
+                    sendstr(dd, handle, buf); /* posli data */
+                else end = 1; /* konec (Ctrl-D) */
+            }
+            if (p[1].revents & POLLIN) {
+                recvstr(dd, handle, buf, 99);
+                printf("%s", buf);
+            }
+        } else if (ret < 0) {
+            perror("poll");
+            exit(1);
+        }
+    }
+}
+
+
+int main(int argc, char *argv[])
+{
+    int dd;
+
+    najdi_zarizeni();
+
+    dd = otevri_bt();
+
+    if (argc < 2) {
+        scan(dd);
+        printf("Ocekavam jako parametr BD adresu\n");
+    } else {
+        char bdstr[20];
+        bdaddr_t bdaddr;
+        uint16_t handle;
+
+        strncpy(bdstr, argv[1], sizeof(bdstr));
+        str2ba(bdstr, &bdaddr);
+
+        /* Navaz ACL spojeni */
+        handle = spojse(dd, bdaddr);
+
+        /* Posilej pakety - nefunguje to. Je potreba nastavit dalsi veci pomoci HCI prikazu */
+        komunikuj(dd, handle);
+
+        printf("Rusim spojeni\n");
+        hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000);
+    }
+
+    if (ioctl(dd, HCISETRAW, 0) < 0) {
+        perror("Can't reset RAW mode");
+        exit(1);
+    }
+
+    /* Zavri BT zarizeni */
+    hci_close_dev(dd);
+
+
+    return 0;
+}
diff --git a/bluez_test/l2captest.c b/bluez_test/l2captest.c
new file mode 100644 (file)
index 0000000..03a7de1
--- /dev/null
@@ -0,0 +1,178 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#define MY_PSM 0x1001           /* Protocol/Service Multiplexor */
+
+static bdaddr_t bdaddr;         /* Adresa lokalniho BT zarizeni  */
+
+
+void komunikuj(int sk)
+{
+    int end = 0;
+    int ret;
+
+    struct pollfd p[2];
+
+    p[0].fd = fileno(stdin);
+    p[0].events = POLLIN;
+    p[1].fd = sk;
+    p[1].events = POLLIN;
+    
+    while (!end) {
+        ret = poll(p, 2, 1000);
+        if (ret > 0) {
+            char buf[100];
+            
+            if (p[0].revents & POLLIN) {
+                if (fgets(buf, 99, stdin) != NULL)
+                    send(sk, buf, strlen(buf), 0); /* posli data */
+                else end = 1; /* konec (Ctrl-D) */
+            }
+            if (p[1].revents & POLLIN) {
+                ret = recv(sk, buf, 99, 0);
+                if (ret >= 0) buf[ret] = '\0';
+                printf("%s", buf);
+            }
+        } else if (ret < 0) {
+            perror("poll");
+            exit(1);
+        }
+    }
+}
+
+
+static void klient(char *dest)
+{
+       struct sockaddr_l2 addr;
+       int sk;
+
+       /* Create socket */
+       sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+       if (sk < 0) {
+               perror("Can't create socket");
+               exit(1);
+       }
+
+       /* Bind to local address */
+       memset(&addr, 0, sizeof(addr));
+       bacpy(&addr.l2_bdaddr, &bdaddr);
+       addr.l2_family = AF_BLUETOOTH;
+
+       if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               perror("Can't bind socket");
+               close(sk);
+               exit(1);
+       }
+
+       /* Connect to remote device */
+       memset(&addr, 0, sizeof(addr));
+       addr.l2_family = AF_BLUETOOTH;
+       str2ba(dest, &addr.l2_bdaddr);
+       addr.l2_psm = htobs(MY_PSM);
+
+       if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               perror("Can't connect");
+               close(sk);
+               exit(1);
+       }
+        printf("Spojeno (Ctrl-D konec)\n");
+
+        /* Komunikace */
+        komunikuj(sk);
+
+        /* Uzavri spojeni */
+        close(sk);
+
+}
+
+static void server()
+{
+       struct sockaddr_l2 addr, client_addr;
+       int sk, sk2;
+        socklen_t addr_len;
+
+       /* Create socket */
+       sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+       if (sk < 0) {
+               perror("Can't create socket");
+               exit(1);
+       }
+
+       /* Bind to local address */
+       memset(&addr, 0, sizeof(addr));
+       addr.l2_family = AF_BLUETOOTH;
+       bacpy(&addr.l2_bdaddr, &bdaddr);
+       addr.l2_psm = htobs(MY_PSM);   /* Protocol/Service Multiplexor */
+
+       if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               perror("Can't bind socket");
+               close(sk);
+               exit(1);
+       }
+
+       /* Pockej az se pripoji klient */
+       if (listen(sk, 1) < 0) {
+               perror("listen");
+               close(sk);
+               exit(1);
+       }
+
+        
+        printf("Cekam na spojeni...\n");
+        addr_len = sizeof(client_addr);
+        sk2 = accept(sk, (struct sockaddr*)&client_addr, &addr_len);
+        printf("Spojeno (Ctrl-D konec)\n");
+
+        /* Komunikace */
+        komunikuj(sk2);
+
+        /* Uzavri spojeni */
+        close(sk2);
+        close(sk);
+
+}
+
+static void usage(void)
+{
+       printf("l2captest - L2CAP test\n");
+       printf("Usage:\n");
+       printf("\tl2captest [-i device] [<server bdaddr>]\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int opt;
+
+       /* Default options */
+       bacpy(&bdaddr, BDADDR_ANY);
+
+       while ((opt=getopt(argc,argv,"i:")) != EOF) {
+               switch(opt) {
+               case 'i':       /* likalni BT zarizeni (hciX nebo BD addresa) */
+                       if (!strncasecmp(optarg, "hci", 3))
+                               hci_devba(atoi(optarg + 3), &bdaddr);
+                       else
+                               str2ba(optarg, &bdaddr);
+                       break;
+
+               default:
+                       usage();
+                       exit(1);
+               }
+       }
+
+       if (!(argc - optind)) {
+            server();           /* ceka na pripojeni libovolneho klienta */
+        } else
+            klient(argv[optind]);
+
+       return 0;
+}