summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKausik Sinnaswamy <kausik@broadcom.com>2012-08-08 22:11:39 +0530
committerMatthew Xie <mattx@google.com>2012-08-13 23:22:54 -0700
commita4eaddaccd236ec5c5add065e1b393072bdb8386 (patch)
tree2e6c52cacc63cc036b72b02c3082c3ba6972ddf2
parent1a0ab4d5bee3bea4c8153a3d147d5adca3be0bed (diff)
downloadexternal_bluetooth_bluedroid-a4eaddaccd236ec5c5add065e1b393072bdb8386.zip
external_bluetooth_bluedroid-a4eaddaccd236ec5c5add065e1b393072bdb8386.tar.gz
external_bluetooth_bluedroid-a4eaddaccd236ec5c5add065e1b393072bdb8386.tar.bz2
Enhanced bluetooth HAL with DUT mode APIs
These APIs are needed to allow the bluetooth chip to be put into DUT mode so that RF/BB BQB tests can be run Change-Id: Ie5be00da567bc94173f35b098abcaf6f6603a129
-rw-r--r--btif/include/btif_api.h23
-rw-r--r--btif/include/btif_util.h1
-rw-r--r--btif/src/bluetooth.c25
-rw-r--r--btif/src/btif_core.c94
-rw-r--r--test/Android.mk3
-rw-r--r--test/bluedroidtest/Android.mk66
-rw-r--r--test/bluedroidtest/README.txt73
-rw-r--r--test/bluedroidtest/bluedroidtest.c743
8 files changed, 1023 insertions, 5 deletions
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index d90ee58..7916b3d 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -377,5 +377,28 @@ bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t *remote_addr,
*******************************************************************************/
bt_status_t btif_dm_get_remote_services(bt_bdaddr_t *remote_addr);
+/*******************************************************************************
+**
+** Function btif_dut_mode_configure
+**
+** Description Configure Test Mode - 'enable' to 1 puts the device in test mode and 0 exits
+** test mode
+**
+** Returns BT_STATUS_SUCCESS on success
+**
+*******************************************************************************/
+bt_status_t btif_dut_mode_configure(uint8_t enable);
+
+/*******************************************************************************
+**
+** Function btif_dut_mode_send
+**
+** Description Sends a HCI Vendor specific command to the controller
+**
+** Returns BT_STATUS_SUCCESS on success
+**
+*******************************************************************************/
+bt_status_t btif_dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len);
+
#endif /* BTIF_API_H */
diff --git a/btif/include/btif_util.h b/btif/include/btif_util.h
index a15d1ca..fd16a40 100644
--- a/btif/include/btif_util.h
+++ b/btif/include/btif_util.h
@@ -109,4 +109,3 @@ void string_to_uuid(char *str, bt_uuid_t *p_uuid);
int ascii_2_hex (char *p_ascii, int len, UINT8 *p_hex);
#endif /* BTIF_UTIL_H */
-
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index f7e80d9..0b9d542 100644
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -347,6 +347,27 @@ static const void* get_profile_interface (const char *profile_id)
return NULL;
}
+int dut_mode_configure(uint8_t enable)
+{
+ ALOGI("dut_mode_configure");
+
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dut_mode_configure(enable);
+}
+
+int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len)
+{
+ ALOGI("dut_mode_send");
+
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dut_mode_send(opcode, buf, len);
+}
static const bt_interface_t bluetoothInterface = {
sizeof(bt_interface_t),
init,
@@ -368,7 +389,9 @@ static const bt_interface_t bluetoothInterface = {
cancel_bond,
pin_reply,
ssp_reply,
- get_profile_interface
+ get_profile_interface,
+ dut_mode_configure,
+ dut_mode_send
};
const bt_interface_t* bluetooth__get_bluetooth_interface ()
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 0b0734e..666efa7 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -135,6 +135,14 @@ static btif_core_state_t btif_core_state = BTIF_CORE_STATE_DISABLED;
static int btif_shutdown_pending = 0;
static tBTA_SERVICE_MASK btif_enabled_services = 0;
+/*
+* This variable should be set to 1, if the Bluedroid+BTIF libraries are to
+* function in DUT mode.
+*
+* To set this, the btif_init_bluetooth needs to be called with argument as 1
+*/
+static UINT8 btif_dut_mode = 0;
+
/************************************************************************************
** Static functions
************************************************************************************/
@@ -249,6 +257,20 @@ bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_p
}
}
+/*******************************************************************************
+**
+** Function btif_is_dut_mode
+**
+** Description checks if BTIF is currently in DUT mode
+**
+** Returns 1 if test mode, otherwize 0
+**
+*******************************************************************************/
+
+UINT8 btif_is_dut_mode(void)
+{
+ return (btif_dut_mode == 1);
+}
/*******************************************************************************
**
@@ -262,7 +284,7 @@ bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_p
int btif_is_enabled(void)
{
- return (btif_core_state == BTIF_CORE_STATE_ENABLED);
+ return ((!btif_is_dut_mode()) && (btif_core_state == BTIF_CORE_STATE_ENABLED));
}
/*******************************************************************************
@@ -294,7 +316,6 @@ static void btif_task(UINT32 params)
* Wait for the trigger to init chip and stack. This trigger will
* be received by btu_task once the UART is opened and ready
*/
-
if (event == BT_EVT_TRIGGER_STACK_INIT)
{
BTIF_TRACE_DEBUG0("btif_task: received trigger stack init event");
@@ -432,7 +453,7 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
**
*******************************************************************************/
-bt_status_t btif_init_bluetooth(void)
+bt_status_t btif_init_bluetooth()
{
UINT8 status;
@@ -672,6 +693,8 @@ bt_status_t btif_shutdown_bluetooth(void)
btif_queue_release();
bte_main_shutdown();
+ btif_dut_mode = 0;
+
BTIF_TRACE_DEBUG1("%s done", __FUNCTION__);
return BT_STATUS_SUCCESS;
@@ -701,8 +724,73 @@ static bt_status_t btif_disassociate_evt(void)
return BT_STATUS_SUCCESS;
}
+/****************************************************************************
+**
+** BTIF Test Mode APIs
+**
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function btif_dut_mode_cback
+**
+** Description Callback invoked on completion of vendor specific test mode command
+**
+** Returns None
+**
+*******************************************************************************/
+static void btif_dut_mode_cback( tBTM_VSC_CMPL *p )
+{
+ /* For now nothing to be done. */
+}
+
+/*******************************************************************************
+**
+** Function btif_dut_mode_configure
+**
+** Description Configure Test Mode - 'enable' to 1 puts the device in test mode and 0 exits
+** test mode
+**
+** Returns BT_STATUS_SUCCESS on success
+**
+*******************************************************************************/
+bt_status_t btif_dut_mode_configure(uint8_t enable)
+{
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ if (btif_core_state != BTIF_CORE_STATE_ENABLED) {
+ BTIF_TRACE_ERROR0("btif_dut_mode_configure : Bluetooth not enabled");
+ return BT_STATUS_NOT_READY;
+ }
+ btif_dut_mode = enable;
+ if (enable == 1) {
+ BTA_EnableTestMode();
+ } else {
+ BTA_DisableTestMode();
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dut_mode_send
+**
+** Description Sends a HCI Vendor specific command to the controller
+**
+** Returns BT_STATUS_SUCCESS on success
+**
+*******************************************************************************/
+bt_status_t btif_dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+ /* TODO: Check that opcode is a vendor command group */
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ if (!btif_is_dut_mode()) {
+ BTIF_TRACE_ERROR0("Bluedroid HAL needs to be init with test_mode set to 1.");
+ return BT_STATUS_FAIL;
+ }
+ BTM_VendorSpecificCommand(opcode, len, buf, btif_dut_mode_cback);
+ return BT_STATUS_SUCCESS;
+}
/*****************************************************************************
**
** btif api adapter property functions
diff --git a/test/Android.mk b/test/Android.mk
new file mode 100644
index 0000000..3c3cb61
--- /dev/null
+++ b/test/Android.mk
@@ -0,0 +1,3 @@
+ifneq ($(TARGET_SIMULATOR),true)
+ include $(call all-subdir-makefiles)
+endif
diff --git a/test/bluedroidtest/Android.mk b/test/bluedroidtest/Android.mk
new file mode 100644
index 0000000..3c65394
--- /dev/null
+++ b/test/bluedroidtest/Android.mk
@@ -0,0 +1,66 @@
+# Copyright (C) 2009-2012 Broadcom Corporation
+#
+# This program is the proprietary software of Broadcom Corporation and/or its
+# licensors, and may only be used, duplicated, modified or distributed
+# pursuant to the terms and conditions of a separate, written license
+# agreement executed between you and Broadcom (an "Authorized License").
+# Except as set forth in an Authorized License, Broadcom grants no license
+# (express or implied), right to use, or waiver of any kind with respect to
+# the Software, and Broadcom expressly reserves all rights in and to the
+# Software and all intellectual property rights therein.
+# IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+# SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+# ALL USE OF THE SOFTWARE.
+#
+# Except as expressly set forth in the Authorized License,
+#
+# 1. This program, including its structure, sequence and organization,
+# constitutes the valuable trade secrets of Broadcom, and you shall
+# use all reasonable efforts to protect the confidentiality thereof,
+# and to use this information only in connection with your use of
+# Broadcom integrated circuit products.
+#
+# 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+# "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+# REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+# OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+# DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+# NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+# ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+# CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+# OF USE OR PERFORMANCE OF THE SOFTWARE.
+#
+# 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+# ITS LICENSORS BE LIABLE FOR
+# (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+# DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+# YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+# HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+# (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+# SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+# LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+# ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ bluedroidtest.c
+
+LOCAL_C_INCLUDES :=
+
+LOCAL_MODULE_TAGS := eng
+
+LOCAL_MODULE:= bdt
+
+LOCAL_LDLIBS += -lpthread -ldl -llog -lreadline
+LIBS_c += -lreadline
+
+LOCAL_SHARED_LIBRARIES += libcutils \
+ libutils \
+ libhardware \
+ libhardware_legacy
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/test/bluedroidtest/README.txt b/test/bluedroidtest/README.txt
new file mode 100644
index 0000000..a443a29
--- /dev/null
+++ b/test/bluedroidtest/README.txt
@@ -0,0 +1,73 @@
+Bluedroid Test Application
+==========================
+The test application provides a small console shell interface that allows
+access to the Bluetooth HAL API library though ASCII commands. This is similar
+to how the real JNI service would operate. The primary objective of this
+application is to allow Bluetooth to be put in DUT Mode for RF/BB BQB test purposes.
+
+This application is mutually exclusive with the Java based Bluetooth.apk. Hence
+before launching the application, it should be ensured that the Settings->Bluetooth is OFF.
+
+This application is built as 'bdt' and shall be available in '/system/bin/bdt'
+
+Limitations
+===========
+1.) Settings->Bluetooth must be OFF for this application to work
+2.) Currently, only the SIG 'HCI Test Mode' commands are supported. The vendor
+specific HCI test mode commands to be added.
+
+Usage instructions
+==================
+The following section describes the various commands and their usage
+
+Launching the test application
+==============================
+$ adb shell
+root@android:/ # /system/bin/bdt
+set_aid_and_cap : pid 1183, uid 0 gid 0
+:::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Bluedroid test app starting
+Loading HAL lib + extensions
+HAL library loaded (Success)
+INIT BT
+HAL REQUEST SUCCESS
+
+Enabling Bluetooth
+==================
+>enable
+ENABLE BT
+HAL REQUEST SUCCESS
+>ADAPTER STATE UPDATED : ON
+
+Enabling Test Mode (Bluetooth must be enabled for this command to work)
+======================================================================
+>enable_test_mode
+ENABLE BT TEST MODE
+HAL REQUEST SUCCESS
+>
+
+Disabling Test Mode
+===================
+>disable_test_mode
+DISABLE BT TEST MODE
+HAL REQUEST SUCCESS
+
+Exit the test application
+=========================
+>quit
+shutdown bdroid test app
+Unloading HAL lib
+HAL library unloaded (Success)
+:: Bluedroid test app terminating
+
+Help (Lists the available commands)
+===================================
+>help
+help lists all available console commands
+
+quit
+enable :: enables bluetooth
+disable :: disables bluetooth
+enable_test_mode :: enters bluedroid test mode
+disable_test_mode :: exits bluedroid test mode
+
diff --git a/test/bluedroidtest/bluedroidtest.c b/test/bluedroidtest/bluedroidtest.c
new file mode 100644
index 0000000..987b6c2
--- /dev/null
+++ b/test/bluedroidtest/bluedroidtest.c
@@ -0,0 +1,743 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+/************************************************************************************
+ *
+ * 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 <linux/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;
+
+/************************************************************************************
+** 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 job_handler(void *param);
+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";
+ }
+}
+
+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)p-(unsigned int)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);
+ }
+}
+
+/*******************************************************************************
+ ** 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 opcode, uint8_t *buf, uint8_t len)
+{
+ bdt_log("DUT MODE RECV : NOT IMPLEMENTED");
+}
+
+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 */
+};
+
+void bdt_init(void)
+{
+ bdt_log("INIT BT ");
+ status = sBtInterface->init(&bt_callbacks);
+ 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);
+}
+
+void bdt_cleanup(void)
+{
+ bdt_log("CLEANUP");
+ sBtInterface->cleanup();
+}
+
+/*******************************************************************************
+ ** Console commands
+ *******************************************************************************/
+
+void do_help(char *p)
+{
+ int i = 0;
+ int max = 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 *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_cleanup(char *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 },
+
+ /* 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 argc, char * argv[])
+{
+ int opt;
+ char cmd[128];
+ int args_processed = 0;
+ int pid = -1;
+
+ 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;
+}