blob: 6229974202146ae5a5c5ce9311dbdd2129bbe68e [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <pthread.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <net/if_arp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ctype.h>
#define RELEASE_DATE "2024_0701"
//tool role
#define SERVER 0
#define CLIENT 1
#define CLIENT_DIRECT 2
#define WLAN_CLIENT 3
//interface
#define UART 0
#define USB 1
#define WLAN 2
//uart param
#define BAUDRATE 1500000
#define DATABITS 8
#define PARTY 'N'
#define STOP '1'
#define SOFTWARE_HANDSHAKE 0
#define HARDWARE_HANDSHAKE 1
//socket param
#define BT_HCI_TOOL_PORT 5001
#define SOCKER_BUFFER_SIZE 1024
#define OK 0
#define ERR -1
#define FALSE 0
#define TRUE 1
#define DOWN_FW_CFG _IOW('E', 176, int)
#define GET_USB_INFO _IOR('E', 180, int)
#define WLAN_CMD_MAX_CNT 256
#define TXRX_PARA SIOCDEVPRIVATE+1
#define ARG_IS(_str) (!strcmp(argv[command_counter], _str))
#define OS_STRCMP(str, _str) (!strcmp(str, _str))
int server_or_client = SERVER;
int interface = USB;
int bt_dev_fd = 0;
char s_baudrate[8];
char* s_hci_command[256];
uint8_t r_hci_command[256];
int r_hci_command_len;
char w_ifname[64];
char *w_command[WLAN_CMD_MAX_CNT];
char hci_event[256];
char dev_path[] = "/dev/aicbt_dev";
char hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 };
char set_filter[] = { 0x01, 0x05, 0x0c, 0x03, 0x02, 0x00, 0x02 };
char scan_on[] = { 0x01, 0x1a, 0x0c, 0x01, 0x03 };
char dut_en[] = { 0x01, 0x03, 0x18, 0x00 };
typedef struct android_wifi_priv_cmd {
char *buf;
int used_len;
int total_len;
} android_wifi_priv_cmd;
enum{
maxLth_DH1=27,
maxLth_DH3=138,
maxLth_DH5=339,
maxLth_2DH1=54,
maxLth_2DH3=367,
maxLth_2DH5=679,
maxLth_3DH1=83,
maxLth_3DH3=552,
maxLth_3DH5=1021,
};
enum{
_dh1,
_dh3,
_dh5,
_2dh1,
_2dh3,
_2dh5,
_3dh1,
_3dh3,
_3dh5,
};
typedef enum{
bt_start,
bt_stop,
ble_start,
ble_stop,
tx_tone,
tx_tonestop,
bt_reset,
dut,
dut_dis_scan,
get_txpwr,
set_txpwr,
set_pwrofst,
} cmd_t;
typedef enum {
tx,
rx,
} trx_mode_t;
struct bt_test_args_t{
trx_mode_t trx_mode;
cmd_t cmd;
int type;
int pattern;
int hopping;
int channel;
uint8_t is_edr;
int whitening;
int tx_pwr;
int len;
uint8_t addr[6];
int le_phy;
int mod_idx;
int8_t tx_pwrofst;
}bt_test_args={
.pattern = 0x00,
.whitening = 0x01,
.addr = { 0x0A, 0x1C, 0x6B, 0xC6, 0x96, 0x7E },
.le_phy = 0x01,
.tx_pwr = 0x7f,
.tx_pwrofst = 0,
};
#if 0
#define isblank(c) ((c) == ' ' || (c) == '\t')
#define isascii(c) (((unsigned char)(c)) <= 0x7F)
static int isdigit(unsigned char c)
{
return ((c >= '0') && (c <='9'));
}
static int isxdigit(unsigned char c)
{
if ((c >= '0') && (c <='9'))
return 1;
if ((c >= 'a') && (c <='f'))
return 1;
if ((c >= 'A') && (c <='F'))
return 1;
return 0;
}
static int islower(unsigned char c)
{
return ((c >= 'a') && (c <='z'));
}
static unsigned char toupper(unsigned char c)
{
if (islower(c))
c -= 'a'-'A';
return c;
}
#endif
void helper() {
printf(
"\tUsage:\n"
"\t\t-s <interface> <params>\n"
"\t\t\tSelect the tool service:\n"
"\t\t\t\tex. \"bt_test -s uart 1500000 /dev/ttyS0\" or \"bt_test -s usb\" or \"bt_test -s wlan wlan0\"\n"
"\t\t-c <hci_cmd> Send an HCI command to the selected interface\n"
"\t\t-v Display Release Date\n"
"\n"
"\tCommands:\n"
"\t\tbt_start [<trx> <chan> <pkt> ...] = Start Bluetooth tx test\n"
"\t\t\t<trx> (man) = tx | rx\n"
"\t\t\t<chan> (man) = 0 ~ 78 (hopen=off) | 255 (hopen=on)\n"
"\t\t\t<pkt> (man) = dh1 | dh3 | dh5 | 2dh1 | 2dh3 | 2dh5 | 3dh1 | 3dh3 | 3dh5\n"
"\t\t\t<pattern> (opt) = pn9 (default) | pn15 | h00 | hff | hf0 | h0f | haa | h55\n"
"\t\t\t<len> (opt) = dec value (default: pkt's max length)\n"
"\t\t\t<whiten> (opt) = on | off (default)\n"
"\t\t\t<addr> (opt) = 0a 1c 6b c6 96 7e (default)\n"
"\t\tbt_stop [<trx>] = Stop Bluetooth tx test\n"
"\t\t\t<trx> (man) = tx | rx\n"
"\t\tble_start [<trx> <chan> <pkt> ...] = Start BLE tx test\n"
"\t\t\t<trx> (man) = tx | rx\n"
"\t\t\t<chan> (man) = 0 ~ 39 (hopen=off) | 255 (hopen=on)\n"
"\t\t\t<pkt> (man) = 1m | 2m | s2 | s8\n"
"\t\t\t<pattern> (opt) = pn9 (default) | pn15 | h00 | hff | hf0 | h0f | haa | h55\n"
"\t\t\t<len> (opt) = dec value (default: 255)\n"
"\t\tble_stop [<trx>] = Stop BLE tx test\n"
"\t\t\t<trx> (man) = tx | rx\n"
"\t\ttx_tone [<chan> ...] = Start a Single-Carrier Bluetooth test\n"
"\t\t\t<chan> (man) = 0 ~ 78\n"
"\t\t\t<pwr> (opt) = 0 ~ 7 (default: 0x07)\n"
"\t\ttx_tonestop = Stop Bluetooth Single-Carrier Test\n"
"\t\tget_txpwr = Get tx power\n"
"\t\tset_txpwr [<pwr>] = Set tx power\n"
"\t\t\t<pwr> (man) = 0 ~ 0x6f (default: 0x6f)\n"
"\t\tbt_reset = reset BT\n"
"\t\tbt_dut <1/0> = bt_dut /bt_dut 1 (dut en & scan on) | bt_dut 0 (scan off)\n"
"\t\tset_pwrofst [<pwrofst>]= Set bt tx power offset\n"
"\t\t\t<pwrofst> (man) = -7 ~ 7\n"
);
}
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base)
{
unsigned int result = 0, value, is_neg = 0;
if (*cp == '0') {
cp++;
if ((*cp == 'x') && isxdigit(cp[1])) {
base = 16;
cp++;
}
if (!base) {
base = 8;
}
}
if (!base) {
base = 10;
}
if (*cp == '-') {
is_neg = 1;
cp++;
}
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' : (islower(*cp) ? toupper(*cp) : *cp) - 'A' + 10) < base) {
result = result * base + value;
cp++;
}
if (is_neg)
result = (unsigned int)((int)result * (-1));
if (endp)
*endp = (char *)cp;
return result;
}
int parse_cmd_line(int argc, char **argv){
int command_number = argc;
int command_counter = 1;
int hci_command_counter = 0;
//int error_command = 0;
int channel = 0;
//int len = 0 ;
while(command_counter < command_number){
if(!strcmp(argv[command_counter], "-s")){
if(!(command_number >= 3)){
printf("error command \r\n");
return ERR;
}
printf("bt_hci_tool server setting\r\n");
server_or_client = SERVER;
command_counter++;
if(!strcmp(argv[command_counter], "usb")){
printf("use USB\r\n");
interface = USB;
return OK;
}else if(!strcmp(argv[command_counter], "uart")){
interface = UART;
if(command_number != 5){
printf("error command \r\n");
return ERR;
}
command_counter++;
memcpy(s_baudrate, argv[command_counter], strlen(argv[command_counter]));
command_counter++;
memset(dev_path, 0, strlen(dev_path));
memcpy(dev_path, argv[command_counter], strlen(argv[command_counter]));
printf("use UART %d %s\r\n", atoi(s_baudrate), dev_path);
return OK;
}else if(!strcmp(argv[command_counter], "wlan")){
interface = WLAN;
if(command_number != 4){
printf("error command \r\n");
return ERR;
}
command_counter++;
memcpy(w_ifname, argv[command_counter], strlen(argv[command_counter]));
printf("use WLAN %s\r\n", w_ifname);
return OK;
}else{
printf("interface set error\r\n");
return ERR;
}
}else if(!strcmp(argv[command_counter], "-c")){
server_or_client = CLIENT;
command_counter++;
hci_command_counter = 0;
while(command_counter < command_number){
s_hci_command[hci_command_counter++] = argv[command_counter];
command_counter++;
}
return OK;
} else if (!strcmp(argv[command_counter], "-w")) {
int w_command_counter = 0;
server_or_client = WLAN_CLIENT;
if (command_number >= WLAN_CMD_MAX_CNT) {
printf("too much args\r\n");
return ERR;
}
command_counter++;
while (command_counter < command_number) {
w_command[w_command_counter++] = argv[command_counter];
command_counter++;
}
return OK;
}else if (ARG_IS("-m")){
// reserved for a variety of chip models
} else if (ARG_IS("bt_start")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = bt_start;
if (command_number < 5) {
printf("wrong args\r\n");
return ERR;
}
//parse trx
if (OS_STRCMP(argv[2], "tx")) {
bt_test_args.trx_mode = tx;
} else if (OS_STRCMP(argv[2], "rx")) {
bt_test_args.trx_mode = rx;
} else {
printf("no find tx or rx\r\n");
return ERR;
}
//parse chan and hopping
channel = command_strtoul(argv[3], NULL, 10);
if (channel < 0 || (channel > 78 && channel != 255)) {
printf("wrong channel\r\n");
return ERR;
} else {
bt_test_args.channel = channel;
if (channel == 255)
bt_test_args.hopping = TRUE;
else
bt_test_args.hopping = FALSE;
}
//parse type
if (OS_STRCMP(argv[4], "dh1")){
bt_test_args.type = _dh1;
bt_test_args.len = maxLth_DH1;
bt_test_args.is_edr = FALSE;
} else if (OS_STRCMP(argv[4], "dh3")){
bt_test_args.type = _dh3;
bt_test_args.len = maxLth_DH3;
bt_test_args.is_edr = FALSE;
} else if (OS_STRCMP(argv[4], "dh5")){
bt_test_args.type = _dh5;
bt_test_args.len = maxLth_DH5;
bt_test_args.is_edr = FALSE;
} else if (OS_STRCMP(argv[4], "2dh1")){
bt_test_args.type = _2dh1;
bt_test_args.len = maxLth_2DH1;
bt_test_args.is_edr = TRUE;
} else if (OS_STRCMP(argv[4], "2dh3")){
bt_test_args.type = _2dh3;
bt_test_args.len = maxLth_2DH3;
bt_test_args.is_edr = TRUE;
} else if (OS_STRCMP(argv[4], "2dh5")){
bt_test_args.type = _2dh5;
bt_test_args.len = maxLth_2DH5;
bt_test_args.is_edr = TRUE;
} else if (OS_STRCMP(argv[4], "3dh1")){
bt_test_args.type = _3dh1;
bt_test_args.len = maxLth_3DH1;
bt_test_args.is_edr = TRUE;
} else if (OS_STRCMP(argv[4], "3dh3")){
bt_test_args.type = _3dh3;
bt_test_args.len = maxLth_3DH3;
bt_test_args.is_edr = TRUE;
} else if (OS_STRCMP(argv[4], "3dh5")){
bt_test_args.type = _3dh5;
bt_test_args.len = maxLth_3DH5;
bt_test_args.is_edr = TRUE;
} else {
printf("wrong type\r\n");
return ERR;
}
//parse pattern
if (command_number > 5) {
if (OS_STRCMP(argv[5], "pn9")){
bt_test_args.pattern = 0x00;
} else if (OS_STRCMP(argv[5], "hf0")){
bt_test_args.pattern = 0x01;
} else if (OS_STRCMP(argv[5], "haa")){
bt_test_args.pattern = 0x02;
} else if (OS_STRCMP(argv[5], "pn15")){
bt_test_args.pattern = 0x03;
} else if (OS_STRCMP(argv[5], "hff")){
bt_test_args.pattern = 0x04;
} else if (OS_STRCMP(argv[5], "h00")){
bt_test_args.pattern = 0x05;
} else if (OS_STRCMP(argv[5], "h0f")){
bt_test_args.pattern = 0x06;
} else if (OS_STRCMP(argv[5], "h55")){
bt_test_args.pattern = 0x07;
} else {
printf("wrong pattern type\r\n");
return ERR;
}
//parse pkt len
if (command_number > 6) {
bt_test_args.len = command_strtoul(argv[6], NULL, 10);
}
}
//parse whitening
if (command_number > 7) {
if (OS_STRCMP(argv[7], "on")){
bt_test_args.whitening = 0x00;
} else if (OS_STRCMP(argv[7], "off")){
bt_test_args.whitening = 0x01;
} else {
printf("wrong whitening args, use on/off\r\n");
return ERR;
}
}
//parse mac addr
if (command_number > 8) {
if (command_number < 14) {
printf("wrong mac addr eg: 0a 1c 6b c6 96 7e\r\n");
return ERR;
}
bt_test_args.addr[5] = command_strtoul(argv[8], NULL, 16);
bt_test_args.addr[4] = command_strtoul(argv[9], NULL, 16);
bt_test_args.addr[3] = command_strtoul(argv[10], NULL, 16);
bt_test_args.addr[2] = command_strtoul(argv[11], NULL, 16);
bt_test_args.addr[1] = command_strtoul(argv[12], NULL, 16);
bt_test_args.addr[0] = command_strtoul(argv[13], NULL, 16);
}
return OK;
} else if (ARG_IS("bt_stop")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = bt_stop;
if (command_number < 3) {
printf("wrong args\r\n");
return ERR;
}
//parse trx
if (OS_STRCMP(argv[2], "tx")) {
bt_test_args.trx_mode = tx;
} else if (OS_STRCMP(argv[2], "rx")) {
bt_test_args.trx_mode = rx;
} else {
printf("no find tx or rx\r\n");
return ERR;
}
return OK;
} else if (ARG_IS("ble_start")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = ble_start;
if (command_number < 5) {
printf("wrong args\r\n");
return ERR;
}
//parse trx
if (OS_STRCMP(argv[2], "tx")) {
bt_test_args.trx_mode = tx;
} else if (OS_STRCMP(argv[2], "rx")) {
bt_test_args.trx_mode = rx;
bt_test_args.mod_idx = 0;//modulation index fix to 0
} else {
printf("no find tx or rx\r\n");
return ERR;
}
//parse chan and hopping
channel = command_strtoul(argv[3], NULL, 10);
if (channel < 0 || (channel > 39 && channel != 255)) {
printf("wrong channel\r\n");
return ERR;
} else {
bt_test_args.channel = channel;
if (channel == 255)
bt_test_args.hopping = TRUE;
else
bt_test_args.hopping = FALSE;
}
//parse le phy
if (OS_STRCMP(argv[4], "1m")){
bt_test_args.le_phy = 0x01;
} else if (OS_STRCMP(argv[4], "2m")){
bt_test_args.le_phy = 0x02;
} else if (OS_STRCMP(argv[4], "s8")){
bt_test_args.le_phy = 0x03;
} else if (OS_STRCMP(argv[4], "s2")){
bt_test_args.le_phy = 0x04;
} else {
printf("wrong type\r\n");
return ERR;
}
//parse pattern
if (command_number > 5) {
if (OS_STRCMP(argv[5], "pn9")){
bt_test_args.pattern = 0x00;
} else if (OS_STRCMP(argv[5], "hf0")){
bt_test_args.pattern = 0x01;
} else if (OS_STRCMP(argv[5], "haa")){
bt_test_args.pattern = 0x02;
} else if (OS_STRCMP(argv[5], "pn15")){
bt_test_args.pattern = 0x03;
} else if (OS_STRCMP(argv[5], "hff")){
bt_test_args.pattern = 0x04;
} else if (OS_STRCMP(argv[5], "h00")){
bt_test_args.pattern = 0x05;
} else if (OS_STRCMP(argv[5], "h0f")){
bt_test_args.pattern = 0x06;
} else if (OS_STRCMP(argv[5], "h55")){
bt_test_args.pattern = 0x07;
} else {
printf("wrong pattern type\r\n");
return ERR;
}
}
//parse pkt len
bt_test_args.len = 255;
if (command_number > 6) {
bt_test_args.len = command_strtoul(argv[6], NULL, 10);
if (bt_test_args.len < 1 || bt_test_args.len > 255) {
printf("len limit 1~255 (default: 255)\r\n");
}
}
return OK;
} else if (ARG_IS("ble_stop")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = ble_stop;
if (command_number < 3) {
printf("wrong args\r\n");
return ERR;
}
//parse trx
if (OS_STRCMP(argv[2], "tx")) {
bt_test_args.trx_mode = tx;
} else if (OS_STRCMP(argv[2], "rx")) {
bt_test_args.trx_mode = rx;
} else {
printf("no find tx or rx\r\n");
return ERR;
}
return OK;
} else if (ARG_IS("tx_tone")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = tx_tone;
if (command_number < 3) {
printf("wrong args\r\n");
return ERR;
}
//parse chan
channel = command_strtoul(argv[2], NULL, 10);
if (channel < 0 || (channel > 78)) {
printf("wrong channel\r\n");
return ERR;
} else {
bt_test_args.channel = channel;
}
//parse tx pwr
bt_test_args.tx_pwr = 7;
if (command_number > 3) {
bt_test_args.tx_pwr = command_strtoul(argv[3], NULL, 16);
if (bt_test_args.tx_pwr < 0 || bt_test_args.tx_pwr > 7) {
printf("pwr limit 0~7 (default: 07)\r\n");
bt_test_args.tx_pwr = 7;
}
}
return OK;
} else if (ARG_IS("tx_tonestop")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = tx_tonestop;
return OK;
} else if (ARG_IS("bt_reset")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = bt_reset;
return OK;
} else if (ARG_IS("bt_dut")){
server_or_client = CLIENT_DIRECT;
if (command_number > 2 && !(command_strtoul(argv[2], NULL, 10)))
bt_test_args.cmd = dut_dis_scan;
else
bt_test_args.cmd = dut;
return OK;
} else if (ARG_IS("get_txpwr")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = get_txpwr;
return OK;
} else if (ARG_IS("set_txpwr")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = set_txpwr;
if (command_number < 2) {
printf("wrong args\r\n");
return ERR;
}
//parse tx pwr
bt_test_args.tx_pwr = 0x6f;
if (command_number > 2) {
bt_test_args.tx_pwr = command_strtoul(argv[2], NULL, 16);
if (bt_test_args.tx_pwr < 0 || bt_test_args.tx_pwr > 0x6f) {
printf("pwr limit 0~0x6f (default: 0x6f)\r\n");
bt_test_args.tx_pwr = 0x6f;
}
}
return OK;
} else if (ARG_IS("set_pwrofst")){
server_or_client = CLIENT_DIRECT;
bt_test_args.cmd = set_pwrofst;
if (command_number < 2) {
printf("wrong args\r\n");
return ERR;
}
//parse tx pwrofst
bt_test_args.tx_pwrofst = 0x0;
if (command_number > 2) {
bt_test_args.tx_pwrofst = command_strtoul(argv[2], NULL, 10);
printf("txpwrofst %d\n", bt_test_args.tx_pwrofst);
if (bt_test_args.tx_pwrofst < -7 || bt_test_args.tx_pwrofst > 7) {
printf("pwrofst limit -7 ~ 7\r\n");
if (bt_test_args.tx_pwrofst > 7) {
bt_test_args.tx_pwrofst = 7;
} else if (bt_test_args.tx_pwrofst < -7) {
bt_test_args.tx_pwrofst = -7;
}
}
}
return OK;
} else if (ARG_IS("-v")){
printf("bt_test %s\n", RELEASE_DATE);
return ERR;
} else {
if (strcmp(argv[1], "-h") != 0) {
printf("unknow command %s \r\n", argv[command_counter]);
}
helper();
return ERR;
}
command_counter++;
}
helper();
return ERR;
}
void uart_set_options(int baudrate, int databits,
char parity, char stop, int softwareHandshake, int hardwareHandshake)
{
struct termios newtio;
if (tcgetattr(bt_dev_fd, &newtio)!=0)
{
printf("tcgetattr() 3 failed \n");
}
speed_t _baud=0;
printf("set baudrate:%d\n", baudrate);
switch (baudrate)
{
#ifdef B0
case 0: _baud=B0; break;
#endif
#ifdef B50
case 50: _baud=B50; break;
#endif
#ifdef B75
case 75: _baud=B75; break;
#endif
#ifdef B110
case 110: _baud=B110; break;
#endif
#ifdef B134
case 134: _baud=B134; break;
#endif
#ifdef B150
case 150: _baud=B150; break;
#endif
#ifdef B200
case 200: _baud=B200; break;
#endif
#ifdef B300
case 300: _baud=B300; break;
#endif
#ifdef B600
case 600: _baud=B600; break;
#endif
#ifdef B1200
case 1200: _baud=B1200; break;
#endif
#ifdef B1800
case 1800: _baud=B1800; break;
#endif
#ifdef B2400
case 2400: _baud=B2400; break;
#endif
#ifdef B4800
case 4800: _baud=B4800; break;
#endif
#ifdef B7200
case 7200: _baud=B7200; break;
#endif
#ifdef B9600
case 9600: _baud=B9600; break;
#endif
#ifdef B14400
case 14400: _baud=B14400; break;
#endif
#ifdef B19200
case 19200: _baud=B19200; break;
#endif
#ifdef B28800
case 28800: _baud=B28800; break;
#endif
#ifdef B38400
case 38400: _baud=B38400; break;
#endif
#ifdef B57600
case 57600: _baud=B57600; break;
#endif
#ifdef B76800
case 76800: _baud=B76800; break;
#endif
#ifdef B115200
case 115200: _baud=B115200; break;
#endif
#ifdef B128000
case 128000: _baud=B128000; break;
#endif
#ifdef B230400
case 230400: _baud=B230400; break;
#endif
#ifdef B460800
case 460800: _baud=B460800; break;
#endif
#ifdef B576000
case 576000: _baud=B576000; break;
#endif
#ifdef B921600
case 921600: _baud=B921600; break;
#endif
#ifdef B1500000
case 1500000: _baud=B1500000; break;
#endif
#ifdef B2000000
case 2000000: _baud=B2000000; break;
#endif
default:
break;
}
cfsetospeed(&newtio, (speed_t)_baud);
cfsetispeed(&newtio, (speed_t)_baud);
/* We generate mark and space parity ourself. */
if (databits == 7 && (parity=='M' || parity == 'S'))
{
databits = 8;
}
switch (databits)
{
case 5:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS5;
break;
case 6:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS6;
break;
case 7:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS7;
break;
case 8:
default:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
break;
}
newtio.c_cflag |= CLOCAL | CREAD;
//parity
newtio.c_cflag &= ~(PARENB | PARODD);
if (parity == 'E')
{
newtio.c_cflag |= PARENB;
}
else if (parity== 'O')
{
newtio.c_cflag |= (PARENB | PARODD);
}
//hardware handshake
newtio.c_cflag &= ~CRTSCTS;
//stopbits
if (stop=='2')
{
newtio.c_cflag |= CSTOPB;
}
else
{
newtio.c_cflag &= ~CSTOPB;
}
newtio.c_iflag=IGNBRK;
//software handshake
if (softwareHandshake)
{
newtio.c_iflag |= IXON | IXOFF;
}
else
{
newtio.c_iflag &= ~(IXON|IXOFF|IXANY);
}
newtio.c_lflag=0;
newtio.c_oflag=0;
// newtio.c_cc[VTIME]=1;
// newtio.c_cc[VMIN]=60;
if (tcsetattr(bt_dev_fd, TCSANOW, &newtio)!=0)
{
printf("tcsetattr() 1 failed \n");
}
if (tcgetattr(bt_dev_fd, &newtio)!=0)
{
printf("tcsetattr() 4 failed \n");
}
//hardware handshake
if (hardwareHandshake)
{
newtio.c_cflag |= CRTSCTS;
}
else
{
newtio.c_cflag &= ~CRTSCTS;
}
if (tcsetattr(bt_dev_fd, TCSANOW, &newtio)!=0)
{
printf("tcsetattr() 2 failed \n");
}
}
unsigned char atoh(char* s_data){
unsigned char ret_value;
char temp_value = 0;
//h
if(s_data[0] >= 48 && s_data[0] <= 57){
temp_value = s_data[0] - 48;
}else if(s_data[0] >= 65 && s_data[0] <= 70){
temp_value = (s_data[0] - 65) + 10;
}else if(s_data[0] >= 97 && s_data[0] <= 102){
temp_value = (s_data[0] - 97) + 10;
}
ret_value = temp_value;
ret_value = ret_value << 4;
//printf("atoh1: ret_value:%x\r\n", ret_value);
//l
if(s_data[1] >= 48 && s_data[1] <= 57){
temp_value = s_data[1] - 48;
}else if(s_data[1] >= 65 && s_data[1] <= 70){
temp_value = (s_data[1] - 65) + 10;
}else if(s_data[1] >= 97 && s_data[1] <= 102){
temp_value = (s_data[1] - 97) + 10;
}
ret_value |= temp_value;
//printf("atoh2: ret_value:%x\r\n", ret_value);
return ret_value;
}
int send_to_server(unsigned char* buffer, int len){
int client_socket;
struct sockaddr_in serverAddr;
//unsigned long long package_totel_counter = 0;
if((client_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0){
return ERR;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(BT_HCI_TOOL_PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(client_socket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){
return ERR;
}
send(client_socket, buffer, len, 0);
return OK;
}
void send_hci_command(){
int i = 0;
int command_len = 0;
unsigned char buffer[SOCKER_BUFFER_SIZE];
// printf("send hci command: \r\n");
for(i = 0;i < 256; i++){
if(s_hci_command[i] == NULL){
command_len = i;
break;
}
buffer[i] = atoh(s_hci_command[i]);
// printf("%02X ", buffer[i]);
}
send_to_server(buffer, i);
// printf("\r\n");
}
void send_raw_hci_command(){
if (bt_test_args.cmd == bt_stop && bt_test_args.trx_mode == tx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x0C;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == bt_stop && bt_test_args.trx_mode == rx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x0C;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x01;
} else if ((bt_test_args.cmd == ble_stop && bt_test_args.trx_mode == tx)
|| bt_test_args.cmd == bt_reset){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x03;
r_hci_command[r_hci_command_len++] = 0x0C;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == ble_stop && bt_test_args.trx_mode == rx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x1F;
r_hci_command[r_hci_command_len++] = 0x20;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == tx_tonestop){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x0C;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x02;
} else if (bt_test_args.cmd == bt_start){
if (bt_test_args.trx_mode == tx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x06;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x0E;
} else {
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x0B;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x0D;
}
switch (bt_test_args.type){
case _dh1:
r_hci_command[r_hci_command_len++] = 0x04;
break;
case _dh3:
r_hci_command[r_hci_command_len++] = 0x0B;
break;
case _dh5:
r_hci_command[r_hci_command_len++] = 0x0F;
break;
case _2dh1:
r_hci_command[r_hci_command_len++] = 0x04;
break;
case _2dh3:
r_hci_command[r_hci_command_len++] = 0x0A;
break;
case _2dh5:
r_hci_command[r_hci_command_len++] = 0x0E;
break;
case _3dh1:
r_hci_command[r_hci_command_len++] = 0x08;
break;
case _3dh3:
r_hci_command[r_hci_command_len++] = 0x0B;
break;
case _3dh5:
r_hci_command[r_hci_command_len++] = 0x0F;
break;
default:
break;
}
r_hci_command[r_hci_command_len++] = bt_test_args.pattern;
if (bt_test_args.trx_mode == tx){
r_hci_command[r_hci_command_len++] = bt_test_args.hopping;
}
r_hci_command[r_hci_command_len++] = bt_test_args.channel;
r_hci_command[r_hci_command_len++] = bt_test_args.is_edr;
if (bt_test_args.trx_mode == tx){
r_hci_command[r_hci_command_len++] = bt_test_args.whitening;
r_hci_command[r_hci_command_len++] = (bt_test_args.len & 0xFF);
r_hci_command[r_hci_command_len++] = ((bt_test_args.len >> 8) & 0xFF);
r_hci_command[r_hci_command_len++] = bt_test_args.addr[5];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[4];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[3];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[2];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[1];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[0];
} else {
r_hci_command[r_hci_command_len++] = (bt_test_args.len & 0xFF);
r_hci_command[r_hci_command_len++] = ((bt_test_args.len >> 8) & 0xFF);
r_hci_command[r_hci_command_len++] = bt_test_args.whitening;
r_hci_command[r_hci_command_len++] = bt_test_args.addr[5];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[4];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[3];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[2];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[1];
r_hci_command[r_hci_command_len++] = bt_test_args.addr[0];
}
}else if (bt_test_args.cmd == ble_start && bt_test_args.trx_mode == tx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x34;
r_hci_command[r_hci_command_len++] = 0x20;
r_hci_command[r_hci_command_len++] = 0x04;
r_hci_command[r_hci_command_len++] = bt_test_args.channel;
r_hci_command[r_hci_command_len++] = (bt_test_args.len & 0xFF);
r_hci_command[r_hci_command_len++] = bt_test_args.pattern;
r_hci_command[r_hci_command_len++] = bt_test_args.le_phy;
} else if (bt_test_args.cmd == ble_start && bt_test_args.trx_mode == rx){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x33;
r_hci_command[r_hci_command_len++] = 0x20;
r_hci_command[r_hci_command_len++] = 0x03;
r_hci_command[r_hci_command_len++] = bt_test_args.channel;
r_hci_command[r_hci_command_len++] = bt_test_args.le_phy;
r_hci_command[r_hci_command_len++] = bt_test_args.mod_idx;
} else if (bt_test_args.cmd == tx_tone){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x0D;
r_hci_command[r_hci_command_len++] = 0x18;
r_hci_command[r_hci_command_len++] = 0x06;
r_hci_command[r_hci_command_len++] = bt_test_args.channel;
r_hci_command[r_hci_command_len++] = (bt_test_args.tx_pwr & 0x0F);;
r_hci_command[r_hci_command_len++] = 0x00;
r_hci_command[r_hci_command_len++] = 0x00;
r_hci_command[r_hci_command_len++] = 0x00;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == dut_dis_scan){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x1A;
r_hci_command[r_hci_command_len++] = 0x0C;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == get_txpwr){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x67;
r_hci_command[r_hci_command_len++] = 0xFC;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == set_txpwr){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x65;
r_hci_command[r_hci_command_len++] = 0xFC;
r_hci_command[r_hci_command_len++] = 0x02;
r_hci_command[r_hci_command_len++] = bt_test_args.tx_pwr;
r_hci_command[r_hci_command_len++] = 0x00;
} else if (bt_test_args.cmd == set_pwrofst){
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = 0x72;
r_hci_command[r_hci_command_len++] = 0xFC;
r_hci_command[r_hci_command_len++] = 0x24;
r_hci_command[r_hci_command_len++] = 0x27;
r_hci_command[r_hci_command_len++] = 0x00;
r_hci_command[r_hci_command_len++] = 0x02;
r_hci_command[r_hci_command_len++] = 0x00;
r_hci_command[r_hci_command_len++] = 0x01;
r_hci_command[r_hci_command_len++] = (uint8_t)bt_test_args.tx_pwrofst;
r_hci_command_len = 0x24 + 4;//payload len + hdr len
}
send_to_server(r_hci_command, r_hci_command_len);
}
void send_wlan_command(void)
{
int i = 0;
int command_len = 0;
unsigned char buffer[SOCKER_BUFFER_SIZE] = {0,};
while ((w_command[i] != NULL) && (i < WLAN_CMD_MAX_CNT)) {
strcat((char*)&buffer[0], w_command[i]);
strcat((char*)&buffer[0], " ");
i++;
}
command_len = strlen((char*)&buffer[0]);
printf("command_len:%d \r\n", command_len);
if (command_len > 1) {
//command_len--; // rm last space
//buffer[command_len] = '\0';
send_to_server(buffer, command_len);
}
}
int hci_send(char* data, int len){
int i = 0;
unsigned char tmp_data[len];
printf("COMMAND(%d): \r\n", len);
for(i = 0; i < len; i++){
tmp_data[i] = (unsigned char)data[i];
printf("%02X ", tmp_data[i]);
}
printf("\r\n");
len = write(bt_dev_fd, tmp_data, len);
if (len < 0) {
printf("write data error \n");
return FALSE;
}
return TRUE;
}
int hci_recv(char* data, int len){
int i = 0;
unsigned char tmp_byte[64];// = 0x00;
memset(data, 0, len);
len = read(bt_dev_fd, data, len);
if (len < 0) {
printf("read error \n");
return FALSE;
}
printf("EVENT(%d): \r\n", len);
for(i = 0; i < len; i++){
tmp_byte[i] = (unsigned char)data[i];
printf("%02X ", tmp_byte[i]);
}
printf("\r\n");
if(tmp_byte[1] == 0x0D) { //bt rx
uint32_t rx_pkt_len = tmp_byte[4] | (tmp_byte[5] << 8) | (tmp_byte[6] << 16) | (tmp_byte[7] << 24);
uint32_t sync_ok = tmp_byte[8] | (tmp_byte[9] << 8) | (tmp_byte[10] << 16) | (tmp_byte[11] << 24);
uint32_t pkt_rx_ok = tmp_byte[12] | (tmp_byte[13] << 8) | (tmp_byte[14] << 16) | (tmp_byte[15] << 24);
uint32_t rx_err_pkts = tmp_byte[16] | (tmp_byte[17] << 8) | (tmp_byte[18] << 16) | (tmp_byte[19] << 24);
uint32_t bit_err = tmp_byte[20] | (tmp_byte[21] << 8) | (tmp_byte[22] << 16) | (tmp_byte[23] << 24);
uint32_t bit_cnt = sync_ok * rx_pkt_len * 8;
float per = (float) 100 * rx_err_pkts / sync_ok;
float ber = (float) 100 * bit_err / bit_cnt;
printf("bt_rx_result: rx_ok = %d, per = %.2f%%, ber = %.3f%%\n", pkt_rx_ok, per, ber);
}
if(tmp_byte[4] == 0x1F && tmp_byte[5] == 0x20) { //ble rx
uint32_t pkt_rx_ok = (tmp_byte[8] << 8) | tmp_byte[7];
printf("ble_rx_result: rx_ok = %d\n", pkt_rx_ok);
}
if(tmp_byte[1] == 0x0E && tmp_byte[4] == 0x67) { //get txpwr
int8_t pwr_in_dbm = tmp_byte[7];
uint8_t pwr_lvl = tmp_byte[8];
printf("tx pwr: pwr_in_dbm = %d dBm, pwr_lvl = 0x%x\n", pwr_in_dbm, pwr_lvl);
}
return len;
}
int wlan_send(char *data, int len)
{
int sock;
struct ifreq ifr;
int ret = 0;
int i = 0;
char wl_cmd[64];
struct android_wifi_priv_cmd priv_cmd;
char is_param_err = 0;
int buf_len = 0;
int argC = 0;
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("bad sock!\n");
return ERR;
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, w_ifname);
if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
printf("%s Could not read interface %s flags: %s",__func__, w_ifname, strerror(errno));
return ERR;
}
if (!(ifr.ifr_flags & IFF_UP)) {
printf("%s is not up!\n",w_ifname);
return ERR;
}
printf("ifr.ifr_name = %s\n", ifr.ifr_name);
memset(&priv_cmd, 0, sizeof(priv_cmd));
memset(wl_cmd, 0, sizeof(wl_cmd));
// extract wlan command & argC
for (i = 0; i < len; i++) {
if (data[i] != ' ') {
if (argC == 0) {
wl_cmd[i] = data[i];
}
} else {
argC++;
}
}
printf("wl_cmd=%s, argC=%d\r\n", wl_cmd, argC);
priv_cmd.buf = data;
priv_cmd.used_len = len;
priv_cmd.total_len = SOCKER_BUFFER_SIZE;
ifr.ifr_data = (void*)&priv_cmd;
if ((strcasecmp(wl_cmd, "BT_RESET") == 0)) {
char bt_reset_hci_cmd[32] = "01 03 0c 00";
if (argC == 1) {
buf_len = priv_cmd.used_len;
memcpy(&priv_cmd.buf[buf_len], &bt_reset_hci_cmd[0], strlen(bt_reset_hci_cmd));
buf_len += strlen(bt_reset_hci_cmd);
priv_cmd.used_len = buf_len;
} else {
is_param_err = 1;
}
} else if ((strcasecmp(wl_cmd, "BT_TXDH") == 0)) {
char bt_txdh_hci_cmd[255] = "01 06 18 0e ";
if (argC == 15) {
buf_len = priv_cmd.used_len;
int arg_len = strlen("BT_TXDH");
int txdh_cmd_len = strlen(bt_txdh_hci_cmd);
memcpy(&bt_txdh_hci_cmd[txdh_cmd_len], &priv_cmd.buf[arg_len+1], buf_len - arg_len - 1);
memcpy(&priv_cmd.buf[arg_len+1], &bt_txdh_hci_cmd[0], strlen(bt_txdh_hci_cmd));
buf_len += strlen(bt_txdh_hci_cmd);
priv_cmd.used_len = buf_len;
} else {
is_param_err = 1;
}
} else if ((strcasecmp(wl_cmd, "BT_RXDH") == 0)) {
if (argC == 14) {
char bt_rxdh_hci_cmd[255] = "01 0b 18 0d ";
buf_len = priv_cmd.used_len;
int arg_len = strlen("BT_RXDH");
int rxdh_cmd_len = strlen(bt_rxdh_hci_cmd);
memcpy(&bt_rxdh_hci_cmd[rxdh_cmd_len], &priv_cmd.buf[arg_len+1], buf_len - arg_len - 1);
memcpy(&priv_cmd.buf[arg_len+1], &bt_rxdh_hci_cmd[0], strlen(bt_rxdh_hci_cmd));
buf_len += strlen(bt_rxdh_hci_cmd);
priv_cmd.used_len = buf_len;
} else {
is_param_err = 1;
}
} else if ((strcasecmp(wl_cmd, "BT_STOP") == 0)) {
char bt_stop_hci_cmd[255] = "01 0C 18 01 ";
if (argC == 2) {
buf_len = priv_cmd.used_len;
int arg_len = strlen("BT_STOP");
int stop_cmd_len = strlen(bt_stop_hci_cmd);
memcpy(&bt_stop_hci_cmd[stop_cmd_len], &priv_cmd.buf[arg_len+1], buf_len - arg_len - 1);
memcpy(&priv_cmd.buf[arg_len+1], &bt_stop_hci_cmd[0], strlen(bt_stop_hci_cmd));
buf_len += strlen(bt_stop_hci_cmd);
priv_cmd.used_len = buf_len;
} else if ((strcasecmp(wl_cmd, "BT_DATA") == 0)) {
//char bt_raw_data_cmd[255];
int arg_len = strlen(wl_cmd);
buf_len = priv_cmd.used_len;
memcpy(&priv_cmd.buf[arg_len+1], &priv_cmd.buf[arg_len+1], buf_len - arg_len - 1);
priv_cmd.used_len = buf_len - arg_len - 1;
} else {
is_param_err = 1;
}
} else {
is_param_err = 0;
}
if (is_param_err) {
printf("param error!!!\n");
return ERR;
}
if ((ret = ioctl(sock, TXRX_PARA, &ifr)) < 0) {
printf("%s: error ioctl[TX_PARA] ret= %d\n", __func__, ret);
return ret;
}
memcpy(&priv_cmd, ifr.ifr_data, sizeof(struct android_wifi_priv_cmd));
if (strcasecmp(wl_cmd, "GET_BT_RX_RESULT") == 0) {
printf("done: get bt rx total=%d, ok=%d, err=%d\n", *(unsigned int *)priv_cmd.buf,
*(unsigned int *)&priv_cmd.buf[4],
*(unsigned int *)&priv_cmd.buf[8]);
} else if (strcasecmp(wl_cmd, "BT_DATA") == 0) {
unsigned char *buff = (unsigned char *)&priv_cmd.buf[1];
int len = priv_cmd.buf[0];
int idx = 0;
printf("done: %d\n", len);
for (idx = 0; idx < len; idx++) {
printf("%02x ", buff[idx]);
}
printf("\n");
} else {
printf("done\n");
}
return OK;
}
int dev_open(){
int n = 0;
bt_dev_fd = open(dev_path, O_RDWR | O_NDELAY);
if(bt_dev_fd < 0) {
printf("dev_path %s fail to open \r\n", dev_path);
return ERR;
}
if(interface == UART){
tcflush(bt_dev_fd, TCIOFLUSH);
n = fcntl(bt_dev_fd, F_GETFL, 0);
fcntl(bt_dev_fd, F_SETFL, n & ~O_NDELAY);
uart_set_options(/*BAUDRATE*/atoi(s_baudrate), DATABITS, PARTY, STOP, SOFTWARE_HANDSHAKE, HARDWARE_HANDSHAKE);
}else{
ioctl(bt_dev_fd, DOWN_FW_CFG);
ioctl(bt_dev_fd, GET_USB_INFO);
}
printf("bt dev open successful\r\n");
return OK;
}
void dev_close(){
close(bt_dev_fd);
}
int socket_init(){
int client;
int server_socket;
struct sockaddr_in server_addr;
struct sockaddr_in clientAddr;
int addr_len = sizeof(clientAddr);
char buffer[SOCKER_BUFFER_SIZE];
int recv_len = 0;
if((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0){
return ERR;
}
//bzero(&server_addr, sizeof(server_addr));
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(BT_HCI_TOOL_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//setsockopt(server_socket ,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));
if(bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
printf("binding error\r\n");
return ERR;
}
if(listen(server_socket, 5) < 0){
printf("listen error");
return ERR;
}
while(1){
client = accept(server_socket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);
if(client == ERR){
return 0;
}
recv_len = recv(client, buffer, SOCKER_BUFFER_SIZE, 0);
if ((interface == USB) || (interface == UART)) {
hci_send(buffer, recv_len);
} else {
wlan_send(buffer, recv_len);
}
}
}
void* hci_recv_thread( void *arg ){
printf("hci recv thread ready %p\r\n", arg);
while(1){
hci_recv(hci_event, sizeof(hci_event));
// exit(0);
}
}
void start_server(){
int ret = ERR;
if ((interface == USB) || (interface == UART)) {
pthread_t hci_recv_th;
//init bt communication
ret = dev_open();
if(ret == ERR){
printf("dev_open fail \r\n");
return;
}
//test to send reset
printf("to test hci reset for bt device\r\n");
hci_send(hci_reset, sizeof(hci_reset));
hci_recv(hci_event, sizeof(hci_event));
ret = pthread_create( &hci_recv_th, NULL, hci_recv_thread, NULL);
printf("bt device test ok \r\n");
} else if (interface == WLAN) {
char buf[SOCKER_BUFFER_SIZE] = {"BT_RESET "};
wlan_send(buf, strlen(buf));
}
//init localhost socket
ret = socket_init();
if (!ret) {
printf("socket init done\r\n");
}
}
int main(int argc, char *argv[]){
int ret = parse_cmd_line(argc, argv);
if (ret) {
return ret;
}
if(server_or_client == SERVER){
start_server();
} else if (server_or_client == CLIENT) {
send_hci_command();
} else if (server_or_client == CLIENT_DIRECT) {
if (bt_test_args.cmd == ble_start) {
send_to_server((unsigned char*)hci_reset, sizeof(hci_reset));
} else if (bt_test_args.cmd == dut) {
send_to_server((unsigned char*)hci_reset, sizeof(hci_reset));
send_to_server((unsigned char*)set_filter, sizeof(set_filter));
send_to_server((unsigned char*)scan_on, sizeof(scan_on));
send_to_server((unsigned char*)dut_en, sizeof(dut_en));
return 0;
}
send_raw_hci_command();
} else {
send_wlan_command();
}
return 0;
}