summaryrefslogtreecommitdiffstats
path: root/btif/src
diff options
context:
space:
mode:
authorAndre Eisenbach <andre@broadcom.com>2012-02-22 13:18:21 -0800
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:11 -0700
commite448862a47c08eb23185aaed574b39264f5005fc (patch)
tree2bc6246e3091315e77224fd798ea2fe8074ef972 /btif/src
parenta2ca4b83ab8bbbfd8d5f6693e927ed4b82094624 (diff)
downloadexternal_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.zip
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.gz
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.bz2
Initial Bluedroid stack commit
Diffstat (limited to 'btif/src')
-rw-r--r--btif/src/bluetooth.c381
-rw-r--r--btif/src/btif_core.c1038
-rw-r--r--btif/src/btif_dm.c1159
-rw-r--r--btif/src/btif_hf.c1010
-rw-r--r--btif/src/btif_storage.c1027
-rw-r--r--btif/src/btif_util.c359
6 files changed, 4974 insertions, 0 deletions
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
new file mode 100644
index 0000000..766f685
--- /dev/null
+++ b/btif/src/bluetooth.c
@@ -0,0 +1,381 @@
+/************************************************************************************
+ *
+ * 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: bluetooth.c
+ *
+ * Description: Bluetooth HAL implementation
+ *
+ ***********************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hf.h>
+
+#define LOG_NDDEBUG 0
+#define LOG_TAG "bluedroid"
+
+#include "btif_api.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#define is_profile(profile, str) ((strlen(str) == strlen(profile)) && strncmp((const char *)profile, str, strlen(str)) == 0)
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+bt_callbacks_t *bt_hal_cbacks = NULL;
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/* list all extended interfaces here */
+
+/* handsfree profile */
+extern bthf_interface_t *btif_hf_get_interface();
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+static uint8_t interface_ready(void)
+{
+ /* add checks here that would prevent API calls other than init to be executed */
+ if (bt_hal_cbacks == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*****************************************************************************
+**
+** BLUETOOTH HAL INTERFACE FUNCTIONS
+**
+*****************************************************************************/
+
+static int init(bt_callbacks_t* callbacks )
+{
+ LOGI("init");
+
+ /* store reference to user callbacks */
+ bt_hal_cbacks = callbacks;
+
+ /* add checks for individual callbacks ? */
+
+ /* init btif */
+ btif_init_bluetooth();
+
+ return BT_STATUS_SUCCESS;
+}
+
+static int enable( void )
+{
+ LOGI("enable");
+
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_enable_bluetooth();
+}
+
+static int disable(void)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_disable_bluetooth();
+}
+
+static void cleanup( void )
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return;
+
+ btif_shutdown_bluetooth();
+
+ /* hal callbacks reset upon shutdown complete callback */
+
+ return;
+}
+
+static int get_adapter_properties(void)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_get_adapter_properties();
+}
+
+static int get_adapter_property(bt_property_type_t type)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_get_adapter_property(type);
+}
+
+static int set_adapter_property(const bt_property_t *property)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_set_adapter_property(property);
+}
+
+int get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_get_remote_device_properties(remote_addr);
+}
+
+int get_remote_device_property(bt_bdaddr_t *remote_addr, bt_property_type_t type)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_get_remote_device_property(remote_addr, type);
+}
+
+int set_remote_device_property(bt_bdaddr_t *remote_addr, const bt_property_t *property)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_set_remote_device_property(remote_addr, property);
+}
+
+int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_get_remote_service_record(remote_addr, uuid);
+}
+
+static int start_discovery(void)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_start_discovery();
+}
+
+static int cancel_discovery(void)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_cancel_discovery();
+}
+
+static int create_bond(const bt_bdaddr_t *bd_addr)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_create_bond(bd_addr);
+}
+
+static int cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_cancel_bond(bd_addr);
+}
+
+static int remove_bond(const bt_bdaddr_t *bd_addr)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_remove_bond(bd_addr);
+}
+
+static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint8_t pin_len, bt_pin_code_t *pin_code)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
+}
+
+static int passkey_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint32_t passkey)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_passkey_reply(bd_addr, accept, passkey);
+}
+
+static int ssp_reply(const bt_bdaddr_t *bd_addr, uint8_t accept)
+{
+ /* sanity check */
+ if (interface_ready() == FALSE)
+ return BT_STATUS_NOT_READY;
+
+ return btif_dm_ssp_reply(bd_addr, accept);
+}
+
+static const void* get_profile_interface (const char *profile_id)
+{
+ LOGI("get_profile_interface %s", profile_id);
+
+ /* check for supported profile interfaces */
+ if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
+ return btif_hf_get_interface();
+
+ if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
+ return NULL;
+
+ return NULL;
+}
+
+static const bt_interface_t bluetoothInterface = {
+ sizeof(bt_interface_t),
+ init,
+ enable,
+ disable,
+ cleanup,
+ get_adapter_properties,
+ get_adapter_property,
+ set_adapter_property,
+ get_remote_device_properties,
+ get_remote_device_property,
+ set_remote_device_property,
+ get_remote_service_record,
+ start_discovery,
+ cancel_discovery,
+ create_bond,
+ remove_bond,
+ cancel_bond,
+ pin_reply,
+ passkey_reply,
+ ssp_reply,
+ get_profile_interface
+};
+
+const bt_interface_t* bluetooth__get_bluetooth_interface ()
+{
+ /* fixme -- add property to disable bt interface ? */
+
+ return &bluetoothInterface;
+}
+
+static int close_bluetooth_stack(struct hw_device_t* device)
+{
+ cleanup();
+ return 0;
+}
+
+static int open_bluetooth_stack (const struct hw_module_t* module, char const* name,
+struct hw_device_t** abstraction)
+{
+ bluetooth_device_t *stack = malloc(sizeof(bluetooth_device_t) );
+ memset(stack, 0, sizeof(bluetooth_device_t) );
+ stack->common.tag = HARDWARE_DEVICE_TAG;
+ stack->common.version = 0;
+ stack->common.module = (struct hw_module_t*)module;
+ stack->common.close = close_bluetooth_stack;
+ stack->get_bluetooth_interface = bluetooth__get_bluetooth_interface;
+ *abstraction = (struct hw_device_t*)stack;
+ return 0;
+}
+
+
+static struct hw_module_methods_t bt_stack_module_methods = {
+ .open = open_bluetooth_stack,
+};
+
+const struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = BT_HARDWARE_MODULE_ID,
+ .name = "Bluetooth Stack",
+ .author = "The Android Open Source Project",
+ .methods = &bt_stack_module_methods
+};
+
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
new file mode 100644
index 0000000..570a7c5
--- /dev/null
+++ b/btif/src/btif_core.c
@@ -0,0 +1,1038 @@
+/************************************************************************************
+ *
+ * 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: btif_core.c
+ *
+ * Description: Contains core functionality related to interfacing between
+ * Bluetooth HAL and BTE core stack.
+ *
+ ***********************************************************************************/
+
+#include <hardware/bluetooth.h>
+#include <string.h>
+
+#define LOG_TAG "BTIF_CORE"
+
+#include "btif_api.h"
+#include "bta_api.h"
+#include "gki.h"
+#include "btu.h"
+#include "bte.h"
+#include "bd.h"
+#include "btif_storage.h"
+#include "btif_util.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef BTIF_TASK_STACK_SIZE
+#define BTIF_TASK_STACK_SIZE 0//0x2000 /* In bytes */
+#endif
+
+#define BTIF_TASK_STR ((INT8 *) "BTIF")
+
+static UINT32 btif_task_stack[(BTIF_TASK_STACK_SIZE + 3) / 4];
+
+/* checks whether any HAL operation other than enable is permitted */
+static int btif_enabled = 0;
+static int btif_shutdown_pending = 0;
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+/* These type definitions are used when passing data from the HAL to BTIF context
+* in the downstream path for the adapter and remote_device property APIs */
+typedef struct {
+ bt_bdaddr_t bd_addr;
+ bt_property_type_t type;
+} btif_storage_read_t;
+
+typedef struct {
+ bt_bdaddr_t bd_addr;
+ bt_property_t prop;
+} btif_storage_write_t;
+
+typedef union {
+ btif_storage_read_t read_req;
+ btif_storage_write_t write_req;
+} btif_storage_req_t;
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+static bt_status_t btif_init_bluetooth_evt(void);
+static bt_status_t btif_shutdown_bluetooth_evt(void);
+
+/* sends message to btif task */
+static void btif_sendmsg(void *p_msg);
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/** TODO: Move these to _common.h */
+void bte_main_boot_entry(void);
+void bte_main_enable(void);
+void bte_main_disable(void);
+void bte_main_shutdown(void);
+#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
+void bte_main_enable_lpm(BOOLEAN enable);
+#endif
+void bte_main_postload_cfg(void);
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+
+/*****************************************************************************
+** Context switching functions
+*****************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function btif_context_switched
+**
+** Description Callback used to execute transferred context callback
+**
+** p_msg : message to be executed in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+
+static void btif_context_switched(void *p_msg)
+{
+ tBTIF_CONTEXT_SWITCH_CBACK *p;
+
+ BTIF_TRACE_VERBOSE0("btif_context_switched");
+
+ p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
+
+ /* each callback knows how to parse the data */
+ if (p->p_cb)
+ p->p_cb(p->event, p->p_param);
+}
+
+
+/*******************************************************************************
+**
+** Function btif_transfer_context
+**
+** Description This function switches context to btif task
+**
+** p_cback : callback used to process message in btif context
+** event : event id of message
+** p_params : parameter area passed to callback (copied)
+** param_len : length of parameter area
+** p_copy_cback : If set this function will be invoked for deep copy
+**
+** Returns void
+**
+*******************************************************************************/
+
+bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback)
+{
+ tBTIF_CONTEXT_SWITCH_CBACK *p_msg;
+
+ BTIF_TRACE_VERBOSE2("btif_transfer_context event %d, len %d", event, param_len);
+
+ /* allocate and send message that will be executed in btif context */
+ if ((p_msg = (tBTIF_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)
+ {
+ p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
+ p_msg->p_cb = p_cback;
+
+ p_msg->event = event; /* callback event */
+
+ /* check if caller has provided a copy callback to do the deep copy */
+ if (p_copy_cback)
+ {
+ p_copy_cback(event, p_msg->p_param, p_params);
+ }
+ else if (p_params)
+ {
+ memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */
+ }
+
+ btif_sendmsg(p_msg);
+ return BT_STATUS_SUCCESS;
+ }
+ else
+ {
+ /* let caller deal with a failed allocation */
+ return BT_STATUS_NOMEM;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_task
+**
+** Description BTIF task handler managing all messages being passed
+** Bluetooth HAL and BTA.
+**
+** Returns void
+**
+*******************************************************************************/
+
+static void btif_task(UINT32 params)
+{
+ UINT16 event;
+ BT_HDR *p_msg;
+
+ BTIF_TRACE_DEBUG0("btif task starting");
+
+ btif_init_bluetooth_evt();
+
+ for(;;)
+ {
+ /* wait for specified events */
+ event = GKI_wait(0xFFFF, 0);
+
+ /*
+ * 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");
+ BTA_EnableBluetooth(bte_dm_evt);
+ }
+
+ if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
+ break;
+
+ if(event & TASK_MBOX_1_EVT_MASK)
+ {
+ while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL)
+ {
+ BTIF_TRACE_VERBOSE1("btif task fetched event %x", p_msg->event);
+
+ switch (p_msg->event)
+ {
+ case BT_EVT_CONTEXT_SWITCH_EVT:
+ btif_context_switched(p_msg);
+ break;
+ default:
+ BTIF_TRACE_ERROR1("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);
+ break;
+ }
+
+ GKI_freebuf(p_msg);
+ }
+ }
+ }
+ btif_shutdown_bluetooth_evt();
+}
+
+
+/*******************************************************************************
+**
+** Function btif_sendmsg
+**
+** Description Sends msg to BTIF task
+**
+** Returns void
+**
+*******************************************************************************/
+
+void btif_sendmsg(void *p_msg)
+{
+ GKI_send_msg(BTIF_TASK, BTU_BTIF_MBOX, p_msg);
+}
+
+/*****************************************************************************
+**
+** btif core api functions
+**
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function btif_init_bluetooth
+**
+** Description Creates BTIF task and prepares BT scheduler for startup
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_init_bluetooth(void)
+{
+ UINT8 status;
+
+ bte_main_boot_entry();
+
+ /* Start the BTIF task */
+ status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
+ (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
+ sizeof(btif_task_stack));
+
+ if (status != GKI_SUCCESS)
+ return BT_STATUS_FAIL;
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_init_bluetooth_evt
+**
+** Description Event indicating bluetooth init is completed
+** Attach btif_task to JVM
+**
+** Returns void
+**
+*******************************************************************************/
+
+static bt_status_t btif_init_bluetooth_evt(void)
+{
+ BTIF_TRACE_DEBUG1("%s: notify ASSOCIATE_JVM", __FUNCTION__);
+ CHECK_CALL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);
+
+ return BT_STATUS_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function btif_enable_bluetooth
+**
+** Description Performs chip power on and kickstarts OS scheduler
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_enable_bluetooth(void)
+{
+ tBTA_STATUS status = BT_STATUS_SUCCESS;
+
+ LOGI("btif_enable_bluetooth");
+
+ if (btif_enabled == 1)
+ {
+ LOGD("already enabled\n");
+ return BT_STATUS_DONE;
+ }
+
+ /* add return status for create tasks functions ? */
+
+ /* Create the GKI tasks and run them */
+ bte_main_enable();
+
+ if (status != BTA_SUCCESS)
+ return BT_STATUS_FAIL;
+
+ return BT_STATUS_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function btif_enable_bluetooth_evt
+**
+** Description Event indicating bluetooth enable is completed
+** Notifies HAL user with updated adapter state
+**
+** Returns void
+**
+*******************************************************************************/
+
+void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd)
+{
+ bt_bdaddr_t bd_addr;
+ bdstr_t bdstr;
+
+ bdcpy(bd_addr.address, local_bd);
+ BTIF_TRACE_DEBUG3("%s: status %d, local bd [%s]", __FUNCTION__, status,
+ bd2str(&bd_addr, &bdstr));
+
+ bte_main_postload_cfg();
+#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
+ bte_main_enable_lpm(TRUE);
+#endif
+ /* add passing up bd address as well ? */
+
+ /* callback to HAL */
+ if (status == BTA_SUCCESS)
+ {
+ /* store state */
+ btif_enabled = 1;
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
+ }
+ else
+ {
+ btif_enabled = 0;
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_disable_bluetooth
+**
+** Description Inititates shutdown of Bluetooth system.
+** Any active links will be dropped and device entering
+** non connectable/discoverable mode
+**
+** Returns void
+**
+*******************************************************************************/
+
+bt_status_t btif_disable_bluetooth(void)
+{
+ tBTA_STATUS status;
+
+ if (btif_enabled == 0)
+ {
+ BTIF_TRACE_ERROR0("btif_disable_bluetooth : not yet enabled");
+ return BT_STATUS_FAIL;
+ }
+
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+
+ status = BTA_DisableBluetooth();
+
+ if (status != BTA_SUCCESS)
+ {
+ BTIF_TRACE_ERROR1("disable bt failed (%d)", status);
+ return BT_STATUS_FAIL;
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_disable_bluetooth_evt
+**
+** Description Event notifying BT disable is now complete.
+** Terminates main stack tasks and notifies HAL
+** user with updated BT state.
+**
+** Returns void
+**
+*******************************************************************************/
+
+void btif_disable_bluetooth_evt(void)
+{
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+
+ bte_main_disable();
+
+ /* callback to HAL */
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
+
+ /* update local state */
+ btif_enabled = 0;
+
+ if (btif_shutdown_pending)
+ {
+ btif_shutdown_bluetooth();
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function btif_shutdown_bluetooth
+**
+** Description Finalizes BT scheduler shutdown and terminates BTIF
+** task.
+**
+** Returns void
+**
+*******************************************************************************/
+
+bt_status_t btif_shutdown_bluetooth(void)
+{
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+
+ if (btif_enabled)
+ {
+ BTIF_TRACE_WARNING0("shutdown while still enabled, initiate disable");
+
+ /* shutdown called prior to disabling, initiate disable */
+ btif_disable_bluetooth();
+ btif_shutdown_pending = 1;
+ return BT_STATUS_SUCCESS;
+ }
+
+ btif_shutdown_pending = 0;
+
+ GKI_destroy_task(BTIF_TASK);
+
+ bte_main_shutdown();
+
+ return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t btif_shutdown_bluetooth_evt(void)
+{
+ BTIF_TRACE_DEBUG1("%s: notify DISASSOCIATE_JVM", __FUNCTION__);
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM);
+
+ /* shutdown complete, all events notified and we reset HAL callbacks */
+ bt_hal_cbacks = NULL;
+
+ return BT_STATUS_SUCCESS;
+}
+
+
+
+/*****************************************************************************
+**
+** btif api adapter property functions
+**
+*****************************************************************************/
+
+static bt_status_t btif_in_get_adapter_properties(void)
+{
+ bt_property_t properties[6];
+ uint32_t num_props;
+
+ bt_bdaddr_t addr;
+ bt_bdname_t name;
+ bt_scan_mode_t mode;
+ uint32_t disc_timeout;
+ bt_bdaddr_t bonded_devices[BTM_SEC_MAX_DEVICE_RECORDS];
+ bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
+ num_props = 0;
+
+ /* BD_ADDR */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDADDR,
+ sizeof(addr), &addr);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ /* BD_NAME */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDNAME,
+ sizeof(name), &name);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ /* SCAN_MODE */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_SCAN_MODE,
+ sizeof(mode), &mode);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ /* DISC_TIMEOUT */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ sizeof(disc_timeout), &disc_timeout);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ /* BONDED_DEVICES */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+ sizeof(bonded_devices), bonded_devices);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ /* LOCAL UUIDs */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_UUIDS,
+ sizeof(local_uuids), local_uuids);
+ btif_storage_get_adapter_property(&properties[num_props]);
+ num_props++;
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb,
+ BT_STATUS_SUCCESS, num_props, properties);
+
+ return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t btif_in_get_remote_device_properties(bt_bdaddr_t *bd_addr)
+{
+ bt_property_t remote_properties[8];
+ uint32_t num_props = 0;
+
+ bt_bdname_t name, alias;
+ uint32_t cod, devtype;
+ bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
+
+ memset(remote_properties, 0, sizeof(remote_properties));
+ BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_BDNAME,
+ sizeof(name), &name);
+ btif_storage_get_remote_device_property(bd_addr,
+ &remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_REMOTE_FRIENDLY_NAME,
+ sizeof(alias), &alias);
+ btif_storage_get_remote_device_property(bd_addr,
+ &remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_CLASS_OF_DEVICE,
+ sizeof(cod), &cod);
+ btif_storage_get_remote_device_property(bd_addr,
+ &remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_TYPE_OF_DEVICE,
+ sizeof(devtype), &devtype);
+ btif_storage_get_remote_device_property(bd_addr,
+ &remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_UUIDS,
+ sizeof(remote_uuids), remote_uuids);
+ btif_storage_get_remote_device_property(bd_addr,
+ &remote_properties[num_props]);
+ num_props++;
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ BT_STATUS_SUCCESS, bd_addr, num_props, remote_properties);
+
+ return BT_STATUS_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function execute_storage_request
+**
+** Description Executes adapter storage request in BTIF context
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static void execute_storage_request(UINT16 event, char *p_param)
+{
+ uint8_t is_local;
+ int num_entries = 0;
+ bt_status_t status = BT_STATUS_SUCCESS;
+
+ BTIF_TRACE_EVENT1("execute storage request event : %d", event);
+
+ switch(event)
+ {
+ case BTIF_CORE_STORAGE_ADAPTER_WRITE:
+ {
+ btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;
+ bt_property_t *p_prop = &(p_req->write_req.prop);
+ BTIF_TRACE_EVENT3("type: %d, len %d, 0x%x", p_prop->type,
+ p_prop->len, p_prop->val);
+
+ status = btif_storage_set_adapter_property(p_prop);
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, p_prop);
+ } break;
+
+ case BTIF_CORE_STORAGE_ADAPTER_READ:
+ {
+ btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;
+ char buf[512];
+ bt_property_t prop;
+ prop.type = p_req->read_req.type;
+ prop.val = (void*)buf;
+ prop.len = sizeof(buf);
+
+ status = btif_storage_get_adapter_property(&prop);
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop);
+ } break;
+
+ case BTIF_CORE_STORAGE_ADAPTER_READ_ALL:
+ {
+ status = btif_in_get_adapter_properties();
+ } break;
+
+ case BTIF_CORE_STORAGE_NOTIFY_STATUS:
+ {
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 0, NULL);
+ } break;
+
+ default:
+ BTIF_TRACE_ERROR2("%s invalid event id (%d)", __FUNCTION__, event);
+ break;
+ }
+}
+
+static void execute_storage_remote_request(UINT16 event, char *p_param)
+{
+ bt_status_t status = BT_STATUS_FAIL;
+ bt_property_t prop;
+
+ BTIF_TRACE_EVENT1("execute storage remote request event : %d", event);
+
+ switch (event)
+ {
+ case BTIF_CORE_STORAGE_REMOTE_READ:
+ {
+ char buf[1024];
+ btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;
+ prop.type = p_req->read_req.type;
+ prop.val = (void*) buf;
+ prop.len = sizeof(buf);
+
+ status = btif_storage_get_remote_device_property(&(p_req->read_req.bd_addr),
+ &prop);
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ status, &(p_req->read_req.bd_addr), 1, &prop);
+ }break;
+ case BTIF_CORE_STORAGE_REMOTE_WRITE:
+ {
+ btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;
+ status = btif_storage_set_remote_device_property(&(p_req->write_req.bd_addr),
+ &(p_req->write_req.prop));
+ }break;
+ case BTIF_CORE_STORAGE_REMOTE_READ_ALL:
+ {
+ btif_storage_req_t *p_req = (btif_storage_req_t*)p_param;
+ btif_in_get_remote_device_properties(&p_req->read_req.bd_addr);
+ }break;
+ }
+}
+
+void btif_adapter_properties_evt(bt_status_t status, uint32_t num_props,
+ bt_property_t *p_props)
+{
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb,
+ status, num_props, p_props);
+
+}
+void btif_remote_properties_evt(bt_status_t status, bt_bdaddr_t *remote_addr,
+ uint32_t num_props, bt_property_t *p_props)
+{
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ status, remote_addr, num_props, p_props);
+}
+
+/*******************************************************************************
+**
+** Function btif_in_storage_request_copy_cb
+**
+** Description Switch context callback function to perform the deep copy for
+** both the adapter and remote_device property API
+**
+** Returns None
+**
+*******************************************************************************/
+static void btif_in_storage_request_copy_cb(UINT16 event,
+ char *p_new_buf, char *p_old_buf)
+{
+ btif_storage_req_t *new_req = (btif_storage_req_t*)p_new_buf;
+ btif_storage_req_t *old_req = (btif_storage_req_t*)p_old_buf;
+
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+ switch (event)
+ {
+ case BTIF_CORE_STORAGE_REMOTE_WRITE:
+ case BTIF_CORE_STORAGE_ADAPTER_WRITE:
+ {
+ bdcpy(new_req->write_req.bd_addr.address, old_req->write_req.bd_addr.address);
+ /* Copy the member variables one at a time */
+ new_req->write_req.prop.type = old_req->write_req.prop.type;
+ new_req->write_req.prop.len = old_req->write_req.prop.len;
+
+ new_req->write_req.prop.val = (UINT8 *)(p_new_buf + sizeof(btif_storage_req_t));
+ memcpy(new_req->write_req.prop.val, old_req->write_req.prop.val,
+ old_req->write_req.prop.len);
+ }break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_get_adapter_properties
+**
+** Description Fetch all available properties (local & remote)
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_get_adapter_properties(void)
+{
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ return btif_transfer_context(execute_storage_request,
+ BTIF_CORE_STORAGE_ADAPTER_READ_ALL,
+ NULL, 0, NULL);
+}
+
+/*******************************************************************************
+**
+** Function btif_get_adapter_property
+**
+** Description Fetches property value from local cache
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_get_adapter_property(bt_property_type_t type)
+{
+ btif_storage_req_t req;
+
+ BTIF_TRACE_EVENT2("%s %d", __FUNCTION__, type);
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ memset(&(req.read_req.bd_addr), 0, sizeof(bt_bdaddr_t));
+ req.read_req.type = type;
+
+ return btif_transfer_context(execute_storage_request,
+ BTIF_CORE_STORAGE_ADAPTER_READ,
+ (char*)&req, sizeof(btif_storage_req_t), NULL);
+}
+
+/*******************************************************************************
+**
+** Function btif_set_adapter_property
+**
+** Description Updates core stack with property value and stores it in
+** local cache
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_set_adapter_property(const bt_property_t *property)
+{
+ btif_storage_req_t req;
+ bt_status_t status = BT_STATUS_SUCCESS;
+ int storage_req_id = BTIF_CORE_STORAGE_NOTIFY_STATUS; /* default */
+
+ BTIF_TRACE_EVENT3("btif_set_adapter_property type: %d, len %d, 0x%x",
+ property->type, property->len, property->val);
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ switch(property->type)
+ {
+ case BT_PROPERTY_BDNAME:
+ {
+ BTIF_TRACE_EVENT1("set property name : %s", (char *)property->val);
+
+ BTA_DmSetDeviceName((char *)property->val);
+
+ storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
+ }
+ break;
+
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ {
+ bt_scan_mode_t mode = *(bt_scan_mode_t*)property->val;
+ tBTA_DM_DISC disc_mode;
+ tBTA_DM_CONN conn_mode;
+
+ switch(mode)
+ {
+ case BT_SCAN_MODE_NONE:
+ disc_mode = BTA_DM_NON_DISC;
+ conn_mode = BTA_DM_NON_CONN;
+ break;
+
+ case BT_SCAN_MODE_CONNECTABLE:
+ disc_mode = BTA_DM_NON_DISC;
+ conn_mode = BTA_DM_CONN;
+ break;
+
+ case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
+ disc_mode = BTA_DM_GENERAL_DISC;
+ conn_mode = BTA_DM_CONN;
+ break;
+
+ default:
+ BTIF_TRACE_ERROR1("invalid scan mode (0x%x)", mode);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ BTIF_TRACE_EVENT1("set property scan mode : %x", mode);
+
+ BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
+
+ storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE;
+ }
+ break;
+ case BT_PROPERTY_BDADDR:
+ case BT_PROPERTY_UUIDS:
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ /* no write support through HAL, these properties are only populated from BTA events */
+ status = BT_STATUS_FAIL;
+ break;
+ default:
+ BTIF_TRACE_ERROR1("btif_get_adapter_property : invalid type %d",
+ property->type);
+ status = BT_STATUS_FAIL;
+ break;
+ }
+
+ if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION)
+ {
+ int btif_status;
+ /* pass on to storage for updating local database */
+
+ memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
+ memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
+
+ return btif_transfer_context(execute_storage_request,
+ storage_req_id,
+ (char*)&req,
+ sizeof(btif_storage_req_t)+property->len,
+ btif_in_storage_request_copy_cb);
+ }
+
+ return status;
+
+}
+
+/*******************************************************************************
+**
+** Function btif_get_remote_device_property
+**
+** Description Fetches the remote device property from the NVRAM
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_get_remote_device_property(bt_bdaddr_t *remote_addr,
+ bt_property_type_t type)
+{
+ btif_storage_req_t req;
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+ req.read_req.type = type;
+ return btif_transfer_context(execute_storage_remote_request,
+ BTIF_CORE_STORAGE_REMOTE_READ,
+ (char*)&req, sizeof(btif_storage_req_t),
+ NULL);
+}
+
+/*******************************************************************************
+**
+** Function btif_get_remote_device_properties
+**
+** Description Fetches all the remote device properties from NVRAM
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+ btif_storage_req_t req;
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+ return btif_transfer_context(execute_storage_remote_request,
+ BTIF_CORE_STORAGE_REMOTE_READ_ALL,
+ (char*)&req, sizeof(btif_storage_req_t),
+ NULL);
+}
+
+/*******************************************************************************
+**
+** Function btif_set_remote_device_property
+**
+** Description Writes the remote device property to NVRAM.
+** Currently, BT_PROPERTY_REMOTE_FRIENDLY_NAME is the only
+** remote device property that can be set
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_set_remote_device_property(bt_bdaddr_t *remote_addr,
+ const bt_property_t *property)
+{
+ btif_storage_req_t req;
+
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ memcpy(&(req.write_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+ memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
+
+ return btif_transfer_context(execute_storage_remote_request,
+ BTIF_CORE_STORAGE_REMOTE_WRITE,
+ (char*)&req,
+ sizeof(btif_storage_req_t)+property->len,
+ btif_in_storage_request_copy_cb);
+}
+
+
+/*******************************************************************************
+**
+** Function btif_get_remote_service_record
+**
+** Description Looks up the service matching uuid on the remote device
+** and fetches the SCN and service_name if the UUID is found
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_get_remote_service_record(bt_bdaddr_t *remote_addr,
+ bt_uuid_t *uuid)
+{
+ if (btif_enabled == 0)
+ return BT_STATUS_FAIL;
+
+ return btif_dm_get_remote_service_record(remote_addr, uuid);
+}
+
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
new file mode 100644
index 0000000..ddd187a
--- /dev/null
+++ b/btif/src/btif_dm.c
@@ -0,0 +1,1159 @@
+/************************************************************************************
+ *
+ * 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: btif_dm.c
+ *
+ * Description: Contains Device Management (DM) related functionality
+ *
+ *
+ ***********************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <hardware/bluetooth.h>
+
+#include <utils/Log.h>
+
+#include "gki.h"
+#include "btu.h"
+#include "bd.h"
+#include "bta_api.h"
+#include "btif_api.h"
+#include "btif_util.h"
+#include "btif_storage.h"
+
+/******************************************************************************
+** Constants & Macros
+******************************************************************************/
+
+#define COD_UNCLASSIFIED ((0x1F) << 8)
+
+#define BTIF_DM_DEFAULT_INQ_MAX_RESULTS 0
+#define BTIF_DM_DEFAULT_INQ_MAX_DURATION 10
+
+typedef struct {
+ BD_ADDR bd_addr;
+ UINT8 is_temp;
+ UINT8 pin_code_len;
+} btif_dm_pairing_cb_t;
+
+#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id))
+
+/******************************************************************************
+** Static functions
+******************************************************************************/
+static btif_dm_pairing_cb_t pairing_cb;
+static bt_status_t btif_dm_get_remote_services(bt_bdaddr_t *remote_addr);
+
+/******************************************************************************
+** Externs
+******************************************************************************/
+extern UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID];
+
+/******************************************************************************
+** Functions
+******************************************************************************/
+
+/*******************************************************************************
+**
+** Function check_eir_remote_name
+**
+** Description Check if remote name is in the EIR data
+**
+** Returns TRUE if remote name found
+** Populate p_remote_name, if provided and remote name found
+**
+*******************************************************************************/
+static BOOLEAN check_eir_remote_name(tBTA_DM_SEARCH *p_search_data,
+ UINT8 *p_remote_name, UINT8 *p_remote_name_len)
+{
+ UINT8 *p_eir_remote_name = NULL;
+ UINT8 remote_name_len = 0;
+
+ /* Check EIR for remote name and services */
+ if (p_search_data->inq_res.p_eir)
+ {
+ p_eir_remote_name = BTA_CheckEirData(p_search_data->inq_res.p_eir,
+ BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
+ if (!p_eir_remote_name)
+ {
+ p_eir_remote_name = BTA_CheckEirData(p_search_data->inq_res.p_eir,
+ BTM_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
+ }
+
+ if (p_eir_remote_name)
+ {
+ if (remote_name_len > BD_NAME_LEN)
+ remote_name_len = BD_NAME_LEN;
+
+ if (p_remote_name && p_remote_name_len)
+ {
+ memcpy(p_remote_name, p_eir_remote_name, remote_name_len);
+ *(p_remote_name + remote_name_len) = 0;
+ *p_remote_name_len = remote_name_len;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function check_cached_remote_name
+**
+** Description Check if remote name is in the NVRAM cache
+**
+** Returns TRUE if remote name found
+** Populate p_remote_name, if provided and remote name found
+**
+*******************************************************************************/
+static BOOLEAN check_cached_remote_name(tBTA_DM_SEARCH *p_search_data,
+ UINT8 *p_remote_name, UINT8 *p_remote_name_len)
+{
+ bt_bdname_t bdname;
+ bt_bdaddr_t remote_bdaddr;
+ bt_property_t prop_name;
+
+ /* check if we already have it in our btif_storage cache */
+ bdcpy(remote_bdaddr.address, p_search_data->inq_res.bd_addr);
+ BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
+ sizeof(bt_bdname_t), &bdname);
+ if (btif_storage_get_remote_device_property(
+ &remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS)
+ {
+ if (p_remote_name && p_remote_name_len)
+ {
+ strcpy((char *)p_remote_name, (char *)bdname.name);
+ *p_remote_name_len = strlen((char *)p_remote_name);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function search_devices_copy_cb
+**
+** Description Deep copy callback for search devices event
+**
+** Returns void
+**
+*******************************************************************************/
+static void search_devices_copy_cb(UINT16 event, char *p_dest, char *p_src)
+{
+ tBTA_DM_SEARCH *p_dest_data = (tBTA_DM_SEARCH *) p_dest;
+ tBTA_DM_SEARCH *p_src_data = (tBTA_DM_SEARCH *) p_src;
+
+ if (!p_src)
+ return;
+
+ BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_dm_search_event(event));
+ memcpy(p_dest_data, p_src_data, sizeof(tBTA_DM_SEARCH));
+ switch (event)
+ {
+ case BTA_DM_INQ_RES_EVT:
+ {
+ if (p_src_data->inq_res.p_eir)
+ {
+ p_dest_data->inq_res.p_eir = (UINT8 *)(p_dest + sizeof(tBTA_DM_SEARCH));
+ memcpy(p_dest_data->inq_res.p_eir, p_src_data->inq_res.p_eir, HCI_EXT_INQ_RESPONSE_LEN);
+ }
+ }
+ break;
+
+ case BTA_DM_DISC_RES_EVT:
+ {
+ if (p_src_data->disc_res.raw_data_size && p_src_data->disc_res.p_raw_data)
+ {
+ p_dest_data->disc_res.p_raw_data = (UINT8 *)(p_dest + sizeof(tBTA_DM_SEARCH));
+ memcpy(p_dest_data->disc_res.p_raw_data,
+ p_src_data->disc_res.p_raw_data, p_src_data->disc_res.raw_data_size);
+ }
+ }
+ break;
+ }
+}
+
+/******************************************************************************
+**
+** BTIF DM callback events
+**
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function btif_dm_pin_req_evt
+**
+** Description Executes pin request event in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ *p_pin_req)
+{
+ bt_bdaddr_t bd_addr;
+ bt_bdname_t bd_name;
+ UINT32 cod;
+
+ bdcpy(bd_addr.address, p_pin_req->bd_addr);
+ memcpy(bd_name.name, p_pin_req->bd_name, BD_NAME_LEN);
+
+ memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
+ bdcpy(pairing_cb.bd_addr, p_pin_req->bd_addr);
+
+ cod = devclass2uint(p_pin_req->dev_class);
+
+ if ( cod == 0) {
+ LOGD("cod is 0, set as unclassified");
+ cod = COD_UNCLASSIFIED;
+ }
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, pin_request_cb,
+ &bd_addr, &bd_name, cod);
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_ssp_cfm_req_evt
+**
+** Description Executes SSP confirm request event in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_ssp_cfm_req)
+{
+ bt_bdaddr_t bd_addr;
+ bt_bdname_t bd_name;
+ UINT32 cod;
+
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ bdcpy(bd_addr.address, p_ssp_cfm_req->bd_addr);
+ memcpy(bd_name.name, p_ssp_cfm_req->bd_name, BD_NAME_LEN);
+
+ /* Set the pairing_cb based on the local & remote authentication requirements */
+ memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
+ bdcpy(pairing_cb.bd_addr, p_ssp_cfm_req->bd_addr);
+
+ if ((p_ssp_cfm_req->loc_auth_req >= BTM_AUTH_AP_NO && p_ssp_cfm_req->rmt_auth_req >= BTM_AUTH_AP_NO) ||
+ (p_ssp_cfm_req->loc_auth_req == BTM_AUTH_AP_NO || p_ssp_cfm_req->loc_auth_req == BTM_AUTH_AP_YES) ||
+ (p_ssp_cfm_req->rmt_auth_req == BTM_AUTH_AP_NO || p_ssp_cfm_req->rmt_auth_req == BTM_AUTH_AP_YES))
+ pairing_cb.is_temp = FALSE;
+ else
+ pairing_cb.is_temp = TRUE;
+
+ /* If JustWorks auto-accept */
+ if (p_ssp_cfm_req->just_works)
+ {
+ BTIF_TRACE_EVENT1("%s: Auto-accept JustWorks pairing", __FUNCTION__);
+ btif_dm_ssp_reply(&bd_addr, TRUE);
+ return;
+ }
+
+ cod = devclass2uint(p_ssp_cfm_req->dev_class);
+
+ if ( cod == 0) {
+ LOGD("cod is 0, set as unclassified");
+ cod = COD_UNCLASSIFIED;
+ }
+
+ /* TODO: pairing variant? */
+ CHECK_CALL_CBACK(bt_hal_cbacks, ssp_request_cb, &bd_addr, &bd_name,
+ cod, BT_SSP_VARIANT_CONSENT,
+ p_ssp_cfm_req->num_val);
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_auth_cmpl_evt
+**
+** Description Executes authentication complete event in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
+{
+ /* Save link key, if not temporary */
+ bt_bdaddr_t bd_addr;
+ bt_status_t status = BT_STATUS_FAIL;
+ bt_bond_state_t state = BT_BOND_STATE_NONE;
+
+ bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
+ if ( (p_auth_cmpl->success == TRUE) && (p_auth_cmpl->key_present) )
+ {
+ if ((p_auth_cmpl->key_type < HCI_LKEY_TYPE_DEBUG_COMB) || (p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB) ||
+ (p_auth_cmpl->key_type == HCI_LKEY_TYPE_CHANGED_COMB) || (!pairing_cb.is_temp))
+ {
+ bt_status_t ret;
+ BTIF_TRACE_DEBUG3("%s: Storing link key. key_type=0x%x, is_temp=%d",
+ __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.is_temp);
+ ret = btif_storage_add_bonded_device(&bd_addr,
+ p_auth_cmpl->key, p_auth_cmpl->key_type,
+ pairing_cb.pin_code_len);
+ ASSERTC(ret == BT_STATUS_SUCCESS, "storing link key failed", ret);
+ }
+ else
+ {
+ BTIF_TRACE_DEBUG3("%s: Temporary key. Not storing. key_type=0x%x, is_temp=%d",
+ __FUNCTION__, p_auth_cmpl->key_type, pairing_cb.is_temp);
+ }
+ }
+
+ if (p_auth_cmpl->success)
+ {
+ status = BT_STATUS_SUCCESS;
+ state = BT_BOND_STATE_BONDED;
+
+ /* Trigger SDP on the device */
+ btif_dm_get_remote_services(&bd_addr);
+ }
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &bd_addr, state);
+
+ memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
+}
+
+/******************************************************************************
+**
+** Function btif_dm_search_devices_evt
+**
+** Description Executes search devices callback events in btif context
+**
+** Returns void
+**
+******************************************************************************/
+static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
+{
+ tBTA_DM_SEARCH *p_search_data;
+ BTIF_TRACE_EVENT2("%s event=%s", __FUNCTION__, dump_dm_search_event(event));
+
+ switch (event)
+ {
+ case BTA_DM_DISC_RES_EVT:
+ {
+ p_search_data = (tBTA_DM_SEARCH *)p_param;
+ /* Remote name update */
+ if (strlen((const char *) p_search_data->disc_res.bd_name))
+ {
+ bt_property_t properties[1];
+ bt_bdaddr_t bdaddr;
+ bt_status_t status;
+
+ properties[0].type = BT_PROPERTY_BDNAME;
+ properties[0].val = p_search_data->disc_res.bd_name;
+ properties[0].len = strlen((char *)p_search_data->disc_res.bd_name)+1;
+ bdcpy(bdaddr.address, p_search_data->disc_res.bd_addr);
+
+ status = btif_storage_set_remote_device_property(&bdaddr, &properties[0]);
+ ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device property", status);
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ status, &bdaddr, 1, properties);
+ }
+ /* TODO: Services? */
+ }
+ break;
+
+ case BTA_DM_INQ_RES_EVT:
+ {
+ /* inquiry result */
+ UINT32 cod;
+ UINT8 *p_eir_remote_name = NULL;
+ bt_bdname_t bdname;
+ bt_bdaddr_t bdaddr;
+ UINT8 remote_name_len;
+ UINT8 *p_cached_name = NULL;
+ tBTA_SERVICE_MASK services = 0;
+ bdstr_t bdstr;
+
+ p_search_data = (tBTA_DM_SEARCH *)p_param;
+ bdcpy(bdaddr.address, p_search_data->inq_res.bd_addr);
+
+ BTIF_TRACE_DEBUG3("%s() %s device_type = 0x%x\n", __FUNCTION__, bd2str(&bdaddr, &bdstr),
+#if (BLE_INCLUDED == TRUE)
+ p_search_data->inq_res.device_type);
+#else
+ BT_DEVICE_TYPE_BREDR);
+#endif
+ bdname.name[0] = 0;
+
+ cod = devclass2uint (p_search_data->inq_res.dev_class);
+
+ if ( cod == 0) {
+ LOGD("cod is 0, set as unclassified");
+ cod = COD_UNCLASSIFIED;
+ }
+
+ if (!check_eir_remote_name(p_search_data, bdname.name, &remote_name_len))
+ check_cached_remote_name(p_search_data, bdname.name, &remote_name_len);
+
+ /* Check EIR for remote name and services */
+ if (p_search_data->inq_res.p_eir)
+ {
+ BTA_GetEirService(p_search_data->inq_res.p_eir, &services);
+ BTIF_TRACE_DEBUG2("%s()EIR BTA services = %08X", __FUNCTION__, (UINT32)services);
+ /* TODO: Get the service list and check to see which uuids we got and send it back to the client. */
+ }
+
+
+ {
+ bt_property_t properties[5];
+ bt_device_type_t dev_type;
+ uint32_t num_properties = 0;
+ bt_status_t status;
+
+ memset(properties, 0, sizeof(properties));
+ /* BD_ADDR */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
+ BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr);
+ num_properties++;
+ /* BD_NAME */
+ /* Don't send BDNAME if it is empty */
+ if (bdname.name[0]) {
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
+ BT_PROPERTY_BDNAME,
+ strlen((char *)bdname.name)+1, &bdname);
+ num_properties++;
+ }
+
+ /* DEV_CLASS */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
+ BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod), &cod);
+ num_properties++;
+ /* DEV_TYPE */
+#if (BLE_INCLUDED == TRUE)
+ /* FixMe: Assumption is that bluetooth.h and BTE enums match */
+ dev_type = p_search_data->inq_res.device_type;
+#else
+ dev_type = BT_DEVICE_TYPE_BREDR;
+#endif
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
+ BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
+ num_properties++;
+ /* RSSI */
+ BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
+ BT_PROPERTY_REMOTE_RSSI, sizeof(int8_t),
+ &(p_search_data->inq_res.rssi));
+ num_properties++;
+
+ status = btif_storage_add_remote_device(&bdaddr, num_properties, properties);
+ ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device (inquiry)", status);
+
+ /* Callback to notify upper layer of device */
+ CHECK_CALL_CBACK(bt_hal_cbacks, device_found_cb,
+ num_properties, properties);
+ }
+ }
+ break;
+
+ case BTA_DM_INQ_CMPL_EVT:
+ {
+ }
+ break;
+
+ case BTA_DM_DISC_CMPL_EVT:
+ case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
+ {
+ CHECK_CALL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STOPPED);
+ }
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_search_services_evt
+**
+** Description Executes search services event in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_search_services_evt(UINT16 event, char *p_param)
+{
+ tBTA_DM_SEARCH *p_data = (tBTA_DM_SEARCH*)p_param;
+
+ BTIF_TRACE_EVENT2("%s: event = %d", __FUNCTION__, event);
+ switch (event)
+ {
+ case BTA_DM_DISC_RES_EVT:
+ {
+ bt_uuid_t uuid_arr[BT_MAX_NUM_UUIDS]; /* Max 32 services */
+ bt_property_t prop;
+ uint32_t i = 0, j = 0;
+ bt_bdaddr_t bd_addr;
+ bt_status_t ret;
+
+ bdcpy(bd_addr.address, p_data->disc_res.bd_addr);
+
+ BTIF_TRACE_DEBUG3("%s:(result=0x%x, services 0x%x)", __FUNCTION__,
+ p_data->disc_res.result, p_data->disc_res.services);
+ prop.type = BT_PROPERTY_UUIDS;
+ prop.val = (void*)uuid_arr;
+ prop.len = 0;
+ for (i=0; i < BTA_MAX_SERVICE_ID; i++)
+ {
+ if(p_data->disc_res.services
+ &(tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i)))
+ {
+ memset(&uuid_arr[j], 0, sizeof(bt_uuid_t));
+ uuid16_to_uuid128(bta_service_id_to_uuid_lkup_tbl[i], &uuid_arr[j]);
+ prop.len += sizeof(bt_uuid_t);
+ j++;
+ }
+ }
+ /* Also write this to the NVRAM */
+ ret = btif_storage_set_remote_device_property(&bd_addr, &prop);
+ ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", ret);
+
+ /* Send the event to the BTIF */
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ BT_STATUS_SUCCESS, &bd_addr, 1, &prop);
+ }
+ break;
+
+ default:
+ {
+ ASSERTC(0, "unhandled search services event", event);
+ }
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_remote_service_record_evt
+**
+** Description Executes search service record event in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_remote_service_record_evt(UINT16 event, char *p_param)
+{
+ tBTA_DM_SEARCH *p_data = (tBTA_DM_SEARCH*)p_param;
+
+ BTIF_TRACE_EVENT2("%s: event = %d", __FUNCTION__, event);
+ switch (event)
+ {
+ case BTA_DM_DISC_RES_EVT:
+ {
+ bt_service_record_t rec;
+ bt_property_t prop;
+ uint32_t i = 0;
+ bt_bdaddr_t bd_addr;
+
+ memset(&rec, 0, sizeof(bt_service_record_t));
+ bdcpy(bd_addr.address, p_data->disc_res.bd_addr);
+
+ BTIF_TRACE_DEBUG3("%s:(result=0x%x, services 0x%x)", __FUNCTION__,
+ p_data->disc_res.result, p_data->disc_res.services);
+ prop.type = BT_PROPERTY_SERVICE_RECORD;
+ prop.val = (void*)&rec;
+ prop.len = sizeof(rec);
+
+ /* disc_res.result is overloaded with SCN. Cannot check result */
+ p_data->disc_res.services &= ~BTA_USER_SERVICE_MASK;
+ /* TODO: Get the UUID as well */
+ rec.channel = p_data->disc_res.result - 3;
+ /* TODO: Need to get the service name using p_raw_data */
+ rec.name[0] = 0;
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+ BT_STATUS_SUCCESS, &bd_addr, 1, &prop);
+ }
+ break;
+
+ default:
+ {
+ ASSERTC(0, "unhandled remote service record event", event);
+ }
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_upstreams_cback
+**
+** Description Executes UPSTREAMS events in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
+{
+ tBTA_DM_SEC_EVT dm_event = (tBTA_DM_SEC_EVT)event;
+ tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param;
+
+ BTIF_TRACE_EVENT1("btif_dm_upstreams_cback ev: %d", event);
+
+ switch (event)
+ {
+ case BTA_DM_ENABLE_EVT:
+ {
+ BD_NAME bdname;
+ bt_status_t status;
+ bt_property_t prop;
+ prop.type = BT_PROPERTY_BDNAME;
+ prop.len = 0;
+ prop.val = (void*)bdname;
+
+ status = btif_storage_get_adapter_property(&prop);
+ /* Storage does not have a name yet.
+ ** Use the default name and write it to the chip
+ */
+ if (status != BT_STATUS_SUCCESS)
+ {
+ /* TODO: BTM_DEF_LOCAL_NAME should be configurable */
+ BTA_DmSetDeviceName(BTM_DEF_LOCAL_NAME);
+ /* Hmmm...Should we store this too??? */
+ }
+ else
+ {
+ /* A name exists in the storage. Make this the device name */
+ BTA_DmSetDeviceName((char*)prop.val);
+ }
+ /* This function will also trigger the adapter_properties_cb
+ ** and bonded_devices_info_cb
+ */
+ btif_storage_load_bonded_devices();
+ btif_enable_bluetooth_evt(p_data->enable.status, p_data->enable.bd_addr);
+ }
+ break;
+
+ case BTA_DM_DISABLE_EVT:
+ btif_disable_bluetooth_evt();
+ break;
+
+ case BTA_DM_PIN_REQ_EVT:
+ btif_dm_pin_req_evt(&p_data->pin_req);
+ break;
+
+ case BTA_DM_AUTH_CMPL_EVT:
+ btif_dm_auth_cmpl_evt(&p_data->auth_cmpl);
+ break;
+
+ case BTA_DM_SP_CFM_REQ_EVT:
+ btif_dm_ssp_cfm_req_evt(&p_data->cfm_req);
+ break;
+
+ case BTA_DM_AUTHORIZE_EVT:
+ case BTA_DM_LINK_DOWN_EVT:
+ case BTA_DM_SIG_STRENGTH_EVT:
+ case BTA_DM_BUSY_LEVEL_EVT:
+ case BTA_DM_BOND_CANCEL_CMPL_EVT:
+ case BTA_DM_SP_KEY_NOTIF_EVT:
+ case BTA_DM_SP_RMT_OOB_EVT:
+ case BTA_DM_SP_KEYPRESS_EVT:
+ case BTA_DM_ROLE_CHG_EVT:
+ case BTA_DM_BLE_KEY_EVT:
+ case BTA_DM_BLE_SEC_REQ_EVT:
+ case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
+ case BTA_DM_BLE_PASSKEY_REQ_EVT:
+ case BTA_DM_BLE_OOB_REQ_EVT:
+ case BTA_DM_BLE_LOCAL_IR_EVT:
+ case BTA_DM_BLE_LOCAL_ER_EVT:
+ case BTA_DM_BLE_AUTH_CMPL_EVT:
+ default:
+ BTIF_TRACE_WARNING1( "btif_dm_cback : unhandled event (%d)", event );
+ break;
+ }
+} /* btui_security_cback() */
+
+
+/*******************************************************************************
+**
+** Function btif_dm_generic_evt
+**
+** Description Executes non-BTA upstream events in BTIF context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_dm_generic_evt(UINT16 event, char* p_param)
+{
+ BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event);
+ switch(event)
+ {
+ case BTIF_DM_CB_DISCOVERY_STARTED:
+ {
+ CHECK_CALL_CBACK(bt_hal_cbacks, discovery_state_changed_cb, BT_DISCOVERY_STARTED);
+ }
+ break;
+
+ case BTIF_DM_CB_REMOVED_BONDING:
+ {
+ bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param;
+ bt_status_t status;
+
+ status = btif_storage_remove_bonded_device(bd_addr);
+ ASSERTC(status == BT_STATUS_SUCCESS, "failed to delete bonded device", status);
+
+ CHECK_CALL_CBACK(bt_hal_cbacks, bond_state_changed_cb,
+ BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_NONE);
+ }
+ break;
+
+ default:
+ {
+ BTIF_TRACE_WARNING2("%s : Unknown event 0x%x", __FUNCTION__, event);
+ }
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bte_dm_evt
+**
+** Description Switches context from BTE to BTIF for all DM events
+**
+** Returns void
+**
+*******************************************************************************/
+
+void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data)
+{
+ bt_status_t status;
+
+ /* switch context to btif task context (copy full union size for convenience) */
+ status = btif_transfer_context(btif_dm_upstreams_evt, (uint16_t)event, (void*)p_data, sizeof(tBTA_DM_SEC), NULL);
+
+ /* catch any failed context transfers */
+ ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
+}
+
+/*******************************************************************************
+**
+** Function bte_search_devices_evt
+**
+** Description Switches context from BTE to BTIF for DM search events
+**
+** Returns void
+**
+*******************************************************************************/
+static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
+{
+ UINT16 param_len = 0;
+
+ if (p_data)
+ param_len += sizeof(tBTA_DM_SEARCH);
+ /* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */
+ switch (event)
+ {
+ case BTA_DM_INQ_RES_EVT:
+ {
+ if (p_data->inq_res.p_eir)
+ param_len += HCI_EXT_INQ_RESPONSE_LEN;
+ }
+ break;
+
+ case BTA_DM_DISC_RES_EVT:
+ {
+ if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data)
+ param_len += p_data->disc_res.raw_data_size;
+ }
+ break;
+ }
+ BTIF_TRACE_DEBUG3("%s event=%s param_len=%d", __FUNCTION__, dump_dm_search_event(event), param_len);
+
+ /* if remote name is available in EIR, set teh flag so that stack doesnt trigger RNR */
+ if (event == BTA_DM_INQ_RES_EVT)
+ p_data->inq_res.remt_name_not_required = check_eir_remote_name(p_data, NULL, NULL);
+
+ btif_transfer_context (btif_dm_search_devices_evt , (UINT16) event, (void *)p_data, param_len,
+ (param_len > sizeof(tBTA_DM_SEARCH)) ? search_devices_copy_cb : NULL);
+}
+
+/*******************************************************************************
+**
+** Function bte_dm_search_services_evt
+**
+** Description Switches context from BTE to BTIF for DM search services
+** event
+**
+** Returns void
+**
+*******************************************************************************/
+static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
+{
+ /* TODO: The only member that needs a deep copy is the p_raw_data. But not sure yet if this is needed. */
+ btif_transfer_context(btif_dm_search_services_evt, event, (char*)p_data, sizeof(tBTA_DM_SEARCH), NULL);
+}
+
+/*******************************************************************************
+**
+** Function bte_dm_remote_service_record_evt
+**
+** Description Switches context from BTE to BTIF for DM search service
+** record event
+**
+** Returns void
+**
+*******************************************************************************/
+static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
+{
+ /* TODO: The only member that needs a deep copy is the p_raw_data. But not sure yet if this is needed. */
+ btif_transfer_context(btif_dm_remote_service_record_evt, event, (char*)p_data, sizeof(tBTA_DM_SEARCH), NULL);
+}
+
+/*****************************************************************************
+**
+** btif api functions (no context switch)
+**
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function btif_dm_start_discovery
+**
+** Description Start device discovery/inquiry
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_dm_start_discovery(void)
+{
+ tBTA_DM_INQ inq_params;
+ tBTA_SERVICE_MASK services = 0;
+
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+ /* TODO: Do we need to handle multiple inquiries at the same time? */
+
+ /* Set inquiry params and call API */
+#if (BLE_INCLUDED == TRUE)
+ inq_params.mode = BTA_DM_GENERAL_INQUIRY|BTA_BLE_GENERAL_INQUIRY;
+#else
+ inq_params.mode = BTA_DM_GENERAL_INQUIRY;
+#endif
+ inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION;
+
+ inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
+ inq_params.report_dup = TRUE;
+
+ inq_params.filter_type = BTA_DM_INQ_CLR;
+ /* TODO: Filter device by BDA needs to be implemented here */
+
+ /* find nearby devices */
+ BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
+
+ /* Invoke the discovery_started callback */
+ btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_DISCOVERY_STARTED, NULL, 0, NULL);
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_cancel_discovery
+**
+** Description Cancels search
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_dm_cancel_discovery(void)
+{
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+ BTA_DmSearchCancel();
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_create_bond
+**
+** Description Initiate bonding with the specified device
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_dm_create_bond(const bt_bdaddr_t *bd_addr)
+{
+ bdstr_t bdstr;
+
+ BTIF_TRACE_EVENT2("%s: bd_addr=%s", __FUNCTION__, bd2str((bt_bdaddr_t *) bd_addr, &bdstr));
+
+ /* TODO:
+ ** 1. Check if ACL is already up with this device
+ ** 2. Disable unpaired devices from connecting while we are bonding
+ ** 3. special handling for HID devices
+ */
+
+ BTA_DmBond ((UINT8 *)bd_addr->address);
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_cancel_bond
+**
+** Description Initiate bonding with the specified device
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_dm_cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+ bdstr_t bdstr;
+
+ BTIF_TRACE_EVENT2("%s: bd_addr=%s", __FUNCTION__, bd2str((bt_bdaddr_t *)bd_addr, &bdstr));
+
+ /* TODO:
+ ** 1. Check if ACL is already up with this device
+ ** 2. Restore scan modes
+ ** 3. special handling for HID devices
+ */
+ BTA_DmBondCancel ((UINT8 *)bd_addr->address);
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_remove_bond
+**
+** Description Removes bonding with the specified device
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr)
+{
+ bdstr_t bdstr;
+
+ BTIF_TRACE_EVENT2("%s: bd_addr=%s", __FUNCTION__, bd2str((bt_bdaddr_t *)bd_addr, &bdstr));
+
+ /* TODO: special handling for HID devices */
+ if (BTA_DmRemoveDevice((UINT8 *)bd_addr->address) == BTA_SUCCESS)
+ {
+ BTIF_TRACE_DEBUG1("Successfully removed bonding with device: %s",
+ bd2str((bt_bdaddr_t *)bd_addr, &bdstr));
+
+ /* Device shall be removed from the storage in the btif context */
+ btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_REMOVED_BONDING,
+ (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+ }
+ else
+ {
+ /* TODO: ACL is already up with this device, disconnect and then issue RemoveBond */
+ BTIF_TRACE_WARNING0("ACL connection exists with device. Disconnect and issue remove bonding");
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_pin_reply
+**
+** Description BT legacy pairing - PIN code reply
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_dm_pin_reply( const bt_bdaddr_t *bd_addr, uint8_t accept,
+ uint8_t pin_len, bt_pin_code_t *pin_code)
+{
+ BTIF_TRACE_EVENT2("%s: accept=%d", __FUNCTION__, accept);
+
+ BTA_DmPinReply( (UINT8 *)bd_addr->address, accept, pin_len, pin_code->pin);
+
+ if (accept)
+ pairing_cb.pin_code_len = pin_len;
+ else
+ memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_passkey_reply
+**
+** Description BT SSP passkey reply
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_dm_passkey_reply(const bt_bdaddr_t *bd_addr,
+ uint8_t accept, uint32_t passkey)
+{
+ /* This is not implemented in the stack.
+ ** For devices with display, this is not needed
+ */
+ BTIF_TRACE_WARNING1("%s: Not implemented", __FUNCTION__);
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_ssp_reply
+**
+** Description BT SSP Reply - Just Works & Numeric Comparison
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_dm_ssp_reply(const bt_bdaddr_t *bd_addr, uint8_t accept)
+{
+ BTIF_TRACE_EVENT2("%s: accept=%d", __FUNCTION__, accept);
+ BTA_DmConfirm( (UINT8 *)bd_addr->address, accept);
+ if (!accept)
+ memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_get_adapter_property
+**
+** Description Queries the BTA for the adapter property
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_dm_get_adapter_property(bt_property_t *prop)
+{
+ bt_status_t status;
+
+ BTIF_TRACE_EVENT2("%s: type=0x%x", __FUNCTION__, prop->type);
+ switch (prop->type)
+ {
+ case BT_PROPERTY_BDNAME:
+ {
+ bt_bdname_t *bd_name = (bt_bdname_t*)prop->val;
+ strcpy((char *)bd_name->name, BTM_DEF_LOCAL_NAME);
+ prop->len = strlen((char *)bd_name->name)+1;
+ }
+ break;
+
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ {
+ /* if the storage does not have it. Most likely app never set it. Default is NONE */
+ bt_scan_mode_t *mode = (bt_scan_mode_t*)prop->val;
+ *mode = BT_SCAN_MODE_NONE;
+ prop->len = sizeof(bt_scan_mode_t);
+ }
+ break;
+
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ {
+ uint32_t *tmt = (uint32_t*)prop->val;
+ *tmt = 0;
+ prop->len = sizeof(uint32_t);
+ }
+ break;
+
+ default:
+ prop->len = 0;
+ return BT_STATUS_FAIL;
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_get_remote_services
+**
+** Description Start SDP to get remote services
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_dm_get_remote_services(bt_bdaddr_t *remote_addr)
+{
+ bdstr_t bdstr;
+
+ BTIF_TRACE_EVENT2("%s: remote_addr=%s", __FUNCTION__, bd2str(remote_addr, &bdstr));
+
+ BTA_DmDiscover(remote_addr->address, BTA_ALL_SERVICE_MASK,
+ bte_dm_search_services_evt, TRUE);
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_dm_get_remote_service_record
+**
+** Description Start SDP to get remote service record
+**
+**
+** Returns bt_status_t
+*******************************************************************************/
+bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t *remote_addr,
+ bt_uuid_t *uuid)
+{
+ tSDP_UUID sdp_uuid;
+ bdstr_t bdstr;
+
+ BTIF_TRACE_EVENT2("%s: remote_addr=%s", __FUNCTION__, bd2str(remote_addr, &bdstr));
+
+ sdp_uuid.len = MAX_UUID_SIZE;
+ memcpy(sdp_uuid.uu.uuid128, uuid->uu, MAX_UUID_SIZE);
+
+ BTA_DmDiscoverUUID(remote_addr->address, &sdp_uuid,
+ bte_dm_remote_service_record_evt, TRUE);
+
+ return BT_STATUS_SUCCESS;
+}
diff --git a/btif/src/btif_hf.c b/btif/src/btif_hf.c
new file mode 100644
index 0000000..7f0e6bc
--- /dev/null
+++ b/btif/src/btif_hf.c
@@ -0,0 +1,1010 @@
+/************************************************************************************
+ *
+ * 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: btif_hf.c
+ *
+ * Description: Handsfree Profile Bluetooth Interface
+ *
+ *
+ ***********************************************************************************/
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hf.h>
+
+#define LOG_TAG "BTIF_HF"
+#include "btif_common.h"
+#include "btif_util.h"
+
+#include "bd.h"
+#include "bta_ag_api.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+/* TODO: Should these be moved to a conf file? */
+#define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK)
+#define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
+#define BTIF_HF_FEATURES (BTA_AG_FEAT_ECNR | \
+ BTA_AG_FEAT_REJECT | \
+ BTA_AG_FEAT_ECS | \
+ BTA_AG_FEAT_ECC | \
+ BTA_AG_FEAT_EXTERR | \
+ BTA_AG_FEAT_BTRH | \
+ BTA_AG_FEAT_VREC)
+#define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
+#define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
+
+#define BTIF_HF_ID_1 0
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+static bthf_callbacks_t *bt_hf_callbacks = NULL;
+
+#define CHECK_BTHF_INIT() if (bt_hf_callbacks == NULL)\
+ {\
+ BTIF_TRACE_WARNING1("BTHF: %s: BTHF not initialized", __FUNCTION__);\
+ return BT_STATUS_NOT_READY;\
+ }\
+ else\
+ {\
+ BTIF_TRACE_EVENT1("BTHF: %s", __FUNCTION__);\
+ }
+
+
+/* BTIF-HF control block to map bdaddr to BTA handle */
+typedef struct _btif_hf_cb
+{
+ UINT16 handle;
+ bt_bdaddr_t connected_bda;
+ bthf_connection_state_t state;
+ bthf_vr_state_t vr_state;
+ tBTA_AG_PEER_FEAT peer_feat;
+ int num_active;
+ int num_held;
+ bthf_call_state_t call_setup_state;
+} btif_hf_cb_t;
+
+static btif_hf_cb_t btif_hf_cb;
+
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function is_connected
+**
+** Description Internal function to check if HF is connected
+**
+** Returns TRUE if connected
+**
+*******************************************************************************/
+static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
+{
+ if ((btif_hf_cb.state == BTHF_CONNECTION_STATE_CONNECTED) &&
+ ((bd_addr == NULL) || (bdcmp(bd_addr->address, btif_hf_cb.connected_bda.address) == 0)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function callstate_to_callsetup
+**
+** Description Converts HAL call state to BTA call setup indicator value
+**
+** Returns BTA call indicator value
+**
+*******************************************************************************/
+static UINT8 callstate_to_callsetup(bthf_call_state_t call_state)
+{
+ UINT8 call_setup = 0;
+ if (call_state == BTHF_CALL_STATE_INCOMING)
+ call_setup = 1;
+ if (call_state == BTHF_CALL_STATE_DIALING)
+ call_setup = 2;
+ if (call_state == BTHF_CALL_STATE_ALERTING)
+ call_setup = 3;
+
+ return call_setup;
+}
+
+/*******************************************************************************
+**
+** Function send_at_result
+**
+** Description Send AT result code (OK/ERROR)
+**
+** Returns void
+**
+*******************************************************************************/
+static void send_at_result(UINT8 ok_flag, UINT16 errcode)
+{
+ tBTA_AG_RES_DATA ag_res;
+ memset (&ag_res, 0, sizeof (ag_res));
+
+ ag_res.ok_flag = ok_flag;
+ if (ok_flag == BTA_AG_OK_ERROR)
+ {
+ ag_res.errcode = errcode;
+ }
+
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
+}
+
+/*******************************************************************************
+**
+** Function send_indicator_update
+**
+** Description Send indicator update (CIEV)
+**
+** Returns void
+**
+*******************************************************************************/
+static void send_indicator_update (UINT16 indicator, UINT16 value)
+{
+ tBTA_AG_RES_DATA ag_res;
+
+ memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
+ ag_res.ind.id = indicator;
+ ag_res.ind.value = value;
+
+ BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
+}
+
+/*****************************************************************************
+** Section name (Group of functions)
+*****************************************************************************/
+
+/*****************************************************************************
+**
+** btif hf api functions (no context switch)
+**
+*****************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function btif_hf_upstreams_evt
+**
+** Description Executes HF UPSTREAMS events in btif context
+**
+** Returns void
+**
+*******************************************************************************/
+static void btif_hf_upstreams_evt(UINT16 event, char* p_param)
+{
+ tBTA_AG *p_data = (tBTA_AG *)p_param;
+ bdstr_t bdstr;
+
+ BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hf_event(event));
+
+ switch (event)
+ {
+ case BTA_AG_ENABLE_EVT:
+ case BTA_AG_DISABLE_EVT:
+ break;
+
+ case BTA_AG_REGISTER_EVT:
+ btif_hf_cb.handle = p_data->reg.hdr.handle;
+ break;
+
+ case BTA_AG_OPEN_EVT:
+ if (p_data->open.status == BTA_AG_SUCCESS)
+ {
+ bdcpy(btif_hf_cb.connected_bda.address, p_data->open.bd_addr);
+ btif_hf_cb.state = BTHF_CONNECTION_STATE_CONNECTED;
+ btif_hf_cb.peer_feat = 0;
+ }
+ else if (btif_hf_cb.state == BTHF_CONNECTION_STATE_CONNECTING)
+ {
+ btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED;
+ }
+ else
+ {
+ BTIF_TRACE_WARNING4("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s",
+ __FUNCTION__, p_data->open.status, btif_hf_cb.state, bd2str(&btif_hf_cb.connected_bda, &bdstr));
+ break;
+ }
+
+ CHECK_CALL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda);
+
+ if (p_data->open.status != BTA_AG_SUCCESS)
+ bdsetany(btif_hf_cb.connected_bda.address);
+ break;
+
+ case BTA_AG_CLOSE_EVT:
+ btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED;
+ CHECK_CALL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda);
+ bdsetany(btif_hf_cb.connected_bda.address);
+ btif_hf_cb.peer_feat = 0;
+ break;
+
+ case BTA_AG_CONN_EVT:
+ btif_hf_cb.peer_feat = p_data->conn.peer_feat;
+ break;
+
+ case BTA_AG_AUDIO_OPEN_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED, &btif_hf_cb.connected_bda);
+ break;
+
+ case BTA_AG_AUDIO_CLOSE_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED, &btif_hf_cb.connected_bda);
+ break;
+
+ /* BTA auto-responds, silently discard */
+ case BTA_AG_SPK_EVT:
+ case BTA_AG_MIC_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, volume_cmd_cb,
+ (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK : BTHF_VOLUME_TYPE_MIC, p_data->val.num);
+ break;
+
+ case BTA_AG_AT_A_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, answer_call_cmd_cb);
+ break;
+
+ /* Java needs to send OK/ERROR for these commands */
+ case BTA_AG_AT_BLDN_EVT:
+ case BTA_AG_AT_D_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, dial_call_cmd_cb,
+ (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL);
+ break;
+
+ case BTA_AG_AT_CHUP_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb);
+ break;
+
+ case BTA_AG_AT_CIND_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, cind_cmd_cb);
+ break;
+
+ case BTA_AG_AT_VTS_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0]);
+ break;
+
+ case BTA_AG_AT_BVRA_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, vr_cmd_cb,
+ (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED : BTHF_VR_STATE_STOPPED);
+ break;
+
+ case BTA_AG_AT_NREC_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, nrec_cmd_cb,
+ (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP);
+ break;
+
+ /* TODO: Add a callback for CBC */
+ case BTA_AG_AT_CBC_EVT:
+ break;
+
+ case BTA_AG_AT_CKPD_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb);
+ break;
+
+ /* Java needs to send OK/ERROR for these commands */
+ case BTA_AG_AT_CHLD_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, chld_cmd_cb, p_data->val.num);
+ break;
+
+ case BTA_AG_AT_CLCC_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, clcc_cmd_cb, p_data->val.num);
+ break;
+
+ case BTA_AG_AT_COPS_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, cops_cmd_cb);
+ break;
+
+ case BTA_AG_AT_UNAT_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb,
+ p_data->val.str);
+ break;
+
+ case BTA_AG_AT_CNUM_EVT:
+ CHECK_CALL_CBACK(bt_hf_callbacks, cnum_cmd_cb);
+ break;
+
+ /* TODO: Some of these commands may need to be sent to app. For now respond with error */
+ case BTA_AG_AT_BINP_EVT:
+ case BTA_AG_AT_BTRH_EVT:
+ send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED);
+ break;
+
+
+ default:
+ BTIF_TRACE_WARNING2("%s: Unhandled event: %d", __FUNCTION__, event);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bte_hf_evt
+**
+** Description Switches context from BTE to BTIF for all HF events
+**
+** Returns void
+**
+*******************************************************************************/
+
+static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
+{
+ bt_status_t status;
+ int param_len = 0;
+
+ /* TODO: BTA sends the union members and not tBTA_AG. If using param_len=sizeof(tBTA_AG), we get a crash on memcpy */
+ if (BTA_AG_REGISTER_EVT == event)
+ param_len = sizeof(tBTA_AG_REGISTER);
+ else if (BTA_AG_OPEN_EVT == event)
+ param_len = sizeof(tBTA_AG_OPEN);
+ else if (BTA_AG_CONN_EVT == event)
+ param_len = sizeof(tBTA_AG_CONN);
+ else if ( (BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event))
+ param_len = sizeof(tBTA_AG_HDR);
+ else if (p_data)
+ param_len = sizeof(tBTA_AG_VAL);
+
+ /* switch context to btif task context (copy full union size for convenience) */
+ status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
+
+ /* catch any failed context transfers */
+ ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
+}
+
+
+/*******************************************************************************
+**
+** Function btif_hf_init
+**
+** Description initializes the hf interface
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t init( bthf_callbacks_t* callbacks )
+{
+ char * p_service_names[] = {BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME};
+
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+
+ bt_hf_callbacks = callbacks;
+
+ /* Enable and register with BTA-AG */
+ BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
+ BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, BTIF_HF_FEATURES,
+ p_service_names, BTIF_HF_ID_1);
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function connect
+**
+** Description connect to headset
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t connect( bt_bdaddr_t *bd_addr )
+{
+ CHECK_BTHF_INIT();
+
+ if (!is_connected(bd_addr))
+ {
+ btif_hf_cb.state = BTHF_CONNECTION_STATE_CONNECTING;
+ bdcpy(btif_hf_cb.connected_bda.address, bd_addr->address);
+
+ BTA_AgOpen(btif_hf_cb.handle, btif_hf_cb.connected_bda.address,
+ BTIF_HF_SECURITY, BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_BUSY;
+}
+
+/*******************************************************************************
+**
+** Function disconnect
+**
+** Description disconnect from headset
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(bd_addr))
+ {
+ BTA_AgClose(btif_hf_cb.handle);
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function connect_audio
+**
+** Description create an audio connection
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(bd_addr))
+ {
+ BTA_AgAudioOpen(btif_hf_cb.handle);
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function disconnect_audio
+**
+** Description close the audio connection
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(bd_addr))
+ {
+ BTA_AgAudioClose(btif_hf_cb.handle);
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function start_voice_recognition
+**
+** Description start voice recognition
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t start_voice_recognition()
+{
+ CHECK_BTHF_INIT();
+ if (is_connected(NULL))
+ {
+ tBTA_AG_RES_DATA ag_res;
+ memset(&ag_res, 0, sizeof(ag_res));
+ ag_res.state = 1;
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_BVRA_RES, &ag_res);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function stop_voice_recognition
+**
+** Description stop voice recognition
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t stop_voice_recognition()
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ tBTA_AG_RES_DATA ag_res;
+ memset(&ag_res, 0, sizeof(ag_res));
+ ag_res.state = 0;
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_BVRA_RES, &ag_res);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function volume_control
+**
+** Description volume control
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t volume_control(bthf_volume_type_t type, int volume)
+{
+ CHECK_BTHF_INIT();
+
+ tBTA_AG_RES_DATA ag_res;
+ memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
+ if (is_connected(NULL))
+ {
+ ag_res.num = volume;
+ BTA_AgResult(btif_hf_cb.handle,
+ (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES,
+ &ag_res);
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function device_status_notification
+**
+** Description Combined device status change notification
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t device_status_notification(bthf_network_state_t ntk_state,
+ bthf_service_type_t svc_type, int signal, int batt_chg)
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ /* send all indicators to BTA.
+ ** BTA will make sure no duplicates are sent out
+ */
+ send_indicator_update(BTA_AG_IND_SERVICE,
+ (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
+ send_indicator_update(BTA_AG_IND_ROAM,
+ (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
+ send_indicator_update(BTA_AG_IND_SIGNAL, signal);
+ send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg);
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function cops_response
+**
+** Description Response for COPS command
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t cops_response(const char *cops)
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ tBTA_AG_RES_DATA ag_res;
+
+ /* Format the response */
+ sprintf (ag_res.str, "0,0,\"%s\"", cops);
+ ag_res.ok_flag = BTA_AG_OK_DONE;
+
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_COPS_RES, &ag_res);
+ return BT_STATUS_SUCCESS;
+ }
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function cind_response
+**
+** Description Response for CIND command
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t cind_response(int svc, int num_active, int num_held,
+ bthf_call_state_t call_setup_state,
+ int signal, int roam, int batt_chg)
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ tBTA_AG_RES_DATA ag_res;
+
+ memset (&ag_res, 0, sizeof (ag_res));
+ sprintf (ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
+ (num_active ? 1 : 0), /* Call state */
+ callstate_to_callsetup(call_setup_state), /* Callsetup state */
+ svc, /* network service */
+ signal, /* Signal strength */
+ roam, /* Roaming indicator */
+ batt_chg, /* Battery level */
+ (num_held ? 1 : 0)); /* Call held */
+
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_CIND_RES, &ag_res);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function formatted_at_response
+**
+** Description Pre-formatted AT response, typically in response to unknown AT cmd
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t formatted_at_response(const char *rsp)
+{
+ CHECK_BTHF_INIT();
+ tBTA_AG_RES_DATA ag_res;
+
+ if (is_connected(NULL))
+ {
+ /* Format the response and send */
+ memset (&ag_res, 0, sizeof (ag_res));
+ strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function at_response
+**
+** Description ok/error response
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t at_response(bthf_at_response_t response_code)
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ /* TODO: Fix the errcode */
+ send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE
+ : BTA_AG_OK_ERROR, 0);
+ }
+
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function clcc_response
+**
+** Description response for CLCC command
+** Can be iteratively called for each call index. Call index
+** of 0 will be treated as NULL termination (Completes response)
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
+ bthf_call_state_t state, bthf_call_mode_t mode,
+ bthf_call_mpty_type_t mpty, const char *number,
+ bthf_call_addrtype_t type)
+{
+ CHECK_BTHF_INIT();
+
+ if (is_connected(NULL))
+ {
+ tBTA_AG_RES_DATA ag_res;
+ int xx;
+
+ memset (&ag_res, 0, sizeof (ag_res));
+
+ /* Format the response */
+ if (index == 0)
+ {
+ ag_res.ok_flag = BTA_AG_OK_DONE;
+ }
+ else
+ {
+ BTIF_TRACE_EVENT6("clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
+ index, dir, state, mode, number, type);
+ xx = sprintf (ag_res.str, "%d,%d,%d,%d,%d",
+ index, dir, state, mode, mpty);
+
+ if (number)
+ {
+ if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
+ sprintf (&ag_res.str[xx], ",\"+%s\",%d", number, type);
+ else
+ sprintf (&ag_res.str[xx], ",\"%s\",%d", number, type);
+ }
+ }
+ BTA_AgResult (btif_hf_cb.handle, BTA_AG_CLCC_RES, &ag_res);
+
+ return BT_STATUS_SUCCESS;
+ }
+
+ return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function phone_state_change
+**
+** Description notify of a call state change
+** number & type: valid only for incoming & waiting call
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t phone_state_change(int num_active, int num_held, bthf_call_state_t call_setup_state,
+ const char *number, bthf_call_addrtype_t type)
+{
+ tBTA_AG_RES res = 0xff;
+ tBTA_AG_RES_DATA ag_res;
+ bt_status_t status = BT_STATUS_SUCCESS;
+
+ CHECK_BTHF_INIT();
+
+ BTIF_TRACE_DEBUG6("phone_state_change: num_active=%d[%d] num_held=%d[%d]"\
+ " call_setup=%d [%d]", num_active, btif_hf_cb.num_active,
+ num_held, btif_hf_cb.num_held,
+ call_setup_state, btif_hf_cb.call_setup_state);
+
+ /* Check what has changed and update the corresponding indicators.
+ ** In ad
+ */
+
+ /* if all indicators are 0, send end call and return */
+ if (num_active == 0 && num_held == 0 && call_setup_state == BTHF_CALL_STATE_IDLE)
+ {
+ BTIF_TRACE_DEBUG1("%s: Phone on hook", __FUNCTION__);
+ BTA_AgResult (BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
+ goto update_call_states;
+ }
+
+ /* Ringing call changed? */
+ if (call_setup_state != btif_hf_cb.call_setup_state)
+ {
+ BTIF_TRACE_DEBUG3("%s: Call setup states changed. old: %s new: %s",
+ __FUNCTION__, dump_hf_call_state(btif_hf_cb.call_setup_state),
+ dump_hf_call_state(call_setup_state));
+ memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
+
+ switch (call_setup_state)
+ {
+ case BTHF_CALL_STATE_IDLE:
+ {
+ switch (btif_hf_cb.call_setup_state)
+ {
+ case BTHF_CALL_STATE_INCOMING:
+ if (num_active > btif_hf_cb.num_active)
+ {
+ res = BTA_AG_IN_CALL_CONN_RES;
+ ag_res.audio_handle = btif_hf_cb.handle;
+ }
+ else if (num_held > btif_hf_cb.num_held)
+ res = BTA_AG_IN_CALL_HELD_RES;
+ else
+ res = BTA_AG_CALL_CANCEL_RES;
+ break;
+ case BTHF_CALL_STATE_DIALING:
+ case BTHF_CALL_STATE_ALERTING:
+ if (num_active > btif_hf_cb.num_active)
+ {
+ ag_res.audio_handle = btif_hf_cb.handle;
+ res = BTA_AG_OUT_CALL_CONN_RES;
+ }
+ else
+ res = BTA_AG_CALL_CANCEL_RES;
+ break;
+ default:
+ BTIF_TRACE_ERROR1("%s: Incorrect Call setup state transition", __FUNCTION__);
+ status = BT_STATUS_PARM_INVALID;
+ break;
+ }
+ } break;
+
+ case BTHF_CALL_STATE_INCOMING:
+ if (num_active || num_held)
+ res = BTA_AG_CALL_WAIT_RES;
+ else
+ res = BTA_AG_IN_CALL_RES;
+ if (number)
+ {
+ strcpy(ag_res.str, number);
+ ag_res.num = type;
+ }
+ break;
+ case BTHF_CALL_STATE_DIALING:
+ ag_res.audio_handle = btif_hf_cb.handle;
+ res = BTA_AG_OUT_CALL_ORIG_RES;
+ break;
+ case BTHF_CALL_STATE_ALERTING:
+ ag_res.audio_handle = btif_hf_cb.handle;
+ res = BTA_AG_OUT_CALL_ALERT_RES;
+ break;
+ default:
+ BTIF_TRACE_ERROR1("%s: Incorrect new ringing call state", __FUNCTION__);
+ status = BT_STATUS_PARM_INVALID;
+ break;
+ }
+ BTIF_TRACE_DEBUG3("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
+
+ if (res)
+ BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
+
+ /* update the call states and return */
+ goto update_call_states;
+ }
+
+ /* Active Changed? */
+ if (num_active != btif_hf_cb.num_active)
+ {
+ BTIF_TRACE_DEBUG3("%s: Active call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb.num_active, num_active);
+ send_indicator_update(BTA_AG_IND_CALL, (num_active ? 1 : 0));
+ }
+
+
+ /* Held Changed? */
+ if (num_held != btif_hf_cb.num_held)
+ {
+ BTIF_TRACE_DEBUG3("%s: Held call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb.num_held, num_held);
+ send_indicator_update(BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
+ }
+
+ /* Calls Swapped? */
+ if ( (call_setup_state == btif_hf_cb.call_setup_state) &&
+ (num_active && num_held) &&
+ (num_active == btif_hf_cb.num_active) &&
+ (num_held == btif_hf_cb.num_held) )
+ {
+ BTIF_TRACE_DEBUG1("%s: Calls swapped", __FUNCTION__);
+ send_indicator_update(BTA_AG_IND_CALLHELD, 1);
+ }
+
+update_call_states:
+ btif_hf_cb.num_active = num_active;
+ btif_hf_cb.num_held = num_held;
+ btif_hf_cb.call_setup_state = call_setup_state;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function cleanup
+**
+** Description Closes the HF interface
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+static void cleanup( void )
+{
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+
+ if (bt_hf_callbacks)
+ {
+ /* De-register AG */
+ BTA_AgDeregister(btif_hf_cb.handle);
+ /* Disable AG */
+ BTA_AgDisable();
+ bt_hf_callbacks = NULL;
+ }
+}
+
+static const bthf_interface_t bthfInterface = {
+ sizeof(bt_interface_t),
+ init,
+ connect,
+ disconnect,
+ connect_audio,
+ disconnect_audio,
+ start_voice_recognition,
+ stop_voice_recognition,
+ volume_control,
+ device_status_notification,
+ cops_response,
+ cind_response,
+ formatted_at_response,
+ at_response,
+ clcc_response,
+ phone_state_change,
+ cleanup,
+};
+
+/*******************************************************************************
+**
+** Function btif_hf_get_interface
+**
+** Description Get the hf callback interface
+**
+** Returns bthf_interface_t
+**
+*******************************************************************************/
+const bthf_interface_t *btif_hf_get_interface()
+{
+ BTIF_TRACE_EVENT1("%s", __FUNCTION__);
+ return &bthfInterface;
+}
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
new file mode 100644
index 0000000..a55821d
--- /dev/null
+++ b/btif/src/btif_storage.c
@@ -0,0 +1,1027 @@
+/************************************************************************************
+ *
+ * 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: btif_storage.c
+ *
+ * Description: Stores the local BT adapter and remote device properties in
+ * NVRAM storage, typically as text files in the
+ * mobile's filesystem
+ *
+ *
+ * Data storage directory structure
+ *
+ * data
+ * `-- misc
+ * `-- bluedroid
+ * `-- LOCAL
+ * |-- adapter_info - Local adapter config
+ * |-- remote_devices - Remote devices and Timestamp
+ * |-- remote_devclass - Remote devices' COD
+ * |-- remote_devtype - Remote devices' type
+ * |-- remote_names - Remote devices' names
+ * |-- remote_aliases - Remote devices' Friendly names
+ * `-- remote_services - Remote devices' services
+ *
+ *
+ * adapter_info - Key/Value
+ * name <space> <Name of Local Bluetooth device>
+ * scan_mode <space> <Scan Mode>
+ * discovery_timeout <space> <Discovery Timeout in seconds>
+ *
+ * remote_devices - Key/Value
+ * <remote device bd_addr> <space> <Timestamp>
+ *
+ * remote_devclass - Key/Value
+ * <remote device bd_addr> <space> <Device class>
+ *
+ * remote_devtype - Key/Value
+ * <remote_device bd_addr><space> <Device Type>
+ *
+ * remote_names - Key/Value
+ * <remote_device bd_addr> <space> <Bluetooth device Name as reported by the controller>
+ *
+ * remote_linkkeys - Key/Value
+ * <remote device bd_addr > <space> <LinkKey> <space> <KeyType> <space> <PinLength>
+ *
+ * remote_aliases - Key/Value
+ * <remote device bd_addr> <space> <Friendy Name>
+ *
+ * remote_services - Key/Value
+ * <remote_device bd_addr> <space> <List of UUIDs separated by semicolons>
+ *
+ ***********************************************************************************/
+#include <stdlib.h>
+#include <time.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BTIF_STORAGE"
+
+#include "btif_api.h"
+
+#include "btif_util.h"
+#include "unv.h"
+#include "bd.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#define BTIF_STORAGE_PATH_BLUEDROID "/data/misc/bluedroid"
+
+#define BTIF_STORAGE_PATH_ADAPTER_INFO "adapter_info"
+#define BTIF_STORAGE_PATH_REMOTE_DEVICES "remote_devices"
+#define BTIF_STORAGE_PATH_REMOTE_DEVCLASSES "remote_devclasses"
+#define BTIF_STORAGE_PATH_REMOTE_DEVTYPES "remote_devtypes"
+#define BTIF_STORAGE_PATH_REMOTE_NAMES "remote_names"
+#define BTIF_STORAGE_PATH_REMOTE_LINKKEYS "remote_linkkeys"
+#define BTIF_STORAGE_PATH_REMOTE_ALIASES "remote_aliases"
+#define BTIF_STORAGE_PATH_REMOTE_SERVICES "remote_services"
+
+#define BTIF_STORAGE_KEY_ADAPTER_NAME "name"
+#define BTIF_STORAGE_KEY_ADAPTER_SCANMODE "scan_mode"
+#define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "discovery_timeout"
+
+/* This is a local property to add a device found */
+#define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF
+
+#define BTIF_STORAGE_GET_ADAPTER_PROP(t,v,l,p) \
+ {p.type=t;p.val=v;p.len=l; btif_storage_get_adapter_property(&p);}
+
+#define BTIF_STORAGE_GET_REMOTE_PROP(b,t,v,l,p) \
+ {p.type=t;p.val=v;p.len=l;btif_storage_get_remote_device_property(b,&p);}
+
+#define STORAGE_BDADDR_STRING_SZ (18) /* 00:11:22:33:44:55 */
+#define STORAGE_UUID_STRING_SIZE (36+1) /* 00001200-0000-1000-8000-00805f9b34fb; */
+#define STORAGE_PINLEN_STRING_MAX_SIZE (2) /* ascii pinlen max chars */
+#define STORAGE_KEYTYPE_STRING_MAX_SIZE (1) /* ascii keytype max chars */
+
+#define STORAGE_KEY_TYPE_MAX (10)
+
+
+/* <18 char bd addr> <space> LIST< <36 char uuid> <;> > <keytype (dec)> <pinlen> */
+#define BTIF_REMOTE_SERVICES_ENTRY_SIZE_MAX (STORAGE_BDADDR_STRING_SZ + 1 +\
+ STORAGE_UUID_STRING_SIZE*BT_MAX_NUM_UUIDS + \
+ STORAGE_PINLEN_STRING_MAX_SIZE +\
+ STORAGE_KEYTYPE_STRING_MAX_SIZE)
+
+#define STORAGE_REMOTE_LINKKEYS_ENTRY_SIZE (LINK_KEY_LEN*2 + 1 + 2 + 1 + 2)
+
+/* currently remote services is the potentially largest entry */
+#define BTIF_STORAGE_MAX_LINE_SZ BTIF_REMOTE_SERVICES_ENTRY_SIZE_MAX
+
+/* check against unv max entry size at compile time */
+#if (BTIF_STORAGE_ENTRY_MAX_SIZE > UNV_MAXLINE_LENGTH)
+#error "btif storage entry size exceeds unv max line size"
+#endif
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+typedef struct {
+ uint32_t num_devices;
+ bt_bdaddr_t devices[BTM_SEC_MAX_DEVICE_RECORDS];
+} btif_bonded_devices_t;
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+/*******************************************************************************
+**
+** Function btif_in_make_filename
+**
+** Description Internal helper function to create NVRAM file path
+** from address and filename
+**
+** Returns NVRAM file path if successfull, NULL otherwise
+**
+*******************************************************************************/
+static char* btif_in_make_filename(bt_bdaddr_t *bd_addr, char *fname)
+{
+ static char path[256];
+ bdstr_t bdstr;
+
+ if (fname == NULL)return NULL;
+ if (bd_addr)
+ {
+ sprintf(path, "%s/%s/%s", BTIF_STORAGE_PATH_BLUEDROID,
+ bd2str(bd_addr, &bdstr), fname);
+ }
+ else
+ {
+ /* local adapter */
+ sprintf(path, "%s/LOCAL/%s", BTIF_STORAGE_PATH_BLUEDROID, fname);
+ }
+
+ return (char*)path;
+}
+
+/*******************************************************************************
+**
+** Function btif_in_adapter_key_from_type
+**
+** Description Internal helper function to map a property type
+** to the NVRAM filename key
+**
+** Returns NVRAM filename key if successfull, 'NO_KEY' otherwise
+**
+*******************************************************************************/
+static const char *btif_in_get_adapter_key_from_type(bt_property_type_t type)
+{
+ switch (type)
+ {
+ case BT_PROPERTY_BDNAME:
+ return BTIF_STORAGE_KEY_ADAPTER_NAME;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ return BTIF_STORAGE_KEY_ADAPTER_SCANMODE;
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ return BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT;
+ default:
+ /* return valid string to avoid passing NULL to NV RAM driver */
+ return "NO_KEY";
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_in_split_uuids_string_to_list
+**
+** Description Internal helper function to split the string of UUIDs
+** read from the NVRAM to an array
+**
+** Returns None
+**
+*******************************************************************************/
+static void btif_in_split_uuids_string_to_list(char *str, bt_uuid_t *p_uuid,
+ uint32_t *p_num_uuid)
+{
+ char buf[64];
+ char *p_start = str;
+ char *p_needle;
+ uint32_t num = 0;
+ do
+ {
+ p_needle = strchr(p_start, ';');
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, p_start, (p_needle-p_start));
+ string_to_uuid(buf, p_uuid + num);
+ num++;
+ p_start = ++p_needle;
+
+ } while (*p_start != 0);
+ *p_num_uuid = num;
+}
+
+/*******************************************************************************
+**
+** Function btif_in_str_to_property
+**
+** Description Internal helper function to convert the string read from
+** NVRAM into a property->val. Also sets the property->len.
+** Assumption is that property->val has enough memory to
+** store the string fetched from NVRAM
+**
+** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+static bt_status_t btif_in_str_to_property(char *value, bt_property_t *property)
+{
+ bt_status_t status = BT_STATUS_SUCCESS;
+ property->len = 0;
+
+ /* if Value is NULL, then just set the property->len to 0 and return.
+ This is possible if the entry does not exist */
+ if (value == NULL) {
+ status = BT_STATUS_FAIL;
+ }
+ switch (property->type)
+ {
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ {
+ *((char*)property->val) = 0;
+ if (value)
+ {
+ property->len = strlen(value)+1;
+ strcpy((char*)property->val, value);
+ }
+ } break;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ {
+ *((uint32_t *)property->val) = 0;
+ if (value)
+ {
+ uint32_t ival;
+ property->len = sizeof(uint32_t);
+ ival = atoi(value);
+ memcpy((uint32_t*)property->val, &ival, sizeof(uint32_t));
+ }
+ } break;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ {
+ *((uint32_t *)property->val) = 0;
+ if (value)
+ {
+ uint32_t ival;
+ property->len = sizeof(uint32_t);
+ ival = strtol(value, NULL, 16);
+ memcpy((uint32_t*)property->val, &ival, sizeof(uint32_t));
+ }
+ } break;
+ case BT_PROPERTY_UUIDS:
+ {
+ if (value)
+ {
+ bt_uuid_t *p_uuid = (bt_uuid_t*)property->val;
+ uint32_t num_uuids = 0;
+ btif_in_split_uuids_string_to_list(value, p_uuid, &num_uuids);
+ property->len = num_uuids * sizeof(bt_uuid_t);
+ }
+ } break;
+ default:
+ {
+ break;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function btif_in_property_to_str
+**
+** Description Internal helper function to convert the property->val
+** to a string that can be written to the NVRAM
+**
+** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+static bt_status_t btif_in_property_to_str(bt_property_t *property, char *value)
+{
+ switch (property->type)
+ {
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ {
+ sprintf(value, "%d", (int)time(NULL));
+ }break;
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ {
+ strcpy(value, (char*)property->val);
+ }break;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ {
+ sprintf(value, "%d", *((uint32_t*)property->val));
+ }break;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ {
+ sprintf(value, "0x%x", *((uint32_t*)property->val));
+ }break;
+ case BT_PROPERTY_UUIDS:
+ {
+ uint32_t i;
+ char buf[64];
+ value[0] = 0;
+ for (i=0; i < (property->len)/sizeof(bt_uuid_t); i++)
+ {
+ bt_uuid_t *p_uuid = (bt_uuid_t*)property->val + i;
+ memset(buf, 0, sizeof(buf));
+ uuid_to_string(p_uuid, buf);
+ strcat(value, buf);
+ strcat(value, ";");
+ }
+ value[strlen(value)] = 0;
+ }break;
+ default:
+ {
+ return BT_STATUS_FAIL;
+ }
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_in_get_remote_device_path_from_property
+**
+** Description Internal helper function to map a property type
+** to the NVRAM filename key
+**
+** Returns NVRAM filename key if successfull, NULL otherwise
+**
+*******************************************************************************/
+static char* btif_in_get_remote_device_path_from_property(bt_property_type_t type)
+{
+ switch (type)
+ {
+ case BT_PROPERTY_BDADDR:
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ return BTIF_STORAGE_PATH_REMOTE_DEVICES;
+ case BT_PROPERTY_BDNAME:
+ return BTIF_STORAGE_PATH_REMOTE_NAMES;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ return BTIF_STORAGE_PATH_REMOTE_DEVCLASSES;
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ return BTIF_STORAGE_PATH_REMOTE_DEVTYPES;
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ return BTIF_STORAGE_PATH_REMOTE_ALIASES;
+ case BT_PROPERTY_UUIDS:
+ return BTIF_STORAGE_PATH_REMOTE_SERVICES;
+ default:
+ return NULL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function btif_in_load_device_iter_cb
+**
+** Description Internal iterator callback from UNV when loading the
+** link-keys
+**
+** Returns
+**
+*******************************************************************************/
+
+int btif_in_load_device_iter_cb(char *key, char *value, void *userdata)
+{
+ btif_bonded_devices_t *p_bonded_devices = (btif_bonded_devices_t *)userdata;
+ DEV_CLASS dev_class = {0, 0, 0};
+ bt_bdaddr_t bd_addr;
+ LINK_KEY link_key;
+ uint8_t key_type;
+ uint8_t pin_length;
+ int offset = 0;
+ int8_t temp[3];
+ uint32_t i;
+
+ memset(temp, 0, sizeof(temp));
+
+ BTIF_TRACE_DEBUG3("%s %s %s", __FUNCTION__, key, value);
+
+ /* convert 32 char linkkey (fixed size) */
+ for (i = 0; i < LINK_KEY_LEN; i++)
+ {
+ memcpy(temp, value + (i * 2), 2);
+ link_key[i] = (uint8_t) strtol((const char *)temp, NULL, 16);
+ offset+=2;
+ }
+
+ /* skip space */
+ offset++;
+
+ /* convert decimal keytype (max 2 ascii chars) */
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, value + offset, 2);
+ key_type = (uint8_t)strtoul((const char *)temp, NULL, 10);
+
+ /* value + space */
+ offset+=2;
+
+ /* convert decimal pinlen (max 2 ascii chars) */
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, value + offset, 2);
+ pin_length = (uint8_t)strtoul((const char *)temp, NULL, 10);
+
+ /* convert bd address (keystring) */
+ str2bd(key, &bd_addr);
+
+ /* add extracted information to BTA security manager */
+ BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0, key_type, 0);
+
+ /* Fill in the bonded devices */
+ memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
+
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function btif_in_fetch_bonded_devices
+**
+** Description Internal helper function to fetch the bonded devices
+** from NVRAM
+**
+** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+static bt_status_t btif_in_fetch_bonded_devices(btif_bonded_devices_t *p_bonded_devices)
+{
+ char *fname;
+ int ret;
+
+ memset(p_bonded_devices, 0, sizeof(btif_bonded_devices_t));
+
+ fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
+
+ if (fname == NULL)
+ return BT_STATUS_FAIL;
+
+ ret = unv_read_key_iter(fname, btif_in_load_device_iter_cb, p_bonded_devices);
+
+ if (ret < 0)
+ return BT_STATUS_FAIL;
+
+ return BT_STATUS_SUCCESS;
+}
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/** functions are synchronous.
+ * functions can be called by both internal modules such as BTIF_DM and by external entiries from HAL via BTIF_context_switch
+ * For OUT parameters, caller is expected to provide the memory.
+ * Caller is expected to provide a valid pointer to 'property->value' based on the property->type
+ */
+/*******************************************************************************
+**
+** Function btif_storage_get_adapter_property
+**
+** Description BTIF storage API - Fetches the adapter property->type
+** from NVRAM and fills property->val.
+** Caller should provide memory for property->val and
+** set the property->val
+**
+** Returns BT_STATUS_SUCCESS if the fetch was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
+{
+ bt_status_t status;
+ char *fname;
+ char *value;
+ int ret;
+ char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
+
+ /* initialize property->len */
+ property->len = 0;
+
+ /* Special handling for adapter BD_ADDR and BONDED_DEVICES */
+ if (property->type == BT_PROPERTY_BDADDR)
+ {
+ BD_ADDR addr;
+ bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)property->val;
+ BTM_GetLocalDeviceAddr(addr);
+ bdcpy(bd_addr->address, addr);
+ property->len = sizeof(bt_bdaddr_t);
+
+ return BT_STATUS_SUCCESS;
+ }
+ else if (property->type == BT_PROPERTY_ADAPTER_BONDED_DEVICES)
+ {
+ btif_bonded_devices_t bonded_devices;
+
+ btif_in_fetch_bonded_devices(&bonded_devices);
+
+ BTIF_TRACE_DEBUG2("%s: Number of bonded devices: %d", __FUNCTION__, bonded_devices.num_devices);
+
+ if (bonded_devices.num_devices > 0)
+ {
+ property->len = bonded_devices.num_devices * sizeof(bt_bdaddr_t);
+ memcpy(property->val, bonded_devices.devices, property->len);
+ }
+
+ /* if there are no bonded_devices, then length shall be 0 */
+ return BT_STATUS_SUCCESS;
+ }
+ else if (property->type == BT_PROPERTY_UUIDS)
+ {
+ /* publish list of local supported services */
+ bt_uuid_t *p_uuid = (bt_uuid_t*)property->val;
+ uint32_t num_uuids = 0;
+
+#if BTA_AG_INCLUDED == TRUE
+ uuid16_to_uuid128(UUID_SERVCLASS_AG_HANDSFREE, p_uuid + num_uuids);
+ num_uuids++;
+ uuid16_to_uuid128(UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, p_uuid + num_uuids);
+ num_uuids++;
+#endif
+
+ property->len = (num_uuids)*sizeof(bt_uuid_t);
+ return BT_STATUS_SUCCESS;
+ }
+
+ /* fall through for other properties */
+
+ /* create filepath */
+ fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_ADAPTER_INFO);
+
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ ret = unv_create_file(fname);
+
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ value = unv_read_key( fname,
+ btif_in_get_adapter_key_from_type(property->type),
+ linebuf, UNV_MAXLINE_LENGTH);
+
+ if (value == NULL)
+ {
+ /* properties not yet existing, request default values from bta */
+ return btif_dm_get_adapter_property(property);
+ }
+ else
+ {
+ /* convert to property_t data structure */
+ status = btif_in_str_to_property(value, property);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_set_adapter_property
+**
+** Description BTIF storage API - Stores the adapter property
+** to NVRAM
+**
+** Returns BT_STATUS_SUCCESS if the store was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_set_adapter_property(bt_property_t *property)
+{
+ char *fname;
+ char value[1200];
+ int ret;
+
+ fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_ADAPTER_INFO);
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+ ret = unv_create_file(fname);
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ if (btif_in_property_to_str(property, value) != BT_STATUS_SUCCESS)
+ {
+ return BT_STATUS_FAIL;
+ }
+ ret = unv_write_key(fname, btif_in_get_adapter_key_from_type(property->type), value);
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_get_remote_device_property
+**
+** Description BTIF storage API - Fetches the remote device property->type
+** from NVRAM and fills property->val.
+** Caller should provide memory for property->val and
+** set the property->val
+**
+** Returns BT_STATUS_SUCCESS if the fetch was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_get_remote_device_property(bt_bdaddr_t *remote_bd_addr,
+ bt_property_t *property)
+{
+ char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
+ char *fname;
+ char *value;
+ int ret;
+ bdstr_t bdstr;
+
+ fname = btif_in_make_filename(NULL,
+ btif_in_get_remote_device_path_from_property(property->type));
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ ret = unv_create_file(fname);
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ value = unv_read_key(fname, bd2str(remote_bd_addr, &bdstr), linebuf, BTIF_STORAGE_MAX_LINE_SZ);
+
+ return btif_in_str_to_property(value, property);
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_set_remote_device_property
+**
+** Description BTIF storage API - Stores the remote device property
+** to NVRAM
+**
+** Returns BT_STATUS_SUCCESS if the store was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_set_remote_device_property(bt_bdaddr_t *remote_bd_addr,
+ bt_property_t *property)
+{
+ char value[1200];
+ char *fname;
+ bdstr_t bdstr;
+ int ret;
+
+ fname = btif_in_make_filename(NULL,
+ btif_in_get_remote_device_path_from_property(property->type));
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+ ret = unv_create_file(fname);
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+ memset(value, 0, sizeof(value));
+
+ if (btif_in_property_to_str(property, value) != BT_STATUS_SUCCESS)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ ret = unv_write_key(fname, bd2str(remote_bd_addr, &bdstr), value);
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_add_remote_device
+**
+** Description BTIF storage API - Adds a newly discovered device to NVRAM
+** along with the timestamp. Also, stores the various
+** properties - RSSI, BDADDR, NAME (if found in EIR)
+**
+** Returns BT_STATUS_SUCCESS if the store was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_add_remote_device(bt_bdaddr_t *remote_bdaddr,
+ uint32_t num_properties,
+ bt_property_t *properties)
+{
+ uint32_t i = 0;
+ /* TODO: If writing a property, fails do we go back undo the earlier
+ * written properties? */
+ for (i=0; i < num_properties; i++)
+ {
+ /* Ignore the RSSI as this is not stored in DB */
+ if (properties[i].type == BT_PROPERTY_REMOTE_RSSI)
+ continue;
+
+ /* BD_ADDR for remote device needs special handling as we also store timestamp */
+ if (properties[i].type == BT_PROPERTY_BDADDR)
+ {
+ bt_property_t addr_prop;
+ memcpy(&addr_prop, &properties[i], sizeof(bt_property_t));
+ addr_prop.type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP;
+ btif_storage_set_remote_device_property(remote_bdaddr,
+ &addr_prop);
+ }
+ else
+ {
+ btif_storage_set_remote_device_property(remote_bdaddr,
+ &properties[i]);
+ }
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_add_bonded_device
+**
+** Description BTIF storage API - Adds the newly bonded device to NVRAM
+** along with the link-key, Key type and Pin key length
+**
+** Returns BT_STATUS_SUCCESS if the store was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+
+bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
+ LINK_KEY link_key,
+ uint8_t key_type,
+ uint8_t pin_length)
+{
+ char value[STORAGE_REMOTE_LINKKEYS_ENTRY_SIZE];
+ uint32_t i = 0;
+ char *fname;
+ bdstr_t bdstr;
+ int ret;
+
+ fname = btif_in_make_filename(NULL,
+ BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+ ret = unv_create_file(fname);
+
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ /* check ascii representations doesn't exceed max size */
+
+ if (key_type > STORAGE_KEY_TYPE_MAX)
+ return BT_STATUS_FAIL;
+
+ if (pin_length > PIN_CODE_LEN)
+ return BT_STATUS_FAIL;
+
+ memset(value, 0, sizeof(value));
+
+ for (i = 0; i < LINK_KEY_LEN; i++)
+ sprintf(value + (i * 2), "%2.2X", link_key[i]);
+
+ sprintf(value + (LINK_KEY_LEN*2), " %d %d", key_type, pin_length);
+
+ ret = unv_write_key(fname, bd2str(remote_bd_addr, &bdstr), value);
+
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_remove_bonded_device
+**
+** Description BTIF storage API - Deletes the bonded device from NVRAM
+**
+** Returns BT_STATUS_SUCCESS if the deletion was successful,
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr)
+{
+ char *fname;
+ int ret;
+ bdstr_t bdstr;
+
+ fname = btif_in_make_filename(NULL,
+ BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
+ if (fname == NULL)
+ {
+ return BT_STATUS_FAIL;
+ }
+ ret = unv_create_file(fname);
+
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ ret = unv_remove_key(fname, bd2str(remote_bd_addr, &bdstr));
+
+ if (ret < 0)
+ {
+ return BT_STATUS_FAIL;
+ }
+
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_load_bonded_devices
+**
+** Description BTIF storage API - Loads all the bonded devices from NVRAM
+** and adds to the BTA.
+** Additionally, this API also invokes the adaper_properties_cb
+** and remote_device_properties_cb for each of the bonded devices.
+**
+** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_storage_load_bonded_devices(void)
+{
+ char *fname;
+ btif_bonded_devices_t bonded_devices;
+ uint32_t i = 0;
+ bt_property_t adapter_props[6];
+ uint32_t num_props = 0;
+ bt_property_t remote_properties[8];
+ bt_bdaddr_t addr;
+ bt_bdname_t name, alias;
+ bt_scan_mode_t mode;
+ uint32_t disc_timeout;
+ bt_bdaddr_t *devices_list;
+ bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
+ bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
+ uint32_t cod, devtype;
+
+ btif_in_fetch_bonded_devices(&bonded_devices);
+
+ /* Now send the adapter_properties_cb with all adapter_properties */
+ {
+ memset(adapter_props, 0, sizeof(adapter_props));
+
+ /* BD_ADDR */
+ BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_BDADDR, &addr, sizeof(addr),
+ adapter_props[num_props]);
+ num_props++;
+
+ /* BD_NAME */
+ BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_BDNAME, &name, sizeof(name),
+ adapter_props[num_props]);
+ num_props++;
+
+ /* SCAN_MODE */
+ BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_ADAPTER_SCAN_MODE, &mode, sizeof(mode),
+ adapter_props[num_props]);
+ num_props++;
+
+ /* DISC_TIMEOUT */
+ BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ &disc_timeout, sizeof(disc_timeout),
+ adapter_props[num_props]);
+ num_props++;
+
+ /* BONDED_DEVICES */
+ devices_list = (bt_bdaddr_t*)malloc(sizeof(bt_bdaddr_t)*bonded_devices.num_devices);
+ adapter_props[num_props].type = BT_PROPERTY_ADAPTER_BONDED_DEVICES;
+ adapter_props[num_props].len = bonded_devices.num_devices * sizeof(bt_bdaddr_t);
+ adapter_props[num_props].val = devices_list;
+ for (i=0; i < bonded_devices.num_devices; i++)
+ {
+ memcpy(devices_list + i, &bonded_devices.devices[i], sizeof(bt_bdaddr_t));
+ }
+ num_props++;
+
+ /* LOCAL UUIDs */
+ BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_UUIDS,
+ local_uuids, sizeof(local_uuids),
+ adapter_props[num_props]);
+ num_props++;
+
+ btif_adapter_properties_evt(BT_STATUS_SUCCESS, num_props, adapter_props);
+
+ free(devices_list);
+ }
+
+ BTIF_TRACE_EVENT2("%s: %d bonded devices found", __FUNCTION__, bonded_devices.num_devices);
+
+ {
+ for (i = 0; i < bonded_devices.num_devices; i++)
+ {
+ bt_bdaddr_t *p_remote_addr;
+
+ num_props = 0;
+ p_remote_addr = &bonded_devices.devices[i];
+ memset(remote_properties, 0, sizeof(remote_properties));
+ BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, BT_PROPERTY_BDNAME,
+ &name, sizeof(name),
+ remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, BT_PROPERTY_REMOTE_FRIENDLY_NAME,
+ &alias, sizeof(alias),
+ remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, BT_PROPERTY_CLASS_OF_DEVICE,
+ &cod, sizeof(cod),
+ remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, BT_PROPERTY_TYPE_OF_DEVICE,
+ &devtype, sizeof(devtype),
+ remote_properties[num_props]);
+ num_props++;
+
+ BTIF_STORAGE_GET_REMOTE_PROP(p_remote_addr, BT_PROPERTY_UUIDS,
+ remote_uuids, sizeof(remote_uuids),
+ remote_properties[num_props]);
+ num_props++;
+
+ btif_remote_properties_evt(BT_STATUS_SUCCESS, p_remote_addr,
+ num_props, remote_properties);
+ }
+ }
+ return BT_STATUS_SUCCESS;
+}
diff --git a/btif/src/btif_util.c b/btif/src/btif_util.c
new file mode 100644
index 0000000..ad3ba86
--- /dev/null
+++ b/btif/src/btif_util.c
@@ -0,0 +1,359 @@
+/************************************************************************************
+ *
+ * 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: btif_util.c
+ *
+ * Description: Miscellaneous helper functions
+ *
+ *
+ ***********************************************************************************/
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hf.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LOG_TAG "BTIF_UTIL"
+#include "btif_common.h"
+#include "bta_api.h"
+#include "gki.h"
+#include "btu.h"
+#include "bte.h"
+#include "bd.h"
+#include "btif_dm.h"
+#include "btif_util.h"
+#include "bta_ag_api.h"
+
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*****************************************************************************
+** Logging helper functions
+*****************************************************************************/
+
+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;
+}
+
+char *bd2str(bt_bdaddr_t *bdaddr, bdstr_t *bdstr)
+{
+ char *addr = (char *) bdaddr->address;
+
+ sprintf((char*)bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
+ (int)addr[0],(int)addr[1],(int)addr[2],
+ (int)addr[3],(int)addr[4],(int)addr[5]);
+ return (char *)bdstr;
+}
+
+UINT32 devclass2uint(DEV_CLASS dev_class)
+{
+ UINT32 cod = 0;
+
+ /* if COD is 0, irrespective of the device type set it to Unclassified device */
+ cod = (dev_class[2]) | (dev_class[1] << 8) | (dev_class[0] << 16);
+
+ return cod;
+}
+
+static const UINT8 sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+
+void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128)
+{
+ uint16_t uuid16_bo;
+ memset(uuid128, 0, sizeof(bt_uuid_t));
+
+ memcpy(uuid128->uu, sdp_base_uuid, MAX_UUID_SIZE);
+ uuid16_bo = ntohs(uuid16);
+ memcpy(uuid128->uu + 2, &uuid16_bo, sizeof(uint16_t));
+}
+
+void string_to_uuid(char *str, bt_uuid_t *p_uuid)
+{
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
+
+ sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+ &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
+
+ uuid0 = htonl(uuid0);
+ uuid1 = htons(uuid1);
+ uuid2 = htons(uuid2);
+ uuid3 = htons(uuid3);
+ uuid4 = htonl(uuid4);
+ uuid5 = htons(uuid5);
+
+ memcpy(&(p_uuid->uu[0]), &uuid0, 4);
+ memcpy(&(p_uuid->uu[4]), &uuid1, 2);
+ memcpy(&(p_uuid->uu[6]), &uuid2, 2);
+ memcpy(&(p_uuid->uu[8]), &uuid3, 2);
+ memcpy(&(p_uuid->uu[10]), &uuid4, 4);
+ memcpy(&(p_uuid->uu[14]), &uuid5, 2);
+
+ return;
+
+}
+
+void uuid_to_string(bt_uuid_t *p_uuid, char *str)
+{
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
+
+ memcpy(&uuid0, &(p_uuid->uu[0]), 4);
+ memcpy(&uuid1, &(p_uuid->uu[4]), 2);
+ memcpy(&uuid2, &(p_uuid->uu[6]), 2);
+ memcpy(&uuid3, &(p_uuid->uu[8]), 2);
+ memcpy(&uuid4, &(p_uuid->uu[10]), 4);
+ memcpy(&uuid5, &(p_uuid->uu[14]), 2);
+
+ sprintf((char *)str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+ ntohl(uuid0), ntohs(uuid1),
+ ntohs(uuid2), ntohs(uuid3),
+ ntohl(uuid4), ntohs(uuid5));
+ return;
+}
+const char* dump_dm_search_event(UINT16 event)
+{
+ switch(event)
+ {
+ CASE_RETURN_STR(BTA_DM_INQ_RES_EVT)
+ CASE_RETURN_STR(BTA_DM_INQ_CMPL_EVT)
+ CASE_RETURN_STR(BTA_DM_DISC_RES_EVT)
+ CASE_RETURN_STR(BTA_DM_DISC_BLE_RES_EVT)
+ CASE_RETURN_STR(BTA_DM_DISC_CMPL_EVT)
+ CASE_RETURN_STR(BTA_DM_DI_DISC_CMPL_EVT)
+ CASE_RETURN_STR(BTA_DM_SEARCH_CANCEL_CMPL_EVT)
+
+ default:
+ return "UNKNOWN MSG ID";
+ }
+}
+
+
+const char* dump_property_type(bt_property_type_t type)
+{
+ switch(type)
+ {
+ CASE_RETURN_STR(BT_PROPERTY_BDNAME)
+ CASE_RETURN_STR(BT_PROPERTY_BDADDR)
+ CASE_RETURN_STR(BT_PROPERTY_UUIDS)
+ CASE_RETURN_STR(BT_PROPERTY_CLASS_OF_DEVICE)
+ CASE_RETURN_STR(BT_PROPERTY_TYPE_OF_DEVICE)
+ CASE_RETURN_STR(BT_PROPERTY_REMOTE_RSSI)
+ CASE_RETURN_STR(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT)
+ CASE_RETURN_STR(BT_PROPERTY_ADAPTER_BONDED_DEVICES)
+ CASE_RETURN_STR(BT_PROPERTY_ADAPTER_SCAN_MODE)
+ CASE_RETURN_STR(BT_PROPERTY_REMOTE_FRIENDLY_NAME)
+
+ default:
+ return "UNKNOWN PROPERTY ID";
+ }
+}
+
+
+const char* dump_hf_event(UINT16 event)
+{
+ switch(event)
+ {
+ CASE_RETURN_STR(BTA_AG_ENABLE_EVT)
+ CASE_RETURN_STR(BTA_AG_REGISTER_EVT)
+ CASE_RETURN_STR(BTA_AG_OPEN_EVT)
+ CASE_RETURN_STR(BTA_AG_CLOSE_EVT)
+ CASE_RETURN_STR(BTA_AG_CONN_EVT)
+ CASE_RETURN_STR(BTA_AG_AUDIO_OPEN_EVT)
+ CASE_RETURN_STR(BTA_AG_AUDIO_CLOSE_EVT)
+ CASE_RETURN_STR(BTA_AG_SPK_EVT)
+ CASE_RETURN_STR(BTA_AG_MIC_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CKPD_EVT)
+ CASE_RETURN_STR(BTA_AG_DISABLE_EVT)
+
+ CASE_RETURN_STR(BTA_AG_AT_A_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_D_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CHLD_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CHUP_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CIND_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_VTS_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BINP_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BLDN_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BVRA_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_NREC_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CNUM_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BTRH_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CLCC_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_COPS_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_UNAT_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_CBC_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BAC_EVT)
+ CASE_RETURN_STR(BTA_AG_AT_BCS_EVT)
+
+ default:
+ return "UNKNOWN MSG ID";
+ }
+}
+
+
+const char* dump_hf_conn_state(UINT16 event)
+{
+ switch(event)
+ {
+ CASE_RETURN_STR(BTHF_CONNECTION_STATE_DISCONNECTED)
+ CASE_RETURN_STR(BTHF_CONNECTION_STATE_CONNECTING)
+ CASE_RETURN_STR(BTHF_CONNECTION_STATE_CONNECTED)
+ CASE_RETURN_STR(BTHF_CONNECTION_STATE_DISCONNECTING)
+ default:
+ return "UNKNOWN MSG ID";
+ }
+}
+
+const char* dump_hf_call_state(bthf_call_state_t call_state)
+{
+ switch(call_state)
+ {
+ CASE_RETURN_STR(BTHF_CALL_STATE_IDLE)
+ CASE_RETURN_STR(BTHF_CALL_STATE_ONHOLD)
+ CASE_RETURN_STR(BTHF_CALL_STATE_DIALING)
+ CASE_RETURN_STR(BTHF_CALL_STATE_ALERTING)
+ CASE_RETURN_STR(BTHF_CALL_STATE_INCOMING)
+ CASE_RETURN_STR(BTHF_CALL_STATE_WAITING)
+ CASE_RETURN_STR(BTHF_CALL_STATE_ACTIVE)
+ default:
+ return "UNKNOWN MSG ID";
+ }
+}
+
+const char* dump_thread_evt(bt_cb_thread_evt evt)
+{
+ switch(evt)
+ {
+ CASE_RETURN_STR(ASSOCIATE_JVM)
+ CASE_RETURN_STR(DISASSOCIATE_JVM)
+
+ default:
+ return "unknown thread evt";
+ }
+}
+
+
+const char* dump_hf_audio_state(UINT16 event)
+{
+ switch(event)
+ {
+ CASE_RETURN_STR(BTHF_AUDIO_STATE_DISCONNECTED)
+ CASE_RETURN_STR(BTHF_AUDIO_STATE_CONNECTING)
+ CASE_RETURN_STR(BTHF_AUDIO_STATE_CONNECTED)
+ CASE_RETURN_STR(BTHF_AUDIO_STATE_DISCONNECTING)
+ default:
+ return "UNKNOWN MSG ID";
+
+ }
+}
+
+
+const char* dump_adapter_scan_mode(bt_scan_mode_t mode)
+{
+ switch(mode)
+ {
+ CASE_RETURN_STR(BT_SCAN_MODE_NONE)
+ CASE_RETURN_STR(BT_SCAN_MODE_CONNECTABLE)
+ CASE_RETURN_STR(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE)
+
+ default:
+ return "unknown scan mode";
+ }
+}
+
+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 scan mode";
+ }
+}
+
+
+