diff options
-rw-r--r-- | Makefile.tools | 2 | ||||
-rw-r--r-- | packaging/bluez.spec | 2 | ||||
-rw-r--r-- | profiles/audio/avrcp.c | 3 | ||||
-rw-r--r-- | tools/hciattach.c | 16 | ||||
-rw-r--r-- | tools/hciattach.h | 3 | ||||
-rw-r--r-- | tools/hciattach_sprd.c | 579 | ||||
-rw-r--r-- | tools/hciattach_sprd.h | 82 | ||||
-rw-r--r-- | tools/pskey_get.c | 384 |
8 files changed, 1066 insertions, 5 deletions
diff --git a/Makefile.tools b/Makefile.tools index 0dba04a3..d171dd2f 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -131,6 +131,8 @@ tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \ tools/hciattach_ath3k.c \ tools/hciattach_qualcomm.c \ tools/hciattach_intel.c \ + tools/hciattach_sprd.c \ + tools/pskey_get.c \ tools/hciattach_bcm43xx.c # src/log.c # tools/hciattach_bcm43xx.c diff --git a/packaging/bluez.spec b/packaging/bluez.spec index 78ebeb69..67de9f30 100644 --- a/packaging/bluez.spec +++ b/packaging/bluez.spec @@ -95,7 +95,7 @@ cp %{SOURCE1001} . %build autoreconf -fiv -export CFLAGS="${CFLAGS} -D__TIZEN_PATCH__ -D__BROADCOM_PATCH__ -DBLUEZ5_27_GATT_CLIENT" +export CFLAGS="${CFLAGS} -D__TIZEN_PATCH__ -DBLUEZ5_27_GATT_CLIENT" export LDFLAGS=" -lncurses -Wl,--as-needed " export CFLAGS+=" -DPBAP_SIM_ENABLE" diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index 9ea41150..fa19d6da 100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -798,8 +798,7 @@ done: * notification. As we are sending changed event eariler * then time interval. */ - DBG("Removing the timer function added by - register notification"); + DBG("Removing the timer function added by register notification"); g_source_remove(pos_timer_id); pos_timer_id = 0; } diff --git a/tools/hciattach.c b/tools/hciattach.c index 150c5d04..b3bb5125 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -1099,9 +1099,21 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) return 0; } +#ifdef __TIZEN_PATCH__ /*SPRD add Start*/ +static int init_sprd_config(int fd, struct uart_t *u, struct termios *ti) +{ + + return sprd_config_init(fd, u->bdaddr, ti); +} +#endif + struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, DISABLE_PM, NULL, NULL }, +#ifdef __TIZEN_PATCH__ /*SPRD*/ + { "sprd", 0x0000, 0x0000, HCI_UART_H4, 3000000, 3000000, + FLOW_CTL, DISABLE_PM, NULL, init_sprd_config }, +#endif { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, DISABLE_PM, NULL, ericsson }, @@ -1409,8 +1421,8 @@ static void usage(void) /* This commented code was present before bluez 5.25 upgrade * printf("\thciattach [-n] [-p] [-b] [-g device_param] [-r] [-f] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");*/ printf("\thciattach [-n] [-p] [-b] [-g device_param] [-r] [-f]" - " [-t timeout] [-s initial_speed]"
- " <tty> <type | id> [speed] [flow|noflow]"
+ " [-t timeout] [-s initial_speed]" + " <tty> <type | id> [speed] [flow|noflow]" " [sleep|nosleep] [bdaddr]\n"); #else printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed]" diff --git a/tools/hciattach.h b/tools/hciattach.h index 2aaf0752..0b7e02e8 100644 --- a/tools/hciattach.h +++ b/tools/hciattach.h @@ -55,6 +55,9 @@ int stlc2500_init(int fd, bdaddr_t *bdaddr); int bgb2xx_init(int dd, bdaddr_t *bdaddr); int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti); +#ifdef __TIZEN_PATCH__ +int sprd_config_init(int fd, char *bdaddr, struct termios *ti); +#endif int ath3k_post(int fd, int pm); int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); int intel_init(int fd, int init_speed, int *speed, struct termios *ti); diff --git a/tools/hciattach_sprd.c b/tools/hciattach_sprd.c new file mode 100644 index 00000000..410a2cf5 --- /dev/null +++ b/tools/hciattach_sprd.c @@ -0,0 +1,579 @@ +#include <linux/kernel.h> +#include <assert.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <syslog.h> +#include <termios.h> +#include <time.h> +#include <sys/time.h> +#include <sys/poll.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include <sys/types.h> +#include <dirent.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> + +#include "hciattach.h" +#include <sys/stat.h> + +#include "hciattach_sprd.h" + +//#include <android/log.h> +//#define DBG +#ifdef DBG +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "pskey_bt", __VA_ARGS__) +#else +#define LOGD(fmt, arg...) fprintf(stderr, "%s:%d()" fmt "\n", __FILE__,__LINE__, ## arg) +#endif +typedef unsigned char UINT8; + +#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);} +#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);} +#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);} +#define UINT8_TO_STREAM(p, u8) {*(p)++ = (UINT8)(u8);} +#define INT8_TO_STREAM(p, u8) {*(p)++ = (INT8)(u8);} + +#define PSKEY_PRELOAD_SIZE 0x04 +#define PSKEY_PREAMBLE_SIZE 0xA2 + + // for bt mac addr +#define BT_MAC_FILE_PATH "/csa/bluetooth/" +#define DATMISC_MAC_ADDR_PATH BT_MAC_FILE_PATH".bd_addr" +#define MAC_ADDR_BUF_LEN (strlen("FF:FF:FF:FF:FF:FF")) +#define MAC_ADDR_FILE_LEN 25 +#define MAC_ADDR_LEN 6 + +#define BD_ADDR_LEN 14 +#define BD_PREFIX "0002\n" + +#if 0 +#ifndef VENDOR_BTWRITE_PROC_NODE +#define VENDOR_BTWRITE_PROC_NODE "/proc/bluetooth/sleep/btwrite" +#endif +#endif + +#define MAX_BT_TMP_PSKEY_FILE_LEN 2048 + +typedef unsigned int UWORD32; +typedef unsigned short UWORD16; +typedef unsigned char UWORD8; + +#define down_bt_is_space(c) (((c) == '\n') || ((c) == ',') || ((c) == '\r') || ((c) == ' ') || ((c) == '{') || ((c) == '}')) +#define down_bt_is_comma(c) (((c) == ',')) +#define down_bt_is_endc(c) (((c) == '}')) // indicate end of data + +/* Macros to swap byte order */ +#define SWAP_BYTE_ORDER_WORD(val) ((((val) & 0x000000FF) << 24) + \ + (((val) & 0x0000FF00) << 8) + \ + (((val) & 0x00FF0000) >> 8) + \ + (((val) & 0xFF000000) >> 24)) +#define INLINE static __inline + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN +#endif + + +// pskey file structure default value +static BT_PSKEY_CONFIG_T bt_para_setting={ + .pskey_cmd = 0x001C0101, + + .g_dbg_source_sink_syn_test_data = 0, + .g_sys_sleep_in_standby_supported = 0, + .g_sys_sleep_master_supported = 0, + .g_sys_sleep_slave_supported = 0, + + .default_ahb_clk = 26000000, + .device_class = 0x001F00, + .win_ext = 30, + + .g_aGainValue = {0x0000F600, 0x0000D000, 0x0000AA00, 0x00008400, 0x00004400, 0x00000A00}, + .g_aPowerValue = {0x0FC80000, 0x0FF80000, 0x0FDA0000, 0x0FCC0000, 0x0FFC0000}, + + .feature_set = {0xFF, 0xFF, 0x8D, 0xFE, 0x9B, 0x7F, 0x79, 0x83, 0xFF, 0xA7, 0xFF, 0x7F, 0x00, 0xE0, 0xF7, 0x3E}, + .device_addr = {0x6A, 0x6B, 0x8C, 0x8A, 0x8B, 0x8C}, + + .g_sys_sco_transmit_mode = 0, //true tramsmit by uart, otherwise by share memory + .g_sys_uart0_communication_supported = 1, //true use uart0, otherwise use uart1 for debug + .edr_tx_edr_delay = 5, + .edr_rx_edr_delay = 14, + + .g_wbs_nv_117 = 0x0031, + + .is_wdg_supported = 0, + + .share_memo_rx_base_addr = 0, + //.share_memo_tx_base_addr = 0, + .g_wbs_nv_118 = 0x0066, + .g_nbv_nv_117 = 0x1063, + + .share_memo_tx_packet_num_addr = 0, + .share_memo_tx_data_base_addr = 0, + + .g_PrintLevel = 0xFFFFFFFF, + + .share_memo_tx_block_length = 0, + .share_memo_rx_block_length = 0, + .share_memo_tx_water_mark = 0, + //.share_memo_tx_timeout_value = 0, + .g_nbv_nv_118 = 0x0E45, + + .uart_rx_watermark = 48, + .uart_flow_control_thld = 63, + .comp_id = 0, + .pcm_clk_divd = 0x26, + + + .reserved = {0} +}; + +extern int getPskeyFromFile(void *pData); +extern int bt_getPskeyFromFile(void *pData); + +static int create_mac_folder(void) +{ + DIR *dp; + int err; + + dp = opendir(BT_MAC_FILE_PATH); + if (dp == NULL) { + if (mkdir(BT_MAC_FILE_PATH, 0755) < 0) { + err = -errno; + LOGD("%s: mkdir: %s(%d)",__FUNCTION__, strerror(-err), -err); + } + return -1; + } + + closedir(dp); + return 0; +} + +static void mac_rand(char *btmac) +{ + int ran; + int i; + unsigned int seed; + struct timeval tv; + + memcpy(btmac, BD_PREFIX, 5); + i = gettimeofday(&tv, NULL); + + if (i < 0) { + LOGD("Fail to call gettimeofday()"); + seed = time(NULL); + } else + seed = (unsigned int)tv.tv_usec; + + for (i = 5; i < BD_ADDR_LEN; i++) { + if (i == 7) { + btmac[i] = '\n'; + continue; + } + ran = rand_r(&seed) % 16; + if (ran < 10) + ran += 0x30; + else + ran += 0x57; + btmac[i] = ran; + } + LOGD("Random number is\r\n"); + for (i = 0; i < BD_ADDR_LEN; i++) { + LOGD("%c", btmac[i]); + } + LOGD("\r\n"); +} + +static void write_btmac2file(char *btmac) +{ + int fd; + int ret; + fd = open(DATMISC_MAC_ADDR_PATH, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + LOGD("write_btmac2file open file, fd=%d", fd); + if(fd >= 0) { + if(chmod(DATMISC_MAC_ADDR_PATH,0666) != -1){ + ret = write(fd, btmac, strlen(btmac)); + if (ret < strlen(btmac)) { + LOGD("Fail to write %s", DATMISC_MAC_ADDR_PATH); + close(fd); + return; + } + } + close(fd); + }else{ + LOGD("write bt mac to file failed!!"); + } +} + +uint8 ConvertHexToBin( + uint8 *hex_ptr, // in: the hexadecimal format string + uint16 length, // in: the length of hexadecimal string + uint8 *bin_ptr // out: pointer to the binary format string + ){ + uint8 *dest_ptr = bin_ptr; + uint32 i = 0; + uint8 ch; + + for(i=0; i<length; i+=2){ + // the bit 8,7,6,5 + ch = hex_ptr[i]; + // digital 0 - 9 + if (ch >= '0' && ch <= '9') + *dest_ptr =(uint8)((ch - '0') << 4); + // a - f + else if (ch >= 'a' && ch <= 'f') + *dest_ptr = (uint8)((ch - 'a' + 10) << 4); + // A - F + else if (ch >= 'A' && ch <= 'F') + *dest_ptr = (uint8)((ch -'A' + 10) << 4); + else{ + return 0; + } + + // the bit 1,2,3,4 + ch = hex_ptr[i+1]; + // digtial 0 - 9 + if (ch >= '0' && ch <= '9') + *dest_ptr |= (uint8)(ch - '0'); + // a - f + else if (ch >= 'a' && ch <= 'f') + *dest_ptr |= (uint8)(ch - 'a' + 10); + // A - F + else if (ch >= 'A' && ch <= 'F') + *dest_ptr |= (uint8)(ch -'A' + 10); + else{ + return 0; + } + + dest_ptr++; + } + + return 1; +} + +static int read_mac_address(char *file_name, uint8 *addr) { + char buf[MAC_ADDR_FILE_LEN] = {0}; + uint32 addr_t[MAC_ADDR_LEN] = {0}; + int i = 0; + + +#if 1 + int fd = open(file_name, O_RDONLY, 0666); + LOGD("%s read file: %s", __func__, file_name); + if (fd < 0) { + LOGD("%s open %s error reason: %s", __func__, file_name, strerror(errno)); + return -1; + } + if (read(fd, buf, BD_ADDR_LEN) < 0) { + LOGD("%s read %s error reason: %s", __func__, file_name, strerror(errno)); + goto done; + } + 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) { + LOGD("%s sscanf %s error reason: %s", __func__, file_name, strerror(errno)); + goto done; + } + + for (i = 0; i < MAC_ADDR_LEN; i++) { + addr[i] = addr_t[i] & 0xFF; + } + 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]); + +done: + close(fd); +#endif + return 0; +} + +static void mac_address_stream_compose(uint8 *addr) { + uint8 tmp, i, j; + for (i = 0, j = MAC_ADDR_LEN - 1; (i < MAC_ADDR_LEN / 2) && (i != j); i++, j--) { + tmp = addr[i]; + addr[i] = addr[j]; + addr[j] = tmp; + } +} + +#if 0 +/* + * random bluetooth mac address + */ +static void random_mac_addr(uint8 *addr) { + int fd, randseed, ret, mac_rd; + uint8 addr_t[MAC_ADDR_LEN] = {0}; + + LOGD("%s", __func__); + /* urandom seed build */ + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0){ + LOGD("%s: open urandom fail", __func__); + } else { + ret = read(fd, &randseed, sizeof(randseed)); + LOGD("%s urandom:0x%08X", __func__, randseed); + close(fd); + } + + /* time seed build */ + if (fd < 0 || ret < 0) { + struct timeval tt; + if (gettimeofday(&tt, (struct timezone *)0) > 0) { + randseed = (unsigned int) tt.tv_usec; + } else { + randseed = (unsigned int) time(NULL); + } + LOGD("urandom fail, using system time for randseed"); + } + + LOGD("%s: randseed = %u",__func__, randseed); + srand(randseed); + mac_rd = rand(); + + addr_t[0] = 0x40; /* FOR */ + addr_t[1] = 0x45; /* SPRD */ + addr_t[2] = 0xDA; /* ADDR */ + addr_t[3] = (uint8)(mac_rd & 0xFF); + addr_t[4] = (uint8)((mac_rd >> 8) & 0xFF); + addr_t[5] = (uint8)((mac_rd >> 16) & 0xFF); + + memcpy(addr, addr_t, MAC_ADDR_LEN); + 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]); +} +#endif +static void get_mac_address(uint8 *addr){ + int ret = -1; + uint8 addr_t[6] = {0}; + char bt_mac[BD_ADDR_LEN] = {0, }; + + LOGD("%s", __func__); + /* check misc mac file exist */ + ret = access(DATMISC_MAC_ADDR_PATH, F_OK); + if (ret != 0) { + LOGD("%s %s miss", __func__, DATMISC_MAC_ADDR_PATH); + + /* Try to make bt address file */ + create_mac_folder(); + + mac_rand(bt_mac); + LOGD("bt random mac=%s",bt_mac); + write_btmac2file(bt_mac); + + } + + /* read mac file */ + read_mac_address(DATMISC_MAC_ADDR_PATH, addr_t); + + /* compose mac stream */ + mac_address_stream_compose(addr_t); + + memcpy(addr, addr_t, MAC_ADDR_LEN); + +} + + +/* + * hci command preload stream, special order + */ +static void pskey_stream_compose(uint8 * buf, BT_PSKEY_CONFIG_T *bt_par) { + int i = 0; + uint8 *p = buf; + + LOGD("%s", __func__); + + UINT24_TO_STREAM(p, bt_par->pskey_cmd); + UINT8_TO_STREAM(p, (uint8)(PSKEY_PREAMBLE_SIZE & 0xFF)); + + UINT8_TO_STREAM(p, bt_par->g_dbg_source_sink_syn_test_data); + UINT8_TO_STREAM(p, bt_par->g_sys_sleep_in_standby_supported); + UINT8_TO_STREAM(p, bt_par->g_sys_sleep_master_supported); + UINT8_TO_STREAM(p, bt_par->g_sys_sleep_slave_supported); + + UINT32_TO_STREAM(p, bt_par->default_ahb_clk); + UINT32_TO_STREAM(p, bt_par->device_class); + UINT32_TO_STREAM(p, bt_par->win_ext); + + for (i = 0; i < 6; i++) { + UINT32_TO_STREAM(p, bt_par->g_aGainValue[i]); + } + for (i = 0; i < 5; i++) { + UINT32_TO_STREAM(p, bt_par->g_aPowerValue[i]); + } + + for (i = 0; i < 16; i++) { + UINT8_TO_STREAM(p, bt_par->feature_set[i]); + } + for (i = 0; i < 6; i++) { + UINT8_TO_STREAM(p, bt_par->device_addr[i]); + } + + UINT8_TO_STREAM(p, bt_par->g_sys_sco_transmit_mode); + UINT8_TO_STREAM(p, bt_par->g_sys_uart0_communication_supported); + UINT8_TO_STREAM(p, bt_par->edr_tx_edr_delay); + UINT8_TO_STREAM(p, bt_par->edr_rx_edr_delay); + + UINT16_TO_STREAM(p, bt_par->g_wbs_nv_117); + + UINT32_TO_STREAM(p, bt_par->is_wdg_supported); + + UINT32_TO_STREAM(p, bt_par->share_memo_rx_base_addr); + //UINT32_TO_STREAM(p, bt_par->share_memo_tx_base_addr); + UINT16_TO_STREAM(p, bt_par->g_wbs_nv_118); + UINT16_TO_STREAM(p, bt_par->g_nbv_nv_117); + + UINT32_TO_STREAM(p, bt_par->share_memo_tx_packet_num_addr); + UINT32_TO_STREAM(p, bt_par->share_memo_tx_data_base_addr); + + UINT32_TO_STREAM(p, bt_par->g_PrintLevel); + + UINT16_TO_STREAM(p, bt_par->share_memo_tx_block_length); + UINT16_TO_STREAM(p, bt_par->share_memo_rx_block_length); + UINT16_TO_STREAM(p, bt_par->share_memo_tx_water_mark); + //UINT16_TO_STREAM(p, bt_par->share_memo_tx_timeout_value); + UINT16_TO_STREAM(p, bt_par->g_nbv_nv_118); + + UINT16_TO_STREAM(p, bt_par->uart_rx_watermark); + UINT16_TO_STREAM(p, bt_par->uart_flow_control_thld); + UINT32_TO_STREAM(p, bt_par->comp_id); + UINT16_TO_STREAM(p, bt_par->pcm_clk_divd); + + + for (i = 0; i < 8; i++) { + UINT32_TO_STREAM(p, bt_par->reserved[i]); + } +} + +void sprd_get_pskey(BT_PSKEY_CONFIG_T * pskey_t) { + BT_PSKEY_CONFIG_T pskey; + uint8 buf[180] = {0}; + + LOGD("%s", __func__); + memset(&pskey, 0 , sizeof(BT_PSKEY_CONFIG_T)); + if (bt_getPskeyFromFile(&pskey) < 0 ) { + LOGD("%s bt_getPskeyFromFile failed", __func__); + memcpy(pskey_t, &bt_para_setting, sizeof(BT_PSKEY_CONFIG_T)); + return; + } + + memset(buf, 0, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE); + + /* get bluetooth mac address */ + get_mac_address(pskey.device_addr); + + /* compose pskey hci command pkt */ + pskey_stream_compose(buf, &pskey); + + memcpy(pskey_t, &pskey, sizeof(BT_PSKEY_CONFIG_T)); +} + + +int sprd_config_init(int fd, char *bdaddr, struct termios *ti) +{ + int ret = 0,r=0; + unsigned char resp[30] = {0}; + BT_PSKEY_CONFIG_T bt_para_tmp; + uint8 data_tmp[5] = {'a'}; + static int index = 0; + uint8 *buf = NULL; +#if 0 + char buffer; + int btsleep_fd_sprd = -1; +#endif + LOGD("sprd_config_init"); + +#if 0 + uart_fd = open(UART_INFO_PATH, O_WRONLY); + if(uart_fd > 0) + { + buffer = '2'; + if (write(uart_fd, &buffer, 1) < 0) + { + LOGD("%s write(%s) failed: %s (%d) 2", __func__, + UART_INFO_PATH, strerror(errno),errno); + } + + close(uart_fd); + } +#endif + +#if 0 + btsleep_fd_sprd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY); + if (btsleep_fd_sprd < 0) + { + LOGD("%s open(%s) for write failed: %s (%d)", __func__, + VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno); + } + else + { + buffer = '1'; + if (write(btsleep_fd_sprd, &buffer, 1) < 0) + { + LOGD("%s write(%s) failed: %s (%d)", __func__, + VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno); + } + } +#endif + + ret = bt_getPskeyFromFile(&bt_para_tmp); + if (ret < 0) { + LOGD("init_sprd_config bt_getPskeyFromFile failed\n"); + memcpy(&bt_para_tmp, &bt_para_setting, sizeof(BT_PSKEY_CONFIG_T)); + } + + buf = (uint8 *)malloc(PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE); + if (buf == NULL) { + LOGD("%s alloc stream memory failed", __func__); + return -1; + } + memset(buf, 0, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE); + + /* get bluetooth mac address */ + get_mac_address(bt_para_tmp.device_addr); + + /* compose pskey hci command pkt */ + pskey_stream_compose(buf, &bt_para_tmp); + + ret = write(fd, buf, PSKEY_PRELOAD_SIZE + PSKEY_PREAMBLE_SIZE); + LOGD("write pskey ret = %d", ret); + + free(buf); + buf = NULL; + + if (ret < 0) { + LOGD("%s write pskey stream failed", __func__); + return -1; + } + + memset(data_tmp, 0xff, sizeof(data_tmp)); + while (1) { + r = read(fd, resp, 1); + + if (r <= 0) + return -1; + else{ + data_tmp[index] = resp[0]; + LOGD("recive from controller 0x%x", data_tmp[index]); + ++index; + } + +/* if ((data_tmp[0] == 0x04) && (data_tmp[1] == 0x6f)&& (data_tmp[2] == 0x01) &&(data_tmp[3] == 0x0)){*/ + if ((data_tmp[0] == 0x04) && (data_tmp[1] == 0xe)&& (data_tmp[2] == 0xa) &&(data_tmp[3] == 0x1)){ + fprintf(stderr, "read response ok \n"); + + if (index == 12) { + index = 0; + memset(data_tmp, 0x0, sizeof(data_tmp)); + break; + } + } + } + + return 0; +} diff --git a/tools/hciattach_sprd.h b/tools/hciattach_sprd.h new file mode 100644 index 00000000..6e59408d --- /dev/null +++ b/tools/hciattach_sprd.h @@ -0,0 +1,82 @@ +#ifndef HCIATTACH_SPRD_H__ +#define HCIATTACH_SPRD_H__ + +#define MAC_ERROR "FF:FF:FF:FF:FF:FF" + +#define BT_MAC_FILE "/productinfo/btmac.txt" +//#define GET_BTMAC_ATCMD "AT+SNVM=0,401" +//#define GET_BTPSKEY_ATCMD "AT+SNVM=0,415" +//#define SET_BTMAC_ATCMD "AT+SNVM=1,401" +#define BT_RAND_MAC_LENGTH 17 + +// used to store BT pskey structure and default values +#define BT_PSKEY_STRUCT_FILE "/system/lib/modules/pskey_bt.txt" +//#define BT_PSKEY_FILE "/system/lib/modules/pskey_bt.txt" + + +typedef unsigned char uint8; +typedef unsigned int uint32; +typedef unsigned short uint16; + +#define BT_ADDRESS_SIZE 6 + + +typedef struct SPRD_BT_PSKEY_INFO_T{ + uint32 pskey_cmd; + + uint8 g_dbg_source_sink_syn_test_data; + uint8 g_sys_sleep_in_standby_supported; + uint8 g_sys_sleep_master_supported; + uint8 g_sys_sleep_slave_supported; + + uint32 default_ahb_clk; + uint32 device_class; + uint32 win_ext; + + uint32 g_aGainValue[6]; + uint32 g_aPowerValue[5]; + + uint8 feature_set[16]; + uint8 device_addr[6]; + + uint8 g_sys_sco_transmit_mode; //true tramsmit by uart, otherwise by share memory + uint8 g_sys_uart0_communication_supported; //true use uart0, otherwise use uart1 for debug + uint8 edr_tx_edr_delay; + uint8 edr_rx_edr_delay; + + uint16 g_wbs_nv_117; + + uint32 is_wdg_supported; + + uint32 share_memo_rx_base_addr; + + // uint32 share_memo_tx_base_addr; + uint16 g_wbs_nv_118; + uint16 g_nbv_nv_117; + + uint32 share_memo_tx_packet_num_addr; + uint32 share_memo_tx_data_base_addr; + + uint32 g_PrintLevel; + + uint16 share_memo_tx_block_length; + uint16 share_memo_rx_block_length; + uint16 share_memo_tx_water_mark; + + //uint16 share_memo_tx_timeout_value; + uint16 g_nbv_nv_118; + + uint16 uart_rx_watermark; + uint16 uart_flow_control_thld; + uint32 comp_id; + uint16 pcm_clk_divd; + + uint32 reserved[8]; +}BT_PSKEY_CONFIG_T; + + +#endif /* HCIATTACH_SPRD_H__ */ + + + + diff --git a/tools/pskey_get.c b/tools/pskey_get.c new file mode 100644 index 00000000..db4d2280 --- /dev/null +++ b/tools/pskey_get.c @@ -0,0 +1,384 @@ +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define LOG_TAG "pskey" +// #include "cutils/log.h" + +#include "hciattach_sprd.h" +//#include "bt_vendor_sprd.h" +#define BT_PSKEY_TRACE_BUF_SIZE 256 +#define MAX_BOARD_TYPE_LEN 32 + +#define _FILE_PARSE_DEBUG_ +#define CMD_ITEM_TABLE(ITEM, MEM_OFFSET, TYPE) { ITEM, (unsigned int)( &( ((BT_PSKEY_CONFIG_T *)(0))->MEM_OFFSET )), TYPE } +#define ALOGI(fmt, arg...) fprintf(stderr, "%s:%d()" fmt "\n", __FILE__,__LINE__, ## arg) +#define ALOGE(fmt, arg...) fprintf(stderr, "%s:%d()" fmt "\n", __FILE__,__LINE__, ## arg) + +#define PSKEY_PATH "/usr/lib/firmware/scx35_pikeavivaltove_3M_MARLIN_connectivity_configure.ini" + +typedef struct +{ + char item[64]; + uint32 par[32]; + int num; +}cmd_par; + +typedef struct +{ + char *item; + unsigned int mem_offset; + int type; +}cmd_par_table; + +static cmd_par_table g_pskey_table[] = +{ + CMD_ITEM_TABLE("pskey_cmd", pskey_cmd, 4), + + CMD_ITEM_TABLE("g_dbg_source_sink_syn_test_data", g_dbg_source_sink_syn_test_data, 1), + CMD_ITEM_TABLE("g_sys_sleep_in_standby_supported", g_sys_sleep_in_standby_supported, 1), + CMD_ITEM_TABLE("g_sys_sleep_master_supported", g_sys_sleep_master_supported, 1), + CMD_ITEM_TABLE("g_sys_sleep_slave_supported", g_sys_sleep_slave_supported, 1), + + CMD_ITEM_TABLE("default_ahb_clk", default_ahb_clk, 4), + CMD_ITEM_TABLE("device_class", device_class, 4), + CMD_ITEM_TABLE("win_ext", win_ext, 4), + + CMD_ITEM_TABLE("g_aGainValue", g_aGainValue, 4), + CMD_ITEM_TABLE("g_aPowerValue", g_aPowerValue, 4), + + CMD_ITEM_TABLE("feature_set", feature_set, 1), + CMD_ITEM_TABLE("device_addr", device_addr, 1), + + CMD_ITEM_TABLE("g_sys_sco_transmit_mode", g_sys_sco_transmit_mode, 1), //true tramsmit by uart, otherwise by share memory + CMD_ITEM_TABLE("g_sys_uart0_communication_supported", g_sys_uart0_communication_supported, 1), //true use uart0, otherwise use uart1 for debug + CMD_ITEM_TABLE("edr_tx_edr_delay", edr_tx_edr_delay, 1), + CMD_ITEM_TABLE("edr_rx_edr_delay", edr_rx_edr_delay, 1), + + CMD_ITEM_TABLE("g_wbs_nv_117", g_wbs_nv_117, 2), + + + CMD_ITEM_TABLE("is_wdg_supported", is_wdg_supported, 4), + + CMD_ITEM_TABLE("share_memo_rx_base_addr", share_memo_rx_base_addr, 4), + //CMD_ITEM_TABLE("share_memo_tx_base_addr", share_memo_tx_base_addr, 4), + + CMD_ITEM_TABLE("g_wbs_nv_118", g_wbs_nv_118, 2), + CMD_ITEM_TABLE("g_nbv_nv_117", g_nbv_nv_117, 2), + + + CMD_ITEM_TABLE("share_memo_tx_packet_num_addr", share_memo_tx_packet_num_addr, 4), + CMD_ITEM_TABLE("share_memo_tx_data_base_addr", share_memo_tx_data_base_addr, 4), + + CMD_ITEM_TABLE("g_PrintLevel", g_PrintLevel, 4), + + CMD_ITEM_TABLE("share_memo_tx_block_length", share_memo_tx_block_length, 2), + CMD_ITEM_TABLE("share_memo_rx_block_length", share_memo_rx_block_length, 2), + CMD_ITEM_TABLE("share_memo_tx_water_mark", share_memo_tx_water_mark, 2), + //CMD_ITEM_TABLE("share_memo_tx_timeout_value", share_memo_tx_timeout_value, 2), + CMD_ITEM_TABLE("g_nbv_nv_118", g_nbv_nv_118, 2), + + CMD_ITEM_TABLE("uart_rx_watermark", uart_rx_watermark, 2), + CMD_ITEM_TABLE("uart_flow_control_thld", uart_flow_control_thld, 2), + CMD_ITEM_TABLE("comp_id", comp_id, 4), + CMD_ITEM_TABLE("pcm_clk_divd", pcm_clk_divd, 2), + + + CMD_ITEM_TABLE("bt_reserved", reserved, 4) +}; + +static int bt_getFileSize(char *file) +{ + struct stat temp; + stat(file, &temp); + return temp.st_size; +} + +static int bt_find_type(char key) +{ + if( (key >= 'a' && key <= 'w') || (key >= 'y' && key <= 'z') || (key >= 'A' && key <= 'W') || (key >= 'Y' && key <= 'Z') || ('_' == key) ) + return 1; + if( (key >= '0' && key <= '9') || ('-' == key) ) + return 2; + if( ('x' == key) || ('X' == key) || ('.' == key) ) + return 3; + if( (key == '\0') || ('\r' == key) || ('\n' == key) || ('#' == key) ) + return 4; + return 0; +} + +static void bt_getCmdOneline(unsigned char *str, cmd_par *cmd) +{ + int i, j, bufType, cType, flag; + char tmp[BT_PSKEY_TRACE_BUF_SIZE]; + char c; + bufType = -1; + cType = 0; + flag = 0; + memset( cmd, 0, sizeof(cmd_par) ); + for(i = 0, j = 0; ; i++) + { + c = str[i]; + cType = bt_find_type(c); + if( (1 == cType) || ( 2 == cType) || (3 == cType) ) + { + tmp[j] = c; + j++; + if(-1 == bufType) + { + if(2 == cType) + bufType = 2; + else + bufType = 1; + } + else if(2 == bufType) + { + if(1 == cType) + bufType = 1; + } + continue; + } + if(-1 != bufType) + { + tmp[j] = '\0'; + + if((1 == bufType) && (0 == flag) ) + { + strcpy(cmd->item, tmp); + flag = 1; + } + else + { + /* compatible with HEX */ + if (tmp[0] == '0' && (tmp[1] == 'x' || tmp[1] == 'X')) { + cmd->par[cmd->num] = strtoul(tmp, 0, 16) & 0xFFFFFFFF; + cmd->num++; + } else { + cmd->par[cmd->num] = strtoul(tmp, 0, 10) & 0xFFFFFFFF; + cmd->num++; + } + } + bufType = -1; + j = 0; + } + if(0 == cType ) + continue; + if(4 == cType) + return; + } + return; +} + +static int bt_getDataFromCmd(cmd_par_table *pTable, cmd_par *cmd, void *pData) +{ + int i; + unsigned char *p; + if( (1 != pTable->type) && (2 != pTable->type) && (4 != pTable->type) ) + return -1; + p = (unsigned char *)(pData) + pTable->mem_offset; +#ifdef _FILE_PARSE_DEBUG_ + char tmp[BT_PSKEY_TRACE_BUF_SIZE] = {0}; + char string[16] = {0}; + sprintf(tmp, "###[pskey]%s, offset:%d, num:%d, value: ", pTable->item, pTable->mem_offset, cmd->num); + for(i=0; i<cmd->num; i++) + { + memset(string, 0, 16); + sprintf(string, "0x%x, ", cmd->par[i] ); + strcat(tmp, string); + } + ALOGI("%s\n", tmp); +#endif + for(i = 0; i < cmd->num; i++) + { + if(1 == pTable->type) + *((unsigned char *)p + i) = (unsigned char)(cmd->par[i]); + else if(2 == pTable->type) + *((unsigned short *)p + i) = (unsigned short)(cmd->par[i]); + else if(4 == pTable->type) + *( (unsigned int *)p + i) = (unsigned int)(cmd->par[i]); + else + ALOGE("%s, type err\n", __func__); + } + return 0; +} + +static cmd_par_table *bt_cmd_table_match(cmd_par *cmd) +{ + int i; + cmd_par_table *pTable = NULL; + int len = sizeof(g_pskey_table) / sizeof(cmd_par_table); + if(NULL == cmd->item) + return NULL; + for(i = 0; i < len; i++) + { + if(NULL == g_pskey_table[i].item) + continue; + if( 0 != strcmp( g_pskey_table[i].item, cmd->item ) ) + continue; + pTable = &g_pskey_table[i]; + break; + } + return pTable; +} + + +static int bt_getDataFromBuf(void *pData, unsigned char *pBuf, int file_len) +{ + int i, p; + cmd_par cmd; + cmd_par_table *pTable = NULL; + if((NULL == pBuf) || (0 == file_len) || (NULL == pData) ) + return -1; + for(i = 0, p = 0; i < file_len; i++) + { + if( ('\n' == *(pBuf + i)) || ( '\r' == *(pBuf + i)) || ( '\0' == *(pBuf + i) ) ) + { + if(5 <= (i - p) ) + { + bt_getCmdOneline((pBuf + p), &cmd); + pTable = bt_cmd_table_match(&cmd); + if(NULL != pTable) + { + bt_getDataFromCmd(pTable, &cmd, pData); + } + } + p = i + 1; + } + + } + return 0; +} + +static int bt_dumpPskey(BT_PSKEY_CONFIG_T *p) +{ + ALOGI("pskey_cmd: 0x%08X", p->pskey_cmd); + + ALOGI("g_dbg_source_sink_syn_test_data: 0x%02X", p->g_dbg_source_sink_syn_test_data); + ALOGI("g_sys_sleep_in_standby_supported: 0x%02X", p->g_sys_sleep_in_standby_supported); + ALOGI("g_sys_sleep_master_supported: 0x%02X", p->g_sys_sleep_master_supported); + ALOGI("g_sys_sleep_slave_supported: 0x%02X", p->g_sys_sleep_slave_supported); + + ALOGI("default_ahb_clk: %d", p->default_ahb_clk); + ALOGI("device_class: 0x%08X", p->device_class); + ALOGI("win_ext: 0x%08X", p->win_ext); + + ALOGI("g_aGainValue: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X", p->g_aGainValue[0], p->g_aGainValue[1], p->g_aGainValue[2], p->g_aGainValue[3], p->g_aGainValue[4], p->g_aGainValue[5]); + ALOGI("g_aPowerValue: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X", p->g_aPowerValue[0], p->g_aPowerValue[1], p->g_aPowerValue[2], p->g_aPowerValue[3], p->g_aPowerValue[4]); + + + ALOGI("feature_set(0~7): 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X", p->feature_set[0], p->feature_set[1], p->feature_set[2], + p->feature_set[3], p->feature_set[4], p->feature_set[5], p->feature_set[6], p->feature_set[7]); + ALOGI("feature_set(8~15): 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X", p->feature_set[8], p->feature_set[9], p->feature_set[10], + p->feature_set[11], p->feature_set[12], p->feature_set[13], p->feature_set[14], p->feature_set[15]); + ALOGI("device_addr: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X", p->device_addr[0], p->device_addr[1], p->device_addr[2], p->device_addr[3], p->device_addr[4], p->device_addr[5]); + + ALOGI("g_sys_sco_transmit_mode: 0x%02X", p->g_sys_sco_transmit_mode); + ALOGI("g_sys_uart0_communication_supported: 0x%02X", p->g_sys_uart0_communication_supported); + ALOGI("edr_tx_edr_delay: %d", p->edr_tx_edr_delay); + ALOGI("edr_rx_edr_delay: %d", p->edr_rx_edr_delay); + + ALOGI("g_wbs_nv_117 : 0x%04X", p->g_wbs_nv_117 ); + + ALOGI("is_wdg_supported: 0x%08X", p->is_wdg_supported); + + ALOGI("share_memo_rx_base_addr: 0x%08X", p->share_memo_rx_base_addr); + //ALOGI("share_memo_tx_base_addr: 0x%08X", p->share_memo_tx_base_addr); + ALOGI("g_wbs_nv_118 : 0x%04X", p->g_wbs_nv_118 ); + ALOGI("g_nbv_nv_117 : 0x%04X", p->g_nbv_nv_117 ); + + + ALOGI("share_memo_tx_packet_num_addr: 0x%08X", p->share_memo_tx_packet_num_addr); + ALOGI("share_memo_tx_data_base_addr: 0x%08X", p->share_memo_tx_data_base_addr); + + ALOGI("g_PrintLevel: 0x%08X", p->g_PrintLevel); + + ALOGI("share_memo_tx_block_length: 0x%04X", p->share_memo_tx_block_length); + ALOGI("share_memo_rx_block_length: 0x%04X", p->share_memo_rx_block_length); + ALOGI("share_memo_tx_water_mark: 0x%04X", p->share_memo_tx_water_mark); + //ALOGI("share_memo_tx_timeout_value: 0x%04X", p->share_memo_tx_timeout_value); + ALOGI("g_nbv_nv_118 : 0x%04X", p->g_nbv_nv_118 ); + + ALOGI("uart_rx_watermark: %d", p->uart_rx_watermark); + ALOGI("uart_flow_control_thld: %d", p->uart_flow_control_thld); + ALOGI("comp_id: 0x%08X", p->comp_id); + ALOGI("pcm_clk_divd : 0x%04X", p->pcm_clk_divd ); + + + ALOGI("reserved(0~7): 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X", p->reserved[0], p->reserved[1], p->reserved[2], + p->reserved[3], p->reserved[4], p->reserved[5], p->reserved[6], p->reserved[7]); + return 0; +} +#if 0 +static int bt_get_config_ver(unsigned char *pBuf, int len) +{ + int i, p; + cmd_par cmd; + int ret = -1; + for(i = 0, p = 0; i < len; i++) + { + if( ('\n' == *(pBuf + i)) || ( '\r' == *(pBuf + i)) || ( '\0' == *(pBuf + i) ) ) + { + if(5 <= (i - p) ) + { + bt_getCmdOneline((pBuf + p), &cmd); + if( 0 == strcmp(cmd.item, "version") ) + { + ret = cmd.par[0]; + break; + } + memset(&cmd, 0, sizeof(cmd_par) ); + } + p = i + 1; + } + + } + return ret; +} +#endif +int bt_getPskeyFromFile(void *pData) +{ + int ret = -1; + int fd; + unsigned char *pBuf = NULL; + int len; + + ALOGI("begin to bt_getPskeyFromFile"); + fd = open(PSKEY_PATH, O_RDONLY, 0644); + if(-1 != fd) + { + len = bt_getFileSize(PSKEY_PATH); + pBuf = (unsigned char *)malloc(len); + ret = read(fd, pBuf, len); + if(-1 == ret) + { + ALOGE("%s read %s ret:%d\n", __FUNCTION__, PSKEY_PATH, ret); + free(pBuf); + close(fd); + return -1; + } + close(fd); + } + else + { + ALOGE("%s open %s ret:%d\n", __FUNCTION__, PSKEY_PATH, fd); + return -1; + } + + ret = bt_getDataFromBuf(pData, pBuf, len); + if(-1 == ret) + { + free(pBuf); + return -1; + } + ALOGI("begin to dumpPskey"); + bt_dumpPskey((BT_PSKEY_CONFIG_T *)pData); + free(pBuf); + return 0; +} + + |