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 ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4],
334 ¶m[5], ¶m[6], ¶m[7], ¶m[8], ¶m[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", ¶m[0], ¶m[1], ¶m[2],
361 ¶m[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