diff options
Diffstat (limited to 'halimpl/utils/phNxpConfig.cpp')
-rw-r--r--[-rwxr-xr-x] | halimpl/utils/phNxpConfig.cpp | 446 |
1 files changed, 405 insertions, 41 deletions
diff --git a/halimpl/utils/phNxpConfig.cpp b/halimpl/utils/phNxpConfig.cpp index 58ac5b9..8c57313 100755..100644 --- a/halimpl/utils/phNxpConfig.cpp +++ b/halimpl/utils/phNxpConfig.cpp @@ -1,4 +1,6 @@ /****************************************************************************** + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Not a Contribution. * * Copyright (C) 2011-2012 Broadcom Corporation * @@ -36,6 +38,16 @@ * ******************************************************************************/ + /** + * @file phNxpConfig.cpp + * @date 24 Aug 2016 + * @brief File containing code for dynamic selection of config files based on target. + * + * The target device has to be configured with some primary setting while booting.So a + * config file will be picked while the target is booted. Here based on the target device + * a configuration file will be selected dynamically and the device will be configured. + */ + #include <phNxpConfig.h> #include <stdio.h> #include <string> @@ -82,6 +94,60 @@ const char default_nxp_config_path[] = const char nxp_rf_config_path[] = "/system/vendor/libnfc-nxp_RF.conf"; +/** + * @brief target platform ID values. + */ + +typedef enum +{ + CONFIG_GENERIC = 0x00, + MTP_TYPE_DEFAULT = 0x01, /**< default MTP config. DC DC ON */ + QRD_TYPE_DEFAULT = 0x02, /**< default QRD config DC DC OFF */ + MTP_TYPE_1 = 0x03, /**< mtp config type1 : newer chip */ + MTP_TYPE_2 = 0x04, /**< mtp config type2 TBD */ + QRD_TYPE_1 = 0x05, /**< qrd config type1 DC DC ON*/ + QRD_TYPE_2 = 0x06, /**< qrd config type2 Newer chip */ + MTP_TYPE_NQ3XX = 0x07, /**< mtp config : for NQ3XX chip */ + QRD_TYPE_NQ3XX = 0x08, /**< qrd config : for NQ3XX chip */ + MTP_TYPE_NQ4XX = 0x09, /**< mtp config : for NQ4XX chip */ + QRD_TYPE_NQ4XX = 0x10, /**< qrd config : for NQ4XX chip */ + DEFAULT_CONFIG = QRD_TYPE_DEFAULT, /**< default is qrd default config */ + CONFIG_INVALID = 0xFF +} CONFIGIDVALUE; + +/** + * @brief Defines the soc_id values for different targets. + */ + +typedef enum +{ + TARGET_GENERIC = 0x00,/**< new targets */ + TARGET_MSM8952 = 264, /**< 8952 target */ + TARGET_MSM8976 = 278, /**< 8976 target */ + TARGET_MSM8937 = 294, /**< 8937 target */ + TARGET_MSM8953 = 293, /**< 8953 target */ + TARGET_MSM8996 = 246, /**< 8996 target*/ + TARGET_MSM8909 = 245, /**< 8909w target */ + TARGET_MSM8998 = 292, /**< 8998 target */ + TARGET_MSM8997 = 306, /**< 8997 target */ + TARGET_MSM8917 = 303, /**< 8917 target */ + TARGET_MSM8940 = 313, /**< 8940 target */ + TARGET_SDM660 = 317, /**< SDM660 target */ + TARGET_SDM670 = 336, /**< SDM670 target */ + TARGET_SDM710 = 360, /**< SDM710 target */ + TARGET_SDM712 = 393, /**< SDM712 target */ + TARGET_QCS605 = 347, /**< QCS605 target */ + TARGET_SDM630 = 318, /**< SDM630 target */ + TARGET_SDM632 = 349, /**< SDM632 target */ + TARGET_SDM439 = 353, /**< SDM439 target */ + TARGET_SDM429 = 354, /**< SDM429 target */ + TARGET_SDM450 = 338, /**< SDM450 target */ + TARGET_SDM455 = 385, /**< SDM455 target */ + TARGET_SDM845 = 321, /**< SDM845 target */ + TARGET_DEFAULT = TARGET_GENERIC, /**< new targets */ + TARGET_INVALID = 0xFF +} TARGETTYPE; + namespace { size_t readConfigFile(const char* fileName, uint8_t** p_data) { @@ -116,6 +182,7 @@ using namespace ::std; namespace nxp { +void findConfigFilePathFromTransportConfigPaths(const string& configName, string& filePath); class CNfcParam : public string { public: @@ -152,6 +219,8 @@ class CNfcConfig : public vector<const CNfcParam*> { private: CNfcConfig(); bool readConfig(const char* name, bool bResetContent); + int file_exist (const char* filename); + int getconfiguration_id (char * config_file); void moveFromList(); void moveToList(); void add(const CNfcParam* pParam); @@ -159,6 +228,7 @@ class CNfcConfig : public vector<const CNfcParam*> { bool isAllowed(const char* name); list<const CNfcParam*> m_list; bool mValidFile; + bool mDynamConfig; uint32_t config_crc32_; uint32_t config_crc32_rf_; uint32_t config_crc32_tr_; @@ -172,6 +242,282 @@ class CNfcConfig : public vector<const CNfcParam*> { inline void Reset(unsigned long f) { state &= ~f; } }; +/** + * @brief This function reads the hardware information from the given path. + * + * This function receives the path and then reads the hardware information + * from the file present in the given path. It reads the details like whether + * it is QRD or MTP. It reads the data from that file and stores in buffer. + * It also receives a count which tells the number of characters to be read + * Finally the length of the buffer is returned. + * + * @param path The path where the file containing hardware details to be read. + * @param buff The hardware details that is read from that path will be stored here. + * @param count It represents the number of characters to be read from that file. + * @return It returns the length of the buffer. + */ + +static int read_line_from_file(const char *path, char *buf, size_t count) +{ + char *fgets_ret = NULL; + FILE *fd = NULL; + int rv = 0; + + // opens the file to read the HW_PLATFORM detail of the target + fd = fopen(path, "r"); + if (fd == NULL) + return -1; + + // stores the data that is read from the given path into buf + fgets_ret = fgets(buf, (int)count, fd); + if (NULL != fgets_ret) + rv = (int)strlen(buf); + else + rv = ferror(fd); + + fclose(fd); + + return rv; +} + +/** + * @brief This function gets the source information from the file. + * + * This function receives a buffer variable to store the read information + * and also receives two different path. The hardware information may be + * present in any one of the received path. So this function checks in + * both the paths. This function internally uses read_line_from_file + * function to read the check and read the hardware details in each path. + * + * @param buf hardware details that is read will be stored. + * @param soc_node_path1 The first path where the file may be present. + * @param soc_node_path2 The second path where the file may be present. + * @return Returns the length of buffer. + */ + +static int get_soc_info(char *buf, const char *soc_node_path1, + const char *soc_node_path2) +{ + int ret = 0; + + // checks whether the hw platform detail is present in this path + ret = read_line_from_file(soc_node_path1, buf, MAX_SOC_INFO_NAME_LEN); + if (ret < 0) { + // if the hw platform detail is not present in the former path it checks here + ret = read_line_from_file(soc_node_path2, buf, MAX_SOC_INFO_NAME_LEN); + if (ret < 0) { + ALOGE("getting socinfo(%s, %d) failed.\n", soc_node_path1, ret); + return ret; + } + } + if (ret && buf[ret - 1] == '\n') + buf[ret - 1] = '\0'; + + return ret; +} + +/** + * @brief finds the cofiguration id value for the particular target. + * + * This function reads the target board platform detail and hardware + * platform detail from the target device and generate a generic + * config file name.If that config file is present then it will be + * used for configuring that target. If not then based on the target + * information a config file will be assigned. + * + * @param config_file The generic config file name will be stored. + * @return it returns the config id for the target. + */ + +int CNfcConfig::getconfiguration_id (char * config_file) +{ + int config_id = QRD_TYPE_DEFAULT; + char target_type[MAX_SOC_INFO_NAME_LEN] = {'\0'}; + char soc_info[MAX_SOC_INFO_NAME_LEN] = {'\0'}; + char nq_chipid[PROPERTY_VALUE_MAX] = {0}; + char nq_fw_ver[PROPERTY_VALUE_MAX] = {0}; + string strPath; + int rc = 0; + int idx = 0; + + rc = get_soc_info(soc_info, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2); + if (rc < 0) { + ALOGE("get_soc_info(SOC_ID) fail!\n"); + return DEFAULT_CONFIG; + } + idx = atoi(soc_info); + + rc = get_soc_info(target_type, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2); + if (rc < 0) { + ALOGE("get_soc_info(HW_PLATFORM) fail!\n"); + return DEFAULT_CONFIG; + } + + rc = __system_property_get("vendor.qti.nfc.chipid", nq_chipid); + if (rc <= 0) + ALOGE("get vendor.qti.nfc.chipid fail, rc = %d\n", rc); + else + ALOGD("vendor.qti.nfc.chipid = %s\n", nq_chipid); + + rc = __system_property_get("vendor.qti.nfc.fwver", nq_fw_ver); + if (rc <= 0) + ALOGE("get vendor.qti.nfc.fwver fail, rc = %d\n", rc); + else + ALOGD("vendor.qti.nfc.fwver = %s\n", nq_fw_ver); + + // Converting the HW_PLATFORM detail that is read from target to lowercase + for (int i=0;target_type[i];i++) + target_type[i] = tolower(target_type[i]); + + // generating a generic config file name based on the target details + snprintf(config_file, MAX_DATA_CONFIG_PATH_LEN, "libnfc-%s_%s.conf", + soc_info, target_type); + + findConfigFilePathFromTransportConfigPaths(config_file, strPath); + if (file_exist(strPath.c_str())) + idx = 0; + + if (DEBUG) + ALOGI("id:%d, config_file_name:%s\n", idx, config_file); + + // if target is QRD platform then config id is assigned here + if (0 == strncmp(target_type, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) { + switch (idx) + { + case TARGET_GENERIC: + config_id = CONFIG_GENERIC; + break; + case TARGET_MSM8952: + case TARGET_MSM8909: + config_id = QRD_TYPE_DEFAULT; + strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN); + break; + case TARGET_MSM8953: + case TARGET_MSM8937: + case TARGET_MSM8917: + case TARGET_MSM8940: + case TARGET_SDM632: + case TARGET_SDM439: + case TARGET_SDM429: + case TARGET_SDM450: + if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) { + // NQ210 or NQ220 + config_id = QRD_TYPE_DEFAULT; + strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN); + } else if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) { + config_id = QRD_TYPE_NQ4XX; + strlcpy(config_file, config_name_qrd_NQ4XX, MAX_DATA_CONFIG_PATH_LEN); + } else { + config_id = QRD_TYPE_NQ3XX; + strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + case TARGET_MSM8976: + case TARGET_MSM8996: + strlcpy(config_file, config_name_qrd1, MAX_DATA_CONFIG_PATH_LEN); + config_id = QRD_TYPE_1; + break; + case TARGET_SDM845: + case TARGET_SDM670: + case TARGET_SDM710: + case TARGET_SDM712: + case TARGET_QCS605: + if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) { + config_id = QRD_TYPE_NQ4XX; + strlcpy(config_file, config_name_qrd_NQ4XX, MAX_DATA_CONFIG_PATH_LEN); + } + else { + config_id = QRD_TYPE_NQ3XX; + strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + case TARGET_SDM660: + case TARGET_SDM630: + case TARGET_SDM455: + case TARGET_MSM8998: + case TARGET_MSM8997: + if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) { + // NQ210 or NQ220 + config_id = QRD_TYPE_2; + strlcpy(config_file, config_name_qrd2, MAX_DATA_CONFIG_PATH_LEN); + } else { + config_id = QRD_TYPE_NQ3XX; + strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + default: + config_id = QRD_TYPE_DEFAULT; + strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN); + break; + } + } + // if target is not QRD platform then default config id is assigned here + else { + switch (idx) + { + case TARGET_GENERIC: + config_id = CONFIG_GENERIC; + break; + case TARGET_MSM8953: + case TARGET_MSM8937: + case TARGET_MSM8917: + case TARGET_MSM8940: + case TARGET_SDM632: + case TARGET_SDM439: + case TARGET_SDM429: + case TARGET_SDM450: + if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) { + // NQ210 or NQ220 + config_id = MTP_TYPE_DEFAULT; + strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN); + } else if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) { + config_id = MTP_TYPE_NQ4XX; + strlcpy(config_file, config_name_mtp_NQ4XX, MAX_DATA_CONFIG_PATH_LEN); + } else { + config_id = MTP_TYPE_NQ3XX; + strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + case TARGET_SDM845: + case TARGET_SDM670: + case TARGET_SDM710: + case TARGET_SDM712: + case TARGET_QCS605: + if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) { + config_id = MTP_TYPE_NQ4XX; + strlcpy(config_file, config_name_mtp_NQ4XX, MAX_DATA_CONFIG_PATH_LEN); + } + else { + config_id = MTP_TYPE_NQ3XX; + strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + case TARGET_SDM660: + case TARGET_SDM630: + case TARGET_SDM455: + case TARGET_MSM8998: + case TARGET_MSM8997: + if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) { + // NQ210 or NQ220 + config_id = MTP_TYPE_1; + strlcpy(config_file, config_name_mtp1, MAX_DATA_CONFIG_PATH_LEN); + } else { + config_id = MTP_TYPE_NQ3XX; + strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN); + } + break; + default: + config_id = MTP_TYPE_DEFAULT; + strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN); + break; + } + } + if (DEBUG) + ALOGI("platform config id:%d, config_file_name:%s\n", config_id, config_file); + + return config_id; +} + /******************************************************************************* ** ** Function: isPrintable() @@ -450,9 +796,8 @@ bool CNfcConfig::readConfig(const char* name, bool bResetContent) { ** Returns: none ** *******************************************************************************/ -CNfcConfig::CNfcConfig() - : mValidFile(true), config_crc32_(0), config_crc32_rf_(0), - config_crc32_tr_(0), state(0) {} +CNfcConfig::CNfcConfig() : mValidFile(true), mDynamConfig(true), config_crc32_(0), + config_crc32_rf_(0), config_crc32_tr_(0), state(0) {} /******************************************************************************* ** @@ -465,6 +810,22 @@ CNfcConfig::CNfcConfig() *******************************************************************************/ CNfcConfig::~CNfcConfig() {} +/** + * @brief checks whether the given file exist. + * + * This function gets the file name and checks whether the given file + * exist in the particular path.Internaly it uses stat system call to + * find the existance. + * + * @param filename The name of the file whose existance has to be checked. + * @return it returns true if the given file name exist. + */ +int CNfcConfig::file_exist (const char* filename) +{ + struct stat buffer; + return (stat (filename, &buffer) == 0); +} + /******************************************************************************* ** ** Function: CNfcConfig::GetInstance() @@ -476,46 +837,49 @@ CNfcConfig::~CNfcConfig() {} *******************************************************************************/ CNfcConfig& CNfcConfig::GetInstance() { static CNfcConfig theInstance; - char valueStr[PROPERTY_VALUE_MAX] = {0}; - string config_file_name = "libnfc-nxp"; - if (theInstance.size() == 0 && theInstance.mValidFile) { - string strPath; - if (alternative_config_path[0] != '\0') { - strPath.assign(alternative_config_path); - strPath += config_name; - theInstance.readConfig(strPath.c_str(), true); - if (!theInstance.empty()) { - return theInstance; - } - } - // update config file based on system property - int len = property_get("persist.vendor.nfc.config_file_name", valueStr, ""); + int gconfigpathid=0; + char config_name_generic[MAX_DATA_CONFIG_PATH_LEN] = {'\0'}; + + if (theInstance.size() == 0 && theInstance.mValidFile) + { + string strPath; + if (alternative_config_path[0] != '\0') + { + strPath.assign(alternative_config_path); + strPath += config_name; + theInstance.readConfig(strPath.c_str(), true); + if (!theInstance.empty()) + { + return theInstance; + } + } + findConfigFilePathFromTransportConfigPaths(config_name, strPath); + //checks whether the default config file is present in th target + if (theInstance.file_exist(strPath.c_str())) { + ALOGI("default config file exists = %s, disables dynamic selection", strPath.c_str()); + theInstance.mDynamConfig = false; + theInstance.readConfig(strPath.c_str(), true); + /* + * if libnfc-nxp.conf exists then dynamic selection will + * be turned off by default we will not have this file. + */ + return theInstance; + } - if (len > 0) { - config_file_name = config_file_name + "_" + valueStr + ".conf"; - } else { - config_file_name = config_name; - } - ALOGD("nxp config referred : %s", config_file_name.c_str()); - - if (findConfigFilePathFromTransportConfigPaths( - android::base::GetProperty("persist.vendor.nfc.config_file_name", ""), - strPath)) { - NXPLOG_EXTNS_D("%s load %s\n", __func__, strPath.c_str()); - } else if (findConfigFilePathFromTransportConfigPaths( - extra_config_base + - android::base::GetProperty("ro.boot.product.hardware.sku", "") + - + extra_config_ext, strPath)) { - NXPLOG_EXTNS_D("%s load %s\n", __func__, strPath.c_str()); - } else { - findConfigFilePathFromTransportConfigPaths(config_name, strPath); - } + gconfigpathid = theInstance.getconfiguration_id(config_name_generic); + findConfigFilePathFromTransportConfigPaths(config_name_generic, strPath); + if (!(theInstance.file_exist(strPath.c_str()))) { + ALOGI("no matching file found, using default file for stability\n"); + findConfigFilePathFromTransportConfigPaths(config_name_default, strPath); + } + ALOGI("config file used = %s\n",strPath.c_str()); + theInstance.readConfig(strPath.c_str(), true); +#if(NXP_EXTNS == TRUE) - ALOGD("nxp config file : %s", strPath.c_str()); - theInstance.readConfig(strPath.c_str(), true); -#if (NXP_EXTNS == TRUE) - theInstance.readNxpTransitConfig(transit_config_path); - theInstance.readNxpRFConfig(nxp_rf_config_path); + + theInstance.readNxpTransitConfig("nxpTransit"); + theInstance.readNxpTransitConfig(transit_config_path); + theInstance.readNxpRFConfig(nxp_rf_config_path); #endif } return theInstance; |