• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2001-2008  Marcel Holtmann <marcel@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 
at_command(int fd,char * cmd,int to)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 
open_device(char * device)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 
open_socket(bdaddr_t * bdaddr,uint8_t channel)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 
usage(void)139 static void usage(void)
140 {
141 	printf("Usage:\n\tattest <device> | <bdaddr> [channel]\n");
142 }
143 
main(int argc,char * argv[])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