/*--------------------------------------------------------------------------
Copyright (c) 2013, The Linux Foundation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of The Linux Foundation nor
      the names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written
      permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <grp.h>
#include <utime.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <unistd.h>
#define LOG_TAG "wcnss_service"
#include <cutils/log.h>
#include <cutils/properties.h>
#ifdef WCNSS_QMI
#include "wcnss_qmi_client.h"
#ifdef MDM_DETECT
#include "mdm_detect.h"
#endif
#endif
#ifdef WCNSS_QMI_OSS
#include <dlfcn.h>
#endif

#define SUCCESS 0
#define FAILED -1
#define BYTE_0  0
#define BYTE_1  8
#define BYTE_2  16
#define BYTE_3  24
#define UNUSED(x)	(void)(x)

#define MAX_FILE_LENGTH    (1024)
#define WCNSS_MAX_CMD_LEN  (128)

/* control messages to wcnss driver */
#define WCNSS_USR_CTRL_MSG_START    0x00000000
#define WCNSS_USR_SERIAL_NUM        (WCNSS_USR_CTRL_MSG_START + 1)
#define WCNSS_USR_HAS_CAL_DATA      (WCNSS_USR_CTRL_MSG_START + 2)
#define WCNSS_USR_WLAN_MAC_ADDR     (WCNSS_USR_CTRL_MSG_START + 3)


#define WCNSS_CAL_CHUNK (3*1024)
#define WCNSS_CAL_FILE  "/data/vendor/wifi/WCNSS_qcom_wlan_cal.bin"
#define WCNSS_FACT_FILE "/data/vendor/wifi/WCN_FACTORY"
#define WCNSS_DEVICE    "/dev/wcnss_wlan"
#define WCNSS_CTRL      "/dev/wcnss_ctrl"
#define WLAN_INI_FILE_DEST   "/data/vendor/wifi/WCNSS_qcom_cfg.ini"
#define WLAN_INI_FILE_SOURCE "/vendor/etc/wifi/WCNSS_qcom_cfg.ini"
#define WCNSS_HAS_CAL_DATA\
		"/sys/module/wcnsscore/parameters/has_calibrated_data"

#define ASCII_A		65
#define ASCII_a		97
#define ASCII_0		48
#define HEXA_A		10
#define HEX_BASE		16

#if defined (WCNSS_QMI) || defined(WCNSS_QMI_OSS)
#define WLAN_ADDR_SIZE   6
unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE];
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"

/* As we Want to write in 00:0a:f5:11:22:33 format in sysfs file
   so taking mac length as 12 char + 5 for ":" + NULL
 */
#define WLAN_MAC_ADDR_STRING 18
#endif

#define MAX_SOC_INFO_NAME_LEN (15)
#define MAX_DATA_NVBIN_PATH_LEN (64)
#define QRD_DYNAMIC_NV_PROP  "persist.sys.dynamic.nv"
#define QRD_HW_PLATFORM  "QRD"
#define QRD_PLATFORM_SUBTYPE_ID  0
#define PERSIST_NVFILE    "/persist/WCNSS_qcom_wlan_nv.bin"
#define DATA_NVFILE_DIR   "/data/misc/wifi/nvbin/"
#define SYSFS_SOCID_PATH1   "/sys/devices/soc0/soc_id"
#define SYSFS_SOCID_PATH2   "/sys/devices/system/soc/soc0/id"
#define SYSFS_HW_PLATFORM_PATH1  "/sys/devices/soc0/hw_platform"
#define SYSFS_HW_PLATFORM_PATH2   "/sys/devices/system/soc/soc0/hw_platform"
#define SYSFS_PLATFORM_SUBTYPE_PATH1   "/sys/devices/soc0/platform_subtype_id"
#define SYSFS_PLATFORM_SUBTYPE_PATH2    "/sys/devices/system/soc/soc0/platform_subtype_id"
#define SYSFS_PLATFORM_VERSION_PATH1  "/sys/devices/soc0/platform_version"
#define SYSFS_PLATFORM_VERSION_PATH2   "/sys/devices/system/soc/soc0/platform_version"
#define SOCINFO_HWVER_MAJOR(ver) (((ver) & 0x00ff0000) >> 16)
#define SOCINFO_HWVER_MINOR(ver) ((ver) & 0x000000ff)
#define GET_SOC_INFO(buf, soc_node_path1, soc_node_path2, info_got) \
		{  if (get_soc_info(buf, soc_node_path1, soc_node_path2) < 0) \
		    { \
		        ALOGE("get_soc_info failed!\n"); \
		        return FAILED; \
		    } \
		    info_got = atoi(buf); \
		}

int wcnss_write_cal_data(int fd_dev)
{
	int rcount = 0;
	int size = 0;
	int rc = 0;
	int wcount = 0;
	int fd_file;
	struct stat st;

	char buf[WCNSS_CAL_CHUNK];

	ALOGI("wcnss_write_cal_data trying to write cal");

	rc = stat(WCNSS_CAL_FILE, &st);
	if (rc < 0) {
		ALOGE("Failed to stat cal file : %s",
				strerror(errno));
		goto exit;
	}

	size = st.st_size;

	fd_file = open(WCNSS_CAL_FILE, O_RDONLY);
	if (fd_file < 0) {
		ALOGE("cal file doesn't exist: %s",
				strerror(errno));
		rc = fd_file;
		goto exit;
	}

	/* write the file size first, so that platform driver knows
	 * when it recieves the full data */
	wcount = write(fd_dev, (void *)&size, 4);
	if (wcount != 4) {
		ALOGE("Failed to write to wcnss device : %s",
				strerror(errno));
		rc = wcount;
		goto exit_close;
	}

	do {
		rcount = read(fd_file, (void *)buf, sizeof(buf));
		if (rcount < 0) {
			ALOGE("Failed to read from cal file ; %s",
					strerror(errno));
			rc = rcount;
			goto exit_remove;
		}

		if (!rcount)
			break;

		wcount = write(fd_dev, buf, rcount);
		if (wcount < 0) {
			ALOGE("Failed to write to wcnss device : %s",
				strerror(errno));
			rc = wcount;
			goto exit_close;
		}

	} while (rcount);
	close(fd_file);

	return SUCCESS;

exit_remove:
	close(fd_file);
	remove("WCNSS_CAL_FILE");
	return rc;

exit_close:
	close(fd_file);

exit:
	return rc;
}


int wcnss_read_and_store_cal_data(int fd_dev)
{
	int rcount = 0;
	int wcount = 0;
	int fd_file = -1;
	int rc = 0;

	char buf[WCNSS_CAL_CHUNK];

	ALOGI("wcnss_read_and_store_cal_data trying to read cal");

	do {
		/* wait on this read until data comes from fw */
		rcount = read(fd_dev, (void *)buf, sizeof(buf));
		if (rcount < 0) {
			ALOGE("Failed to read from wcnss device : %s",
					strerror(errno));
			rc = rcount;
			goto exit;
		}

		/* truncate the file only if there is fw data, this read
		 * may never return if the fw decides that no more cal is
		 * required; and the data we have now is good enough.
		 */
		if (fd_file < 0) {
			fd_file = open(WCNSS_CAL_FILE, O_WRONLY
					| O_CREAT | O_TRUNC, 0664);
			if (fd_file < 0) {
				ALOGE("Failed to open cal file : %s",
						strerror(errno));
				rc = fd_file;
				goto exit;
			}
		}

		if (!rcount)
			break;

		wcount = write(fd_file, buf, rcount);
		if (wcount < 0) {
			ALOGE("Failed to write to cal file : %s",
				strerror(errno));
			rc = wcount;
			goto exit_remove;
		}

	} while (rcount);

	close(fd_file);

	return SUCCESS;

exit_remove:
	close(fd_file);
	remove(WCNSS_CAL_FILE);

exit:
	return rc;
}


void find_full_path(char *cur_dir, char *file_to_find, char *full_path)
{
	DIR *dir;
	struct stat st;
	struct dirent *dr;
	char cwd[1024];
	int rc;

	chdir(cur_dir);

	dir = opendir(".");

	if (dir != NULL) {
		while ((dr = readdir(dir))) {

			rc = lstat(dr->d_name, &st);
			if (rc < 0) {
				ALOGE("lstat failed %s", strerror(errno));
				return;
			}
			if (S_ISDIR(st.st_mode)) {
				if ((strcmp(dr->d_name, ".")) &&
					(strcmp(dr->d_name, ".."))) {
				find_full_path(dr->d_name,
						file_to_find, full_path);
				}
			} else if (!strcmp(file_to_find, dr->d_name)) {
				getcwd(cwd, sizeof(cwd));
				snprintf(full_path, MAX_FILE_LENGTH, "%s/%s",
					cwd, file_to_find);
			}
		}
		closedir(dir);
	}

	chdir("..");
}

void setup_wlan_config_file()
{
	int rfd;
	int wfd;
	struct stat st_dest, st_src;
	int rc_dest;
	int rc;
	struct group *grp;
	struct utimbuf new_time;

	rc = stat(WLAN_INI_FILE_SOURCE, &st_src);
	if (rc != 0) {
		ALOGE("source file do not exist %s", WLAN_INI_FILE_SOURCE);
		return;
	}

	rc_dest = stat(WLAN_INI_FILE_DEST, &st_dest);
	if (rc_dest == 0 && st_dest.st_size &&
			(st_dest.st_mtime > st_src.st_mtime)) {
		ALOGE("wlan ini file exists %s and is newer than %s",
				WLAN_INI_FILE_DEST, WLAN_INI_FILE_SOURCE);
		goto out_nocopy;
	}

	rfd = open(WLAN_INI_FILE_SOURCE, O_RDONLY);
	if (rfd < 0) {
		ALOGE("Failed to open ini source file: %s", strerror(errno));
		return;
	}

	wfd = open(WLAN_INI_FILE_DEST, O_WRONLY | O_CREAT | O_TRUNC, 0660);
	if (wfd < 0) {
		ALOGE("Failed to open ini dest file: %s", strerror(errno));
		close(rfd);
		return;
	}

	rc = sendfile(wfd, rfd, 0, st_src.st_size);
	if (rc != st_src.st_size) {
		ALOGE("Failed to copy ini file: %s", strerror(errno));
		goto out;
	}

	new_time.actime = st_src.st_atime;
	new_time.modtime = st_src.st_mtime;

	rc = utime(WLAN_INI_FILE_DEST, &new_time);
	if (rc != 0)
		ALOGE("could not preserve the timestamp %s", strerror(errno));

	grp = getgrnam("wifi");
	if (grp != NULL) {
		rc = chown(WLAN_INI_FILE_DEST, -1, grp->gr_gid);
		if (rc != 0)
			ALOGE("Failed change group of ini file %s", strerror(errno));
	} else {
			ALOGE("Failed to get group wifi %s", strerror(errno));
	}

	property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST);

out:
	close(rfd);
	close(wfd);
	return;

out_nocopy:
	property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST);
	return;
}
unsigned int convert_string_to_hex(char* string)
{
	int idx;
	unsigned long int hex_num = 0;
	for(idx = 0; string[idx] != '\0'; idx++){
		if(isalpha(string[idx])) {
			if(string[idx] >='a' && string[idx] <='f') {
				hex_num = hex_num * HEX_BASE + ((int)string[idx]
					       - ASCII_a + HEXA_A);
			} else if ( string[idx] >='A' && string[idx] <='F') {
				hex_num = hex_num * HEX_BASE + ((int)string[idx]
						- ASCII_A + HEXA_A);
			} else
				hex_num = hex_num * HEX_BASE + (int)string[idx];
		} else {
			hex_num = hex_num * HEX_BASE + (string[idx]- ASCII_0);
		}
	}
	hex_num = hex_num & 0xFFFFFFFF;
	return hex_num;
}


#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
void setup_wcnss_parameters(int *cal, int nv_mac_addr)
#else
void setup_wcnss_parameters(int *cal)
#endif
{
	char msg[WCNSS_MAX_CMD_LEN];
	int fd, rc, pos = 0;
	struct stat st;

	fd = open(WCNSS_CTRL, O_WRONLY);
	if (fd < 0) {
		ALOGE("Failed to open %s : %s", WCNSS_CTRL, strerror(errno));
		return;
	}

#if defined(WCNSS_QMI) || defined (WCNSS_QMI_OSS)
	if (SUCCESS == nv_mac_addr)
	{
		pos = 0;
		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_1;
		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_0;
		msg[pos++] = wlan_nv_mac_addr[0];
		msg[pos++] = wlan_nv_mac_addr[1];
		msg[pos++] = wlan_nv_mac_addr[2];
		msg[pos++] = wlan_nv_mac_addr[3];
		msg[pos++] = wlan_nv_mac_addr[4];
		msg[pos++] = wlan_nv_mac_addr[5];

		ALOGI("WLAN MAC Addr:" MAC_ADDRESS_STR,
			MAC_ADDR_ARRAY(wlan_nv_mac_addr));

		if (write(fd, msg, pos) < 0) {
			ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
						strerror(errno));
			goto fail;
		}
	}
#endif

	pos = 0;
	msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_1;
	msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_0;

	rc = stat(WCNSS_FACT_FILE, &st);
	if (rc == 0) {
		ALOGE("Factory file found, deleting cal file");
		unlink(WCNSS_CAL_FILE);
		goto fail_resp;
	}

	rc = stat(WCNSS_CAL_FILE, &st);
	if (rc != 0) {
		ALOGE("CAL file not found");
		goto fail_resp;
	}

	/* has cal data */
	msg[pos++] = 1;

	if (write(fd, msg, pos) < 0) {
		ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
				strerror(errno));
		goto fail;
	}

	ALOGI("Correctly triggered cal file");
	*cal = SUCCESS;
	close(fd);
	return;

fail_resp:
	msg[pos++] = 0;
	if (write(fd, msg, pos) < 0)
		ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
				strerror(errno));

fail:
	*cal = FAILED;
	close(fd);
	return;
}

#ifdef MDM_DETECT
int check_modem_compatability(struct dev_info *mdm_detect_info)
{
	char args[MODEM_BASEBAND_PROPERTY_SIZE] = {0};
	int ret = 0;
	/* Get the hardware property */
	ret = property_get(MODEM_BASEBAND_PROPERTY, args, "");
	if (ret > MODEM_BASEBAND_PROPERTY_SIZE) {
		ALOGE("property [%s] has size [%d] that exceeds max [%d]",
				MODEM_BASEBAND_PROPERTY, ret, MODEM_BASEBAND_PROPERTY_SIZE);
		return 0;
	}
	/* This will check for the type of hardware, and if the
	   hardware type needs external modem, it will check if the
	   modem type is external*/
	if(!strncmp(MODEM_BASEBAND_VALUE_APQ, args, 3)) {

		for (ret = 0; ret < mdm_detect_info->num_modems; ret++) {
			if (mdm_detect_info->mdm_list[ret].type == MDM_TYPE_EXTERNAL) {
				ALOGE("Hardware supports external modem");
				return 1;
			}
		}
		ALOGE("Hardware does not support external modem");
		return 0;
	}
	return 1;
}
#endif

static int read_line_from_file(const char *path, char *buf, size_t count)
{
	char * fgets_ret;
	FILE * fd;
	int rv;

	fd = fopen(path, "r");
	if (fd == NULL)
	return -1;

	fgets_ret = fgets(buf, (int)count, fd);
	if (NULL != fgets_ret) {
	    rv = (int)strlen(buf);
	} else {
	    rv = ferror(fd);
	}

	fclose(fd);

	return rv;
}

static int get_soc_info(char *buf, char *soc_node_path1,
			char *soc_node_path2)
{
	int ret = 0;

	ret = read_line_from_file(soc_node_path1, buf,
					MAX_SOC_INFO_NAME_LEN);
	if (ret < 0) {
		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;
}

static int get_data_nvfile_path(char *data_nvfile_path,
	struct stat *pdata_nvfile_stat)
{
	char target_board_platform[PROP_VALUE_MAX] = {'\0'};
	char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'};
	int  soc_id, platform_subtype_id, platform_version;
	int  major_hwver, minor_hwver;
	int  rc;

	rc = property_get("ro.board.platform", target_board_platform, "");
	if (!rc)
	{
		ALOGE("get ro.board.platform fail, rc=%d(%s)\n",
				rc, strerror(errno));
		return FAILED;
	}

	GET_SOC_INFO(buf, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2, soc_id);
	GET_SOC_INFO(buf, SYSFS_PLATFORM_SUBTYPE_PATH1,
			SYSFS_PLATFORM_SUBTYPE_PATH2, platform_subtype_id);
	GET_SOC_INFO(buf, SYSFS_PLATFORM_VERSION_PATH1,
			SYSFS_PLATFORM_VERSION_PATH2, platform_version);

	major_hwver = SOCINFO_HWVER_MAJOR(platform_version);
	minor_hwver = SOCINFO_HWVER_MINOR(platform_version);

	snprintf(data_nvfile_path, MAX_DATA_NVBIN_PATH_LEN,
		"%s%s_%d_0x%02x_0x%02x_0x%02x_nv.bin", DATA_NVFILE_DIR,
		target_board_platform, soc_id, platform_subtype_id&0xff,
		major_hwver&0xff, minor_hwver&0xff);
	ALOGI("data_nvfile_path %s\n",
			data_nvfile_path);

	if (stat(data_nvfile_path, pdata_nvfile_stat) != 0)
	{
		ALOGE("source file do not exist %s\n",
				data_nvfile_path);
		return FAILED;
	}

	return SUCCESS;
}

static int nvbin_sendfile(const char *dst, const char *src,
	struct stat *src_stat)
{
	struct utimbuf new_time;
	int fp_src, fp_dst;
	int rc;
	if ((fp_src = open(src, O_RDONLY)) < 0)
	{
		ALOGE("open %s failed(%s).\n",
				src, strerror(errno));
		return FAILED;
	}

	if ((fp_dst = open(dst, O_WRONLY |O_TRUNC)) < 0)
	{
		close(fp_src);
		ALOGE("open %s failed(%s).\n",
				dst, strerror(errno));
		return FAILED;
	}

	if (sendfile(fp_dst, fp_src, 0, src_stat->st_size) == -1)
	{
		ALOGE("dynamic nv sendfile failed: (%s).\n",
				strerror(errno));
		rc = FAILED;
		goto exit;
	}

	new_time.actime  = src_stat->st_atime;
	new_time.modtime = src_stat->st_mtime;
	if (utime(dst, &new_time) != 0)
	{
		ALOGE("could not preserve the timestamp %s",
				strerror(errno));
		rc = FAILED;
		goto exit;
	}

	rc = SUCCESS;
exit:
	close(fp_dst);
	close(fp_src);
	return rc;
}
void dynamic_nv_replace()
{
	char data_nvfile_path[MAX_DATA_NVBIN_PATH_LEN] = {'\0'};
	char property_nv_replaced_status [PROPERTY_VALUE_MAX] = { '\0' };
	char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'};
	struct stat  data_nvfile_stat;
	int rc;

	if (property_get(QRD_DYNAMIC_NV_PROP, property_nv_replaced_status, NULL)
		&& strcmp(property_nv_replaced_status, "done") == 0) {
		ALOGI("dynamic nv have been replaced. leave\n");
		return;
	}

	rc = get_soc_info(buf, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2);
	if (rc < 0)
	{
		ALOGE("get_soc_info(HW_PLATFORM) fail!\n");
		return;
	} else {
		if( 0 != strncmp(buf, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN))
		{
			ALOGI("dynamic nv only for QRD platform, current platform:%s.\n",
					buf);
			return;
		}
	}

	rc = get_data_nvfile_path(data_nvfile_path, &data_nvfile_stat);
	if (rc != SUCCESS)
	{
		ALOGE("Get source file path fail !\n");
		return;
	}

	if (property_set(QRD_DYNAMIC_NV_PROP, "replacing") < 0)
	{
		ALOGE("set %s to replacing failed (%s).\n",
				QRD_DYNAMIC_NV_PROP, strerror(errno));
		return;
	}

	rc = nvbin_sendfile(PERSIST_NVFILE, data_nvfile_path, &data_nvfile_stat);
	if ( rc != SUCCESS)
	{
		ALOGE("nvbin_sendfile failed.\n");
		return;
	}

	if (property_set(QRD_DYNAMIC_NV_PROP, "done") < 0)
	{
		ALOGE("set %s to done failed(%s).\n",
				QRD_DYNAMIC_NV_PROP, strerror(errno));
		return;
	}

	ALOGI("dynamic nv replace sucessfully!\n");

}

#ifdef WCNSS_QMI_OSS
static void *wcnss_qmi_handle = NULL;
static int (*wcnss_init_qmi)(void) = NULL;
static int (*wcnss_qmi_get_wlan_address)(unsigned char *) = NULL;
static void (*wcnss_qmi_deinit)(void) = NULL;

static int setup_wcnss_qmi(void)
{
	const char *error = NULL;

	/* initialize the DMS client and request the wlan mac address */
	wcnss_qmi_handle = dlopen("libwcnss_qmi.so", RTLD_NOW);
	if (!wcnss_qmi_handle) {
		ALOGE("Failed to open libwcnss_qmi.so: %s", dlerror());
		goto dlopen_err;
	}

	dlerror();

	wcnss_init_qmi = dlsym(wcnss_qmi_handle, "wcnss_init_qmi");
	if ((error = dlerror()) != NULL) {
		ALOGE("Failed to resolve function: %s: %s",
				"wcnss_init_qmi", error);
		goto dlsym_err;
	}

	dlerror();

	wcnss_qmi_get_wlan_address = dlsym(wcnss_qmi_handle,
			"wcnss_qmi_get_wlan_address");
	if ((error = dlerror()) != NULL) {
		ALOGE("Failed to resolve function: %s: %s",
				"wcnss_qmi_get_wlan_address", error);
		goto dlsym_err;
	}

	dlerror();

	wcnss_qmi_deinit = dlsym(wcnss_qmi_handle, "wcnss_qmi_deinit");
	if ((error = dlerror()) != NULL) {
		ALOGE("Failed to resolve function: %s: %s",
				"wcnss_qmi_deinit", error);
		goto dlsym_err;
	}

	return SUCCESS;

dlsym_err:
	dlclose(wcnss_qmi_handle);
dlopen_err:
	return FAILED;
}
#endif

int main(int argc, char *argv[])
{
	UNUSED(argc), UNUSED(argv);
	int rc;
	int fd_dev, ret_cal;
#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
	int nv_mac_addr = FAILED;
#ifdef MDM_DETECT
	struct dev_info mdm_detect_info;
	int nom = 0;
#endif
#endif

	setup_wlan_config_file();

#ifdef WCNSS_QMI_OSS
	/* dlopen WCNSS QMI lib */

	rc = setup_wcnss_qmi();
	if (rc == SUCCESS) {
		if (SUCCESS == (*wcnss_init_qmi)()) {
			rc = (*wcnss_qmi_get_wlan_address)(wlan_nv_mac_addr);
			if (rc == SUCCESS) {
				nv_mac_addr = SUCCESS;
				ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR,
						MAC_ADDR_ARRAY(wlan_nv_mac_addr));
			} else
				ALOGE("Failed to Get MAC addr from modem");

			(*wcnss_qmi_deinit)();
		}
		else
			ALOGE("Failed to Initialize wcnss QMI Interface");
	} else {
		ALOGE("Failed to Initialize wcnss QMI interface library");
	}
#endif
#ifdef WCNSS_QMI
#ifdef MDM_DETECT
	/* Call ESOC API to get the number of modems.
	   If the number of modems is not zero, only then proceed
	   with the eap_proxy intialization.*/

	nom = get_system_info(&mdm_detect_info);

	if (nom > 0)
		ALOGE("Failed to get system info, ret %d", nom);

	if (mdm_detect_info.num_modems == 0) {
		ALOGE("wcnss_service: No Modem support for this target"
				" number of modems is %d", mdm_detect_info.num_modems);
		goto nomodem;
	}

	ALOGE("wcnss_service: num_modems = %d", mdm_detect_info.num_modems);

	if(!check_modem_compatability(&mdm_detect_info)) {
		ALOGE("wcnss_service: Target does not have external modem");
		goto nomodem;
	}
#endif

	/* initialize the DMS client and request the wlan mac address */

	if (SUCCESS == wcnss_init_qmi()) {

		rc = wcnss_qmi_get_wlan_address(wlan_nv_mac_addr);

		if (rc == SUCCESS) {
			nv_mac_addr = SUCCESS;
			ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(wlan_nv_mac_addr));
		} else
			ALOGE("Failed to Get MAC addr from modem");

		wcnss_qmi_deinit();
	}
	else
		ALOGE("Failed to Initialize wcnss QMI Interface");

nomodem:
#endif

	dynamic_nv_replace();

#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
	setup_wcnss_parameters(&ret_cal, nv_mac_addr);
#else
	setup_wcnss_parameters(&ret_cal);
#endif

	fd_dev = open(WCNSS_DEVICE, O_RDWR);
	if (fd_dev < 0) {
		ALOGE("Failed to open wcnss device : %s",
				strerror(errno));
		return fd_dev;
	}

	if (ret_cal != FAILED) {
		rc = wcnss_write_cal_data(fd_dev);
		if (rc != SUCCESS)
			ALOGE("No cal data is written to WCNSS %d", rc);
		else
			ALOGE("Cal data is successfully written to WCNSS");
	}

	rc = wcnss_read_and_store_cal_data(fd_dev);
	if (rc != SUCCESS)
		ALOGE("Failed to read and save cal data %d", rc);
	else
		ALOGI("Calibration data was successfull written to %s",
			WCNSS_CAL_FILE);

	close(fd_dev);

#ifdef WCNSS_QMI_OSS
	dlclose(wcnss_qmi_handle);
#endif

	return rc;
}
