1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2001-2010 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <stdio.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <termios.h> 35 #include <sys/ioctl.h> 36 #include <sys/socket.h> 37 38 #include <bluetooth/bluetooth.h> 39 #include <bluetooth/rfcomm.h> 40 41 static int at_command(int fd, char *cmd, int to) 42 { 43 fd_set rfds; 44 struct timeval timeout; 45 char buf[1024]; 46 int sel, len, i, n; 47 48 len = write(fd, cmd, strlen(cmd)); 49 50 for (i = 0; i < 100; i++) { 51 52 FD_ZERO(&rfds); 53 FD_SET(fd, &rfds); 54 55 timeout.tv_sec = 0; 56 timeout.tv_usec = to; 57 58 if ((sel = select(fd + 1, &rfds, NULL, NULL, &timeout)) > 0) { 59 60 if (FD_ISSET(fd, &rfds)) { 61 memset(buf, 0, sizeof(buf)); 62 len = read(fd, buf, sizeof(buf)); 63 for (n = 0; n < len; n++) 64 printf("%c", buf[n]); 65 if (strstr(buf, "\r\nOK") != NULL) 66 break; 67 if (strstr(buf, "\r\nERROR") != NULL) 68 break; 69 if (strstr(buf, "\r\nCONNECT") != NULL) 70 break; 71 } 72 73 } 74 75 } 76 77 return 0; 78 } 79 80 static int open_device(char *device) 81 { 82 struct termios ti; 83 int fd; 84 85 fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); 86 if (fd < 0) { 87 fprintf(stderr, "Can't open serial port: %s (%d)\n", 88 strerror(errno), errno); 89 return -1; 90 } 91 92 tcflush(fd, TCIOFLUSH); 93 94 /* Switch tty to RAW mode */ 95 cfmakeraw(&ti); 96 tcsetattr(fd, TCSANOW, &ti); 97 98 return fd; 99 } 100 101 static int open_socket(bdaddr_t *bdaddr, uint8_t channel) 102 { 103 struct sockaddr_rc addr; 104 int sk; 105 106 sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 107 if (sk < 0) { 108 fprintf(stderr, "Can't create socket: %s (%d)\n", 109 strerror(errno), errno); 110 return -1; 111 } 112 113 memset(&addr, 0, sizeof(addr)); 114 addr.rc_family = AF_BLUETOOTH; 115 bacpy(&addr.rc_bdaddr, BDADDR_ANY); 116 117 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 118 fprintf(stderr, "Can't bind socket: %s (%d)\n", 119 strerror(errno), errno); 120 close(sk); 121 return -1; 122 } 123 124 memset(&addr, 0, sizeof(addr)); 125 addr.rc_family = AF_BLUETOOTH; 126 bacpy(&addr.rc_bdaddr, bdaddr); 127 addr.rc_channel = channel; 128 129 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 130 fprintf(stderr, "Can't connect: %s (%d)\n", 131 strerror(errno), errno); 132 close(sk); 133 return -1; 134 } 135 136 return sk; 137 } 138 139 static void usage(void) 140 { 141 printf("Usage:\n\tattest <device> | <bdaddr> [channel]\n"); 142 } 143 144 int main(int argc, char *argv[]) 145 { 146 int fd; 147 148 bdaddr_t bdaddr; 149 uint8_t channel; 150 151 switch (argc) { 152 case 2: 153 str2ba(argv[1], &bdaddr); 154 channel = 1; 155 break; 156 case 3: 157 str2ba(argv[1], &bdaddr); 158 channel = atoi(argv[2]); 159 break; 160 default: 161 usage(); 162 exit(-1); 163 } 164 165 if (bacmp(BDADDR_ANY, &bdaddr)) { 166 printf("Connecting to %s on channel %d\n", argv[1], channel); 167 fd = open_socket(&bdaddr, channel); 168 } else { 169 printf("Opening device %s\n", argv[1]); 170 fd = open_device(argv[1]); 171 } 172 173 if (fd < 0) 174 exit(-2); 175 176 at_command(fd, "ATZ\r\n", 10000); 177 at_command(fd, "AT+CPBS=\"ME\"\r\n", 10000); 178 at_command(fd, "AT+CPBR=1,100\r\n", 100000); 179 180 close(fd); 181 182 return 0; 183 } 184