1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2018 Realtek 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 #define LOG_TAG "bt_hwcfg_usb"
20 #define RTKBT_RELEASE_NAME "20190717_BT_ANDROID_9.0"
21
22 #include <utils/Log.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <signal.h>
26 #include <time.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <dirent.h>
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include "bt_hci_bdroid.h"
33 #include "bt_vendor_rtk.h"
34 #include "userial.h"
35 #include "userial_vendor.h"
36 #include "upio.h"
37 #include <unistd.h>
38 #include <endian.h>
39 #include <byteswap.h>
40 #include <unistd.h>
41
42 #include "bt_vendor_lib.h"
43 #include "hardware.h"
44 #include "rtk_common.h"
45
46 /******************************************************************************
47 ** Constants & Macros
48 ******************************************************************************/
49
50 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
51 extern bool rtkbt_auto_restart;
52 void hw_usb_config_cback(void *p_evt_buf);
53 extern bt_hw_cfg_cb_t hw_cfg_cb;
54 extern int getmacaddr(unsigned char *addr);
55 extern struct rtk_epatch_entry *rtk_get_patch_entry(bt_hw_cfg_cb_t *cfg_cb);
56 extern int rtk_get_bt_firmware(uint8_t **fw_buf, char *fw_short_name);
57 extern uint8_t rtk_get_fw_project_id(uint8_t *p_buf);
58
59 #define EXTRA_CONFIG_FILE "/vendor/etc/bluetooth/rtk_btconfig.txt"
60 static struct rtk_bt_vendor_config_entry *extra_extry;
61 static struct rtk_bt_vendor_config_entry *extra_entry_inx = NULL;
62
63 #define BT_VENDOR_CFG_TIMEDELAY_ 40
64
65 typedef void (*tTIMER_HANDLE_CBACK)(union sigval sigval_value);
66
OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)67 static timer_t OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)
68 {
69 struct sigevent sigev;
70 timer_t timerid;
71
72 (void)memset_s(&sigev, sizeof(struct sigevent), 0, sizeof(struct sigevent));
73 // Create the POSIX timer to generate signo
74 sigev.sigev_notify = SIGEV_THREAD;
75 sigev.sigev_notify_function = timer_callback;
76 sigev.sigev_value.sival_ptr = &timerid;
77
78 // Create the Timer using timer_create signal
79
80 if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0)
81 {
82 return timerid;
83 }
84 else
85 {
86 HILOGE("timer_create error!");
87 return (timer_t)-1;
88 }
89 }
90
OsFreeTimer(timer_t timerid)91 static int OsFreeTimer(timer_t timerid)
92 {
93 int ret = 0;
94 ret = timer_delete(timerid);
95 if (ret != 0)
96 {
97 HILOGE("timer_delete fail with errno(%d)", errno);
98 }
99
100 return ret;
101 }
102
OsStartTimer(timer_t timerid,int msec,int mode)103 static int OsStartTimer(timer_t timerid, int msec, int mode)
104 {
105 struct itimerspec itval;
106
107 itval.it_value.tv_sec = msec / 1000;
108 itval.it_value.tv_nsec = (long)(msec % 1000) * (1000000L);
109
110 if (mode == 1)
111 {
112 itval.it_interval.tv_sec = itval.it_value.tv_sec;
113 itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
114 }
115 else
116 {
117 itval.it_interval.tv_sec = 0;
118 itval.it_interval.tv_nsec = 0;
119 }
120
121 // Set the Timer when to expire through timer_settime
122
123 if (timer_settime(timerid, 0, &itval, NULL) != 0)
124 {
125 HILOGE("time_settime error!");
126 return -1;
127 }
128
129 return 0;
130 }
131
132 static timer_t localtimer = 0;
local_timer_handler(union sigval sigev_value)133 static void local_timer_handler(union sigval sigev_value)
134 {
135 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_SUCCESS);
136 OsFreeTimer(localtimer);
137 }
138
start_fwcfg_cbtimer(void)139 static void start_fwcfg_cbtimer(void)
140 {
141 if (localtimer == 0)
142 {
143 localtimer = OsAllocateTimer(local_timer_handler);
144 }
145 OsStartTimer(localtimer, BT_VENDOR_CFG_TIMEDELAY_, 0);
146 }
147
148 /******************************************************************************
149 ** Static variables
150 ******************************************************************************/
151 // static bt_hw_cfg_cb_t hw_cfg_cb;
152
153 typedef struct
154 {
155 uint16_t vid;
156 uint16_t pid;
157 uint16_t lmp_sub_default;
158 uint16_t lmp_sub;
159 uint16_t eversion;
160 char *mp_patch_name;
161 char *patch_name;
162 char *config_name;
163 uint8_t *fw_cache;
164 int fw_len;
165 uint16_t mac_offset;
166 uint32_t max_patch_size;
167 } usb_patch_info;
168
169 static usb_patch_info usb_fw_patch_table[] = {
170 /* { vid, pid, lmp_sub_default, lmp_sub, everion, mp_fw_name, fw_name, config_name, fw_cache, fw_len, mac_offset } */
171 {0x0BDA, 0xD723, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0, CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DU */
172 /* todo: RTL8703CU */
173
174 /* NOTE: must append patch entries above the null entry */
175 {0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, 0, 0}};
176
177 uint16_t usb_project_id[] = {
178 ROM_LMP_8723a,
179 ROM_LMP_8723b,
180 ROM_LMP_8821a,
181 ROM_LMP_8761a,
182 ROM_LMP_8703a,
183 ROM_LMP_8763a,
184 ROM_LMP_8703b,
185 ROM_LMP_8723c,
186 ROM_LMP_8822b,
187 ROM_LMP_8723d,
188 ROM_LMP_8821c,
189 ROM_LMP_NONE,
190 ROM_LMP_NONE,
191 ROM_LMP_8822c,
192 ROM_LMP_8761b,
193 ROM_LMP_NONE};
194 // signature: realtech
195 static const uint8_t RTK_EPATCH_SIGNATURE[8] = {0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x63, 0x68};
196 // Extension Section IGNATURE:0x77FD0451
197 static const uint8_t EXTENSION_SECTION_SIGNATURE[4] = {0x51, 0x04, 0xFD, 0x77};
198
usb_line_process(char * buf,unsigned short * offset,int * t)199 static void usb_line_process(char *buf, unsigned short *offset, int *t)
200 {
201 char *head = buf;
202 char *ptr = buf;
203 char *argv[32];
204 int argc = 0;
205 unsigned char len = 0;
206 int i = 0;
207 static int alt_size = 0;
208
209 if (buf[0] == '\0' || buf[0] == '#' || buf[0] == '[')
210 return;
211 if (alt_size > MAX_ALT_CONFIG_SIZE - 4)
212 {
213 HILOGW("Extra Config file is too large");
214 return;
215 }
216 if (extra_entry_inx == NULL)
217 extra_entry_inx = extra_extry;
218 HILOGI("line_process:%s", buf);
219 while ((ptr = strsep(&head, ", \t")) != NULL)
220 {
221 if (!ptr[0])
222 continue;
223 argv[argc++] = ptr;
224 if (argc >= 32)
225 {
226 HILOGW("Config item is too long");
227 break;
228 }
229 }
230
231 if (argc < 4)
232 {
233 HILOGE("Invalid Config item, ignore");
234 return;
235 }
236
237 offset[(*t)] = (unsigned short)((strtoul(argv[0], NULL, 16)) | (strtoul(argv[1], NULL, 16) << 8));
238 HILOGI("Extra Config offset %04x", offset[(*t)]);
239 extra_entry_inx->offset = offset[(*t)];
240 (*t)++;
241 len = (unsigned char)strtoul(argv[2], NULL, 16);
242 if (len != (unsigned char)(argc - 3))
243 {
244 HILOGE("Extra Config item len %d is not match, we assume the actual len is %d", len, (argc - 3));
245 len = argc - 3;
246 }
247 extra_entry_inx->entry_len = len;
248
249 alt_size += len + sizeof(struct rtk_bt_vendor_config_entry);
250 if (alt_size > MAX_ALT_CONFIG_SIZE)
251 {
252 HILOGW("Extra Config file is too large");
253 extra_entry_inx->offset = 0;
254 extra_entry_inx->entry_len = 0;
255 alt_size -= (len + sizeof(struct rtk_bt_vendor_config_entry));
256 return;
257 }
258 for (i = 0; i < len; i++)
259 {
260 extra_entry_inx->entry_data[i] = (uint8_t)strtoul(argv[3 + i], NULL, 16);
261 HILOGI("data[%d]:%02x", i, extra_entry_inx->entry_data[i]);
262 }
263 extra_entry_inx = (struct rtk_bt_vendor_config_entry *)((uint8_t *)extra_entry_inx + len + sizeof(struct rtk_bt_vendor_config_entry));
264 }
265
usb_parse_extra_config(const char * path,usb_patch_info * patch_entry,unsigned short * offset,int * t)266 static void usb_parse_extra_config(const char *path, usb_patch_info *patch_entry, unsigned short *offset, int *t)
267 {
268 int fd, ret;
269 unsigned char buf[1024];
270
271 fd = open(path, O_RDONLY);
272 if (fd == -1)
273 {
274 HILOGI("Couldn't open extra config %s, err:%s", path, strerror(errno));
275 return;
276 }
277
278 ret = read(fd, buf, sizeof(buf));
279 if (ret == -1)
280 {
281 HILOGE("Couldn't read %s, err:%s", path, strerror(errno));
282 close(fd);
283 return;
284 }
285 else if (ret == 0)
286 {
287 HILOGE("%s is empty", path);
288 close(fd);
289 return;
290 }
291
292 if (ret > 1022)
293 {
294 HILOGE("Extra config file is too big");
295 close(fd);
296 return;
297 }
298 buf[ret++] = '\n';
299 buf[ret++] = '\0';
300 close(fd);
301 char *head = (void *)buf;
302 char *ptr = (void *)buf;
303 ptr = strsep(&head, "\n\r");
304 if (strncmp(ptr, patch_entry->config_name, strlen(ptr)))
305 {
306 HILOGW("Extra config file not set for %s, ignore", patch_entry->config_name);
307 return;
308 }
309 while ((ptr = strsep(&head, "\n\r")) != NULL)
310 {
311 if (!ptr[0])
312 continue;
313 usb_line_process(ptr, offset, t);
314 }
315 }
316
getUsbAltSettings(usb_patch_info * patch_entry,unsigned short * offset)317 static inline int getUsbAltSettings(usb_patch_info *patch_entry, unsigned short *offset) //(patch_info *patch_entry, unsigned short *offset, int max_group_cnt)
318 {
319 int n = 0;
320 if (patch_entry)
321 offset[n++] = patch_entry->mac_offset;
322 else
323 return n;
324 /*
325 //sample code, add special settings
326
327 offset[n++] = 0x15B;
328 */
329 if (extra_extry)
330 usb_parse_extra_config(EXTRA_CONFIG_FILE, patch_entry, offset, &n);
331
332 return n;
333 }
334
getUsbAltSettingVal(usb_patch_info * patch_entry,unsigned short offset,unsigned char * val)335 static inline int getUsbAltSettingVal(usb_patch_info *patch_entry, unsigned short offset, unsigned char *val)
336 {
337 int res = 0;
338
339 int i = 0;
340 struct rtk_bt_vendor_config_entry *ptr = extra_extry;
341
342 while (ptr->offset)
343 {
344 if (ptr->offset == offset)
345 {
346 if (offset != patch_entry->mac_offset)
347 {
348 memcpy(val, ptr->entry_data, ptr->entry_len);
349 res = ptr->entry_len;
350 HILOGI("Get Extra offset:%04x, val:", offset);
351 for (i = 0; i < ptr->entry_len; i++)
352 HILOGI("%02x", ptr->entry_data[i]);
353 }
354 break;
355 }
356 ptr = (struct rtk_bt_vendor_config_entry *)((uint8_t *)ptr + ptr->entry_len + sizeof(struct rtk_bt_vendor_config_entry));
357 }
358
359 /* switch(offset)
360 {
361 //sample code, add special settings
362 case 0x15B:
363 val[0] = 0x0B;
364 val[1] = 0x0B;
365 val[2] = 0x0B;
366 val[3] = 0x0B;
367 res = 4;
368 break;
369
370 default:
371 res = 0;
372 break;
373 }
374 */
375 if ((patch_entry) && (offset == patch_entry->mac_offset) && (res == 0))
376 {
377 if (getmacaddr(val) == 0)
378 {
379 HILOGI("MAC: %02x:%02x:%02x:%02x:%02x:%02x", val[5], val[4], val[3], val[2], val[1], val[0]);
380 res = 6;
381 }
382 }
383 return res;
384 }
385
rtk_usb_update_altsettings(usb_patch_info * patch_entry,unsigned char * config_buf_ptr,size_t * config_len_ptr)386 static void rtk_usb_update_altsettings(usb_patch_info *patch_entry, unsigned char *config_buf_ptr, size_t *config_len_ptr)
387 {
388 unsigned short offset[256], data_len;
389 unsigned char val[256];
390
391 struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)config_buf_ptr;
392 struct rtk_bt_vendor_config_entry *entry = config->entry;
393 size_t config_len = *config_len_ptr;
394 unsigned int i = 0;
395 int count = 0, temp = 0, j;
396
397 if ((extra_extry = (struct rtk_bt_vendor_config_entry *)malloc(MAX_ALT_CONFIG_SIZE)) == NULL)
398 {
399 HILOGE("malloc buffer for extra_extry failed");
400 }
401 else
402 memset(extra_extry, 0, MAX_ALT_CONFIG_SIZE);
403
404 HILOGI("ORG Config len=%08zx:\n", config_len);
405 for (i = 0; i <= config_len; i += 0x10)
406 {
407 HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
408 config_buf_ptr[i], config_buf_ptr[i + 1], config_buf_ptr[i + 2], config_buf_ptr[i + 3], config_buf_ptr[i + 4], config_buf_ptr[i + 5], config_buf_ptr[i + 6], config_buf_ptr[i + 7],
409 config_buf_ptr[i + 8], config_buf_ptr[i + 9], config_buf_ptr[i + 10], config_buf_ptr[i + 11], config_buf_ptr[i + 12], config_buf_ptr[i + 13], config_buf_ptr[i + 14], config_buf_ptr[i + 15]);
410 }
411
412 memset(offset, 0, sizeof(offset));
413 memset(val, 0, sizeof(val));
414 data_len = le16_to_cpu(config->data_len);
415
416 count = getUsbAltSettings(patch_entry, offset); // getAltSettings(patch_entry, offset, sizeof(offset)/sizeof(unsigned short));
417 if (count <= 0)
418 {
419 HILOGI("rtk_update_altsettings: No AltSettings");
420 return;
421 }
422 else
423 {
424 HILOGI("rtk_update_altsettings: %d AltSettings", count);
425 }
426
427 if (data_len != config_len - sizeof(struct rtk_bt_vendor_config))
428 {
429 HILOGE("rtk_update_altsettings: config len(%x) is not right(%lx)", data_len, (unsigned long)(config_len - sizeof(struct rtk_bt_vendor_config)));
430 return;
431 }
432
433 for (i = 0; i < data_len;)
434 {
435 for (j = 0; j < count; j++)
436 {
437 if (le16_to_cpu(entry->offset) == offset[j])
438 {
439 if (offset[j] == patch_entry->mac_offset)
440 offset[j] = 0;
441 else
442 {
443 struct rtk_bt_vendor_config_entry *t = extra_extry;
444 while (t->offset)
445 {
446 if (t->offset == le16_to_cpu(entry->offset))
447 {
448 if (t->entry_len == entry->entry_len)
449 offset[j] = 0;
450 break;
451 }
452 t = (struct rtk_bt_vendor_config_entry *)((uint8_t *)t + t->entry_len + sizeof(struct rtk_bt_vendor_config_entry));
453 }
454 }
455 }
456 }
457 if (getUsbAltSettingVal(patch_entry, le16_to_cpu(entry->offset), val) == entry->entry_len)
458 {
459 HILOGI("rtk_update_altsettings: replace %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
460 memcpy(entry->entry_data, val, entry->entry_len);
461 }
462 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
463 i += temp;
464 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
465 }
466
467 for (j = 0; j < count; j++)
468 {
469 if (offset[j] == 0)
470 continue;
471 entry->entry_len = getUsbAltSettingVal(patch_entry, offset[j], val);
472 if (entry->entry_len <= 0)
473 continue;
474 entry->offset = cpu_to_le16(offset[j]);
475 memcpy(entry->entry_data, val, entry->entry_len);
476 HILOGI("rtk_update_altsettings: add %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
477 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
478 i += temp;
479 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
480 }
481 config->data_len = cpu_to_le16(i);
482 *config_len_ptr = i + sizeof(struct rtk_bt_vendor_config);
483
484 if (extra_extry)
485 {
486 free(extra_extry);
487 extra_extry = NULL;
488 extra_entry_inx = NULL;
489 }
490
491 HILOGI("NEW Config len=%08zx:\n", *config_len_ptr);
492 for (i = 0; i <= (*config_len_ptr); i += 0x10)
493 {
494 HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
495 config_buf_ptr[i], config_buf_ptr[i + 1], config_buf_ptr[i + 2], config_buf_ptr[i + 3], config_buf_ptr[i + 4], config_buf_ptr[i + 5], config_buf_ptr[i + 6], config_buf_ptr[i + 7],
496 config_buf_ptr[i + 8], config_buf_ptr[i + 9], config_buf_ptr[i + 10], config_buf_ptr[i + 11], config_buf_ptr[i + 12], config_buf_ptr[i + 13], config_buf_ptr[i + 14], config_buf_ptr[i + 15]);
497 }
498 return;
499 }
500
rtk_usb_parse_config_file(unsigned char ** config_buf,size_t * filelen,uint8_t bt_addr[6],uint16_t mac_offset)501 static void rtk_usb_parse_config_file(unsigned char **config_buf, size_t *filelen, uint8_t bt_addr[6], uint16_t mac_offset)
502 {
503 struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)*config_buf;
504 uint16_t config_len = le16_to_cpu(config->data_len), temp = 0;
505 struct rtk_bt_vendor_config_entry *entry = config->entry;
506 unsigned int i = 0;
507 uint8_t heartbeat_buf = 0;
508 // uint32_t config_has_bdaddr = 0;
509 uint8_t *p;
510
511 HILOGD("bt_addr = %x", bt_addr[0]);
512 if (le32_to_cpu(config->signature) != RTK_VENDOR_CONFIG_MAGIC)
513 {
514 HILOGE("config signature magic number(0x%x) is not set to RTK_VENDOR_CONFIG_MAGIC", config->signature);
515 return;
516 }
517
518 if (config_len != *filelen - sizeof(struct rtk_bt_vendor_config))
519 {
520 HILOGE("config len(0x%x) is not right(0x%zx)", config_len, *filelen - sizeof(struct rtk_bt_vendor_config));
521 return;
522 }
523
524 hw_cfg_cb.heartbeat = 0;
525 for (i = 0; i < config_len;)
526 {
527 switch (le16_to_cpu(entry->offset))
528 {
529 case 0x017a:
530 {
531 if (mac_offset == CONFIG_MAC_OFFSET_GEN_1_2)
532 {
533 p = (uint8_t *)entry->entry_data;
534 STREAM_TO_UINT8(heartbeat_buf, p);
535 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10))
536 hw_cfg_cb.heartbeat = 1;
537 else
538 hw_cfg_cb.heartbeat = 0;
539
540 HILOGI("config 0x017a heartbeat = %d", hw_cfg_cb.heartbeat);
541 }
542 break;
543 }
544 case 0x01be:
545 {
546 if (mac_offset == CONFIG_MAC_OFFSET_GEN_3PLUS || mac_offset == CONFIG_MAC_OFFSET_GEN_4PLUS)
547 {
548 p = (uint8_t *)entry->entry_data;
549 STREAM_TO_UINT8(heartbeat_buf, p);
550 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10))
551 hw_cfg_cb.heartbeat = 1;
552 else
553 hw_cfg_cb.heartbeat = 0;
554
555 HILOGI("config 0x01be heartbeat = %d", hw_cfg_cb.heartbeat);
556 }
557 break;
558 }
559 default:
560 HILOGI("config offset(0x%x),length(0x%x)", entry->offset, entry->entry_len);
561 break;
562 }
563 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
564 i += temp;
565 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
566 }
567
568 return;
569 }
570
rtk_usb_get_bt_config(unsigned char ** config_buf,char * config_file_short_name,uint16_t mac_offset)571 static uint32_t rtk_usb_get_bt_config(unsigned char **config_buf,
572 char *config_file_short_name, uint16_t mac_offset)
573 {
574 char bt_config_file_name[PATH_MAX] = {0};
575 struct stat st;
576 size_t filelen;
577 int fd;
578 // FILE* file = NULL;
579
580 sprintf(bt_config_file_name, BT_CONFIG_DIRECTORY, config_file_short_name);
581 HILOGI("BT config file: %s", bt_config_file_name);
582
583 if (stat(bt_config_file_name, &st) < 0)
584 {
585 HILOGE("can't access bt config file:%s, errno:%d\n", bt_config_file_name, errno);
586 return 0;
587 }
588
589 filelen = st.st_size;
590 if (filelen > MAX_ORG_CONFIG_SIZE)
591 {
592 HILOGE("bt config file is too large(>0x%04x)", MAX_ORG_CONFIG_SIZE);
593 return 0;
594 }
595
596 if ((fd = open(bt_config_file_name, O_RDONLY)) < 0)
597 {
598 HILOGE("Can't open bt config file");
599 return 0;
600 }
601
602 if ((*config_buf = malloc(MAX_ORG_CONFIG_SIZE + MAX_ALT_CONFIG_SIZE)) == NULL)
603 {
604 HILOGE("malloc buffer for config file fail(0x%zx)\n", filelen);
605 close(fd);
606 return 0;
607 }
608
609 if (read(fd, *config_buf, filelen) < (ssize_t)filelen)
610 {
611 HILOGE("Can't load bt config file");
612 free(*config_buf);
613 close(fd);
614 return 0;
615 }
616
617 rtk_usb_parse_config_file(config_buf, &filelen, vnd_local_bd_addr, mac_offset);
618
619 close(fd);
620 return filelen;
621 }
622
rtk_usb_get_fw_table_entry(uint16_t vid,uint16_t pid)623 static usb_patch_info *rtk_usb_get_fw_table_entry(uint16_t vid, uint16_t pid)
624 {
625 usb_patch_info *patch_entry = usb_fw_patch_table;
626
627 uint32_t entry_size = sizeof(usb_fw_patch_table) / sizeof(usb_fw_patch_table[0]);
628 uint32_t i;
629
630 for (i = 0; i < entry_size; i++, patch_entry++)
631 {
632 if ((vid == patch_entry->vid) && (pid == patch_entry->pid))
633 break;
634 }
635
636 if (i == entry_size)
637 {
638 HILOGE("%s: No fw table entry found", __func__);
639 return NULL;
640 }
641
642 return patch_entry;
643 }
644
rtk_usb_get_bt_final_patch(bt_hw_cfg_cb_t * cfg_cb)645 static void rtk_usb_get_bt_final_patch(bt_hw_cfg_cb_t *cfg_cb)
646 {
647 uint8_t proj_id = 0;
648 struct rtk_epatch_entry *entry = NULL;
649 struct rtk_epatch *patch = (struct rtk_epatch *)cfg_cb->fw_buf;
650 // int iBtCalLen = 0;
651
652 if (cfg_cb->lmp_subversion == LMPSUBVERSION_8723a)
653 {
654 if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, 8) == 0)
655 {
656 HILOGE("8723as check signature error!");
657 cfg_cb->dl_fw_flag = 0;
658 goto free_buf;
659 }
660 else
661 {
662 cfg_cb->total_len = cfg_cb->fw_len + cfg_cb->config_len;
663 if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len)))
664 {
665 HILOGE("can't alloc memory for fw&config, errno:%d", errno);
666 cfg_cb->dl_fw_flag = 0;
667 goto free_buf;
668 }
669 else
670 {
671 HILOGI("8723as, fw copy direct");
672 memcpy(cfg_cb->total_buf, cfg_cb->fw_buf, cfg_cb->fw_len);
673 memcpy(cfg_cb->total_buf + cfg_cb->fw_len, cfg_cb->config_buf, cfg_cb->config_len);
674 // cfg_cb->lmp_sub_current = *(uint16_t *)(cfg_cb->total_buf + cfg_cb->total_len - cfg_cb->config_len - 4);
675 cfg_cb->dl_fw_flag = 1;
676 goto free_buf;
677 }
678 }
679 }
680
681 if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, 8))
682 {
683 HILOGE("check signature error");
684 cfg_cb->dl_fw_flag = 0;
685 goto free_buf;
686 }
687
688 /* check the extension section signature */
689 if (memcmp(cfg_cb->fw_buf + cfg_cb->fw_len - 4, EXTENSION_SECTION_SIGNATURE, 4))
690 {
691 HILOGE("check extension section signature error");
692 cfg_cb->dl_fw_flag = 0;
693 goto free_buf;
694 }
695
696 proj_id = rtk_get_fw_project_id(cfg_cb->fw_buf + cfg_cb->fw_len - 5);
697 if (usb_project_id[proj_id] != hw_cfg_cb.lmp_subversion_default)
698 {
699 HILOGE("usb_project_id is 0x%08x, fw project_id is %d, does not match!!!",
700 usb_project_id[proj_id], hw_cfg_cb.lmp_subversion);
701 cfg_cb->dl_fw_flag = 0;
702 goto free_buf;
703 }
704
705 entry = rtk_get_patch_entry(cfg_cb);
706 if (entry)
707 {
708 cfg_cb->total_len = entry->patch_length + cfg_cb->config_len;
709 }
710 else
711 {
712 cfg_cb->dl_fw_flag = 0;
713 goto free_buf;
714 }
715
716 HILOGI("total_len = 0x%x", cfg_cb->total_len);
717
718 if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len)))
719 {
720 HILOGE("Can't alloc memory for multi fw&config, errno:%d", errno);
721 cfg_cb->dl_fw_flag = 0;
722 goto free_buf;
723 }
724 else
725 {
726 memcpy(cfg_cb->total_buf, cfg_cb->fw_buf + entry->patch_offset, entry->patch_length);
727 memcpy(cfg_cb->total_buf + entry->patch_length - 4, &patch->fw_version, 4);
728 memcpy(&entry->svn_version, cfg_cb->total_buf + entry->patch_length - 8, 4);
729 memcpy(&entry->coex_version, cfg_cb->total_buf + entry->patch_length - 12, 4);
730
731 HILOGI("BTCOEX:20%06d-%04x svn_version:%d lmp_subversion:0x%x hci_version:0x%x hci_revision:0x%x chip_type:%d Cut:%d libbt-vendor_uart version:%s, patch->fw_version = %x\n",
732 ((entry->coex_version >> 16) & 0x7ff) + ((entry->coex_version >> 27) * 10000),
733 (entry->coex_version & 0xffff), entry->svn_version, cfg_cb->lmp_subversion, cfg_cb->hci_version, cfg_cb->hci_revision, cfg_cb->chip_type, cfg_cb->eversion + 1, RTK_VERSION, patch->fw_version);
734 }
735
736 if (cfg_cb->config_len)
737 {
738 memcpy(cfg_cb->total_buf + entry->patch_length, cfg_cb->config_buf, cfg_cb->config_len);
739 }
740
741 cfg_cb->dl_fw_flag = 1;
742 HILOGI("Fw:%s exists, config file:%s exists", (cfg_cb->fw_len > 0) ? "" : "not", (cfg_cb->config_len > 0) ? "" : "not");
743
744 free_buf:
745 if (cfg_cb->fw_len > 0)
746 {
747 free(cfg_cb->fw_buf);
748 cfg_cb->fw_len = 0;
749 }
750
751 if (cfg_cb->config_len > 0)
752 {
753 free(cfg_cb->config_buf);
754 cfg_cb->config_len = 0;
755 }
756
757 if (entry)
758 {
759 free(entry);
760 }
761 }
762
usb_hci_download_patch_h4(HC_BT_HDR * p_buf,int index,uint8_t * data,int len)763 static int usb_hci_download_patch_h4(HC_BT_HDR *p_buf, int index, uint8_t *data, int len)
764 {
765 int retval = FALSE;
766 uint8_t *p = (uint8_t *)(p_buf + 1);
767
768 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_FW_PATCH);
769 *p++ = 1 + len; /* parameter length */
770 *p++ = index;
771 memcpy(p, data, len);
772 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1 + len;
773
774 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
775
776 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_DOWNLOAD_FW_PATCH, p_buf);
777 return retval;
778 }
779
rtk_usb_get_fw_version(bt_hw_cfg_cb_t * cfg_cb)780 static void rtk_usb_get_fw_version(bt_hw_cfg_cb_t *cfg_cb)
781 {
782 struct rtk_epatch *patch = (struct rtk_epatch *)cfg_cb->fw_buf;
783
784 if (cfg_cb->lmp_subversion == LMPSUBVERSION_8723a)
785 {
786 cfg_cb->lmp_sub_current = 0;
787 }
788 else
789 {
790 cfg_cb->lmp_sub_current = (uint16_t)patch->fw_version;
791 }
792 }
793 /*******************************************************************************
794 **
795 ** Function hw_usb_config_cback
796 **
797 ** Description Callback function for controller configuration
798 **
799 ** Returns None
800 **
801 *******************************************************************************/
hw_usb_config_cback(void * p_mem)802 void hw_usb_config_cback(void *p_mem)
803 {
804 HC_BT_HDR *p_evt_buf = NULL;
805 uint8_t *p = NULL; //, *pp=NULL;
806 uint8_t status = 0;
807 uint16_t opcode = 0;
808 HC_BT_HDR *p_buf = NULL;
809 int is_proceeding = FALSE;
810 // int i = 0;
811 uint8_t iIndexRx = 0;
812 // patch_info* prtk_patch_file_info = NULL;
813 usb_patch_info *prtk_usb_patch_file_info = NULL;
814 // uint32_t host_baudrate = 0;
815
816 #if (USE_CONTROLLER_BDADDR == TRUE)
817 // const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
818 #endif
819
820 if (p_mem != NULL)
821 {
822 p_evt_buf = (HC_BT_HDR *)p_mem;
823 status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET);
824 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE_OFFSET;
825 STREAM_TO_UINT16(opcode, p);
826 }
827
828 /* Ask a new buffer big enough to hold any HCI commands sent in here */
829 /*a cut fc6d status==1*/
830 if (((status == 0) || (opcode == HCI_VSC_READ_ROM_VERSION)) && bt_vendor_cbacks)
831 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_MAX_LEN);
832
833 if (p_buf != NULL)
834 {
835 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
836 p_buf->offset = 0;
837 p_buf->len = 0;
838 p_buf->layer_specific = 0;
839
840 BTVNDDBG("hw_cfg_cb.state = %i", hw_cfg_cb.state);
841 switch (hw_cfg_cb.state)
842 {
843 case HW_CFG_RESET_CHANNEL_CONTROLLER:
844 {
845 usleep(300000);
846 hw_cfg_cb.state = HW_CFG_READ_LOCAL_VER;
847 p = (uint8_t *)(p_buf + 1);
848 UINT16_TO_STREAM(p, HCI_READ_LMP_VERSION);
849 *p++ = 0;
850 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
851 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LMP_VERSION, p_buf);
852 break;
853 }
854 case HW_CFG_READ_LOCAL_VER:
855 {
856 if (status == 0 && p_evt_buf)
857 {
858 p = ((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_VERSION_OFFSET);
859 STREAM_TO_UINT16(hw_cfg_cb.hci_version, p);
860 p = ((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_REVISION_OFFSET);
861 STREAM_TO_UINT16(hw_cfg_cb.hci_revision, p);
862 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_LMP_SUBVERSION_OFFSET;
863 STREAM_TO_UINT16(hw_cfg_cb.lmp_subversion, p);
864
865 prtk_usb_patch_file_info = rtk_usb_get_fw_table_entry(hw_cfg_cb.vid, hw_cfg_cb.pid);
866 if ((prtk_usb_patch_file_info == NULL) || (prtk_usb_patch_file_info->lmp_sub_default == 0))
867 {
868 HILOGE("get patch entry error");
869 is_proceeding = FALSE;
870 break;
871 }
872 hw_cfg_cb.config_len = rtk_usb_get_bt_config(&hw_cfg_cb.config_buf, prtk_usb_patch_file_info->config_name, prtk_usb_patch_file_info->mac_offset);
873 hw_cfg_cb.fw_len = rtk_get_bt_firmware(&hw_cfg_cb.fw_buf, prtk_usb_patch_file_info->patch_name);
874 rtk_usb_get_fw_version(&hw_cfg_cb);
875
876 hw_cfg_cb.lmp_subversion_default = prtk_usb_patch_file_info->lmp_sub_default;
877 BTVNDDBG("lmp_subversion = 0x%x hw_cfg_cb.hci_version = 0x%x hw_cfg_cb.hci_revision = 0x%x, hw_cfg_cb.lmp_sub_current = 0x%x",
878 hw_cfg_cb.lmp_subversion, hw_cfg_cb.hci_version, hw_cfg_cb.hci_revision, hw_cfg_cb.lmp_sub_current);
879
880 if (prtk_usb_patch_file_info->lmp_sub_default == hw_cfg_cb.lmp_subversion)
881 {
882 BTVNDDBG("%s: Cold BT controller startup", __func__);
883 // hw_cfg_cb.state = HW_CFG_START;
884 // goto CFG_USB_START;
885 hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
886 p = (uint8_t *)(p_buf + 1);
887 UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
888 *p++ = 0;
889 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
890 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
891 }
892 else if (hw_cfg_cb.lmp_subversion != hw_cfg_cb.lmp_sub_current)
893 {
894 BTVNDDBG("%s: Warm BT controller startup with updated lmp", __func__);
895 goto RESET_HW_CONTROLLER;
896 }
897 else
898 {
899 BTVNDDBG("%s: Warm BT controller startup with same lmp", __func__);
900 userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
901 free(hw_cfg_cb.total_buf);
902 hw_cfg_cb.total_len = 0;
903
904 bt_vendor_cbacks->dealloc(p_buf);
905 start_fwcfg_cbtimer();
906 hw_cfg_cb.state = 0;
907 is_proceeding = TRUE;
908 }
909
910 /* if(hw_cfg_cb.lmp_subversion == LMPSUBVERSION_8723a)
911 {
912 hw_cfg_cb.state = HW_CFG_START;
913 goto CFG_USB_START;
914 }
915 else
916 {
917 hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
918 p = (uint8_t *) (p_buf + 1);
919 UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
920 *p++ = 0;
921 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
922 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
923 }*/
924 }
925 else
926 {
927 HILOGE("status = %d, or p_evt_buf is NULL", status);
928 }
929 break;
930 }
931 RESET_HW_CONTROLLER:
932 case HW_RESET_CONTROLLER:
933 {
934 if (status == 0)
935 {
936 // usleep(300000);//300ms
937 userial_vendor_usb_ioctl(RESET_CONTROLLER, NULL); // reset controller
938 hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
939 p = (uint8_t *)(p_buf + 1);
940 UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
941 *p++ = 0;
942 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
943 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
944 }
945 break;
946 }
947 case HW_CFG_READ_ECO_VER:
948 {
949 if (status == 0 && p_evt_buf)
950 {
951 hw_cfg_cb.eversion = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPFC6D_EVERSION_OFFSET);
952 BTVNDDBG("hw_usb_config_cback chip_id of the IC:%d", hw_cfg_cb.eversion + 1);
953 }
954 else if (1 == status)
955 {
956 hw_cfg_cb.eversion = 0;
957 }
958 else
959 {
960 is_proceeding = FALSE;
961 break;
962 }
963
964 hw_cfg_cb.state = HW_CFG_START;
965 goto CFG_USB_START;
966 }
967 CFG_USB_START:
968 case HW_CFG_START:
969 {
970 // get efuse config file and patch code file
971 prtk_usb_patch_file_info = rtk_usb_get_fw_table_entry(hw_cfg_cb.vid, hw_cfg_cb.pid);
972
973 if ((prtk_usb_patch_file_info == NULL) || (prtk_usb_patch_file_info->lmp_sub_default == 0))
974 {
975 HILOGE("get patch entry error");
976 is_proceeding = FALSE;
977 break;
978 }
979 hw_cfg_cb.max_patch_size = prtk_usb_patch_file_info->max_patch_size;
980 hw_cfg_cb.config_len = rtk_usb_get_bt_config(&hw_cfg_cb.config_buf, prtk_usb_patch_file_info->config_name, prtk_usb_patch_file_info->mac_offset);
981 if (hw_cfg_cb.config_len)
982 {
983 HILOGE("update altsettings");
984 rtk_usb_update_altsettings(prtk_usb_patch_file_info, hw_cfg_cb.config_buf, &(hw_cfg_cb.config_len));
985 }
986
987 hw_cfg_cb.fw_len = rtk_get_bt_firmware(&hw_cfg_cb.fw_buf, prtk_usb_patch_file_info->patch_name);
988 if (hw_cfg_cb.fw_len < 0)
989 {
990 HILOGE("Get BT firmware fail");
991 hw_cfg_cb.fw_len = 0;
992 is_proceeding = FALSE;
993 break;
994 }
995 else
996 {
997 // hw_cfg_cb.project_id_mask = prtk_usb_patch_file_info->project_id_mask;
998 rtk_usb_get_bt_final_patch(&hw_cfg_cb);
999 }
1000
1001 BTVNDDBG("Check total_len(0x%08x) max_patch_size(0x%08x)", hw_cfg_cb.total_len, hw_cfg_cb.max_patch_size);
1002 if (hw_cfg_cb.total_len > hw_cfg_cb.max_patch_size)
1003 {
1004 HILOGE("total length of fw&config(0x%08x) larger than max_patch_size(0x%08x)", hw_cfg_cb.total_len, hw_cfg_cb.max_patch_size);
1005 is_proceeding = FALSE;
1006 break;
1007 }
1008
1009 if ((hw_cfg_cb.total_len > 0) && hw_cfg_cb.dl_fw_flag)
1010 {
1011 hw_cfg_cb.patch_frag_cnt = hw_cfg_cb.total_len / PATCH_DATA_FIELD_MAX_SIZE;
1012 hw_cfg_cb.patch_frag_tail = hw_cfg_cb.total_len % PATCH_DATA_FIELD_MAX_SIZE;
1013 if (hw_cfg_cb.patch_frag_tail)
1014 hw_cfg_cb.patch_frag_cnt += 1;
1015 else
1016 hw_cfg_cb.patch_frag_tail = PATCH_DATA_FIELD_MAX_SIZE;
1017 BTVNDDBG("patch fragment count %d, tail len %d", hw_cfg_cb.patch_frag_cnt, hw_cfg_cb.patch_frag_tail);
1018 }
1019 else
1020 {
1021 is_proceeding = FALSE;
1022 break;
1023 }
1024
1025 goto DOWNLOAD_USB_FW;
1026 }
1027 /* fall through intentionally */
1028
1029 DOWNLOAD_USB_FW:
1030 case HW_CFG_DL_FW_PATCH:
1031 BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, opcode:0x%x", status, opcode);
1032
1033 // recv command complete event for patch code download command
1034 if (opcode == HCI_VSC_DOWNLOAD_FW_PATCH)
1035 {
1036 iIndexRx = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET + 1);
1037 BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, iIndexRx:%i", status, iIndexRx);
1038 hw_cfg_cb.patch_frag_idx++;
1039
1040 if (iIndexRx & 0x80)
1041 {
1042 BTVNDDBG("vendor lib fwcfg completed");
1043 userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
1044 free(hw_cfg_cb.total_buf);
1045 hw_cfg_cb.total_len = 0;
1046
1047 bt_vendor_cbacks->dealloc(p_buf);
1048 // bt_vendor_cbacks->fwcfg_cb(BTC_OP_RESULT_SUCCESS);
1049 start_fwcfg_cbtimer();
1050
1051 hw_cfg_cb.state = 0;
1052 is_proceeding = TRUE;
1053 break;
1054 }
1055 }
1056
1057 if (hw_cfg_cb.patch_frag_idx < hw_cfg_cb.patch_frag_cnt)
1058 {
1059 iIndexRx = hw_cfg_cb.patch_frag_idx ? ((hw_cfg_cb.patch_frag_idx - 1) % 0x7f + 1) : 0;
1060 if (hw_cfg_cb.patch_frag_idx == hw_cfg_cb.patch_frag_cnt - 1)
1061 {
1062 BTVNDDBG("HW_CFG_DL_FW_PATCH: send last fw fragment");
1063 iIndexRx |= 0x80;
1064 hw_cfg_cb.patch_frag_len = hw_cfg_cb.patch_frag_tail;
1065 }
1066 else
1067 {
1068 iIndexRx &= 0x7F;
1069 hw_cfg_cb.patch_frag_len = PATCH_DATA_FIELD_MAX_SIZE;
1070 }
1071 }
1072
1073 is_proceeding = usb_hci_download_patch_h4(p_buf, iIndexRx,
1074 hw_cfg_cb.total_buf + (hw_cfg_cb.patch_frag_idx * PATCH_DATA_FIELD_MAX_SIZE),
1075 hw_cfg_cb.patch_frag_len);
1076 break;
1077 default:
1078 break;
1079 } // switch(hw_cfg_cb.state)
1080 } // if (p_buf != NULL)
1081
1082 if (is_proceeding == FALSE)
1083 {
1084 HILOGE("vendor lib fwcfg aborted!!!");
1085 if (bt_vendor_cbacks)
1086 {
1087 if (p_buf != NULL)
1088 bt_vendor_cbacks->dealloc(p_buf);
1089
1090 userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
1091 // bt_vendor_cbacks->fwcfg_cb(BTC_OP_RESULT_FAIL);
1092
1093 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1094 }
1095
1096 if (hw_cfg_cb.config_len)
1097 {
1098 free(hw_cfg_cb.config_buf);
1099 hw_cfg_cb.config_len = 0;
1100 }
1101
1102 if (hw_cfg_cb.fw_len)
1103 {
1104 free(hw_cfg_cb.fw_buf);
1105 hw_cfg_cb.fw_len = 0;
1106 }
1107
1108 if (hw_cfg_cb.total_len)
1109 {
1110 free(hw_cfg_cb.total_buf);
1111 hw_cfg_cb.total_len = 0;
1112 }
1113 hw_cfg_cb.state = 0;
1114 }
1115 }
1116
1117 /*******************************************************************************
1118 **
1119 ** Function hw__usb_config_start
1120 **
1121 ** Description Kick off controller initialization process
1122 **
1123 ** Returns None
1124 **
1125 *******************************************************************************/
hw_usb_config_start(char transtype,uint32_t usb_id)1126 void hw_usb_config_start(char transtype, uint32_t usb_id)
1127 {
1128 RTK_UNUSED(transtype);
1129 memset(&hw_cfg_cb, 0, sizeof(bt_hw_cfg_cb_t));
1130 hw_cfg_cb.dl_fw_flag = 1;
1131 hw_cfg_cb.chip_type = CHIPTYPE_NONE;
1132 hw_cfg_cb.pid = usb_id & 0x0000ffff;
1133 hw_cfg_cb.vid = (usb_id >> 16) & 0x0000ffff;
1134 BTVNDDBG("RTKBT_RELEASE_NAME: %s", RTKBT_RELEASE_NAME);
1135 BTVNDDBG("\nRealtek libbt-vendor_usb Version %s \n", RTK_VERSION);
1136 HC_BT_HDR *p_buf = NULL;
1137 uint8_t *p;
1138
1139 BTVNDDBG("hw_usb_config_start, transtype = 0x%x, pid = 0x%04x, vid = 0x%04x \n", transtype, hw_cfg_cb.pid, hw_cfg_cb.vid);
1140
1141 if (bt_vendor_cbacks)
1142 {
1143 /* Must allocate command buffer via HC's alloc API */
1144 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE +
1145 HCI_CMD_PREAMBLE_SIZE);
1146 if (p_buf)
1147 {
1148 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1149 p_buf->offset = 0;
1150 p_buf->layer_specific = 0;
1151 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1152
1153 p = (uint8_t *)(p_buf + 1);
1154
1155 p = (uint8_t *)(p_buf + 1);
1156 UINT16_TO_STREAM(p, HCI_VENDOR_RESET);
1157 *p++ = 0;
1158 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1159
1160 hw_cfg_cb.state = HW_CFG_RESET_CHANNEL_CONTROLLER;
1161 bt_vendor_cbacks->xmit_cb(HCI_VENDOR_RESET, p_buf);
1162 }
1163 else
1164 {
1165 HILOGE("%s buffer alloc fail!", __func__);
1166 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1167 }
1168 }
1169 else
1170 HILOGE("%s call back is null", __func__);
1171 }
1172