/****************************************************************************** * * Copyright (C) 2014, The linux Foundation. All rights reserved. * * Not a Contribution. * * Copyright (C) 2009-2012 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /************************************************************************************ * * Filename: rfcommtest.c * * Description: RFCOMM Test application * ***********************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bt_target.h" #include "bt_testapp.h" /************************************************************************************ ** Constants & Macros ************************************************************************************/ #define PID_FILE "/data/.bdt_pid" #ifndef MAX #define MAX(x, y) ((x) > (y) ? (x) : (y)) #endif #define CASE_RETURN_STR(const) case const: return #const; #define DISCONNECT 3 /************************************************************************************ ** Local type definitions ************************************************************************************/ /************************************************************************************ ** Static variables ************************************************************************************/ static unsigned char main_done = 0; static bt_status_t status; /* Main API */ static bluetooth_device_t* bt_device; const bt_interface_t* sBtInterface = NULL; const btrfcomm_interface_t *sRfcInterface = NULL; static gid_t groups[] = { AID_NET_BT, AID_INET, AID_NET_BT_ADMIN, AID_SYSTEM, AID_MISC, AID_SDCARD_RW, AID_NET_ADMIN, AID_VPN}; /* Set to 1 when the Bluedroid stack is enabled */ static unsigned char bt_enabled = 0; static bool strict_mode = FALSE; /************************************************************************************ ** Static functions ************************************************************************************/ static void process_cmd(char *p, unsigned char is_job); static void bdt_log(const char *fmt_str, ...); /************************************************************************************ ** Externs ************************************************************************************/ /************************************************************************************ ** Functions ************************************************************************************/ /************************************************************************************ ** Shutdown helper functions ************************************************************************************/ static void bdt_shutdown(void) { bdt_log("shutdown bdroid test app\n"); main_done = 1; } /***************************************************************************** ** Android's init.rc does not yet support applying linux capabilities *****************************************************************************/ static int str2bd(char *str, bt_bdaddr_t *addr) { int32_t i = 0; for (i = 0; i < 6; i++) { addr->address[i] = (uint8_t) strtoul(str, (char **)&str, 16); str++; } return 0; } static void config_permissions(void) { struct __user_cap_header_struct header; struct __user_cap_data_struct cap[2]; bdt_log("set_aid_and_cap : pid %d, uid %d gid %d", getpid(), getuid(), getgid()); header.pid = 0; prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); setuid(AID_BLUETOOTH); setgid(AID_BLUETOOTH); header.version = _LINUX_CAPABILITY_VERSION_3; cap[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW); cap[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN); cap[CAP_TO_INDEX(CAP_NET_BIND_SERVICE)].permitted |= CAP_TO_MASK(CAP_NET_BIND_SERVICE); cap[CAP_TO_INDEX(CAP_SYS_RAWIO)].permitted |= CAP_TO_MASK(CAP_SYS_RAWIO); cap[CAP_TO_INDEX(CAP_SYS_NICE)].permitted |= CAP_TO_MASK(CAP_SYS_NICE); cap[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID); cap[CAP_TO_INDEX(CAP_WAKE_ALARM)].permitted |= CAP_TO_MASK(CAP_WAKE_ALARM); cap[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW); cap[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN); cap[CAP_TO_INDEX(CAP_NET_BIND_SERVICE)].effective |= CAP_TO_MASK(CAP_NET_BIND_SERVICE); cap[CAP_TO_INDEX(CAP_SYS_RAWIO)].effective |= CAP_TO_MASK(CAP_SYS_RAWIO); cap[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); cap[CAP_TO_INDEX(CAP_SETGID)].effective |= CAP_TO_MASK(CAP_SETGID); cap[CAP_TO_INDEX(CAP_WAKE_ALARM)].effective |= CAP_TO_MASK(CAP_WAKE_ALARM); capset(&header, &cap[0]); setgroups(sizeof(groups)/sizeof(groups[0]), groups); } #if 0 /*Pin_Request_cb */ static void pin_remote_request_callback (bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, uint32_t cod) { bt_pin_code_t pin_code; /* Default 1234 is the Pin code */ pin_code.pin[0] = 0x31; pin_code.pin[1] = 0x32; pin_code.pin[2] = 0x33; pin_code.pin[3] = 0x34; bdt_log("bdt PIN Remote Request"); sBtInterface->pin_reply(remote_bd_addr ,1 , 4 , &pin_code); } #endif /* Pairing in Case of SSP */ static void ssp_remote_requst_callback(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key) { if (pairing_variant == BT_SSP_VARIANT_PASSKEY_ENTRY) { bdt_log("bdt ssp remote request not supported"); return; } bdt_log("bdt accept SSP pairing"); sBtInterface->ssp_reply(remote_bd_addr, pairing_variant, 1, pass_key); } /***************************************************************************** ** Logger API *****************************************************************************/ void bdt_log(const char *fmt_str, ...) { static char buffer[1024]; va_list ap; va_start(ap, fmt_str); vsnprintf(buffer, 1024, fmt_str, ap); va_end(ap); fprintf(stdout, "%s\n", buffer); } /******************************************************************************* ** Misc helper functions *******************************************************************************/ static const char* dump_bt_status(bt_status_t status) { switch(status) { CASE_RETURN_STR(BT_STATUS_SUCCESS) CASE_RETURN_STR(BT_STATUS_FAIL) CASE_RETURN_STR(BT_STATUS_NOT_READY) CASE_RETURN_STR(BT_STATUS_NOMEM) CASE_RETURN_STR(BT_STATUS_BUSY) CASE_RETURN_STR(BT_STATUS_UNSUPPORTED) default: return "unknown status code"; } } #if 0 static void hex_dump(char *msg, void *data, int size, int trunc) { unsigned char *p = data; unsigned char c; int n; char bytestr[4] = {0}; char addrstr[10] = {0}; char hexstr[ 16*3 + 5] = {0}; char charstr[16*1 + 5] = {0}; bdt_log("%s \n", msg); /* truncate */ if(trunc && (size>32)) size = 32; for(n=1;n<=size;n++) { if (n%16 == 1) { /* store address for this line */ snprintf(addrstr, sizeof(addrstr), "%.4x", (unsigned int)((uintptr_t)p-(uintptr_t)data) ); } c = *p; if (isalnum(c) == 0) { c = '.'; } /* store hex str (for left side) */ snprintf(bytestr, sizeof(bytestr), "%02X ", *p); strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); /* store char str (for right side) */ snprintf(bytestr, sizeof(bytestr), "%c", c); strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); if(n%16 == 0) { /* line completed */ bdt_log("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); hexstr[0] = 0; charstr[0] = 0; } else if(n%8 == 0) { /* half line: add whitespaces */ strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); } p++; /* next byte */ } if (strlen(hexstr) > 0) { /* print rest of buffer if not empty */ bdt_log("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); } } #endif /******************************************************************************* ** Console helper functions *******************************************************************************/ void skip_blanks(char **p) { while (**p == ' ') (*p)++; } uint32_t get_int(char **p, int DefaultValue) { uint32_t Value = 0; unsigned char UseDefault; UseDefault = 1; skip_blanks(p); while ( ((**p)<= '9' && (**p)>= '0') ) { Value = Value * 10 + (**p) - '0'; UseDefault = 0; (*p)++; } if (UseDefault) return DefaultValue; else return Value; } int get_signed_int(char **p, int DefaultValue) { int Value = 0; unsigned char UseDefault; unsigned char NegativeNum = 0; UseDefault = 1; skip_blanks(p); if ( (**p) == '-') { NegativeNum = 1; (*p)++; } while ( ((**p)<= '9' && (**p)>= '0') ) { Value = Value * 10 + (**p) - '0'; UseDefault = 0; (*p)++; } if (UseDefault) return DefaultValue; else return ((NegativeNum == 0)? Value : -Value); } void get_str(char **p, char *Buffer) { skip_blanks(p); while (**p != 0 && **p != ' ') { *Buffer = **p; (*p)++; Buffer++; } *Buffer = 0; } uint32_t get_hex(char **p, int DefaultValue) { uint32_t Value = 0; unsigned char UseDefault; UseDefault = 1; skip_blanks(p); while ( ((**p)<= '9' && (**p)>= '0') || ((**p)<= 'f' && (**p)>= 'a') || ((**p)<= 'F' && (**p)>= 'A') ) { if (**p >= 'a') Value = Value * 16 + (**p) - 'a' + 10; else if (**p >= 'A') Value = Value * 16 + (**p) - 'A' + 10; else Value = Value * 16 + (**p) - '0'; UseDefault = 0; (*p)++; } if (UseDefault) return DefaultValue; else return Value; } void get_bdaddr(const char *str, bt_bdaddr_t *bd) { char *d = ((char *)bd), *endp; int i; for(i = 0; i < 6; i++) { *d++ = strtol(str, &endp, 16); if (*endp != ':' && i != 5) { memset(bd, 0, sizeof(bt_bdaddr_t)); return; } str = endp + 1; } } #define is_cmd(str) ((strlen(str) == strlen(cmd)) && strncmp((const char *)&cmd, str, strlen(str)) == 0) #define if_cmd(str) if (is_cmd(str)) typedef void (t_console_cmd_handler) (char *p); typedef struct { const char *name; t_console_cmd_handler *handler; const char *help; unsigned char is_job; } t_cmd; const t_cmd console_cmd_list[]; static int console_cmd_maxlen = 0; static void cmdjob_handler(void *param) { char *job_cmd = (char*)param; bdt_log("cmdjob starting (%s)", job_cmd); process_cmd(job_cmd, 1); bdt_log("cmdjob terminating"); free(job_cmd); } static int create_cmdjob(char *cmd) { pthread_t thread_id; char *job_cmd; job_cmd = malloc(strlen(cmd)+1); /* freed in job handler */ if (job_cmd) { strlcpy(job_cmd, cmd, sizeof(job_cmd)); if (pthread_create(&thread_id, NULL, (void*)cmdjob_handler, (void*)job_cmd)!=0) perror("pthread_create"); } else bdt_log("Rfcomm_test: Cannot allocate memory for cmdjob"); return 0; } /******************************************************************************* ** Load stack lib *******************************************************************************/ int HAL_load(void) { int err = 0; hw_module_t* module; hw_device_t* device; bdt_log("Loading HAL lib + extensions"); err = hw_get_module(BT_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device); if (err == 0) { bt_device = (bluetooth_device_t *)device; sBtInterface = bt_device->get_bluetooth_interface(); } } bdt_log("HAL library loaded (%s)", strerror(err)); return err; } int HAL_unload(void) { int err = 0; bdt_log("Unloading HAL lib"); sBtInterface = NULL; sRfcInterface = NULL; bdt_log("HAL library unloaded (%s)", strerror(err)); return err; } /******************************************************************************* ** HAL test functions & callbacks *******************************************************************************/ void setup_test_env(void) { int i = 0; while (console_cmd_list[i].name != NULL) { console_cmd_maxlen = MAX(console_cmd_maxlen, (int)strlen(console_cmd_list[i].name)); i++; } } void check_return_status(bt_status_t status) { if (status != BT_STATUS_SUCCESS) { bdt_log("HAL REQUEST FAILED status : %d (%s)", status, dump_bt_status(status)); } else { bdt_log("HAL REQUEST SUCCESS"); } } static void adapter_state_changed(bt_state_t state) { bdt_log("ADAPTER STATE UPDATED : %s", (state == BT_STATE_OFF)?"OFF":"ON"); if (state == BT_STATE_ON) { bt_enabled = 1; } else { bt_enabled = 0; } } static void dut_mode_recv(uint16_t opcode, uint8_t *buf, uint8_t len) { bdt_log("DUT MODE RECV : NOT IMPLEMENTED"); } #if BLE_INCLUDED == TRUE static void le_test_mode(bt_status_t status, uint16_t packet_count) { bdt_log("LE TEST MODE END status:%s number_of_packets:%d", dump_bt_status(status), packet_count); } #endif static void device_found_cb(int num_properties, bt_property_t *properties) { int i; for (i = 0; i < num_properties; i++) { if (properties[i].type == BT_PROPERTY_BDNAME) { bdt_log("AP name is : %s\n", (char*)properties[i].val); } } } static bt_callbacks_t bt_callbacks = { sizeof(bt_callbacks_t), adapter_state_changed, NULL, /*adapter_properties_cb */ NULL, /* remote_device_properties_cb */ device_found_cb, /* device_found_cb */ NULL, /* discovery_state_changed_cb */ NULL, /* pin_request_cb */ ssp_remote_requst_callback, /* ssp_request_cb */ NULL, /*bond_state_changed_cb */ NULL, /* acl_state_changed_cb */ NULL, /* thread_evt_cb */ dut_mode_recv, /*dut_mode_recv_cb */ // NULL, /*authorize_request_cb */ #if BLE_INCLUDED == TRUE le_test_mode, /* le_test_mode_cb */ #else NULL, #endif NULL, /* energy_info_cb */ NULL /* get_testapp_interface */ }; static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data) { static timer_t timer; static bool timer_created; if (!timer_created) { struct sigevent sigevent; memset(&sigevent, 0, sizeof(sigevent)); sigevent.sigev_notify = SIGEV_THREAD; sigevent.sigev_notify_function = (void (*)(union sigval))cb; sigevent.sigev_value.sival_ptr = data; timer_create(CLOCK_MONOTONIC, &sigevent, &timer); timer_created = true; } struct itimerspec new_value; new_value.it_value.tv_sec = delay_millis / 1000; new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000; new_value.it_interval.tv_sec = 0; new_value.it_interval.tv_nsec = 0; timer_settime(timer, 0, &new_value, NULL); return true; } static int acquire_wake_lock(const char *lock_name) { return BT_STATUS_SUCCESS; } static int release_wake_lock(const char *lock_name) { return BT_STATUS_SUCCESS; } static bt_os_callouts_t callouts = { sizeof(bt_os_callouts_t), set_wake_alarm, acquire_wake_lock, release_wake_lock, }; /* Rfcomm Client */ void bdt_rfcomm(void) { bdt_log("rfcomm client"); sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm(0); } else { bdt_log("interface not loaded"); } } /* Rfcomm Server */ void bdt_rfcomm_server (void) { bdt_log("rfcomm server"); sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm(1); } else { bdt_log("interface not loaded"); } } /* Rfcomm disconnect */ void bdt_rfcomm_disc_from_server(void) { bdt_log("rfcomm disc from Server"); sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm(3); } else { bdt_log("interface not loaded"); } } void bdt_init(void) { bdt_log("INIT BT "); status = sBtInterface->init(&bt_callbacks, false); if (status == BT_STATUS_SUCCESS) { status = sBtInterface->set_os_callouts(&callouts); } check_return_status(status); } void bdt_enable(void) { bdt_log("ENABLE BT"); if (bt_enabled) { bdt_log("Bluetooth is already enabled"); return; } status = sBtInterface->enable(strict_mode); check_return_status(status); } void bdt_disable(void) { bdt_log("DISABLE BT"); if (!bt_enabled) { bdt_log("Bluetooth is already disabled"); return; } status = sBtInterface->disable(); check_return_status(status); } void bdt_dut_mode_configure(char *p) { int32_t mode = -1; bdt_log("BT DUT MODE CONFIGURE"); if (!bt_enabled) { bdt_log("Bluetooth must be enabled for test_mode to work."); return; } mode = get_signed_int(&p, mode); if ((mode != 0) && (mode != 1)) { bdt_log("Please specify mode: 1 to enter, 0 to exit"); return; } status = sBtInterface->dut_mode_configure(mode); check_return_status(status); } #define HCI_LE_RECEIVER_TEST_OPCODE 0x201D #define HCI_LE_TRANSMITTER_TEST_OPCODE 0x201E #define HCI_LE_END_TEST_OPCODE 0x201F void bdt_le_test_mode(char *p) { int cmd; unsigned char buf[3]; int arg1, arg2, arg3; bdt_log("BT LE TEST MODE"); if (!bt_enabled) { bdt_log("Bluetooth must be enabled for le_test to work."); return; } memset(buf, 0, sizeof(buf)); cmd = get_int(&p, 0); switch (cmd) { case 0x1: /* RX TEST */ arg1 = get_int(&p, -1); if (arg1 < 0) bdt_log("%s Invalid arguments", __FUNCTION__); buf[0] = arg1; status = sBtInterface->le_test_mode(HCI_LE_RECEIVER_TEST_OPCODE, buf, 1); break; case 0x2: /* TX TEST */ arg1 = get_int(&p, -1); arg2 = get_int(&p, -1); arg3 = get_int(&p, -1); if ((arg1 < 0) || (arg2 < 0) || (arg3 < 0)) bdt_log("%s Invalid arguments", __FUNCTION__); buf[0] = arg1; buf[1] = arg2; buf[2] = arg3; status = sBtInterface->le_test_mode(HCI_LE_TRANSMITTER_TEST_OPCODE, buf, 3); break; case 0x3: /* END TEST */ status = sBtInterface->le_test_mode(HCI_LE_END_TEST_OPCODE, buf, 0); break; default: bdt_log("Unsupported command"); return; break; } if (status != BT_STATUS_SUCCESS) { bdt_log("%s Test 0x%x Failed with status:0x%x", __FUNCTION__, cmd, status); } return; } void bdt_cleanup(void) { bdt_log("CLEANUP"); sBtInterface->cleanup(); } /******************************************************************************* ** Console commands *******************************************************************************/ static int pos = 0; void do_help(char *p) { int i = 0; char line[128]; while (console_cmd_list[i].name != NULL) { pos = snprintf(line, sizeof(line), "%s", (char*)console_cmd_list[i].name); bdt_log("%s %s\n", (char*)line, (char*)console_cmd_list[i].help); i++; } } void do_quit(char *p) { bdt_shutdown(); } /******************************************************************* * * BT TEST CONSOLE COMMANDS * * Parses argument lists and passes to API test function * */ void do_init(char *p) { bdt_init(); } void do_enable(char *p) { bdt_enable(); } void do_disable(char *p) { bdt_disable(); } void do_dut_mode_configure(char *p) { bdt_dut_mode_configure(p); } void do_le_test_mode(char *p) { bdt_le_test_mode(p); } void do_cleanup(char *p) { bdt_cleanup(); } /********* Rfcomm Test toot ***************/ void do_rfcomm(char *p) { bdt_rfcomm(); } /********************************************** Rfcomm connection to remote device ************************************************/ void do_rfc_con( char *p) { char buf[64]; tRFC conn_param; bdt_log("bdt do_rfc_con"); memset(buf, 0, 64); /*Enter BD address */ get_str(&p, buf); str2bd(buf, &conn_param.data.conn.bdadd); memset(buf ,0 , 64); get_str(&p, buf); conn_param.data.conn.scn = atoi(buf); bdt_log("SCN =%d",conn_param.data.conn.scn); /* Connection */ conn_param.param = RFC_TEST_CLIENT; sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm_test_interface(&conn_param); } else { bdt_log("interface not loaded"); } } /* For PTS test case BV21 and BV22 */ void do_rfc_con_for_test_msc_data(char *p) { char buf[64]; tRFC conn_param; bdt_log("bdt do_rfc_con_for_test_msc_data"); memset(buf, 0, 64); /*Enter BD address */ get_str(&p, buf); str2bd(buf, &conn_param.data.conn.bdadd); memset(buf ,0 , 64); get_str(&p, buf); conn_param.data.conn.scn = atoi(buf); bdt_log("SCN =%d",conn_param.data.conn.scn); /* Connection */ conn_param.param = RFC_TEST_CLIENT_TEST_MSC_DATA; sRfcInterface = (btrfcomm_interface_t *)sBtInterface-> get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm_test_interface(&conn_param); } else { bdt_log("interface not loaded"); } } /* Role Switch */ void do_role_switch(char *p) { char buf[64]; tRFC conn_param ; bdt_log("bdt do_role_switch"); memset(buf ,0 , 64); /* Bluetooth Device address */ get_str(&p, buf); str2bd(buf, &conn_param.data.role_switch.bdadd); memset(buf ,0 , 64); get_str(&p, buf); conn_param.data.role_switch.role = atoi(buf); /* Role Switch */ conn_param.param = RFC_TEST_ROLE_SWITCH; //role switch sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm_test_interface(&conn_param); } else { bdt_log("interface not loaded"); } } void do_rfc_rls (char *p) { tRFC conn_param; bdt_log("bdt rfc_rls"); conn_param.param = RFC_TEST_FRAME_ERROR; sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm_test_interface(&conn_param); } else { bdt_log("interface not loaded"); } } void do_rfc_send_data (char *p) { tRFC conn_param; bdt_log("bdt rfc_send_data"); conn_param.param = RFC_TEST_WRITE_DATA; sRfcInterface = (btrfcomm_interface_t *)sBtInterface->get_testapp_interface(TEST_APP_RFCOMM); if (sRfcInterface) { sRfcInterface->rdut_rfcomm_test_interface(&conn_param); } else { bdt_log("interface not loaded"); } } void do_rfcomm_server(char *p) { bdt_rfcomm_server(); } void do_rfcomm_disc_frm_server(char *p) { bdt_rfcomm_disc_from_server(); } /******************************************************************* * * CONSOLE COMMAND TABLE * */ const t_cmd console_cmd_list[] = { /* * INTERNAL */ { "help", do_help, "lists all available console commands", 0 }, { "quit", do_quit, "", 0}, /* * API CONSOLE COMMANDS */ /* Init and Cleanup shall be called automatically */ { "enable", do_enable, ":: enables bluetooth", 0 }, { "disable", do_disable, ":: disables bluetooth", 0 }, { "dut_mode_configure", do_dut_mode_configure, ":: DUT mode - 1 to enter,0 to exit", 0 }, { "le_test_mode", do_le_test_mode, ":: LE Test Mode - RxTest - 1 , \n\t \ TxTest - 2 , \n\t \ End Test - 3 ", 0 }, /* add here */ { "rfcomm", do_rfcomm, "rfcomm test", 0}, { "server_rfcomm", do_rfcomm_server ,"rfcomm server test", 0}, { "dis_client", do_rfcomm_disc_frm_server, "disc from Server", 0}, { "rfc_con", do_rfc_con, "rfc_con", 0 }, { "rfc_msccon", do_rfc_con_for_test_msc_data, "rfc_msccon", 0 }, { "rfc_rls", do_rfc_rls, "rls", 0 }, { "rfc_senddata", do_rfc_send_data, "rfc_senddata", 0 }, { "role_sw", do_role_switch, "role_sw", 0}, /* last entry */ {NULL, NULL, "", 0}, }; /* * Main console command handler */ static void process_cmd(char *p, unsigned char is_job) { char cmd[128]; int i = 0; char *p_saved = p; get_str(&p, cmd); /* table commands */ while (console_cmd_list[i].name != NULL) { if (is_cmd(console_cmd_list[i].name)) { if (!is_job && console_cmd_list[i].is_job) create_cmdjob(p_saved); else { console_cmd_list[i].handler(p); } return; } i++; } bdt_log("%s : unknown command\n", p_saved); do_help(NULL); } int main (int argc, char * argv[]) { config_permissions(); bdt_log("\n:::::::::::::::::::::::::::::::::::::::::::::::::::"); bdt_log(":: Bluedroid test app starting"); if ( HAL_load() < 0 ) { perror("HAL failed to initialize, exit\n"); unlink(PID_FILE); exit(0); } setup_test_env(); /* Automatically perform the init */ bdt_init(); while(!main_done) { char line[128]; /* command prompt */ printf( ">" ); fflush(stdout); fgets (line, 128, stdin); if (line[0]!= '\0') { /* remove linefeed */ line[strlen(line)-1] = 0; process_cmd(line, 0); memset(line, '\0', 128); } } /* FIXME: Commenting this out as for some reason, the application does not exit otherwise*/ //bdt_cleanup(); //cleanup: HAL_unload(); bdt_log(":: Bluedroid test app terminating"); return 0; }