summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--btif/include/btif_hh.h5
-rw-r--r--btif/src/btif_config.c10
-rwxr-xr-xbtif/src/btif_dm.c1
-rwxr-xr-xbtif/src/btif_hh.c211
-rwxr-xr-xbtif/src/btif_storage.c30
5 files changed, 230 insertions, 27 deletions
diff --git a/btif/include/btif_hh.h b/btif/include/btif_hh.h
index 2849d63..ad438f9 100644
--- a/btif/include/btif_hh.h
+++ b/btif/include/btif_hh.h
@@ -66,6 +66,11 @@
#define BTIF_HH_MAX_HID 8
#define BTIF_HH_MAX_ADDED_DEV 32
+#define BTIF_HH_MAX_KEYSTATES 3
+#define BTIF_HH_KEYSTATE_MASK_NUMLOCK 0x01
+#define BTIF_HH_KEYSTATE_MASK_CAPSLOCK 0x02
+#define BTIF_HH_KEYSTATE_MASK_SCROLLLOCK 0x04
+
typedef struct
{
bthh_connection_state_t dev_status;
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
index 8856b5a..2470110 100644
--- a/btif/src/btif_config.c
+++ b/btif/src/btif_config.c
@@ -541,9 +541,10 @@ static cfg_node* find_node(const char* section, const char* key, const char* nam
static short find_next_node(const cfg_node* p, short start, char* name, int* bytes)
{
asrt(0 <= start && start < GET_CHILD_MAX_COUNT(p));
- //debug("in");
- //dump_node("parent", p);
+ //debug("in, start:%d, max child count:%d", start, GET_CHILD_MAX_COUNT(p));
+ //dump_node("find_next_node, parent", p);
short next = -1;
+ if(name) *name = 0;
if(0 <= start && start < GET_CHILD_MAX_COUNT(p))
{
int i;
@@ -752,8 +753,9 @@ static void cfg_test_load()
kname_size = sizeof(kname);
kname[0] = 0;
kpos = 0;
- while((kpos = btif_config_next_key(kpos, "Remote Devices", kname, &kname_size)) != -1)
+ do
{
+ kpos = btif_config_next_key(kpos, "Remote Devices", kname, &kname_size);
debug("Remote devices:%s, size:%d", kname, kname_size);
vpos = 0;
vname[0] = 0;
@@ -772,7 +774,7 @@ static void cfg_test_load()
}
kname[0] = 0;
kname_size = sizeof(kname);
- }
+ } while(kpos != -1);
debug("out");
}
static void cfg_test_write()
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index 90131aa..5eb46a0 100755
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -1546,6 +1546,7 @@ bt_status_t btif_dm_cancel_bond(const bt_bdaddr_t *bd_addr)
}
/* Cancel bonding, in case it is in ACL connection setup state */
BTA_DmBondCancel ((UINT8 *)bd_addr->address);
+ btif_storage_remove_bonded_device((bt_bdaddr_t *)bd_addr);
}
return BT_STATUS_SUCCESS;
diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c
index 2e9387a..9a599dd 100755
--- a/btif/src/btif_hh.c
+++ b/btif/src/btif_hh.c
@@ -83,19 +83,17 @@
#define KEYSTATE_FILEPATH "/data/misc/bluedroid/bt_hh_ks" //keep this in sync with HID host jni
-#define HID_REPORT_CAPSLOCK 0x39
-#define HID_REPORT_NUMLOCK 0x53
+#define HID_REPORT_CAPSLOCK 0x39
+#define HID_REPORT_NUMLOCK 0x53
#define HID_REPORT_SCROLLLOCK 0x47
-#define MAX_KEYSTATES 3
-#define KEYSTATE_MASK_NUMLOCK 0x01
-#define KEYSTATE_MASK_CAPSLOCK 0x02
-#define KEYSTATE_MASK_SCROLLLOCK 0x04
-
//For Apple Magic Mouse
#define MAGICMOUSE_VENDOR_ID 0x05ac
#define MAGICMOUSE_PRODUCT_ID 0x030d
+#define LOGITECH_KB_MX5500_VENDOR_ID 0x046D
+#define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
+
extern const int BT_UID;
extern const int BT_GID;
static int btif_hh_prev_keyevents=0; //The previous key events
@@ -133,6 +131,13 @@ typedef enum
** Local type definitions
************************************************************************************/
+typedef struct hid_kb_list
+{
+ UINT16 product_id;
+ UINT16 version_id;
+ char* kb_name;
+} tHID_KB_LIST;
+
/************************************************************************************
** Static variables
************************************************************************************/
@@ -140,6 +145,17 @@ btif_hh_cb_t btif_hh_cb;
static bthh_callbacks_t *bt_hh_callbacks = NULL;
+/* List of HID keyboards for which the NUMLOCK state needs to be
+ * turned ON by default. Add devices to this list to apply the
+ * NUMLOCK state toggle on fpr first connect.*/
+static tHID_KB_LIST hid_kb_numlock_on_list[] =
+{
+ {LOGITECH_KB_MX5500_PRODUCT_ID,
+ LOGITECH_KB_MX5500_VENDOR_ID,
+ "Logitech MX5500 Keyboard"}
+};
+
+
#define CHECK_BTHH_INIT() if (bt_hh_callbacks == NULL)\
{\
BTIF_TRACE_WARNING1("BTHH: %s: BTHH not initialized", __FUNCTION__);\
@@ -169,9 +185,165 @@ extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr);
extern int scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex);
+/*****************************************************************************
+** Local Function prototypes
+*****************************************************************************/
+static void set_keylockstate(int keymask, BOOLEAN isSet);
+static void toggle_os_keylockstates(int fd, int changedkeystates);
+static void sync_lockstate_on_connect(btif_hh_device_t *p_dev);
+//static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev);
+
+
/************************************************************************************
** Functions
************************************************************************************/
+
+static int get_keylockstates()
+{
+ return btif_hh_keylockstates;
+}
+
+static void set_keylockstate(int keymask, BOOLEAN isSet)
+{
+ if(isSet)
+ btif_hh_keylockstates |= keymask;
+}
+
+/*******************************************************************************
+**
+** Function toggle_os_keylockstates
+**
+** Description Function to toggle the keyboard lock states managed by the linux.
+** This function is used in by two call paths
+** (1) if the lock state change occurred from an onscreen keyboard,
+** this function is called to update the lock state maintained
+ for the HID keyboard(s)
+** (2) if a HID keyboard is disconnected and reconnected,
+** this function is called to update the lock state maintained
+ for the HID keyboard(s)
+** Returns void
+*******************************************************************************/
+
+static void toggle_os_keylockstates(int fd, int changedlockstates)
+{
+ BTIF_TRACE_EVENT3("%s: fd = %d, changedlockstates = 0x%x",
+ __FUNCTION__, fd, changedlockstates);
+ UINT8 hidreport[9];
+ int reportIndex;
+ memset(hidreport,0,9);
+ hidreport[0]=1;
+ reportIndex=4;
+
+ if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) {
+ BTIF_TRACE_DEBUG1("%s Setting CAPSLOCK", __FUNCTION__);
+ hidreport[reportIndex++] = (UINT8)HID_REPORT_CAPSLOCK;
+ }
+
+ if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) {
+ BTIF_TRACE_DEBUG1("%s Setting NUMLOCK", __FUNCTION__);
+ hidreport[reportIndex++] = (UINT8)HID_REPORT_NUMLOCK;
+ }
+
+ if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) {
+ BTIF_TRACE_DEBUG1("%s Setting SCROLLLOCK", __FUNCTION__);
+ hidreport[reportIndex++] = (UINT8) HID_REPORT_SCROLLLOCK;
+ }
+
+ BTIF_TRACE_DEBUG4("Writing hidreport #1 to os: "\
+ "%s: %x %x %x", __FUNCTION__,
+ hidreport[0], hidreport[1], hidreport[2]);
+ BTIF_TRACE_DEBUG4("%s: %x %x %x", __FUNCTION__,
+ hidreport[3], hidreport[4], hidreport[5]);
+ BTIF_TRACE_DEBUG4("%s: %x %x %x", __FUNCTION__,
+ hidreport[6], hidreport[7], hidreport[8]);
+ bta_hh_co_write(fd , hidreport, sizeof(hidreport));
+ usleep(200000);
+ memset(hidreport,0,9);
+ hidreport[0]=1;
+ BTIF_TRACE_DEBUG4("Writing hidreport #2 to os: "\
+ "%s: %x %x %x", __FUNCTION__,
+ hidreport[0], hidreport[1], hidreport[2]);
+ BTIF_TRACE_DEBUG4("%s: %x %x %x", __FUNCTION__,
+ hidreport[3], hidreport[4], hidreport[5]);
+ BTIF_TRACE_DEBUG4("%s: %x %x %x ", __FUNCTION__,
+ hidreport[6], hidreport[7], hidreport[8]);
+ bta_hh_co_write(fd , hidreport, sizeof(hidreport));
+}
+
+/*******************************************************************************
+**
+** Function update_keyboard_lockstates
+**
+** Description Sends a report to the keyboard to set the lock states of keys
+**
+*******************************************************************************/
+static void update_keyboard_lockstates(btif_hh_device_t *p_dev)
+{
+ UINT8 len = 2; /* reportid + 1 byte report*/
+ BD_ADDR* bda;
+
+ /* Set report for other keyboards */
+ BTIF_TRACE_EVENT3("%s: setting report on dev_handle %d to 0x%x",
+ __FUNCTION__, p_dev->dev_handle, btif_hh_keylockstates);
+
+ if (p_dev->p_buf != NULL) {
+ GKI_freebuf(p_dev->p_buf);
+ }
+ /* Get SetReport buffer */
+ p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET +
+ sizeof(BT_HDR)));
+ if (p_dev->p_buf != NULL) {
+ p_dev->p_buf->len = len;
+ p_dev->p_buf->offset = BTA_HH_MIN_OFFSET;
+
+ /* LED status updated by data event */
+ UINT8 *pbuf_data = (UINT8 *)(p_dev->p_buf + 1)
+ + p_dev->p_buf->offset;
+ pbuf_data[0]=0x01; /*report id */
+ pbuf_data[1]=btif_hh_keylockstates; /*keystate*/
+ bda = (BD_ADDR*) (&p_dev->bd_addr);
+ BTA_HhSendData(p_dev->dev_handle, *bda,
+ p_dev->p_buf);
+ }
+}
+
+/*******************************************************************************
+**
+** Function sync_lockstate_on_connect
+**
+** Description Function to update the keyboard lock states managed by the OS
+** when a HID keyboard is connected or disconnected and reconnected
+** Returns void
+*******************************************************************************/
+static void sync_lockstate_on_connect(btif_hh_device_t *p_dev)
+{
+ int keylockstates;
+
+ BTIF_TRACE_EVENT1("%s: Syncing keyboard lock states after "\
+ "reconnect...",__FUNCTION__);
+ /*If the device is connected, update keyboard state */
+ update_keyboard_lockstates(p_dev);
+
+ /*Check if the lockstate of caps,scroll,num is set.
+ If so, send a report to the kernel
+ so the lockstate is in sync */
+ keylockstates = get_keylockstates();
+ if (keylockstates)
+ {
+ BTIF_TRACE_DEBUG2("%s: Sending hid report to kernel "\
+ "indicating lock key state 0x%x",__FUNCTION__,
+ keylockstates);
+ usleep(200000);
+ toggle_os_keylockstates(p_dev->fd, keylockstates);
+ }
+ else
+ {
+ BTIF_TRACE_DEBUG2("%s: NOT sending hid report to kernel "\
+ "indicating lock key state 0x%x",__FUNCTION__,
+ keylockstates);
+ }
+}
+
/*******************************************************************************
**
** Function btif_hh_find_dev_by_handle
@@ -533,7 +705,8 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
tBTA_HH *p_data = (tBTA_HH *)p_param;
bdstr_t bdstr;
btif_hh_device_t *p_dev = NULL;
- int len;
+ int i;
+ int len, tmplen;
BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hh_event(event));
@@ -730,6 +903,28 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
//Device already added.
BTIF_TRACE_WARNING1("%s: Device already added ",__FUNCTION__);
}
+ /*Sync HID Keyboard lockstates */
+ tmplen = sizeof(hid_kb_numlock_on_list)
+ / sizeof(tHID_KB_LIST);
+ for(i = 0; i< tmplen; i++)
+ {
+ if(p_data->dscp_info.vendor_id
+ == hid_kb_numlock_on_list[i].version_id &&
+ p_data->dscp_info.product_id
+ == hid_kb_numlock_on_list[i].product_id)
+ {
+ BTIF_TRACE_DEBUG3("%s() idx[%d] Enabling "\
+ "NUMLOCK for device :: %s", __FUNCTION__,
+ i, hid_kb_numlock_on_list[i].kb_name);
+ /* Enable NUMLOCK by default so that numeric
+ keys work from first keyboard connect */
+ set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK,
+ TRUE);
+ sync_lockstate_on_connect(p_dev);
+ /* End Sync HID Keyboard lockstates */
+ break;
+ }
+ }
}
break;
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index 0110d04..0596ccd 100755
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -282,8 +282,11 @@ static int prop2cfg(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
case BT_PROPERTY_BDNAME:
strncpy(value, (char*)prop->val, prop->len);
value[prop->len]='\0';
- btif_config_set_str("Remote", bdstr,
+ if(remote_bd_addr)
+ btif_config_set_str("Remote", bdstr,
BTIF_STORAGE_PATH_REMOTE_NAME, value);
+ else btif_config_set_str("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_NAME, value);
break;
case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
strncpy(value, (char*)prop->val, prop->len);
@@ -351,8 +354,11 @@ static int cfg2prop(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
case BT_PROPERTY_BDNAME:
{
int len = prop->len;
- ret = btif_config_get_str("Remote", bdstr,
+ if(remote_bd_addr)
+ ret = btif_config_get_str("Remote", bdstr,
BTIF_STORAGE_PATH_REMOTE_NAME, (char*)prop->val, &len);
+ else ret = btif_config_get_str("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_NAME, (char*)prop->val, &len);
if(ret && len && len <= prop->len)
prop->len = len - 1;
else
@@ -440,8 +446,9 @@ static bt_status_t btif_in_fetch_bonded_devices(btif_bonded_devices_t *p_bonded_
kname_size = sizeof(kname);
kname[0] = 0;
kpos = 0;
- while((kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size)) != -1)
+ do
{
+ kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size);
debug("Remote device:%s, size:%d", kname, kname_size);
int type = BTIF_CFG_TYPE_BIN;
LINK_KEY link_key;
@@ -470,7 +477,7 @@ static bt_status_t btif_in_fetch_bonded_devices(btif_bonded_devices_t *p_bonded_
else debug("Remote device:%s, no link key", kname);
kname_size = sizeof(kname);
kname[0] = 0;
- }
+ } while(kpos != -1);
debug("out");
return BT_STATUS_SUCCESS;
}
@@ -527,9 +534,6 @@ static int hex_str_to_int(const char* str, int size)
bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
{
- /* initialize property->len */
- property->len = 0;
-
/* Special handling for adapter BD_ADDR and BONDED_DEVICES */
if (property->type == BT_PROPERTY_BDADDR)
{
@@ -931,8 +935,9 @@ bt_status_t btif_storage_load_bonded_hid_info(void)
kname[0] = 0;
kpos = 0;
memset(&dscp_info, 0, sizeof(dscp_info));
- while((kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size)) != -1)
+ do
{
+ kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size);
debug("Remote device:%s, size:%d", kname, kname_size);
int value;
if(btif_config_get_int("Remote", kname, "HidAttrMask", &value))
@@ -974,7 +979,7 @@ bt_status_t btif_storage_load_bonded_hid_info(void)
app_id, dscp_info);
}
}
- }
+ } while(kpos != -1);
return BT_STATUS_SUCCESS;
}
@@ -1268,7 +1273,7 @@ bt_status_t btif_storage_write_hl_mdl_data(UINT8 app_idx, char *value, int value
bt_status_t btif_storage_load_autopair_device_list()
{
char *key_name, *key_value;
- int ret , i=0;
+ int i=0;
char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
char *line;
FILE *fp;
@@ -1277,11 +1282,6 @@ bt_status_t btif_storage_load_autopair_device_list()
{
/* first time loading of auto pair blacklist configuration */
- if (ret < 0)
- {
- ALOGE("%s: Failed to create dynamic auto pair blacklist", __FUNCTION__);
- return BT_STATUS_FAIL;
- }
fp = fopen (BTIF_AUTO_PAIR_CONF_FILE, "r");
if (fp == NULL)