• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  *
3  *  Copyright (C) 2009-2011 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /*****************************************************************************
20 **
21 **  Name:          brcm_patchram_plus.c
22 **
23 **  Description:   This program downloads a patchram files in the HCD format
24 **                 to Broadcom Bluetooth based silicon and combo chips and
25 **				   and other utility functions.
26 **
27 **                 It can be invoked from the command line in the form
28 **						<-d> to print a debug log
29 **						<--patchram patchram_file>
30 **						<--baudrate baud_rate>
31 **						<--bd_addr bd_address>
32 **						<--enable_lpm>
33 **						<--enable_hci>
34 **						<--use_baudrate_for_download>
35 **						<--scopcm=sco_routing,pcm_interface_rate,frame_type,
36 **							sync_mode,clock_mode,lsb_first,fill_bits,
37 **							fill_method,fill_num,right_justify>
38 **
39 **							Where
40 **
41 **							sco_routing is 0 for PCM, 1 for Transport,
42 **							2 for Codec and 3 for I2S,
43 **
44 **							pcm_interface_rate is 0 for 128KBps, 1 for
45 **							256 KBps, 2 for 512KBps, 3 for 1024KBps,
46 **							and 4 for 2048Kbps,
47 **
48 **							frame_type is 0 for short and 1 for long,
49 **
50 **							sync_mode is 0 for slave and 1 for master,
51 **
52 **							clock_mode is 0 for slabe and 1 for master,
53 **
54 **							lsb_first is 0 for false aand 1 for true,
55 **
56 **							fill_bits is the value in decimal for unused bits,
57 **
58 **							fill_method is 0 for 0's and 1 for 1's, 2 for
59 **								signed and 3 for programmable,
60 **
61 **							fill_num is the number or bits to fill,
62 **
63 **							right_justify is 0 for false and 1 for true
64 **
65 **						<--i2s=i2s_enable,is_master,sample_rate,clock_rate>
66 **
67 **							Where
68 **
69 **							i2s_enable is 0 for disable and 1 for enable,
70 **
71 **							is_master is 0 for slave and 1 for master,
72 **
73 **							sample_rate is 0 for 8KHz, 1 for 16Khz and
74 **								2 for 4 KHz,
75 **
76 **							clock_rate is 0 for 128KHz, 1 for 256KHz, 3 for
77 **								1024 KHz and 4 for 2048 KHz.
78 **
79 **						<--no2bytes skips waiting for two byte confirmation
80 **							before starting patchram download. Newer chips
81 **                          do not generate these two bytes.>
82 **						<--tosleep=number of microsseconds to sleep before
83 **							patchram download begins.>
84 **						uart_device_name
85 **
86 **                 For example:
87 **
88 **                 brcm_patchram_plus -d --patchram  \
89 **						BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0
90 **
91 **                 It will return 0 for success and a number greater than 0
92 **                 for any errors.
93 **
94 **                 For Android, this program invoked using a
95 **                 "system(2)" call from the beginning of the bt_enable
96 **                 function inside the file
97 **                 system/bluetooth/bluedroid/bluetooth.c.
98 **
99 **                 If the Android system property "ro.bt.bcm_bdaddr_path" is
100 **                 set, then the bd_addr will be read from this path.
101 **                 This is overridden by --bd_addr on the command line.
102 **
103 ******************************************************************************/
104 
105 // TODO: Integrate BCM support into Bluez hciattach
106 
107 #include <stdio.h>
108 #include <getopt.h>
109 #include <errno.h>
110 
111 #include <sys/types.h>
112 #include <sys/stat.h>
113 #include <fcntl.h>
114 
115 #include <stdlib.h>
116 
117 #ifdef ANDROID
118 #include <termios.h>
119 #else
120 #include <sys/termios.h>
121 #include <sys/ioctl.h>
122 #include <limits.h>
123 #endif
124 
125 #include <string.h>
126 #include <signal.h>
127 
128 #ifdef ANDROID
129 #include <cutils/properties.h>
130 #define LOG_TAG "brcm_patchram_plus"
131 #include <cutils/log.h>
132 #undef printf
133 #define printf ALOGD
134 #undef fprintf
135 #define fprintf(x, ...) \
136   { if(x==stderr) ALOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); }
137 
138 #endif //ANDROID
139 
140 #ifndef N_HCI
141 #define N_HCI	15
142 #endif
143 
144 #define HCIUARTSETPROTO		_IOW('U', 200, int)
145 #define HCIUARTGETPROTO		_IOR('U', 201, int)
146 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
147 
148 #define HCI_UART_H4		0
149 #define HCI_UART_BCSP	1
150 #define HCI_UART_3WIRE	2
151 #define HCI_UART_H4DS	3
152 #define HCI_UART_LL		4
153 
154 typedef unsigned char uchar;
155 
156 int uart_fd = -1;
157 int hcdfile_fd = -1;
158 int termios_baudrate = 0;
159 int bdaddr_flag = 0;
160 int enable_lpm = 0;
161 int enable_hci = 0;
162 int use_baudrate_for_download = 0;
163 int debug = 0;
164 int scopcm = 0;
165 int i2s = 0;
166 int no2bytes = 0;
167 int tosleep = 0;
168 
169 struct termios termios;
170 uchar buffer[1024];
171 
172 uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
173 
174 uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 };
175 
176 uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00,
177 	0x00, 0x00, 0x00, 0x00 };
178 
179 uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06,
180 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
181 
182 uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c,
183 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
184 	0x00, 0x00 };
185 
186 uchar hci_write_sco_pcm_int[] =
187 	{ 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
188 
189 uchar hci_write_pcm_data_format[] =
190 	{ 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
191 
192 uchar hci_write_i2spcm_interface_param[] =
193 	{ 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 };
194 
195 int
parse_patchram(char * optarg)196 parse_patchram(char *optarg)
197 {
198 	char *p;
199 
200 	if (!(p = strrchr(optarg, '.'))) {
201 		fprintf(stderr, "file %s not an HCD file\n", optarg);
202 		exit(3);
203 	}
204 
205 	p++;
206 
207 	if (strcasecmp("hcd", p) != 0) {
208 		fprintf(stderr, "file %s not an HCD file\n", optarg);
209 		exit(4);
210 	}
211 
212 	if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) {
213 		fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno);
214 		exit(5);
215 	}
216 
217 	return(0);
218 }
219 
220 void
BRCM_encode_baud_rate(uint baud_rate,uchar * encoded_baud)221 BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud)
222 {
223 	if(baud_rate == 0 || encoded_baud == NULL) {
224 		fprintf(stderr, "Baudrate not supported!");
225 		return;
226 	}
227 
228 	encoded_baud[3] = (uchar)(baud_rate >> 24);
229 	encoded_baud[2] = (uchar)(baud_rate >> 16);
230 	encoded_baud[1] = (uchar)(baud_rate >> 8);
231 	encoded_baud[0] = (uchar)(baud_rate & 0xFF);
232 }
233 
234 typedef struct {
235 	int baud_rate;
236 	int termios_value;
237 } tBaudRates;
238 
239 tBaudRates baud_rates[] = {
240 	{ 115200, B115200 },
241 	{ 230400, B230400 },
242 	{ 460800, B460800 },
243 	{ 500000, B500000 },
244 	{ 576000, B576000 },
245 	{ 921600, B921600 },
246 	{ 1000000, B1000000 },
247 	{ 1152000, B1152000 },
248 	{ 1500000, B1500000 },
249 	{ 2000000, B2000000 },
250 	{ 2500000, B2500000 },
251 	{ 3000000, B3000000 },
252 #ifndef __CYGWIN__
253 	{ 3500000, B3500000 },
254 	{ 4000000, B4000000 }
255 #endif
256 };
257 
258 int
validate_baudrate(int baud_rate,int * value)259 validate_baudrate(int baud_rate, int *value)
260 {
261 	unsigned int i;
262 
263 	for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) {
264 		if (baud_rates[i].baud_rate == baud_rate) {
265 			*value = baud_rates[i].termios_value;
266 			return(1);
267 		}
268 	}
269 
270 	return(0);
271 }
272 
273 int
parse_baudrate(char * optarg)274 parse_baudrate(char *optarg)
275 {
276 	int baudrate = atoi(optarg);
277 
278 	if (validate_baudrate(baudrate, &termios_baudrate)) {
279 		BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]);
280 	}
281 
282 	return(0);
283 }
284 
285 int
parse_bdaddr(char * optarg)286 parse_bdaddr(char *optarg)
287 {
288 	int bd_addr[6];
289 	int i;
290 
291 	sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X",
292 		&bd_addr[5], &bd_addr[4], &bd_addr[3],
293 		&bd_addr[2], &bd_addr[1], &bd_addr[0]);
294 
295 	for (i = 0; i < 6; i++) {
296 		hci_write_bd_addr[4 + i] = bd_addr[i];
297 	}
298 
299 	bdaddr_flag = 1;
300 
301 	return(0);
302 }
303 
304 int
parse_enable_lpm(char * optarg)305 parse_enable_lpm(char *optarg)
306 {
307 	enable_lpm = 1;
308 	return(0);
309 }
310 
311 int
parse_use_baudrate_for_download(char * optarg)312 parse_use_baudrate_for_download(char *optarg)
313 {
314 	use_baudrate_for_download = 1;
315 	return(0);
316 }
317 
318 int
parse_enable_hci(char * optarg)319 parse_enable_hci(char *optarg)
320 {
321 	enable_hci = 1;
322 	return(0);
323 }
324 
325 int
parse_scopcm(char * optarg)326 parse_scopcm(char *optarg)
327 {
328 	int param[10];
329 	int ret;
330 	int i;
331 
332 	ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
333 		&param[0], &param[1], &param[2], &param[3], &param[4],
334 		&param[5], &param[6], &param[7], &param[8], &param[9]);
335 
336 	if (ret != 10) {
337 		return(1);
338 	}
339 
340 	scopcm = 1;
341 
342 	for (i = 0; i < 5; i++) {
343 		hci_write_sco_pcm_int[4 + i] = param[i];
344 	}
345 
346 	for (i = 0; i < 5; i++) {
347 		hci_write_pcm_data_format[4 + i] = param[5 + i];
348 	}
349 
350 	return(0);
351 }
352 
353 int
parse_i2s(char * optarg)354 parse_i2s(char *optarg)
355 {
356 	int param[4];
357 	int ret;
358 	int i;
359 
360 	ret = sscanf(optarg, "%d,%d,%d,%d", &param[0], &param[1], &param[2],
361 		&param[3]);
362 
363 	if (ret != 4) {
364 		return(1);
365 	}
366 
367 	i2s = 1;
368 
369 	for (i = 0; i < 4; i++) {
370 		hci_write_i2spcm_interface_param[4 + i] = param[i];
371 	}
372 
373 	return(0);
374 }
375 
376 int
parse_no2bytes(char * optarg)377 parse_no2bytes(char *optarg)
378 {
379 	no2bytes = 1;
380 	return(0);
381 }
382 
383 int
parse_tosleep(char * optarg)384 parse_tosleep(char *optarg)
385 {
386 	tosleep = atoi(optarg);
387 
388 	if (tosleep <= 0) {
389 		return(1);
390 	}
391 
392 	return(0);
393 }
394 
395 void
usage(char * argv0)396 usage(char *argv0)
397 {
398 	printf("Usage %s:\n", argv0);
399 	printf("\t<-d> to print a debug log\n");
400 	printf("\t<--patchram patchram_file>\n");
401 	printf("\t<--baudrate baud_rate>\n");
402 	printf("\t<--bd_addr bd_address>\n");
403 	printf("\t<--enable_lpm>\n");
404 	printf("\t<--enable_hci>\n");
405 	printf("\t<--use_baudrate_for_download> - Uses the\n");
406 	printf("\t\tbaudrate for downloading the firmware\n");
407 	printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n");
408 	printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n");
409 	printf("\t\tfill_method,fill_num,right_justify>\n");
410 	printf("\n\t\tWhere\n");
411 	printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n");
412 	printf("\t\t2 for Codec and 3 for I2S,\n");
413 	printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n");
414 	printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n");
415 	printf("\t\tand 4 for 2048Kbps,\n");
416 	printf("\n\t\tframe_type is 0 for short and 1 for long,\n");
417 	printf("\t\tsync_mode is 0 for slave and 1 for master,\n");
418 	printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n");
419 	printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n");
420 	printf("\n\t\tfill_bits is the value in decimal for unused bits,\n");
421 	printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n");
422 	printf("\t\tsigned and 3 for programmable,\n");
423 	printf("\n\t\tfill_num is the number or bits to fill,\n");
424 	printf("\n\t\tright_justify is 0 for false and 1 for true\n");
425 	printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n");
426 	printf("\n\t\tWhere\n");
427 	printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n");
428 	printf("\n\t\tis_master is 0 for slave and 1 for master,\n");
429 	printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n");
430 	printf("\t\t2 for 4 KHz,\n");
431 	printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n");
432 	printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n");
433 	printf("\t<--no2bytes skips waiting for two byte confirmation\n");
434 	printf("\t\tbefore starting patchram download. Newer chips\n");
435 	printf("\t\tdo not generate these two bytes.>\n");
436 	printf("\t<--tosleep=microseconds>\n");
437 	printf("\tuart_device_name\n");
438 }
439 
440 int
parse_cmd_line(int argc,char ** argv)441 parse_cmd_line(int argc, char **argv)
442 {
443 	int c;
444 	int ret = 0;
445 
446 	typedef int (*PFI)();
447 
448 	PFI parse[] = { parse_patchram, parse_baudrate,
449 		parse_bdaddr, parse_enable_lpm, parse_enable_hci,
450 		parse_use_baudrate_for_download,
451 		parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep};
452 
453 	while (1) {
454 		int this_option_optind = optind ? optind : 1;
455 		int option_index = 0;
456 
457 		static struct option long_options[] = {
458 			{"patchram", 1, 0, 0},
459 			{"baudrate", 1, 0, 0},
460 			{"bd_addr", 1, 0, 0},
461 			{"enable_lpm", 0, 0, 0},
462 			{"enable_hci", 0, 0, 0},
463 			{"use_baudrate_for_download", 0, 0, 0},
464 			{"scopcm", 1, 0, 0},
465 			{"i2s", 1, 0, 0},
466 			{"no2bytes", 0, 0, 0},
467 			{"tosleep", 1, 0, 0},
468 			{0, 0, 0, 0}
469 		};
470 
471 		c = getopt_long_only (argc, argv, "d", long_options,
472 				&option_index);
473 
474 		if (c == -1) {
475 			break;
476 		}
477 
478 		switch (c) {
479 			case 0:
480 				if (debug) {
481 					printf ("option %s",
482 						long_options[option_index].name);
483 					if (optarg)
484 						printf (" with arg %s", optarg);
485 					printf ("\n");
486 				}
487 
488 				ret = (*parse[option_index])(optarg);
489 
490 				break;
491 			case 'd':
492 				debug = 1;
493 				break;
494 
495 			case '?':
496 				//nobreak
497 			default:
498 				usage(argv[0]);
499 				break;
500 		}
501 
502 		if (ret) {
503 			usage(argv[0]);
504 			break;
505 		}
506 	}
507 
508 	if (ret) {
509 		return(1);
510 	}
511 
512 	if (optind < argc) {
513 		if (debug)
514 			printf ("%s \n", argv[optind]);
515 		if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) {
516 			fprintf(stderr, "port %s could not be opened, error %d\n",
517 					argv[2], errno);
518 		}
519 	}
520 
521 	return(0);
522 }
523 
524 void
init_uart()525 init_uart()
526 {
527 	tcflush(uart_fd, TCIOFLUSH);
528 	tcgetattr(uart_fd, &termios);
529 
530 #ifndef __CYGWIN__
531 	cfmakeraw(&termios);
532 #else
533 	termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
534                 | INLCR | IGNCR | ICRNL | IXON);
535 	termios.c_oflag &= ~OPOST;
536 	termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
537 	termios.c_cflag &= ~(CSIZE | PARENB);
538 	termios.c_cflag |= CS8;
539 #endif
540 
541 	termios.c_cflag |= CRTSCTS;
542 	tcsetattr(uart_fd, TCSANOW, &termios);
543 	tcflush(uart_fd, TCIOFLUSH);
544 	tcsetattr(uart_fd, TCSANOW, &termios);
545 	tcflush(uart_fd, TCIOFLUSH);
546 	tcflush(uart_fd, TCIOFLUSH);
547 	cfsetospeed(&termios, B115200);
548 	cfsetispeed(&termios, B115200);
549 	tcsetattr(uart_fd, TCSANOW, &termios);
550 }
551 
552 void
dump(uchar * out,int len)553 dump(uchar *out, int len)
554 {
555 	int i;
556 
557 	for (i = 0; i < len; i++) {
558 		if (i && !(i % 16)) {
559 			fprintf(stderr, "\n");
560 		}
561 
562 		fprintf(stderr, "%02x ", out[i]);
563 	}
564 
565 	fprintf(stderr, "\n");
566 }
567 
568 void
read_event(int fd,uchar * buffer)569 read_event(int fd, uchar *buffer)
570 {
571 	int i = 0;
572 	int len = 3;
573 	int count;
574 
575 	while ((count = read(fd, &buffer[i], len)) < len) {
576 		i += count;
577 		len -= count;
578 	}
579 
580 	i += count;
581 	len = buffer[2];
582 
583 	while ((count = read(fd, &buffer[i], len)) < len) {
584 		i += count;
585 		len -= count;
586 	}
587 
588 	if (debug) {
589 		count += i;
590 
591 		fprintf(stderr, "received %d\n", count);
592 		dump(buffer, count);
593 	}
594 }
595 
596 void
hci_send_cmd(uchar * buf,int len)597 hci_send_cmd(uchar *buf, int len)
598 {
599 	if (debug) {
600 		fprintf(stderr, "writing\n");
601 		dump(buf, len);
602 	}
603 
604 	write(uart_fd, buf, len);
605 }
606 
607 void
expired(int sig)608 expired(int sig)
609 {
610 	hci_send_cmd(hci_reset, sizeof(hci_reset));
611 	alarm(4);
612 }
613 
614 void
proc_reset()615 proc_reset()
616 {
617 	signal(SIGALRM, expired);
618 
619 
620 	hci_send_cmd(hci_reset, sizeof(hci_reset));
621 
622 	alarm(4);
623 
624 	read_event(uart_fd, buffer);
625 
626 	alarm(0);
627 }
628 
629 void
proc_patchram()630 proc_patchram()
631 {
632 	int len;
633 
634 	hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver));
635 
636 	read_event(uart_fd, buffer);
637 
638 	if (!no2bytes) {
639 		read(uart_fd, &buffer[0], 2);
640 	}
641 
642 	if (tosleep) {
643 		usleep(tosleep);
644 	}
645 
646 	while (read(hcdfile_fd, &buffer[1], 3)) {
647 		buffer[0] = 0x01;
648 
649 		len = buffer[3];
650 
651 		read(hcdfile_fd, &buffer[4], len);
652 
653 		hci_send_cmd(buffer, len + 4);
654 
655 		read_event(uart_fd, buffer);
656 	}
657 
658 	if (use_baudrate_for_download) {
659 		cfsetospeed(&termios, B115200);
660 		cfsetispeed(&termios, B115200);
661 		tcsetattr(uart_fd, TCSANOW, &termios);
662 	}
663 	proc_reset();
664 }
665 
666 void
proc_baudrate()667 proc_baudrate()
668 {
669 	hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));
670 
671 	read_event(uart_fd, buffer);
672 
673 	cfsetospeed(&termios, termios_baudrate);
674 	cfsetispeed(&termios, termios_baudrate);
675 	tcsetattr(uart_fd, TCSANOW, &termios);
676 
677 	if (debug) {
678 		fprintf(stderr, "Done setting baudrate\n");
679 	}
680 }
681 
682 void
proc_bdaddr()683 proc_bdaddr()
684 {
685 	hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));
686 
687 	read_event(uart_fd, buffer);
688 }
689 
690 void
proc_enable_lpm()691 proc_enable_lpm()
692 {
693 	hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));
694 
695 	read_event(uart_fd, buffer);
696 }
697 
698 void
proc_scopcm()699 proc_scopcm()
700 {
701 	hci_send_cmd(hci_write_sco_pcm_int,
702 		sizeof(hci_write_sco_pcm_int));
703 
704 	read_event(uart_fd, buffer);
705 
706 	hci_send_cmd(hci_write_pcm_data_format,
707 		sizeof(hci_write_pcm_data_format));
708 
709 	read_event(uart_fd, buffer);
710 }
711 
712 void
proc_i2s()713 proc_i2s()
714 {
715 	hci_send_cmd(hci_write_i2spcm_interface_param,
716 		sizeof(hci_write_i2spcm_interface_param));
717 
718 	read_event(uart_fd, buffer);
719 }
720 
721 void
proc_enable_hci()722 proc_enable_hci()
723 {
724 	int i = N_HCI;
725 	int proto = HCI_UART_H4;
726 	if (ioctl(uart_fd, TIOCSETD, &i) < 0) {
727 		fprintf(stderr, "Can't set line discipline\n");
728 		return;
729 	}
730 
731 	if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) {
732 		fprintf(stderr, "Can't set hci protocol\n");
733 		return;
734 	}
735 	fprintf(stderr, "Done setting line discpline\n");
736 	return;
737 }
738 
739 #ifdef ANDROID
740 void
read_default_bdaddr()741 read_default_bdaddr()
742 {
743 	int sz;
744 	int fd;
745 
746 	char path[PROPERTY_VALUE_MAX];
747 
748 	char bdaddr[18];
749 	int len = 17;
750 	memset(bdaddr, 0, (len + 1) * sizeof(char));
751 
752 	property_get("ro.bt.bdaddr_path", path, "");
753 	if (path[0] == 0)
754 		return;
755 
756 	fd = open(path, O_RDONLY);
757 	if (fd < 0) {
758 		fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno),
759 				errno);
760 		return;
761 	}
762 
763 	sz = read(fd, bdaddr, len);
764 	if (sz < 0) {
765 		fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno),
766 				errno);
767 		close(fd);
768 		return;
769 	} else if (sz != len) {
770 		fprintf(stderr, "read(%s) unexpected size %d", path, sz);
771 		close(fd);
772 		return;
773 	}
774 
775 	if (debug) {
776 		printf("Read default bdaddr of %s\n", bdaddr);
777 	}
778 
779 	parse_bdaddr(bdaddr);
780 }
781 #endif
782 
783 
784 int
main(int argc,char ** argv)785 main (int argc, char **argv)
786 {
787 #ifdef ANDROID
788 	read_default_bdaddr();
789 #endif
790 
791 	if (parse_cmd_line(argc, argv)) {
792 		exit(1);
793 	}
794 
795 	if (uart_fd < 0) {
796 		exit(2);
797 	}
798 
799 	init_uart();
800 
801 	proc_reset();
802 
803 	if (use_baudrate_for_download) {
804 		if (termios_baudrate) {
805 			proc_baudrate();
806 		}
807 	}
808 
809 	if (hcdfile_fd > 0) {
810 		proc_patchram();
811 	}
812 
813 	if (termios_baudrate) {
814 		proc_baudrate();
815 	}
816 
817 	if (bdaddr_flag) {
818 		proc_bdaddr();
819 	}
820 
821 	if (enable_lpm) {
822 		proc_enable_lpm();
823 	}
824 
825 	if (scopcm) {
826 		proc_scopcm();
827 	}
828 
829 	if (i2s) {
830 		proc_i2s();
831 	}
832 
833 	if (enable_hci) {
834 		proc_enable_hci();
835 
836 		while (1) {
837 			sleep(UINT_MAX);
838 		}
839 	}
840 
841 	exit(0);
842 }
843