interop: Add support for Version based Blacklisting
Add support for Version based blacklisting to IOP database.
CRs-Fixed: 2432078
Change-Id: I6bf26fd511f7378a2e537ffde49b086207449b9a
diff --git a/system_bt_ext/conf/interop_database.conf b/system_bt_ext/conf/interop_database.conf
index 05f2d89..d909adf 100644
--- a/system_bt_ext/conf/interop_database.conf
+++ b/system_bt_ext/conf/interop_database.conf
@@ -8,7 +8,7 @@
#1. Below are the four tags for blacklist
# A. Address_Based C. Manufacturer_based
# B. Name_Based D. Vndr_Prdt_Based
-# E. SSR_Max_Lat_Based
+# E. SSR_Max_Lat_Based F: Version_Based
##
# A. Address_Based : This tag refers to Address based blacklist
# Input Type : Input value should be only 3 to 6 bytes of BD address
@@ -28,16 +28,21 @@
#####
# D. Vndr_Prdt_Based : This tag refers to vendor and product based blacklist
# Input type : Input should be in Hexadecimal value
-# Format Type : 4 bytes hex value( 2bytes of vendor and 2 bytes of product),
+# Format Type : 4 bytes hex value( 2 bytes of vendor and 2 bytes of product),
# Vendor and product hex values should be separated with delimiter(-).
# Examples : 0X00AB-0X00BC = Vndr_Prdt_Based
#####
-# E. SSR_Max_Lat_Based : This tag refers to SSR Max LAtency based blacklist
+# E. SSR_Max_Lat_Based : This tag refers to SSR Max Latency based blacklist
# Input type : Input value should be combination of first 3 bytes of BD address and
# Hexadecimal value of SSR Max Latency
# Format Type : Address should be in XX:XX:XX format followed by 2 bytes hex value
# of max latency Address and Max Latency should be separated with delimiter(-).
# Examples : 00:01:03-0X00AB = SSR_Max_Lat_Based
+#####
+# F. Version_Based : This tag refers to DID Version based blacklist
+# Input type : Input value should be Hexadecimal value
+# Format Type : 2 bytes hex value
+# Examples : 0X00AB = Version_Based
# ******************************* Start of Blacklist Database ********************************
#Disable secure connections
#This is for pre BT 4.1/2 devices that do not handle secure mode very well.
diff --git a/system_bt_ext/device/include/interop_config.h b/system_bt_ext/device/include/interop_config.h
index a2c5e62..35f3e8c 100644
--- a/system_bt_ext/device/include/interop_config.h
+++ b/system_bt_ext/device/include/interop_config.h
@@ -34,6 +34,7 @@
void interop_database_add_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
void interop_database_add_addr_max_lat(const interop_feature_t feature, const RawAddress *addr,
size_t length, uint16_t max_lat);
+void interop_database_add_version(const interop_feature_t feature, uint16_t version);
// API's for removing entries from dynamic interop database
bool interop_database_remove_addr(const interop_feature_t feature, const RawAddress *addr);
@@ -42,6 +43,7 @@
bool interop_database_remove_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
bool interop_database_remove_addr_max_lat(const interop_feature_t feature,
const RawAddress *addr, size_t length, uint16_t max_lat);
+bool interop_database_remove_version(const interop_feature_t feature, uint16_t version);
// API's to match entries with in dynamic interop database
bool interop_database_match_addr(const interop_feature_t feature, const RawAddress *addr);
@@ -50,4 +52,5 @@
bool interop_database_match_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
bool interop_database_match_addr_get_max_lat(const interop_feature_t feature,
const RawAddress *addr, uint16_t *max_lat);
+bool interop_database_match_version(const interop_feature_t feature, uint16_t version);
diff --git a/system_bt_ext/device/src/interop.cc b/system_bt_ext/device/src/interop.cc
index 637fe44..2381669 100644
--- a/system_bt_ext/device/src/interop.cc
+++ b/system_bt_ext/device/src/interop.cc
@@ -69,6 +69,7 @@
#define VALID_VNDR_PRDT_LEN (13)
#define VALID_MNFR_STR_LEN (6)
#define VALID_SSR_LAT_LEN (15)
+#define VALID_VERSION_LEN (6)
#define VENDOR_VALUE_SEPARATOR "-"
#define ADDR_BASED "Address_Based"
@@ -76,6 +77,7 @@
#define MNFR_BASED "Manufacturer_Based"
#define VNDR_PRDT_BASED "Vndr_Prdt_Based"
#define SSR_MAX_LAT_BASED "SSR_Max_Lat_Based"
+#define VERSION_BASED "Version_Based"
struct config_t {
list_t *sections;
@@ -98,12 +100,18 @@
interop_feature_t feature;
} interop_hid_ssr_max_lat_t;
+typedef struct {
+ uint16_t version;
+ interop_feature_t feature;
+} interop_version_t;
+
typedef enum {
INTEROP_BL_TYPE_ADDR = 0,
INTEROP_BL_TYPE_NAME,
INTEROP_BL_TYPE_MANUFACTURE,
INTEROP_BL_TYPE_VNDR_PRDT,
INTEROP_BL_TYPE_SSR_MAX_LAT,
+ INTEROP_BL_TYPE_VERSION,
} interop_bl_type;
@@ -123,6 +131,7 @@
interop_manufacturer_t mnfr_entry;
interop_hid_multitouch_t vnr_pdt_entry;
interop_hid_ssr_max_lat_t ssr_max_lat_entry;
+ interop_version_t version_entry;
} entry_type;
} interop_db_entry_t;
@@ -488,6 +497,18 @@
interop_config_flush();
break;
}
+ case INTEROP_BL_TYPE_VERSION:
+ {
+ interop_feature_t feature =
+ db_entry->entry_type.version_entry.feature;
+ char m_vendor[KEY_MAX_LENGTH] = { '\0' };
+ snprintf(m_vendor, sizeof(m_vendor), "0x%04x",
+ db_entry->entry_type.version_entry.version);
+ interop_config_set_str(interop_feature_string_(feature),
+ m_vendor, VERSION_BASED);
+ interop_config_flush();
+ break;
+ }
}
}
@@ -594,6 +615,20 @@
}
break;
}
+ case INTEROP_BL_TYPE_VERSION:
+ {
+ interop_version_t *src = &entry->entry_type.version_entry;
+ interop_version_t *cur = &db_entry->entry_type.version_entry;
+
+ if ((src->feature == cur->feature) &&
+ (src->version == cur->version)) {
+ if (ret_entry) {
+ *ret_entry = db_entry;
+ }
+ found = true;
+ }
+ break;
+ }
}
if (found) {
@@ -690,6 +725,19 @@
interop_config_flush();
break;
}
+ case INTEROP_BL_TYPE_VERSION:
+ {
+ interop_version_t *src = &entry->entry_type.version_entry;
+
+ interop_feature_t feature = src->feature;
+ char m_version[KEY_MAX_LENGTH] = { '\0' };
+ snprintf(m_version, sizeof(m_version), "0x%04x",
+ src->version);
+ interop_config_remove(interop_feature_string_(feature),
+ m_version);
+ interop_config_flush();
+ break;
+ }
default:
status = false;
}
@@ -923,6 +971,28 @@
entry->entry_type.ssr_max_lat_entry.length = len;
entry->entry_type.ssr_max_lat_entry.max_lat = max_lat;
interop_database_add_(entry, false);
+ } else if ( !strncasecmp( value, VERSION_BASED, strlen(VERSION_BASED))) {
+
+ uint16_t version;
+ char *e;
+
+ if ( strlen(key) != VALID_VERSION_LEN ) {
+ LOG_WARN(LOG_TAG,
+ " ignoring %s due to invalid version in config file", key);
+ return false;
+ }
+
+ version = (uint16_t)strtoul(key, &e, 16);
+ errno = 0;
+ if( *e || errno == EINVAL || errno == ERANGE )
+ return false;
+
+ interop_db_entry_t *entry = (interop_db_entry_t *)osi_calloc(sizeof(interop_db_entry_t));
+ entry->bl_type = INTEROP_BL_TYPE_VERSION;
+ entry->bl_entry_type = entry_type;
+ entry->entry_type.version_entry.feature = (interop_feature_t)feature;
+ entry->entry_type.version_entry.version = version;
+ interop_database_add_(entry, false);
}
LOG_WARN(LOG_TAG, " feature:: %d, key :: %s, value :: %s",
feature, key, value);
@@ -1065,6 +1135,17 @@
interop_database_add_(entry, true);
}
+void interop_database_add_version(const interop_feature_t feature, uint16_t version)
+{
+
+ interop_db_entry_t *entry = (interop_db_entry_t *)osi_calloc(sizeof(interop_db_entry_t));
+ entry->bl_type = INTEROP_BL_TYPE_VERSION;
+ entry->bl_entry_type = INTEROP_ENTRY_TYPE_DYNAMIC;
+ entry->entry_type.version_entry.feature = (interop_feature_t)feature;
+ entry->entry_type.version_entry.version = version;
+ interop_database_add_(entry, true);
+}
+
bool interop_database_match_manufacturer(const interop_feature_t feature,
uint16_t manufacturer)
{
@@ -1178,6 +1259,27 @@
return false;
}
+bool interop_database_match_version(const interop_feature_t feature, uint16_t version)
+{
+
+ interop_db_entry_t entry;
+ interop_db_entry_t *ret_entry = NULL;
+
+ entry.bl_type = INTEROP_BL_TYPE_VERSION;
+
+ entry.entry_type.version_entry.feature = (interop_feature_t)feature;
+ entry.entry_type.version_entry.version = version;
+ if (interop_database_match_(&entry, &ret_entry, (interop_entry_type)(INTEROP_ENTRY_TYPE_STATIC |
+ INTEROP_ENTRY_TYPE_DYNAMIC))) {
+ LOG_WARN(LOG_TAG,
+ "%s() Device with version: 0x%04x is a match for interop workaround %s", __func__, version,
+ interop_feature_string_(feature));
+ return true;
+ }
+
+ return false;
+}
+
bool interop_database_remove_name( const interop_feature_t feature, const char *name)
{
assert(name);
@@ -1291,3 +1393,25 @@
return false;
}
+bool interop_database_remove_version(const interop_feature_t feature, uint16_t version)
+{
+
+ interop_db_entry_t entry;
+
+ entry.bl_type = INTEROP_BL_TYPE_VERSION;
+ entry.bl_entry_type = INTEROP_ENTRY_TYPE_DYNAMIC;
+
+ entry.entry_type.version_entry.feature = (interop_feature_t)feature;
+ entry.entry_type.version_entry.version = version;
+
+ if (interop_database_remove_(&entry)) {
+ LOG_WARN(LOG_TAG,
+ "%s() Device with version: 0x%04x is removed from"
+ "interop workaround %s", __func__, version,
+ interop_feature_string_(feature));
+ return true;
+ }
+ return false;
+}
+
+