• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2007-2008  Texas Instruments, Inc.
6  *  Copyright (C) 2005-2009  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <termios.h>
34 #include <time.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/ioctl.h>
39 #include <sys/socket.h>
40 #include <sys/uio.h>
41 
42 #include <bluetooth/bluetooth.h>
43 #include <bluetooth/hci.h>
44 #include <bluetooth/hci_lib.h>
45 
46 #include "hciattach.h"
47 
48 #ifdef HCIATTACH_DEBUG
49 #define DPRINTF(x...)	printf(x)
50 #else
51 #define DPRINTF(x...)
52 #endif
53 
54 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
55 
56 #define MAKEWORD(a, b)  ((uint16_t)(((uint8_t)(a)) | ((uint16_t)((uint8_t)(b))) << 8))
57 
58 #define TI_MANUFACTURER_ID	13
59 
60 #define FIRMWARE_DIRECTORY	"/lib/firmware/"
61 
62 #define ACTION_SEND_COMMAND	1
63 #define ACTION_WAIT_EVENT	2
64 #define ACTION_SERIAL		3
65 #define ACTION_DELAY		4
66 #define ACTION_RUN_SCRIPT	5
67 #define ACTION_REMARKS		6
68 
69 #define BRF_DEEP_SLEEP_OPCODE_BYTE_1	0x0c
70 #define BRF_DEEP_SLEEP_OPCODE_BYTE_2	0xfd
71 #define BRF_DEEP_SLEEP_OPCODE		\
72 	(BRF_DEEP_SLEEP_OPCODE_BYTE_1 | (BRF_DEEP_SLEEP_OPCODE_BYTE_2 << 8))
73 
74 #define FILE_HEADER_MAGIC	0x42535442
75 
76 /*
77  * BRF Firmware header
78  */
79 struct bts_header {
80 	uint32_t	magic;
81 	uint32_t	version;
82 	uint8_t	future[24];
83 	uint8_t	actions[0];
84 }__attribute__ ((packed));
85 
86 /*
87  * BRF Actions structure
88  */
89 struct bts_action {
90 	uint16_t	type;
91 	uint16_t	size;
92 	uint8_t	data[0];
93 } __attribute__ ((packed));
94 
95 struct bts_action_send {
96 	uint8_t data[0];
97 } __attribute__ ((packed));
98 
99 struct bts_action_wait {
100 	uint32_t msec;
101 	uint32_t size;
102 	uint8_t data[0];
103 }__attribute__ ((packed));
104 
105 struct bts_action_delay {
106 	uint32_t msec;
107 }__attribute__ ((packed));
108 
109 struct bts_action_serial {
110 	uint32_t baud;
111 	uint32_t flow_control;
112 }__attribute__ ((packed));
113 
bts_load_script(const char * file_name,uint32_t * version)114 static FILE *bts_load_script(const char* file_name, uint32_t* version)
115 {
116 	struct bts_header header;
117 	FILE* fp;
118 
119 	fp = fopen(file_name, "rb");
120 	if (!fp) {
121 		perror("can't open firmware file");
122 		goto out;
123 	}
124 
125 	if (1 != fread(&header, sizeof(struct bts_header), 1, fp)) {
126 		perror("can't read firmware file");
127 		goto errclose;
128 	}
129 
130 	if (header.magic != FILE_HEADER_MAGIC) {
131 		fprintf(stderr, "%s not a legal TI firmware file\n", file_name);
132 		goto errclose;
133 	}
134 
135 	if (NULL != version)
136 		*version = header.version;
137 
138 	goto out;
139 
140 errclose:
141 	fclose(fp);
142 	fp = NULL;
143 out:
144 	return fp;
145 }
146 
bts_fetch_action(FILE * fp,unsigned char * action_buf,unsigned long buf_size,uint16_t * action_type)147 static unsigned long bts_fetch_action(FILE* fp, unsigned char* action_buf,
148 				unsigned long buf_size, uint16_t* action_type)
149 {
150 	struct bts_action action_hdr;
151 	unsigned long nread;
152 
153 	if (!fp)
154 		return 0;
155 
156 	if (1 != fread(&action_hdr, sizeof(struct bts_action), 1, fp))
157 		return 0;
158 
159 	if (action_hdr.size > buf_size) {
160 		fprintf(stderr, "bts_next_action: not enough space to read next action\n");
161 		return 0;
162 	}
163 
164 	nread = fread(action_buf, sizeof(uint8_t), action_hdr.size, fp);
165 	if (nread != (action_hdr.size)) {
166 		fprintf(stderr, "bts_next_action: fread failed to read next action\n");
167 		return 0;
168 	}
169 
170 	*action_type = action_hdr.type;
171 
172 	return nread * sizeof(uint8_t);
173 }
174 
bts_unload_script(FILE * fp)175 static void bts_unload_script(FILE* fp)
176 {
177 	if (fp)
178 		fclose(fp);
179 }
180 
is_it_texas(const uint8_t * respond)181 static int is_it_texas(const uint8_t *respond)
182 {
183 	uint16_t manufacturer_id;
184 
185 	manufacturer_id = MAKEWORD(respond[11], respond[12]);
186 
187 	return TI_MANUFACTURER_ID == manufacturer_id ? 1 : 0;
188 }
189 
get_firmware_name(const uint8_t * respond)190 static const char *get_firmware_name(const uint8_t *respond)
191 {
192 	static char firmware_file_name[PATH_MAX] = {0};
193 	uint16_t version = 0, chip = 0, min_ver = 0, maj_ver = 0;
194 
195 	version = MAKEWORD(respond[13], respond[14]);
196 	chip =  (version & 0x7C00) >> 10;
197 	min_ver = (version & 0x007F);
198 	maj_ver = (version & 0x0380) >> 7;
199 
200 	if (version & 0x8000)
201 		maj_ver |= 0x0008;
202 
203 	sprintf(firmware_file_name, FIRMWARE_DIRECTORY "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
204 
205 	return firmware_file_name;
206 }
207 
brf_delay(struct bts_action_delay * delay)208 static void brf_delay(struct bts_action_delay *delay)
209 {
210 	usleep(1000 * delay->msec);
211 }
212 
brf_set_serial_params(struct bts_action_serial * serial_action,int fd,struct termios * ti)213 static int brf_set_serial_params(struct bts_action_serial *serial_action,
214 						int fd, struct termios *ti)
215 {
216 	fprintf(stderr, "texas: changing baud rate to %u, flow control to %u\n",
217 				serial_action->baud, serial_action->flow_control );
218 	tcflush(fd, TCIOFLUSH);
219 
220 	if (serial_action->flow_control)
221 		ti->c_cflag |= CRTSCTS;
222 	else
223 		ti->c_cflag &= ~CRTSCTS;
224 
225 	if (tcsetattr(fd, TCSANOW, ti) < 0) {
226 		perror("Can't set port settings");
227 		return -1;
228 	}
229 
230 	tcflush(fd, TCIOFLUSH);
231 
232 	if (set_speed(fd, ti, serial_action->baud) < 0) {
233 		perror("Can't set baud rate");
234 		return -1;
235 	}
236 
237 	return 0;
238 }
239 
brf_send_command_socket(int fd,struct bts_action_send * send_action)240 static int brf_send_command_socket(int fd, struct bts_action_send* send_action)
241 {
242 	char response[1024] = {0};
243 	hci_command_hdr *cmd = (hci_command_hdr *) send_action->data;
244 	uint16_t opcode = cmd->opcode;
245 
246 	struct hci_request rq;
247 	memset(&rq, 0, sizeof(rq));
248 	rq.ogf    = cmd_opcode_ogf(opcode);
249 	rq.ocf    = cmd_opcode_ocf(opcode);
250 	rq.event  = EVT_CMD_COMPLETE;
251 	rq.cparam = &send_action->data[3];
252 	rq.clen   = send_action->data[2];
253 	rq.rparam = response;
254 	rq.rlen   = sizeof(response);
255 
256 	if (hci_send_req(fd, &rq, 15) < 0) {
257 		perror("Cannot send hci command to socket");
258 		return -1;
259 	}
260 
261 	/* verify success */
262 	if (response[0]) {
263 		errno = EIO;
264 		return -1;
265 	}
266 
267 	return 0;
268 }
269 
brf_send_command_file(int fd,struct bts_action_send * send_action,long size)270 static int brf_send_command_file(int fd, struct bts_action_send* send_action, long size)
271 {
272 	unsigned char response[1024] = {0};
273 	long ret = 0;
274 
275 	/* send command */
276 	if (size != write(fd, send_action, size)) {
277 		perror("Texas: Failed to write action command");
278 		return -1;
279 	}
280 
281 	/* read response */
282 	ret = read_hci_event(fd, response, sizeof(response));
283 	if (ret < 0) {
284 		perror("texas: failed to read command response");
285 		return -1;
286 	}
287 
288 	/* verify success */
289 	if (ret < 7 || 0 != response[6]) {
290 		fprintf( stderr, "TI init command failed.\n" );
291 		errno = EIO;
292 		return -1;
293 	}
294 
295 	return 0;
296 }
297 
298 
brf_send_command(int fd,struct bts_action_send * send_action,long size,int hcill_installed)299 static int brf_send_command(int fd, struct bts_action_send* send_action, long size, int hcill_installed)
300 {
301 	int ret = 0;
302 	char *fixed_action;
303 
304 	/* remove packet type when giving to socket API */
305 	if (hcill_installed) {
306 		fixed_action = ((char *) send_action) + 1;
307 		ret = brf_send_command_socket(fd, (struct bts_action_send *) fixed_action);
308 	} else {
309 		ret = brf_send_command_file(fd, send_action, size);
310 	}
311 
312 	return ret;
313 }
314 
brf_do_action(uint16_t brf_type,uint8_t * brf_action,long brf_size,int fd,struct termios * ti,int hcill_installed)315 static int brf_do_action(uint16_t brf_type, uint8_t *brf_action, long brf_size,
316 				int fd, struct termios *ti, int hcill_installed)
317 {
318 	int ret = 0;
319 
320 	switch (brf_type) {
321 	case ACTION_SEND_COMMAND:
322 		DPRINTF("W");
323 		ret = brf_send_command(fd, (struct bts_action_send*) brf_action, brf_size, hcill_installed);
324 		break;
325 	case ACTION_WAIT_EVENT:
326 		DPRINTF("R");
327 		break;
328 	case ACTION_SERIAL:
329 		DPRINTF("S");
330 		ret = brf_set_serial_params((struct bts_action_serial *) brf_action, fd, ti);
331 		break;
332 	case ACTION_DELAY:
333 		DPRINTF("D");
334 		brf_delay((struct bts_action_delay *) brf_action);
335 		break;
336 	case ACTION_REMARKS:
337 		DPRINTF("C");
338 		break;
339 	default:
340 		fprintf(stderr, "brf_init: unknown firmware action type (%d)\n", brf_type);
341 		break;
342 	}
343 
344 	return ret;
345 }
346 
347 /*
348  * tests whether a given brf action is a HCI_VS_Sleep_Mode_Configurations cmd
349  */
brf_action_is_deep_sleep(uint8_t * brf_action,long brf_size,uint16_t brf_type)350 static int brf_action_is_deep_sleep(uint8_t *brf_action, long brf_size,
351 							uint16_t brf_type)
352 {
353 	uint16_t opcode;
354 
355 	if (brf_type != ACTION_SEND_COMMAND)
356 		return 0;
357 
358 	if (brf_size < 3)
359 		return 0;
360 
361 	if (brf_action[0] != HCI_COMMAND_PKT)
362 		return 0;
363 
364 	/* HCI data is little endian */
365 	opcode = brf_action[1] | (brf_action[2] << 8);
366 
367 	if (opcode != BRF_DEEP_SLEEP_OPCODE)
368 		return 0;
369 
370 	/* action is deep sleep configuration command ! */
371 	return 1;
372 }
373 
374 /*
375  * This function is called twice.
376  * The first time it is called, it loads the brf script, and executes its
377  * commands until it reaches a deep sleep command (or its end).
378  * The second time it is called, it assumes HCILL protocol is set up,
379  * and sends rest of brf script via the supplied socket.
380  */
brf_do_script(int fd,struct termios * ti,const char * bts_file)381 static int brf_do_script(int fd, struct termios *ti, const char *bts_file)
382 {
383 	int ret = 0,  hcill_installed = bts_file ? 0 : 1;
384 	uint32_t vers;
385 	static FILE *brf_script_file = NULL;
386 	static uint8_t brf_action[512];
387 	static long brf_size;
388 	static uint16_t brf_type;
389 
390 	/* is it the first time we are called ? */
391 	if (0 == hcill_installed) {
392 		DPRINTF("Sending script to serial device\n");
393 		brf_script_file = bts_load_script(bts_file, &vers );
394 		if (!brf_script_file) {
395 			fprintf(stderr, "Warning: cannot find BTS file: %s\n",
396 					bts_file);
397 			return 0;
398 		}
399 
400 		fprintf( stderr, "Loaded BTS script version %u\n", vers );
401 
402 		brf_size = bts_fetch_action(brf_script_file, brf_action,
403 						sizeof(brf_action), &brf_type);
404 		if (brf_size == 0) {
405 			fprintf(stderr, "Warning: BTS file is empty !");
406 			return 0;
407 		}
408 	}
409 	else {
410 		DPRINTF("Sending script to bluetooth socket\n");
411 	}
412 
413 	/* execute current action and continue to parse brf script file */
414 	while (brf_size != 0) {
415 		ret = brf_do_action(brf_type, brf_action, brf_size,
416 						fd, ti, hcill_installed);
417 		if (ret == -1)
418 			break;
419 
420 		brf_size = bts_fetch_action(brf_script_file, brf_action,
421 						sizeof(brf_action), &brf_type);
422 
423 		/* if this is the first time we run (no HCILL yet) */
424 		/* and a deep sleep command is encountered */
425 		/* we exit */
426 		if (!hcill_installed &&
427 				brf_action_is_deep_sleep(brf_action,
428 							brf_size, brf_type))
429 			return 0;
430 	}
431 
432 	bts_unload_script(brf_script_file);
433 	brf_script_file = NULL;
434 	DPRINTF("\n");
435 
436 	return ret;
437 }
438 
texas_init(int fd,struct termios * ti)439 int texas_init(int fd, struct termios *ti)
440 {
441 	struct timespec tm = {0, 50000};
442 	char cmd[4];
443 	unsigned char resp[100];		/* Response */
444 	const char *bts_file;
445 	int n;
446 
447 	memset(resp,'\0', 100);
448 
449 	/* It is possible to get software version with manufacturer specific
450 	   HCI command HCI_VS_TI_Version_Number. But the only thing you get more
451 	   is if this is point-to-point or point-to-multipoint module */
452 
453 	/* Get Manufacturer and LMP version */
454 	cmd[0] = HCI_COMMAND_PKT;
455 	cmd[1] = 0x01;
456 	cmd[2] = 0x10;
457 	cmd[3] = 0x00;
458 
459 	do {
460 		n = write(fd, cmd, 4);
461 		if (n < 0) {
462 			perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
463 			return -1;
464 		}
465 		if (n < 4) {
466 			fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n);
467 			return -1;
468 		}
469 
470 		/* Read reply. */
471 		if (read_hci_event(fd, resp, 100) < 0) {
472 			perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
473 			return -1;
474 		}
475 
476 		/* Wait for command complete event for our Opcode */
477 	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
478 
479 	/* Verify manufacturer */
480 	if (! is_it_texas(resp)) {
481 		fprintf(stderr,"ERROR: module's manufacturer is not Texas Instruments\n");
482 		return -1;
483 	}
484 
485 	fprintf(stderr, "Found a Texas Instruments' chip!\n");
486 
487 	bts_file = get_firmware_name(resp);
488 	fprintf(stderr, "Firmware file : %s\n", bts_file);
489 
490 	n = brf_do_script(fd, ti, bts_file);
491 
492 	nanosleep(&tm, NULL);
493 
494 	return n;
495 }
496 
texas_post(int fd,struct termios * ti)497 int texas_post(int fd, struct termios *ti)
498 {
499 	int dev_id, dd, ret = 0;
500 
501 	sleep(1);
502 
503 	dev_id = ioctl(fd, HCIUARTGETDEVICE, 0);
504 	if (dev_id < 0) {
505 		perror("cannot get device id");
506 		return -1;
507 	}
508 
509 	DPRINTF("\nAdded device hci%d\n", dev_id);
510 
511 	dd = hci_open_dev(dev_id);
512 	if (dd < 0) {
513 		perror("HCI device open failed");
514 		return -1;
515 	}
516 
517 	ret = brf_do_script(dd, ti, NULL);
518 
519 	hci_close_dev(dd);
520 
521 	return ret;
522 }
523