+++ /dev/null
-/******************************************************************************
- *
- * 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: bluedroidtest.c
- *
- * Description: Bluedroid Test application
- *
- ***********************************************************************************/
-
-#include <stdio.h>
-#include <dlfcn.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <sys/prctl.h>
-#include <sys/capability.h>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <private/android_filesystem_config.h>
-#include <android/log.h>
-
-#include <hardware/hardware.h>
-#include <hardware/bluetooth.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 UNUSED __attribute__((unused))
-
-/************************************************************************************
-** 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;
-
-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 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 void config_permissions(void)
-{
- struct __user_cap_header_struct header;
- struct __user_cap_data_struct cap;
-
- 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;
-
- cap.effective = cap.permitted = cap.inheritable =
- 1 << CAP_NET_RAW |
- 1 << CAP_NET_ADMIN |
- 1 << CAP_NET_BIND_SERVICE |
- 1 << CAP_SYS_RAWIO |
- 1 << CAP_SYS_NICE |
- 1 << CAP_SETGID;
-
- capset(&header, &cap);
- setgroups(sizeof(groups)/sizeof(groups[0]), groups);
-}
-
-
-
-/*****************************************************************************
-** 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";
- }
-}
-
-/*******************************************************************************
- ** 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 */
- strcpy(job_cmd, cmd);
-
- if (pthread_create(&thread_id, NULL,
- (void*)cmdjob_handler, (void*)job_cmd)!=0)
- perror("pthread_create");
-
- 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;
-
- 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 UNUSED opcode, uint8_t UNUSED *buf, uint8_t UNUSED len)
-{
- bdt_log("DUT MODE RECV : NOT IMPLEMENTED");
-}
-
-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);
-}
-
-static bt_callbacks_t bt_callbacks = {
- sizeof(bt_callbacks_t),
- adapter_state_changed,
- NULL, /* adapter_properties_cb */
- NULL, /* remote_device_properties_cb */
- NULL, /* device_found_cb */
- NULL, /* discovery_state_changed_cb */
- NULL, /* pin_request_cb */
- NULL, /* ssp_request_cb */
- NULL, /* bond_state_changed_cb */
- NULL, /* acl_state_changed_cb */
- NULL, /* thread_evt_cb */
- dut_mode_recv, /* dut_mode_recv_cb */
-#if BLE_INCLUDED == TRUE
- le_test_mode, /* le_test_mode_cb */
-#else
- NULL, /* le_test_mode_cb */
-#endif
- NULL /* energy_info_cb */
-};
-
-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,
-};
-
-void bdt_init(void)
-{
- bdt_log("INIT BT ");
- status = sBtInterface->init(&bt_callbacks);
-
- 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();
-
- 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
- *******************************************************************************/
-
-void do_help(char UNUSED *p)
-{
- int i = 0;
- char line[128];
- int pos = 0;
-
- while (console_cmd_list[i].name != NULL)
- {
- pos = sprintf(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 UNUSED *p)
-{
- bdt_shutdown();
-}
-
-/*******************************************************************
- *
- * BT TEST CONSOLE COMMANDS
- *
- * Parses argument lists and passes to API test function
- *
-*/
-
-void do_init(char UNUSED *p)
-{
- bdt_init();
-}
-
-void do_enable(char UNUSED *p)
-{
- bdt_enable();
-}
-
-void do_disable(char UNUSED *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 UNUSED *p)
-{
- bdt_cleanup();
-}
-
-/*******************************************************************
- *
- * 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 <rx_freq>, \n\t \
- TxTest - 2 <tx_freq> <test_data_len> <payload_pattern>, \n\t \
- End Test - 3 <no_args>", 0 },
- /* add here */
-
- /* last entry */
- {NULL, NULL, "", 0},
-};
-
-/*
- * Main console command handler
-*/
-
-static void process_cmd(char *p, unsigned char is_job)
-{
- char cmd[64];
- 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 UNUSED argc, char UNUSED *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();
-
- HAL_unload();
-
- bdt_log(":: Bluedroid test app terminating");
-
- return 0;
-}