721 lines
23 KiB
C++
721 lines
23 KiB
C++
/* Copyright Statement:
|
|
* *
|
|
* * This software/firmware and related documentation ("MediaTek Software") are
|
|
* * protected under relevant copyright laws. The information contained herein
|
|
* * is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
|
* * Without the prior written permission of MediaTek inc. and/or its licensors,
|
|
* * any reproduction, modification, use or disclosure of MediaTek Software,
|
|
* * and information contained herein, in whole or in part, shall be strictly
|
|
* * prohibited.
|
|
* *
|
|
* * MediaTek Inc. (C) 2016. All rights reserved.
|
|
* *
|
|
* * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
|
* * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
|
* * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
|
|
* * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
|
|
* * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
|
|
* * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
|
* * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
|
|
* * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
|
|
* * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER
|
|
* * AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING
|
|
* * THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE
|
|
* * RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED
|
|
* * IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY
|
|
* * MEDIATEK SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM
|
|
* * TO A PARTICULAR STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE
|
|
* * REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE
|
|
* * MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO
|
|
* * REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE
|
|
* * LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH
|
|
* * MEDIATEK SOFTWARE AT ISSUE.
|
|
* *
|
|
* * The following software/firmware and/or related documentation ("MediaTek
|
|
* * Software")
|
|
* * have been modified by MediaTek Inc. All revisions are subject to any
|
|
* * receiver's applicable license agreements with MediaTek Inc.
|
|
* */
|
|
|
|
/******************************************************************************
|
|
*
|
|
* This file contains functions for the MTK defined interop function
|
|
*
|
|
******************************************************************************/
|
|
#define LOG_TAG "bt_device_interop_mtk"
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "interop_mtk.h"
|
|
|
|
#if MTK_INTEROP_CONF == 1
|
|
#if defined(MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
#include <base/logging.h>
|
|
#include <base/strings/stringprintf.h>
|
|
|
|
#include "btif_config.h"
|
|
#include "btm_api.h"
|
|
#include "btm_api_types.h"
|
|
#include "module.h"
|
|
#include "osi/include/config.h"
|
|
#include "osi/include/future.h"
|
|
|
|
using base::StringPrintf;
|
|
|
|
#define MTK_STACK_CONFIG_VALUE_SEPARATOR ","
|
|
#define MTK_STACK_CONFIG_NAME_VALUE_MAX 1024
|
|
#define MTK_STACK_CONFIG_VERSION 0x7
|
|
#define MTK_STACK_CONFIG_VERSION_LMP_VER 0x4
|
|
#define MTK_STACK_CONFIG_VERSION_MFCT 0x2
|
|
#define MTK_STACK_CONFIG_VERSION_LMP_SUBVER 0x1
|
|
|
|
|
|
static std::unique_ptr<config_t> config_org;
|
|
static std::unique_ptr<config_t> config_ext;
|
|
|
|
|
|
|
|
const char* BLACKLIST_ADDR_KEY = "AddressBlacklist";
|
|
const char* BLACKLIST_NAME_KEY = "ExactNameBlacklist";
|
|
const char* BLACKLIST_PARTIAL_NAME_KEY = "PartialNameBlacklist";
|
|
const char* BLACKLIST_VERSION_KEY = "VersionBlacklist";
|
|
/** M: New feature: add device information to black list {@ */
|
|
const char* BTIOT_CONFIG_FILE_NAME = "/etc/bluetooth/bt_mtk_iot_list.conf";
|
|
const char* BTIOT_UPDATE_FILE_NAME = "/data/misc/bluedroid/bt_mtk_iot_list.conf";
|
|
/**@}*/
|
|
|
|
static const std::string* get_blacklist_content(const config_t& config, const char* section, const std::string& key) {
|
|
return config_get_string(config, section, key, NULL);
|
|
}
|
|
|
|
|
|
static void set_blacklist_content(const char* section, const std::string& key, const char* strvalue) {
|
|
LOG(INFO) << StringPrintf("%s: %s save %s: %s", LOG_TAG, __func__, section, strvalue);
|
|
config_set_string(config_ext.get(), section, key, strvalue);
|
|
config_save(*config_ext, BTIOT_UPDATE_FILE_NAME);
|
|
}
|
|
|
|
|
|
static future_t* init() {
|
|
// TODO(armansito): Find a better way than searching by a hardcoded path.
|
|
#if defined(OS_GENERIC)
|
|
const char* path = "bt_mtk_iot_list.conf";
|
|
#else // !defined(OS_GENERIC)
|
|
const char* path = "/etc/bluetooth/bt_mtk_iot_list.conf";
|
|
#endif // defined(OS_GENERIC)
|
|
|
|
/** M: New feature: add device information to black list {@ */
|
|
config_ext = config_new(BTIOT_UPDATE_FILE_NAME);
|
|
if (!config_ext) {
|
|
int fd;
|
|
|
|
mode_t old = umask(0007);
|
|
fd = open(BTIOT_UPDATE_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 00660);
|
|
umask(old);
|
|
if (fd < 0) {
|
|
LOG(INFO) << StringPrintf("%s: %s file >%s< creat fail", LOG_TAG, __func__,
|
|
BTIOT_UPDATE_FILE_NAME);
|
|
return future_new_immediate(FUTURE_FAIL);
|
|
}
|
|
close(fd);
|
|
config_ext = config_new(BTIOT_UPDATE_FILE_NAME);
|
|
}
|
|
|
|
config_org = config_new(path);
|
|
if (!config_org) {
|
|
LOG(INFO) << StringPrintf("%s: %s file >%s< not found", LOG_TAG, __func__,
|
|
path);
|
|
return future_new_immediate(FUTURE_FAIL);
|
|
}
|
|
/**@}*/
|
|
|
|
return future_new_immediate(FUTURE_SUCCESS);
|
|
}
|
|
|
|
static future_t* clean_up() {
|
|
config_org.reset();
|
|
config_ext.reset();
|
|
return future_new_immediate(FUTURE_SUCCESS);
|
|
}
|
|
|
|
EXPORT_SYMBOL extern const module_t mtk_iot_list_module = {
|
|
.name = MTK_IOT_LIST_MODULE,
|
|
.init = init,
|
|
.start_up = NULL,
|
|
.shut_down = NULL,
|
|
.clean_up = clean_up,
|
|
.dependencies = {NULL}};
|
|
|
|
bt_status_t btmtk_get_ble_device_name(const RawAddress* addr, BD_NAME bd_name) {
|
|
if (addr) {
|
|
std::string addrstr = addr->ToString();
|
|
const char* bdstr = addrstr.c_str();
|
|
|
|
int length = BD_NAME_LEN;
|
|
bool ret = btif_config_get_str(bdstr, "Name",
|
|
reinterpret_cast<char*>(bd_name), &length);
|
|
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
|
}
|
|
return BT_STATUS_FAIL;
|
|
}
|
|
|
|
bool interop_mtk_match_addr_byconfig(const config_t& config, const char* section, const RawAddress* addr) {
|
|
|
|
char* token;
|
|
char* start_ptr = NULL;
|
|
const std::string* value;
|
|
std::string addrstr = addr->ToString();
|
|
const char* bdstr = addrstr.c_str();
|
|
char addr_list[MTK_STACK_CONFIG_NAME_VALUE_MAX] = {0};
|
|
int copy_len;
|
|
|
|
if ((value = get_blacklist_content(config, section, BLACKLIST_ADDR_KEY)) != NULL) {
|
|
VLOG(2) << StringPrintf("%s:[%s] check %s in %s", __func__, section, bdstr,
|
|
value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
copy_len = value->length();
|
|
else
|
|
copy_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(addr_list, value->c_str(), copy_len);
|
|
|
|
token = strtok_r(addr_list, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
while (token != NULL) {
|
|
if (strncasecmp(bdstr, token, strlen(token)) == 0) {
|
|
LOG(INFO) << StringPrintf("%s:[%s] %s got matched", __func__, section,
|
|
bdstr);
|
|
|
|
return TRUE;
|
|
}
|
|
token = strtok_r(NULL, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
bool interop_mtk_match_addr(const char* section, const RawAddress* addr) {
|
|
if (config_org == NULL || section == NULL || addr == NULL) return FALSE;
|
|
|
|
bool result;
|
|
|
|
result = interop_mtk_match_addr_byconfig(*config_org, section, addr);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
if (config_ext != NULL)
|
|
result = interop_mtk_match_addr_byconfig(*config_ext, section, addr);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/** M: New feature: framework get black list information {@ */
|
|
bool interop_mtk_match_name_byconfig(const config_t& config, const char* section, const char* name) {
|
|
char* token;
|
|
char* start_ptr = NULL;
|
|
const std::string* value;
|
|
char name_list[MTK_STACK_CONFIG_NAME_VALUE_MAX] = {0};
|
|
int copy_len;
|
|
|
|
if ((value = get_blacklist_content(config, section, BLACKLIST_NAME_KEY)) != NULL) {
|
|
VLOG(2) << StringPrintf("%s:[%s] check %s in %s", __func__, section,
|
|
name, value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
copy_len = value->length();
|
|
else
|
|
copy_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(name_list, value->c_str(), copy_len);
|
|
|
|
token = strtok_r(name_list, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
while (token != NULL) {
|
|
if (!strcmp(token, name)) {
|
|
LOG(INFO) << StringPrintf("%s:[%s] %s got matched", __func__, section,
|
|
name);
|
|
return TRUE;
|
|
}
|
|
token = strtok_r(NULL, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
}
|
|
}
|
|
|
|
memset(name_list, 0, sizeof(name_list));
|
|
|
|
if ((value = get_blacklist_content(config, section, BLACKLIST_PARTIAL_NAME_KEY)) != NULL) {
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
copy_len = value->length();
|
|
else
|
|
copy_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(name_list, value->c_str(), copy_len);
|
|
|
|
LOG(INFO) << StringPrintf("%s:[%s] check name %s in partial name list %s", __func__,
|
|
section, name, name_list);
|
|
token = strtok_r(name_list, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
while (token != NULL) {
|
|
if (strstr(name, token) != NULL) {
|
|
LOG(INFO) << StringPrintf("%s:[%s] %s got matched", __func__, section,
|
|
name);
|
|
return TRUE;
|
|
}
|
|
token = strtok_r(NULL, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
/**@}*/
|
|
|
|
|
|
bool interop_mtk_match_name_byaddr(const config_t& config, const char* section, const RawAddress* addr) {
|
|
|
|
char* dev_name_str;
|
|
BD_NAME remote_name = {0};
|
|
bool result;
|
|
|
|
dev_name_str = BTM_SecReadDevName(*addr);
|
|
|
|
// need to load ble device name from config
|
|
if (dev_name_str == NULL || dev_name_str[0] == '\0') {
|
|
dev_name_str = reinterpret_cast<char*>(remote_name);
|
|
btmtk_get_ble_device_name(addr, remote_name);
|
|
}
|
|
|
|
if (dev_name_str == NULL || dev_name_str[0] == '\0') return FALSE;
|
|
|
|
result = interop_mtk_match_name_byconfig(config, section, dev_name_str);
|
|
return result;
|
|
|
|
}
|
|
|
|
bool interop_mtk_match_name(const char* section, const RawAddress* addr) {
|
|
if (config_org == NULL || section == NULL || addr == NULL) return FALSE;
|
|
|
|
bool result;
|
|
|
|
result = interop_mtk_match_name_byaddr(*config_org, section, addr);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
if (config_ext != NULL)
|
|
result = interop_mtk_match_name_byaddr(*config_ext, section, addr);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
bool interop_mtk_match_name(const char* section, const char* name) {
|
|
if (config_org == NULL || section == NULL || name == NULL) return FALSE;
|
|
|
|
bool result;
|
|
|
|
result = interop_mtk_match_name_byconfig(*config_org, section, name);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
if (config_ext != NULL)
|
|
result = interop_mtk_match_name_byconfig(*config_ext, section, name);
|
|
if (result)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool interop_mtk_match_addr_name(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_addr(section, addr) ||
|
|
interop_mtk_match_name(section, addr);
|
|
}
|
|
|
|
char *utoa(unsigned int value, char * str, int radix, int len)
|
|
{
|
|
const char * format = NULL;
|
|
|
|
switch(radix)
|
|
{
|
|
case 8:
|
|
format = "%o";
|
|
break;
|
|
case 10:
|
|
format = "%u";
|
|
break;
|
|
case 16:
|
|
if (len == 2)
|
|
format = "%02x";
|
|
else
|
|
format = "%04x";
|
|
break;
|
|
}
|
|
|
|
if(format == NULL)
|
|
return str;
|
|
|
|
int size = sprintf(str, format, value);
|
|
return &str[size];
|
|
}
|
|
|
|
bool interop_mtk_match_ver_byconfig(const config_t& config, const char* section,
|
|
const uint8_t state, const uint8_t lmp_ver,
|
|
const uint16_t mfct_set, const uint16_t lmp_subver) {
|
|
|
|
char* token;
|
|
char* start_ptr = NULL;
|
|
const std::string* value;
|
|
int copy_len;
|
|
char ver_list[MTK_STACK_CONFIG_NAME_VALUE_MAX] = {0};
|
|
char pattern[13] = {0};
|
|
char buffer[5];
|
|
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
if (state & MTK_STACK_CONFIG_VERSION_LMP_VER) {
|
|
utoa(lmp_ver, buffer, 16, 2);
|
|
strcat(pattern, buffer);
|
|
strcat(pattern, ":");
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
}
|
|
if (state & MTK_STACK_CONFIG_VERSION_MFCT) {
|
|
utoa(mfct_set, buffer, 16, 4);
|
|
strcat(pattern, buffer);
|
|
strcat(pattern, ":");
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
}
|
|
if (state & MTK_STACK_CONFIG_VERSION_LMP_SUBVER) {
|
|
utoa(lmp_subver, buffer, 16, 4);
|
|
strcat(pattern, buffer);
|
|
}
|
|
|
|
if ((value = get_blacklist_content(config, section, BLACKLIST_VERSION_KEY)) != NULL) {
|
|
VLOG(2) << StringPrintf("%s:[%s] check %s in %s", __func__, section, pattern,
|
|
value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
copy_len = value->length();
|
|
else
|
|
copy_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(ver_list, value->c_str(), copy_len);
|
|
|
|
token = strtok_r(ver_list, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
while (token != NULL) {
|
|
if (strstr(token, pattern) != NULL) {
|
|
LOG(INFO) << StringPrintf("%s:[%s] %s got matched", __func__, section, pattern);
|
|
return TRUE;
|
|
}
|
|
token = strtok_r(NULL, MTK_STACK_CONFIG_VALUE_SEPARATOR, &start_ptr);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
bool interop_mtk_match_ver_byaddr(const char* section, const RawAddress* addr,
|
|
const uint8_t state) {
|
|
if (config_org == NULL || section == NULL || addr == NULL) return FALSE;
|
|
|
|
bool result = FALSE;
|
|
|
|
uint8_t lmp_ver = 0;
|
|
uint16_t mfct_set = 0;
|
|
uint16_t lmp_subver = 0;
|
|
|
|
if (!BTM_ReadRemoteVersion(*addr, &lmp_ver, &mfct_set, &lmp_subver)) {
|
|
LOG(INFO) << StringPrintf("%s: %s BTM_ReadRemoteVersion", LOG_TAG, __func__);
|
|
return FALSE;
|
|
}
|
|
|
|
if (0 == lmp_ver && 0 == mfct_set && 0 == lmp_subver) {
|
|
LOG(INFO) << StringPrintf("%s: %s get remote version fail", LOG_TAG, __func__);
|
|
return FALSE;
|
|
}
|
|
|
|
if (interop_mtk_match_ver_byconfig(*config_org, section, state, lmp_ver, mfct_set, lmp_subver))
|
|
return TRUE;
|
|
|
|
if (config_ext != NULL)
|
|
result = interop_mtk_match_ver_byconfig(*config_ext, section, state, lmp_ver, mfct_set, lmp_subver);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool interop_mtk_match_lmp_ver(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_ver_byaddr(section, addr, MTK_STACK_CONFIG_VERSION_LMP_VER);
|
|
}
|
|
|
|
bool interop_mtk_match_mfct(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_ver_byaddr(section, addr, MTK_STACK_CONFIG_VERSION_MFCT);
|
|
}
|
|
|
|
bool interop_mtk_match_lmp_subver(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_ver_byaddr(section, addr, MTK_STACK_CONFIG_VERSION_LMP_SUBVER);
|
|
}
|
|
|
|
bool interop_mtk_match_ver(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_ver_byaddr(section, addr, MTK_STACK_CONFIG_VERSION);
|
|
}
|
|
|
|
bool interop_mtk_match_any(const char* section, const RawAddress* addr) {
|
|
return interop_mtk_match_addr(section, addr) ||
|
|
interop_mtk_match_name(section, addr) ||
|
|
interop_mtk_match_ver(section, addr);
|
|
}
|
|
|
|
/** M: New feature: add device information to black list {@ */
|
|
bool interop_mtk_set_addr(const char* section, const RawAddress* addr, int size) {
|
|
if (config_ext == NULL || section == NULL || addr == NULL) return FALSE;
|
|
|
|
const std::string* value;
|
|
std::string addrstr = addr->ToString();
|
|
const char* bdstr = addrstr.c_str();
|
|
char addr_list[MTK_STACK_CONFIG_NAME_VALUE_MAX] = {0};
|
|
int value_len = 0;
|
|
int addr_len = 0;
|
|
int addrsize = size * 2 + size - 1;
|
|
char addr_add[18] = {0};
|
|
|
|
if (interop_mtk_match_addr_byconfig(*config_org, section, addr))
|
|
return TRUE;
|
|
|
|
if (interop_mtk_match_addr_byconfig(*config_ext, section, addr))
|
|
return TRUE;
|
|
|
|
if ((value = get_blacklist_content(*config_ext, section, BLACKLIST_ADDR_KEY)) != NULL) {
|
|
VLOG(2) << StringPrintf("%s:[%s] check %s in %s", __func__, section, addr_add,
|
|
value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
value_len = value->length();
|
|
else
|
|
value_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(addr_list, value->c_str(), value_len);
|
|
|
|
strncpy(addr_add, bdstr, addrsize);
|
|
addr_len = strlen(addr_add);
|
|
if ((MTK_STACK_CONFIG_NAME_VALUE_MAX - value_len) < addr_len + 1) {
|
|
LOG(INFO) << StringPrintf("%s:[%s][size:%d] %s[len:%d] too long", __func__, section,
|
|
value_len, addr_add, addr_len);
|
|
return FALSE;
|
|
}
|
|
|
|
addr_list[value_len] = ',';
|
|
strcpy(addr_list + value_len + 1, addr_add);
|
|
|
|
set_blacklist_content(section, BLACKLIST_ADDR_KEY, addr_list);
|
|
return TRUE;
|
|
|
|
} else {
|
|
strncpy(addr_list, bdstr, addrsize);
|
|
set_blacklist_content(section, BLACKLIST_ADDR_KEY, addr_list);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
bool interop_mtk_set_name_bykey(const char* section, const char* name, bool partialname) {
|
|
const std::string* value;
|
|
const char* key;
|
|
char name_list[MTK_STACK_CONFIG_NAME_VALUE_MAX]= {0};
|
|
int value_len = 0;
|
|
int name_len = 0;
|
|
|
|
if (interop_mtk_match_name_byconfig(*config_org, section, name))
|
|
return TRUE;
|
|
|
|
if (interop_mtk_match_name_byconfig(*config_ext, section, name))
|
|
return TRUE;
|
|
|
|
if (partialname)
|
|
key = BLACKLIST_PARTIAL_NAME_KEY;
|
|
else
|
|
key = BLACKLIST_NAME_KEY;
|
|
|
|
value = get_blacklist_content(*config_ext, section, key);
|
|
if (value != NULL) {
|
|
LOG(INFO) << StringPrintf("%s:[%s] check %s in %s", __func__, section,
|
|
name, value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
value_len = value->length();
|
|
else
|
|
value_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
|
|
name_len = strlen(name);
|
|
if ((MTK_STACK_CONFIG_NAME_VALUE_MAX - value_len) < name_len + 1) {
|
|
LOG(INFO) << StringPrintf("%s:[%s][size:%d] %s[len:%d] too long", __func__, section,
|
|
value_len, name, name_len);
|
|
return FALSE;
|
|
}
|
|
|
|
strncpy(name_list, value->c_str(), value_len);
|
|
name_list[value_len] = ',';
|
|
strcpy(name_list + value_len + 1, name);
|
|
|
|
set_blacklist_content(section, key, name_list);
|
|
return TRUE;
|
|
} else {
|
|
strcpy(name_list, name);
|
|
set_blacklist_content(section, key, name_list);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
bool interop_mtk_set_name(const char* section, const char* name) {
|
|
|
|
if (config_ext == NULL || section == NULL || name == NULL) return FALSE;
|
|
|
|
return interop_mtk_set_name_bykey(section, name, FALSE);
|
|
}
|
|
|
|
bool interop_mtk_set_partial_name(const char* section, const char* name) {
|
|
|
|
if (config_ext == NULL || section == NULL || name == NULL) return FALSE;
|
|
|
|
return interop_mtk_set_name_bykey(section, name, TRUE);
|
|
}
|
|
|
|
bool interop_mtk_set_ver(const char* section, const RawAddress* addr) {
|
|
if (config_ext == NULL || section == NULL || addr == NULL) return FALSE;
|
|
|
|
const std::string* value;
|
|
char ver_list[MTK_STACK_CONFIG_NAME_VALUE_MAX] = {0};
|
|
int value_len = 0;
|
|
int pattern_len = 0;
|
|
|
|
uint8_t lmp_ver = 0;
|
|
uint16_t mfct_set = 0;
|
|
uint16_t lmp_subver = 0;
|
|
uint8_t state = MTK_STACK_CONFIG_VERSION;
|
|
char pattern[13] = {0};
|
|
char buffer[5];
|
|
|
|
if (!BTM_ReadRemoteVersion(*addr, &lmp_ver, &mfct_set, &lmp_subver)) {
|
|
LOG(INFO) << StringPrintf("%s: %s BTM_ReadRemoteVersion", LOG_TAG, __func__);
|
|
return FALSE;
|
|
}
|
|
|
|
if (0 == lmp_ver && 0 == mfct_set && 0 == lmp_subver) {
|
|
LOG(INFO) << StringPrintf("%s: %s get remote version fail", LOG_TAG, __func__);
|
|
return FALSE;
|
|
}
|
|
|
|
if (interop_mtk_match_ver_byconfig(*config_org, section, state, lmp_ver, mfct_set, lmp_subver))
|
|
return TRUE;
|
|
|
|
if (interop_mtk_match_ver_byconfig(*config_ext, section, state, lmp_ver, mfct_set, lmp_subver))
|
|
return TRUE;
|
|
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
if (state & MTK_STACK_CONFIG_VERSION_LMP_VER) {
|
|
utoa(lmp_ver, buffer, 16, 2);
|
|
strcat(pattern, buffer);
|
|
strcat(pattern, ":");
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
}
|
|
if (state & MTK_STACK_CONFIG_VERSION_MFCT) {
|
|
utoa(mfct_set, buffer, 16, 4);
|
|
strcat(pattern, buffer);
|
|
strcat(pattern, ":");
|
|
memset(buffer, '\0', sizeof(buffer));
|
|
}
|
|
if (state & MTK_STACK_CONFIG_VERSION_LMP_SUBVER) {
|
|
utoa(lmp_subver, buffer, 16, 4);
|
|
strcat(pattern, buffer);
|
|
}
|
|
|
|
if ((value = get_blacklist_content(*config_ext, section, BLACKLIST_VERSION_KEY)) != NULL) {
|
|
VLOG(2) << StringPrintf("%s:[%s] check %s in %s", __func__, section, pattern,
|
|
value->c_str());
|
|
if (value->length() < MTK_STACK_CONFIG_NAME_VALUE_MAX)
|
|
value_len = value->length();
|
|
else
|
|
value_len = MTK_STACK_CONFIG_NAME_VALUE_MAX - 1;
|
|
strncpy(ver_list, value->c_str(), value_len);
|
|
|
|
pattern_len = strlen(pattern);
|
|
if ((MTK_STACK_CONFIG_NAME_VALUE_MAX - value_len) < pattern_len + 1) {
|
|
LOG(INFO) << StringPrintf("%s:[%s][size:%d] %s[len:%d] too long", __func__, section,
|
|
value_len, pattern, pattern_len);
|
|
return FALSE;
|
|
}
|
|
|
|
ver_list[value_len] = ',';
|
|
strcpy(ver_list + value_len + 1, pattern);
|
|
|
|
set_blacklist_content(section, BLACKLIST_VERSION_KEY, ver_list);
|
|
return TRUE;
|
|
|
|
} else {
|
|
strncpy(ver_list, pattern, strlen(pattern));
|
|
set_blacklist_content(section, BLACKLIST_VERSION_KEY, ver_list);
|
|
return TRUE;
|
|
}
|
|
}
|
|
/**@}*/
|
|
#endif
|
|
|
|
/** M: New feature: framework get black list information {@ */
|
|
bool interop_mtk_match_addr_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_addr_name(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool interop_mtk_match_name_fwk(const char* section, const char* name) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_name(section, name);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
|
|
bool interop_mtk_match_addr_name_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_addr_name(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool interop_mtk_match_lmp_ver_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_lmp_ver(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool interop_mtk_match_mfct_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_mfct(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool interop_mtk_match_lmp_subver_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_lmp_subver(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool interop_mtk_match_ver_fwk(const char* section, const RawAddress* addr) {
|
|
#if defined (MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
return interop_mtk_match_ver(section, addr);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
static const btinterop_mtk_interface_t interop_if = {
|
|
sizeof(btinterop_mtk_interface_t), interop_mtk_match_addr_fwk, interop_mtk_match_name_fwk,
|
|
interop_mtk_match_addr_name_fwk, interop_mtk_match_lmp_ver_fwk, interop_mtk_match_mfct_fwk,
|
|
interop_mtk_match_lmp_subver_fwk, interop_mtk_match_ver_fwk};
|
|
|
|
const btinterop_mtk_interface_t* btif_interop_mtk_get_interface() {
|
|
return &interop_if;
|
|
}
|
|
/**@}*/
|
|
#endif
|