Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / tools / hciattach_sprd.c
1 #include <linux/kernel.h>
2 #include <assert.h>
3 #include <stdio.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <syslog.h>
11 #include <termios.h>
12 #include <time.h>
13 #include <sys/time.h>
14 #include <sys/poll.h>
15 #include <sys/param.h>
16 #include <sys/ioctl.h>
17 #include <sys/socket.h>
18 #include <sys/uio.h>
19
20 #include <sys/types.h>
21 #include <dirent.h>
22
23 #include <bluetooth/bluetooth.h>
24 #include <bluetooth/hci.h>
25 #include <bluetooth/hci_lib.h>
26
27 #include "hciattach.h"
28 #include <sys/stat.h>
29
30 #include "hciattach_sprd.h"
31
32 //#include <android/log.h>
33 //#define DBG
34 #ifdef DBG
35 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "pskey_bt", __VA_ARGS__)
36 #else
37 #define LOGD(fmt, arg...)  fprintf(stderr, "%s:%d()" fmt "\n", __FILE__,__LINE__, ## arg)
38 #endif
39 typedef unsigned char   UINT8;
40
41 #define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
42 #define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
43 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
44 #define UINT8_TO_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
45 #define INT8_TO_STREAM(p, u8)    {*(p)++ = (INT8)(u8);}
46
47 #define PSKEY_PRELOAD_SIZE    0x04
48 #define PSKEY_PREAMBLE_SIZE    0xA2
49
50         // for bt mac addr
51 #define BT_MAC_FILE_PATH        "/csa/bluetooth/"
52 #define DATMISC_MAC_ADDR_PATH   BT_MAC_FILE_PATH".bd_addr"
53 #define MAC_ADDR_BUF_LEN    (strlen("FF:FF:FF:FF:FF:FF"))
54 #define MAC_ADDR_FILE_LEN    25
55 #define MAC_ADDR_LEN    6
56
57 #define BD_ADDR_LEN     14
58 #define BD_PREFIX       "0002\n"
59
60 #if 0
61 #ifndef VENDOR_BTWRITE_PROC_NODE
62 #define VENDOR_BTWRITE_PROC_NODE "/proc/bluetooth/sleep/btwrite"
63 #endif
64 #endif
65
66 #define MAX_BT_TMP_PSKEY_FILE_LEN 2048
67
68 typedef unsigned int   UWORD32;
69 typedef unsigned short UWORD16;
70 typedef unsigned char  UWORD8;
71
72 #define down_bt_is_space(c)     (((c) == '\n') || ((c) == ',') || ((c) == '\r') || ((c) == ' ') || ((c) == '{') || ((c) == '}'))
73 #define down_bt_is_comma(c)     (((c) == ','))
74 #define down_bt_is_endc(c)      (((c) == '}')) // indicate end of data
75
76 /* Macros to swap byte order */
77 #define SWAP_BYTE_ORDER_WORD(val) ((((val) & 0x000000FF) << 24) + \
78                                    (((val) & 0x0000FF00) << 8)  + \
79                                    (((val) & 0x00FF0000) >> 8)   + \
80                                    (((val) & 0xFF000000) >> 24))
81 #define INLINE static __inline
82
83 #ifndef LITTLE_ENDIAN
84 #define LITTLE_ENDIAN
85 #endif
86
87
88 // pskey file structure default value
89 static BT_PSKEY_CONFIG_T bt_para_setting={
90         .pskey_cmd = 0x001C0101,
91
92         .g_dbg_source_sink_syn_test_data = 0,
93         .g_sys_sleep_in_standby_supported = 0,
94         .g_sys_sleep_master_supported = 0,
95         .g_sys_sleep_slave_supported = 0,
96
97         .default_ahb_clk = 26000000,
98         .device_class = 0x001F00,
99         .win_ext = 30,
100
101         .g_aGainValue = {0x0000F600, 0x0000D000, 0x0000AA00, 0x00008400, 0x00004400, 0x00000A00},
102         .g_aPowerValue = {0x0FC80000, 0x0FF80000, 0x0FDA0000, 0x0FCC0000, 0x0FFC0000},
103
104         .feature_set = {0xFF, 0xFF, 0x8D, 0xFE, 0x9B, 0x7F, 0x79, 0x83, 0xFF, 0xA7, 0xFF, 0x7F, 0x00, 0xE0, 0xF7, 0x3E},
105         .device_addr = {0x6A, 0x6B, 0x8C, 0x8A, 0x8B, 0x8C},
106
107         .g_sys_sco_transmit_mode = 0, //true tramsmit by uart, otherwise by share memory
108         .g_sys_uart0_communication_supported = 1, //true use uart0, otherwise use uart1 for debug
109         .edr_tx_edr_delay = 5,
110         .edr_rx_edr_delay = 14,
111
112         .g_wbs_nv_117 = 0x0031,
113
114         .is_wdg_supported = 0,
115
116         .share_memo_rx_base_addr = 0,
117         //.share_memo_tx_base_addr = 0,
118         .g_wbs_nv_118 = 0x0066,
119         .g_nbv_nv_117 = 0x1063,
120
121         .share_memo_tx_packet_num_addr = 0,
122         .share_memo_tx_data_base_addr = 0,
123
124         .g_PrintLevel = 0xFFFFFFFF,
125
126         .share_memo_tx_block_length = 0,
127         .share_memo_rx_block_length = 0,
128         .share_memo_tx_water_mark = 0,
129         //.share_memo_tx_timeout_value = 0,
130         .g_nbv_nv_118 = 0x0E45,
131
132         .uart_rx_watermark = 48,
133         .uart_flow_control_thld = 63,
134         .comp_id = 0,
135         .pcm_clk_divd = 0x26,
136
137
138         .reserved = {0}
139 };
140
141 extern int getPskeyFromFile(void *pData);
142 extern int bt_getPskeyFromFile(void *pData);
143
144 static int create_mac_folder(void)
145 {
146         DIR *dp;
147         int err;
148
149         dp = opendir(BT_MAC_FILE_PATH);
150         if (dp == NULL) {
151                 if (mkdir(BT_MAC_FILE_PATH, 0755) < 0) {
152                         err = -errno;
153                         LOGD("%s:  mkdir: %s(%d)",__FUNCTION__, strerror(-err), -err);
154                 }
155                 return -1;
156         }
157
158         closedir(dp);
159         return 0;
160 }
161
162 static void mac_rand(char *btmac)
163 {
164         int ran;
165         int i;
166         unsigned int seed;
167         struct timeval tv;
168
169         memcpy(btmac, BD_PREFIX, 5);
170         i = gettimeofday(&tv, NULL);
171
172         if (i < 0) {
173                 LOGD("Fail to call gettimeofday()");
174                 seed = time(NULL);
175         } else
176                 seed = (unsigned int)tv.tv_usec;
177
178         for (i = 5; i < BD_ADDR_LEN; i++) {
179                 if (i == 7) {
180                         btmac[i] = '\n';
181                         continue;
182                 }
183                 ran = rand_r(&seed) % 16;
184                 if (ran < 10)
185                         ran += 0x30;
186                 else
187                         ran += 0x57;
188                 btmac[i] = ran;
189         }
190         LOGD("Random number is\r\n");
191         for (i = 0; i < BD_ADDR_LEN; i++) {
192                 LOGD("%c", btmac[i]);
193         }
194         LOGD("\r\n");
195 }
196
197 static void write_btmac2file(char *btmac)
198 {
199         int fd;
200         int ret;
201         fd = open(DATMISC_MAC_ADDR_PATH, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
202         LOGD("write_btmac2file open file, fd=%d", fd);
203         if(fd >= 0) {
204                 if(chmod(DATMISC_MAC_ADDR_PATH,0666) != -1){
205                         ret = write(fd, btmac, strlen(btmac));
206                         if (ret < strlen(btmac)) {
207                                 LOGD("Fail to write %s", DATMISC_MAC_ADDR_PATH);
208                                 close(fd);
209                                 return;
210                         }
211                 }
212                 close(fd);
213         }else{
214                 LOGD("write bt mac to file failed!!");
215         }
216 }
217
218 uint8 ConvertHexToBin(
219                 uint8        *hex_ptr,     // in: the hexadecimal format string
220                 uint16       length,       // in: the length of hexadecimal string
221                 uint8        *bin_ptr      // out: pointer to the binary format string
222                 ){
223         uint8        *dest_ptr = bin_ptr;
224         uint32        i = 0;
225         uint8        ch;
226
227         for(i=0; i<length; i+=2){
228                 // the bit 8,7,6,5
229                 ch = hex_ptr[i];
230                 // digital 0 - 9
231                 if (ch >= '0' && ch <= '9')
232                         *dest_ptr =(uint8)((ch - '0') << 4);
233                 // a - f
234                 else if (ch >= 'a' && ch <= 'f')
235                         *dest_ptr = (uint8)((ch - 'a' + 10) << 4);
236                 // A - F
237                 else if (ch >= 'A' && ch <= 'F')
238                         *dest_ptr = (uint8)((ch -'A' + 10) << 4);
239                 else{
240                         return 0;
241                 }
242
243                 // the bit 1,2,3,4
244                 ch = hex_ptr[i+1];
245                 // digtial 0 - 9
246                 if (ch >= '0' && ch <= '9')
247                         *dest_ptr |= (uint8)(ch - '0');
248                 // a - f
249                 else if (ch >= 'a' && ch <= 'f')
250                         *dest_ptr |= (uint8)(ch - 'a' + 10);
251                 // A - F
252                 else if (ch >= 'A' && ch <= 'F')
253                         *dest_ptr |= (uint8)(ch -'A' + 10);
254                 else{
255                         return 0;
256                 }
257
258                 dest_ptr++;
259         }
260
261         return 1;
262 }
263
264 static int read_mac_address(char *file_name, uint8 *addr) {
265         char buf[MAC_ADDR_FILE_LEN] = {0};
266         uint32 addr_t[MAC_ADDR_LEN] = {0};
267         int i = 0;
268
269
270 #if 1
271         int fd = open(file_name, O_RDONLY, 0666);
272         LOGD("%s read file: %s", __func__, file_name);
273         if (fd < 0) {
274                 LOGD("%s open %s error reason: %s", __func__, file_name, strerror(errno));
275                 return -1;
276         }
277         if (read(fd, buf, BD_ADDR_LEN) < 0) {
278                 LOGD("%s read %s error reason: %s", __func__, file_name, strerror(errno));
279                 goto done;
280         }
281         if (sscanf(buf, "%02X%02X\n%02X\n%02X%02X%02X", &addr_t[0], &addr_t[1], &addr_t[2], &addr_t[3], &addr_t[4], &addr_t[5]) < 0) {
282                 LOGD("%s sscanf %s error reason: %s", __func__, file_name, strerror(errno));
283                 goto done;
284         }
285
286         for (i = 0; i < MAC_ADDR_LEN; i++) {
287                 addr[i] = addr_t[i] & 0xFF;
288         }
289         LOGD("%s %s addr: [%02X:%02X:%02X:%02X:%02X:%02X]", __func__, file_name, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
290
291 done:
292         close(fd);
293 #endif
294         return 0;
295 }
296
297 static void mac_address_stream_compose(uint8 *addr) {
298         uint8 tmp, i, j;
299         for (i = 0, j = MAC_ADDR_LEN - 1; (i < MAC_ADDR_LEN / 2) && (i != j); i++, j--) {
300                 tmp = addr[i];
301                 addr[i] = addr[j];
302                 addr[j] = tmp;
303         }
304 }
305
306 #if 0
307 /*
308  * random bluetooth mac address
309  */
310 static void random_mac_addr(uint8 *addr) {
311         int fd, randseed, ret, mac_rd;
312         uint8 addr_t[MAC_ADDR_LEN] = {0};
313
314         LOGD("%s", __func__);
315         /* urandom seed build */
316         fd = open("/dev/urandom", O_RDONLY);
317         if (fd < 0){
318                 LOGD("%s: open urandom fail", __func__);
319         } else {
320                 ret = read(fd, &randseed, sizeof(randseed));
321                 LOGD("%s urandom:0x%08X", __func__, randseed);
322                 close(fd);
323         }
324
325         /* time seed build */
326         if (fd < 0 || ret < 0) {
327                 struct timeval tt;
328                 if (gettimeofday(&tt, (struct timezone *)0) > 0) {
329                         randseed = (unsigned int) tt.tv_usec;
330                 } else {
331                         randseed = (unsigned int) time(NULL);
332                 }
333                 LOGD("urandom fail, using system time for randseed");
334         }
335
336         LOGD("%s: randseed = %u",__func__, randseed);
337         srand(randseed);
338         mac_rd = rand();
339
340         addr_t[0] = 0x40; /* FOR */
341         addr_t[1] = 0x45; /* SPRD */
342         addr_t[2] = 0xDA; /* ADDR */
343         addr_t[3] = (uint8)(mac_rd & 0xFF);
344         addr_t[4] = (uint8)((mac_rd >> 8) & 0xFF);
345         addr_t[5] = (uint8)((mac_rd >> 16) & 0xFF);
346
347         memcpy(addr, addr_t, MAC_ADDR_LEN);
348         LOGD("%s: MAC ADDR: [%02X:%02X:%02X:%02X:%02X:%02X]",__func__, addr_t[0], addr_t[1], addr_t[2], addr_t[3], addr_t[4], addr_t[5]);
349 }
350 #endif
351 static void get_mac_address(uint8 *addr){
352         int ret = -1;
353         uint8 addr_t[6] = {0};
354         char bt_mac[BD_ADDR_LEN] = {0, };
355
356         LOGD("%s", __func__);
357         /* check misc mac file exist */
358         ret = access(DATMISC_MAC_ADDR_PATH, F_OK);
359         if (ret != 0) {
360                 LOGD("%s %s miss", __func__, DATMISC_MAC_ADDR_PATH);
361
362                 /* Try to make bt address file */
363                 create_mac_folder();
364
365                 mac_rand(bt_mac);
366                 LOGD("bt random mac=%s",bt_mac);
367                 write_btmac2file(bt_mac);
368
369         }
370
371         /* read mac file */
372         read_mac_address(DATMISC_MAC_ADDR_PATH, addr_t);
373
374         /* compose mac stream */
375         mac_address_stream_compose(addr_t);
376
377         memcpy(addr, addr_t, MAC_ADDR_LEN);
378
379 }
380
381
382 /*
383  * hci command preload stream,  special order
384  */
385 static void pskey_stream_compose(uint8 * buf, BT_PSKEY_CONFIG_T *bt_par) {
386         int i = 0;
387         uint8 *p = buf;
388
389         LOGD("%s", __func__);
390
391         UINT24_TO_STREAM(p, bt_par->pskey_cmd);
392         UINT8_TO_STREAM(p, (uint8)(PSKEY_PREAMBLE_SIZE & 0xFF));
393
394         UINT8_TO_STREAM(p, bt_par->g_dbg_source_sink_syn_test_data);
395         UINT8_TO_STREAM(p, bt_par->g_sys_sleep_in_standby_supported);
396         UINT8_TO_STREAM(p, bt_par->g_sys_sleep_master_supported);
397         UINT8_TO_STREAM(p, bt_par->g_sys_sleep_slave_supported);
398
399         UINT32_TO_STREAM(p, bt_par->default_ahb_clk);
400         UINT32_TO_STREAM(p, bt_par->device_class);
401         UINT32_TO_STREAM(p, bt_par->win_ext);
402
403         for (i = 0; i < 6; i++) {
404                 UINT32_TO_STREAM(p, bt_par->g_aGainValue[i]);
405         }
406         for (i = 0; i < 5; i++) {
407                 UINT32_TO_STREAM(p, bt_par->g_aPowerValue[i]);
408         }
409
410         for (i = 0; i < 16; i++) {
411                 UINT8_TO_STREAM(p, bt_par->feature_set[i]);
412         }
413         for (i = 0; i < 6; i++) {
414                 UINT8_TO_STREAM(p, bt_par->device_addr[i]);
415         }
416
417         UINT8_TO_STREAM(p, bt_par->g_sys_sco_transmit_mode);
418         UINT8_TO_STREAM(p, bt_par->g_sys_uart0_communication_supported);
419         UINT8_TO_STREAM(p, bt_par->edr_tx_edr_delay);
420         UINT8_TO_STREAM(p, bt_par->edr_rx_edr_delay);
421
422         UINT16_TO_STREAM(p, bt_par->g_wbs_nv_117);
423
424         UINT32_TO_STREAM(p, bt_par->is_wdg_supported);
425
426         UINT32_TO_STREAM(p, bt_par->share_memo_rx_base_addr);
427         //UINT32_TO_STREAM(p, bt_par->share_memo_tx_base_addr);
428         UINT16_TO_STREAM(p, bt_par->g_wbs_nv_118);
429         UINT16_TO_STREAM(p, bt_par->g_nbv_nv_117);
430
431         UINT32_TO_STREAM(p, bt_par->share_memo_tx_packet_num_addr);
432         UINT32_TO_STREAM(p, bt_par->share_memo_tx_data_base_addr);
433
434         UINT32_TO_STREAM(p, bt_par->g_PrintLevel);
435
436         UINT16_TO_STREAM(p, bt_par->share_memo_tx_block_length);
437         UINT16_TO_STREAM(p, bt_par->share_memo_rx_block_length);
438         UINT16_TO_STREAM(p, bt_par->share_memo_tx_water_mark);
439         //UINT16_TO_STREAM(p, bt_par->share_memo_tx_timeout_value);
440         UINT16_TO_STREAM(p, bt_par->g_nbv_nv_118);
441
442         UINT16_TO_STREAM(p, bt_par->uart_rx_watermark);
443         UINT16_TO_STREAM(p, bt_par->uart_flow_control_thld);
444         UINT32_TO_STREAM(p, bt_par->comp_id);
445         UINT16_TO_STREAM(p, bt_par->pcm_clk_divd);
446
447
448         for (i = 0; i < 8; i++) {
449                 UINT32_TO_STREAM(p, bt_par->reserved[i]);
450         }
451 }
452
453 void sprd_get_pskey(BT_PSKEY_CONFIG_T * pskey_t) {
454         BT_PSKEY_CONFIG_T pskey;
455         uint8 buf[180] = {0};
456
457         LOGD("%s", __func__);
458         memset(&pskey, 0 , sizeof(BT_PSKEY_CONFIG_T));
459         if (bt_getPskeyFromFile(&pskey) < 0 ) {
460                 LOGD("%s bt_getPskeyFromFile failed", __func__);
461                 memcpy(pskey_t, &bt_para_setting, sizeof(BT_PSKEY_CONFIG_T));
462                 return;
463         }
464
465         memset(buf, 0, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE);
466
467         /* get bluetooth mac address */
468         get_mac_address(pskey.device_addr);
469
470         /* compose pskey hci command pkt */
471         pskey_stream_compose(buf, &pskey);
472
473         memcpy(pskey_t, &pskey, sizeof(BT_PSKEY_CONFIG_T));
474 }
475
476 #define HCI_HDR_LEN     3
477
478 int sprd_config_init(int fd, char *bdaddr, struct termios *ti)
479 {
480         int ret = 0,r=0;
481         unsigned char resp[30] = {0};
482         BT_PSKEY_CONFIG_T bt_para_tmp;
483         uint8 data_tmp[30] = {'a'};
484         static int index = 0;
485         uint8 *buf = NULL;
486         uint8 hci_len = 0;
487         uint8 is_expected_hci_evt = 0;
488 #if 0
489         char buffer;
490         int btsleep_fd_sprd = -1;
491 #endif
492         LOGD("sprd_config_init");
493
494 #if 0
495         uart_fd = open(UART_INFO_PATH, O_WRONLY);
496         if(uart_fd > 0)
497         {
498                 buffer = '2';
499                 if (write(uart_fd, &buffer, 1) < 0)
500                 {
501                         LOGD("%s write(%s) failed: %s (%d) 2", __func__,
502                                         UART_INFO_PATH, strerror(errno),errno);
503                 }
504
505                 close(uart_fd);
506         }
507 #endif
508
509 #if 0
510         btsleep_fd_sprd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY);
511         if (btsleep_fd_sprd < 0)
512         {
513                 LOGD("%s open(%s) for write failed: %s (%d)", __func__,
514                                 VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno);
515         }
516         else
517         {
518                 buffer = '1';
519                 if (write(btsleep_fd_sprd, &buffer, 1) < 0)
520                 {
521                         LOGD("%s write(%s) failed: %s (%d)", __func__,
522                                         VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno);
523                 }
524         }
525 #endif
526
527         ret = bt_getPskeyFromFile(&bt_para_tmp);
528         if (ret < 0) {
529                 LOGD("init_sprd_config bt_getPskeyFromFile failed\n");
530                 memcpy(&bt_para_tmp, &bt_para_setting, sizeof(BT_PSKEY_CONFIG_T));
531         }
532
533         buf = (uint8 *)malloc(PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE);
534         if (buf == NULL) {
535                 LOGD("%s alloc stream memory failed", __func__);
536                 return -1;
537         }
538         memset(buf, 0, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE);
539
540         /* get bluetooth mac address */
541         get_mac_address(bt_para_tmp.device_addr);
542
543         /* compose pskey hci command pkt */
544         pskey_stream_compose(buf, &bt_para_tmp);
545
546         ret = write(fd, buf, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE);
547         LOGD("write pskey ret = %d", ret);
548
549         free(buf);
550         buf = NULL;
551
552         if (ret < 0) {
553                 LOGD("%s write pskey stream failed", __func__);
554                 return -1;
555         }
556
557         memset(data_tmp, 0xff, sizeof(data_tmp));
558         while (1) {
559                 r = read(fd, resp, 1);
560
561                 if (r <= 0)
562                         return -1;
563                 else{
564                         data_tmp[index] = resp[0];
565                         LOGD("recive from controller 0x%x", data_tmp[index]);
566                         ++index;
567                 }
568
569                 if (index >= 6) {
570                         hci_len = data_tmp[2]+HCI_HDR_LEN;
571
572                         if ((data_tmp[0] == 0x04) && (data_tmp[1] == 0xe) &&
573                                 (data_tmp[2] == 0xa) &&(data_tmp[3] == 0x1) &&
574                                 (data_tmp[4] == 0xa0) &&(data_tmp[5] == 0xfc)) {
575                                         LOGD("read response ok \n");
576                                         is_expected_hci_evt = 1;
577                                 } else {
578                                         LOGD("this is not what we expect HCI evt\n");
579                                         is_expected_hci_evt = 0;
580                                 }
581
582                         if (index == hci_len) {
583                                 index = 0;
584                                 memset(data_tmp, 0x0, sizeof(data_tmp));
585
586                                 if(is_expected_hci_evt)
587                                         break;
588                         }
589                 }
590         }
591         return 0;
592 }