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 #include <time.h>
117
118 #ifdef ANDROID
119 #include <termios.h>
120 #else
121 #include <sys/termios.h>
122 #include <sys/ioctl.h>
123 #include <limits.h>
124 #endif
125
126 #include <string.h>
127 #include <signal.h>
128
129 #ifdef ANDROID
130 #include <cutils/properties.h>
131 #define LOG_TAG "brcm_patchram_plus"
132 #include <cutils/log.h>
133 #undef printf
134 #define printf ALOGD
135 #undef fprintf
136 #define fprintf(x, ...) \
137 { if(x==stderr) ALOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); }
138
139 #endif //ANDROID
140
141 #ifndef N_HCI
142 #define N_HCI 15
143 #endif
144
145 #define HCIUARTSETPROTO _IOW('U', 200, int)
146 #define HCIUARTGETPROTO _IOR('U', 201, int)
147 #define HCIUARTGETDEVICE _IOR('U', 202, int)
148 #define AP_NAME_SUFFIX_LEN 18
149
150 #define HCI_UART_H4 0
151 #define HCI_UART_BCSP 1
152 #define HCI_UART_3WIRE 2
153 #define HCI_UART_H4DS 3
154 #define HCI_UART_LL 4
155
156 typedef unsigned char uchar;
157
158 int uart_fd = -1;
159 int hcdfile_fd = -1;
160 int termios_baudrate = 0;
161 int bdaddr_flag = 0;
162 int enable_lpm = 0;
163 int enable_hci = 0;
164 int use_baudrate_for_download = 0;
165 int debug = 0;
166 int scopcm = 0;
167 int i2s = 0;
168 int no2bytes = 0;
169 int tosleep = 0;
170
171 struct termios termios;
172 uchar buffer[1024];
173
174 uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
175
176 uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 };
177
178 uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00 };
180
181 uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
183
184 uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c,
185 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
186 0x00, 0x00 };
187
188 uchar hci_write_sco_pcm_int[] =
189 { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
190
191 uchar hci_write_pcm_data_format[] =
192 { 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
193
194 uchar hci_write_i2spcm_interface_param[] =
195 { 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 };
196
197 int
parse_patchram(char * optarg)198 parse_patchram(char *optarg)
199 {
200 char *p;
201
202 if (!(p = strrchr(optarg, '.'))) {
203 fprintf(stderr, "file %s not an HCD file\n", optarg);
204 exit(3);
205 }
206
207 p++;
208
209 if (strcasecmp("hcd", p) != 0) {
210 fprintf(stderr, "file %s not an HCD file\n", optarg);
211 exit(4);
212 }
213
214 if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) {
215 fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno);
216 exit(5);
217 }
218
219 return(0);
220 }
221
222 void
BRCM_encode_baud_rate(uint baud_rate,uchar * encoded_baud)223 BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud)
224 {
225 if(baud_rate == 0 || encoded_baud == NULL) {
226 fprintf(stderr, "Baudrate not supported!");
227 return;
228 }
229
230 encoded_baud[3] = (uchar)(baud_rate >> 24);
231 encoded_baud[2] = (uchar)(baud_rate >> 16);
232 encoded_baud[1] = (uchar)(baud_rate >> 8);
233 encoded_baud[0] = (uchar)(baud_rate & 0xFF);
234 }
235
236 typedef struct {
237 int baud_rate;
238 int termios_value;
239 } tBaudRates;
240
241 tBaudRates baud_rates[] = {
242 { 115200, B115200 },
243 { 230400, B230400 },
244 { 460800, B460800 },
245 { 500000, B500000 },
246 { 576000, B576000 },
247 { 921600, B921600 },
248 { 1000000, B1000000 },
249 { 1152000, B1152000 },
250 { 1500000, B1500000 },
251 { 2000000, B2000000 },
252 { 2500000, B2500000 },
253 { 3000000, B3000000 },
254 #ifndef __CYGWIN__
255 { 3500000, B3500000 },
256 { 4000000, B4000000 }
257 #endif
258 };
259
260 int
validate_baudrate(int baud_rate,int * value)261 validate_baudrate(int baud_rate, int *value)
262 {
263 unsigned int i;
264
265 for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) {
266 if (baud_rates[i].baud_rate == baud_rate) {
267 *value = baud_rates[i].termios_value;
268 return(1);
269 }
270 }
271
272 return(0);
273 }
274
275 int
parse_baudrate(char * optarg)276 parse_baudrate(char *optarg)
277 {
278 int baudrate = atoi(optarg);
279
280 if (validate_baudrate(baudrate, &termios_baudrate)) {
281 BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]);
282 }
283
284 return(0);
285 }
286
287 int
parse_bdaddr(char * optarg)288 parse_bdaddr(char *optarg)
289 {
290 int bd_addr[6];
291 int i;
292
293 sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X",
294 &bd_addr[5], &bd_addr[4], &bd_addr[3],
295 &bd_addr[2], &bd_addr[1], &bd_addr[0]);
296
297 for (i = 0; i < 6; i++) {
298 hci_write_bd_addr[4 + i] = bd_addr[i];
299 }
300
301 bdaddr_flag = 1;
302
303 return(0);
304 }
305
306 int
readApName(char * name,int len)307 readApName(char *name, int len)
308 {
309 FILE* devInfo = NULL;
310
311 if(len < AP_NAME_SUFFIX_LEN) {
312 return -1;
313 }
314
315 devInfo = fopen("/data/cfg/device_info.txt","rb+");
316 if(devInfo) {
317 fseek(devInfo, 36, SEEK_SET);
318 fread(name, 1, AP_NAME_SUFFIX_LEN, devInfo);
319 fclose(devInfo);
320 // is default value or not
321 if(0 == strncmp(name, "11:22:33:44:55:66", 17)) {
322 return -1;
323 }
324 } else {
325 return -1;
326 }
327
328 return 0;
329 }
330
331 int
writeApName(const char * name,int len)332 writeApName(const char* name, int len)
333 {
334 FILE* devInfo = NULL;
335 char nameBuf[AP_NAME_SUFFIX_LEN] = {0};
336
337 if(len < 17) {
338 return;
339 }
340
341 if(0 != strncmp(name, "11:22:33:44:55", 17)) {
342 devInfo = fopen("/data/cfg/device_info.txt","rb+");
343 if(devInfo) {
344 fseek(devInfo, 36, SEEK_SET);
345 snprintf(nameBuf, AP_NAME_SUFFIX_LEN, "%s", name);
346 fwrite(nameBuf, 1, AP_NAME_SUFFIX_LEN, devInfo);
347 fflush(devInfo);
348 fsync(fileno(devInfo));
349 fclose(devInfo);
350 }
351 system("cp /data/cfg/device_info.txt /data/cfg/device_info");
352 }
353 }
354
355 int
parse_bdaddr_rand(char * optarg)356 parse_bdaddr_rand(char *optarg)
357 {
358 int bd_addr[6];
359 int i,j;
360 char optargtest[18];
361
362 char mh[]=":";
363 char metachar[]="ABCDEF0123456789";
364 if(0 != readApName(optargtest,AP_NAME_SUFFIX_LEN)){
365 srand(time(NULL));
366 for(j=0;j<17;j++){
367 if(j%3 == 2){
368 optargtest[j]= mh[0];
369 }else{
370 optargtest[j] = metachar[rand()%16];
371 }
372 }
373 optargtest[17]="\0";
374
375 writeApName(optargtest,AP_NAME_SUFFIX_LEN);
376 }
377
378 sscanf(optargtest, "%02X:%02X:%02X:%02X:%02X:%02X",
379 &bd_addr[5], &bd_addr[4], &bd_addr[3],
380 &bd_addr[2], &bd_addr[1], &bd_addr[0]);
381
382 for (i = 0; i < 6; i++) {
383 hci_write_bd_addr[4 + i] = bd_addr[i];
384 }
385
386 bdaddr_flag = 1;
387
388 return(0);
389 }
390
391 int
parse_enable_lpm(char * optarg)392 parse_enable_lpm(char *optarg)
393 {
394 enable_lpm = 1;
395 return(0);
396 }
397
398 int
parse_use_baudrate_for_download(char * optarg)399 parse_use_baudrate_for_download(char *optarg)
400 {
401 use_baudrate_for_download = 1;
402 return(0);
403 }
404
405 int
parse_enable_hci(char * optarg)406 parse_enable_hci(char *optarg)
407 {
408 enable_hci = 1;
409 return(0);
410 }
411
412 int
parse_scopcm(char * optarg)413 parse_scopcm(char *optarg)
414 {
415 int param[10];
416 int ret;
417 int i;
418
419 ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
420 ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4],
421 ¶m[5], ¶m[6], ¶m[7], ¶m[8], ¶m[9]);
422
423 if (ret != 10) {
424 return(1);
425 }
426
427 scopcm = 1;
428
429 for (i = 0; i < 5; i++) {
430 hci_write_sco_pcm_int[4 + i] = param[i];
431 }
432
433 for (i = 0; i < 5; i++) {
434 hci_write_pcm_data_format[4 + i] = param[5 + i];
435 }
436
437 return(0);
438 }
439
440 int
parse_i2s(char * optarg)441 parse_i2s(char *optarg)
442 {
443 int param[4];
444 int ret;
445 int i;
446
447 ret = sscanf(optarg, "%d,%d,%d,%d", ¶m[0], ¶m[1], ¶m[2],
448 ¶m[3]);
449
450 if (ret != 4) {
451 return(1);
452 }
453
454 i2s = 1;
455
456 for (i = 0; i < 4; i++) {
457 hci_write_i2spcm_interface_param[4 + i] = param[i];
458 }
459
460 return(0);
461 }
462
463 int
parse_no2bytes(char * optarg)464 parse_no2bytes(char *optarg)
465 {
466 no2bytes = 1;
467 return(0);
468 }
469
470 int
parse_tosleep(char * optarg)471 parse_tosleep(char *optarg)
472 {
473 tosleep = atoi(optarg);
474
475 if (tosleep <= 0) {
476 return(1);
477 }
478
479 return(0);
480 }
481
482 void
usage(char * argv0)483 usage(char *argv0)
484 {
485 printf("Usage %s:\n", argv0);
486 printf("\t<-d> to print a debug log\n");
487 printf("\t<--patchram patchram_file>\n");
488 printf("\t<--baudrate baud_rate>\n");
489 printf("\t<--bd_addr bd_address>\n");
490 printf("\t<--enable_lpm>\n");
491 printf("\t<--enable_hci>\n");
492 printf("\t<--use_baudrate_for_download> - Uses the\n");
493 printf("\t\tbaudrate for downloading the firmware\n");
494 printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n");
495 printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n");
496 printf("\t\tfill_method,fill_num,right_justify>\n");
497 printf("\n\t\tWhere\n");
498 printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n");
499 printf("\t\t2 for Codec and 3 for I2S,\n");
500 printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n");
501 printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n");
502 printf("\t\tand 4 for 2048Kbps,\n");
503 printf("\n\t\tframe_type is 0 for short and 1 for long,\n");
504 printf("\t\tsync_mode is 0 for slave and 1 for master,\n");
505 printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n");
506 printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n");
507 printf("\n\t\tfill_bits is the value in decimal for unused bits,\n");
508 printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n");
509 printf("\t\tsigned and 3 for programmable,\n");
510 printf("\n\t\tfill_num is the number or bits to fill,\n");
511 printf("\n\t\tright_justify is 0 for false and 1 for true\n");
512 printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n");
513 printf("\n\t\tWhere\n");
514 printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n");
515 printf("\n\t\tis_master is 0 for slave and 1 for master,\n");
516 printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n");
517 printf("\t\t2 for 4 KHz,\n");
518 printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n");
519 printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n");
520 printf("\t<--no2bytes skips waiting for two byte confirmation\n");
521 printf("\t\tbefore starting patchram download. Newer chips\n");
522 printf("\t\tdo not generate these two bytes.>\n");
523 printf("\t<--tosleep=microseconds>\n");
524 printf("\tuart_device_name\n");
525 }
526
527 int
parse_cmd_line(int argc,char ** argv)528 parse_cmd_line(int argc, char **argv)
529 {
530 int c;
531 int ret = 0;
532
533 typedef int (*PFI)();
534
535 PFI parse[] = { parse_patchram, parse_baudrate,
536 parse_bdaddr,parse_bdaddr_rand, parse_enable_lpm, parse_enable_hci,
537 parse_use_baudrate_for_download,
538 parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep};
539
540 while (1) {
541 int this_option_optind = optind ? optind : 1;
542 int option_index = 0;
543
544 static struct option long_options[] = {
545 {"patchram", 1, 0, 0},
546 {"baudrate", 1, 0, 0},
547 {"bd_addr", 1, 0, 0},
548 {"bd_addr_rand", 0, 0, 0},
549 {"enable_lpm", 0, 0, 0},
550 {"enable_hci", 0, 0, 0},
551 {"use_baudrate_for_download", 0, 0, 0},
552 {"scopcm", 1, 0, 0},
553 {"i2s", 1, 0, 0},
554 {"no2bytes", 0, 0, 0},
555 {"tosleep", 1, 0, 0},
556 {0, 0, 0, 0}
557 };
558
559 c = getopt_long_only (argc, argv, "d", long_options,
560 &option_index);
561
562 if (c == -1) {
563 break;
564 }
565
566 switch (c) {
567 case 0:
568 if (debug) {
569 printf ("option %s",
570 long_options[option_index].name);
571 if (optarg)
572 printf (" with arg %s", optarg);
573 printf ("\n");
574 }
575
576 ret = (*parse[option_index])(optarg);
577
578 break;
579 case 'd':
580 debug = 1;
581 break;
582
583 case '?':
584 //nobreak
585 default:
586 usage(argv[0]);
587 break;
588 }
589
590 if (ret) {
591 usage(argv[0]);
592 break;
593 }
594 }
595
596 if (ret) {
597 return(1);
598 }
599
600 if (optind < argc) {
601 if (debug)
602 printf ("%s \n", argv[optind]);
603 if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) {
604 fprintf(stderr, "port %s could not be opened, error %d\n",
605 argv[2], errno);
606 }
607 }
608
609 return(0);
610 }
611
612 void
init_uart()613 init_uart()
614 {
615 tcflush(uart_fd, TCIOFLUSH);
616 tcgetattr(uart_fd, &termios);
617
618 #ifndef __CYGWIN__
619 cfmakeraw(&termios);
620 #else
621 termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
622 | INLCR | IGNCR | ICRNL | IXON);
623 termios.c_oflag &= ~OPOST;
624 termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
625 termios.c_cflag &= ~(CSIZE | PARENB);
626 termios.c_cflag |= CS8;
627 #endif
628
629 termios.c_cflag |= CRTSCTS;
630 tcsetattr(uart_fd, TCSANOW, &termios);
631 tcflush(uart_fd, TCIOFLUSH);
632 tcsetattr(uart_fd, TCSANOW, &termios);
633 tcflush(uart_fd, TCIOFLUSH);
634 tcflush(uart_fd, TCIOFLUSH);
635 cfsetospeed(&termios, B115200);
636 cfsetispeed(&termios, B115200);
637 tcsetattr(uart_fd, TCSANOW, &termios);
638 }
639
640 void
dump(uchar * out,int len)641 dump(uchar *out, int len)
642 {
643 int i;
644
645 for (i = 0; i < len; i++) {
646 if (i && !(i % 16)) {
647 fprintf(stderr, "\n");
648 }
649
650 fprintf(stderr, "%02x ", out[i]);
651 }
652
653 fprintf(stderr, "\n");
654 }
655
656 void
read_event(int fd,uchar * buffer)657 read_event(int fd, uchar *buffer)
658 {
659 int i = 0;
660 int len = 3;
661 int count;
662
663 while ((count = read(fd, &buffer[i], len)) < len) {
664 i += count;
665 len -= count;
666 //fprintf(stderr, "received11 %d\n", count);
667 }
668
669 i += count;
670 len = buffer[2];
671 //fprintf(stderr, "received22 %d\n", count);
672
673 while ((count = read(fd, &buffer[i], len)) < len) {
674 i += count;
675 len -= count;
676 }
677 //fprintf(stderr, "received33 %d\n", count);
678
679 if (debug) {
680 count += i;
681
682 fprintf(stderr, "received %d\n", count);
683 dump(buffer, count);
684 }
685 }
686
687 void
hci_send_cmd(uchar * buf,int len)688 hci_send_cmd(uchar *buf, int len)
689 {
690 if (debug) {
691 fprintf(stderr, "writing\n");
692 dump(buf, len);
693 }
694
695 write(uart_fd, buf, len);
696 }
697
698 void
expired(int sig)699 expired(int sig)
700 {
701 hci_send_cmd(hci_reset, sizeof(hci_reset));
702 alarm(4);
703 }
704
705 void
proc_reset()706 proc_reset()
707 {
708 signal(SIGALRM, expired);
709
710 fprintf(stderr, "proc_reset");
711
712 hci_send_cmd(hci_reset, sizeof(hci_reset));
713
714 alarm(4);
715
716 read_event(uart_fd, buffer);
717
718 alarm(0);
719 }
720
721 void
proc_patchram()722 proc_patchram()
723 {
724 int len;
725
726 hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver));
727
728 fprintf(stderr, "send hci_download_minidriver");
729
730 read_event(uart_fd, buffer);
731
732 if (!no2bytes) {
733 read(uart_fd, &buffer[0], 2);
734 }
735
736 if (tosleep) {
737 usleep(tosleep);
738 }
739
740 while (read(hcdfile_fd, &buffer[1], 3)) {
741 buffer[0] = 0x01;
742
743 len = buffer[3];
744
745 read(hcdfile_fd, &buffer[4], len);
746
747 hci_send_cmd(buffer, len + 4);
748
749 read_event(uart_fd, buffer);
750 }
751 usleep(200000);
752
753 if (use_baudrate_for_download) {
754 cfsetospeed(&termios, B115200);
755 cfsetispeed(&termios, B115200);
756 tcsetattr(uart_fd, TCSANOW, &termios);
757 }
758 proc_reset();
759 }
760
761 void
proc_baudrate()762 proc_baudrate()
763 {
764 hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate));
765
766 read_event(uart_fd, buffer);
767
768 usleep(200000);
769
770 cfsetospeed(&termios, termios_baudrate);
771 cfsetispeed(&termios, termios_baudrate);
772 tcsetattr(uart_fd, TCSANOW, &termios);
773
774 if (debug) {
775 fprintf(stderr, "Done setting baudrate\n");
776 }
777 }
778
779 void
proc_bdaddr()780 proc_bdaddr()
781 {
782 hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr));
783
784 read_event(uart_fd, buffer);
785 }
786
787 void
proc_enable_lpm()788 proc_enable_lpm()
789 {
790 hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode));
791
792 read_event(uart_fd, buffer);
793 }
794
795 void
proc_scopcm()796 proc_scopcm()
797 {
798 hci_send_cmd(hci_write_sco_pcm_int,
799 sizeof(hci_write_sco_pcm_int));
800
801 read_event(uart_fd, buffer);
802
803 hci_send_cmd(hci_write_pcm_data_format,
804 sizeof(hci_write_pcm_data_format));
805
806 read_event(uart_fd, buffer);
807 }
808
809 void
proc_i2s()810 proc_i2s()
811 {
812 hci_send_cmd(hci_write_i2spcm_interface_param,
813 sizeof(hci_write_i2spcm_interface_param));
814
815 read_event(uart_fd, buffer);
816 }
817
818 void
proc_enable_hci()819 proc_enable_hci()
820 {
821 int i = N_HCI;
822 int proto = HCI_UART_H4;
823 if (ioctl(uart_fd, TIOCSETD, &i) < 0) {
824 fprintf(stderr, "Can't set line discipline\n");
825 return;
826 }
827
828 if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) {
829 fprintf(stderr, "Can't set hci protocol\n");
830 return;
831 }
832 fprintf(stderr, "Done setting line discpline\n");
833 return;
834 }
835
836 #ifdef ANDROID
837 void
read_default_bdaddr()838 read_default_bdaddr()
839 {
840 int sz;
841 int fd;
842
843 char path[PROPERTY_VALUE_MAX];
844
845 char bdaddr[18];
846 int len = 17;
847 memset(bdaddr, 0, (len + 1) * sizeof(char));
848
849 property_get("ro.bt.bdaddr_path", path, "");
850 if (path[0] == 0)
851 return;
852
853 fd = open(path, O_RDONLY);
854 if (fd < 0) {
855 fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno),
856 errno);
857 return;
858 }
859
860 sz = read(fd, bdaddr, len);
861 if (sz < 0) {
862 fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno),
863 errno);
864 close(fd);
865 return;
866 } else if (sz != len) {
867 fprintf(stderr, "read(%s) unexpected size %d", path, sz);
868 close(fd);
869 return;
870 }
871
872 if (debug) {
873 printf("Read default bdaddr of %s\n", bdaddr);
874 }
875
876 parse_bdaddr(bdaddr);
877 }
878 #endif
879
880
881 int
main(int argc,char ** argv)882 main (int argc, char **argv)
883 {
884 #ifdef ANDROID
885 read_default_bdaddr();
886 #endif
887
888 if (parse_cmd_line(argc, argv)) {
889 exit(1);
890 }
891
892 if (uart_fd < 0) {
893 exit(2);
894 }
895
896 init_uart();
897
898 proc_reset();
899
900 if (use_baudrate_for_download) {
901 if (termios_baudrate) {
902 proc_baudrate();
903 }
904 }
905
906 if (hcdfile_fd > 0) {
907 proc_patchram();
908 }
909
910 if (termios_baudrate) {
911 proc_baudrate();
912 }
913
914 if (bdaddr_flag) {
915 proc_bdaddr();
916 }
917
918 if (enable_lpm) {
919 proc_enable_lpm();
920 }
921
922 if (scopcm) {
923 proc_scopcm();
924 }
925
926 if (i2s) {
927 proc_i2s();
928 }
929
930 if (enable_hci) {
931 proc_enable_hci();
932
933 while (1) {
934 sleep(UINT_MAX);
935 }
936 }
937
938 exit(0);
939 }
940