[Feature] add GA346 baseline version

Change-Id: Ic62933698569507dcf98240cdf5d9931ae34348f
diff --git a/src/telephonyware/3.0/ccci_mdinit/files/ccci_mdinit.init b/src/telephonyware/3.0/ccci_mdinit/files/ccci_mdinit.init
new file mode 100644
index 0000000..a580dd9
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/files/ccci_mdinit.init
@@ -0,0 +1,17 @@
+#!/bin/sh /etc/rc.common
+
+START=00
+STOP=47
+
+USE_PROCD=1
+NAME=ccci_mdinit
+PROG=/usr/bin/ccci_mdinit
+
+start_service() {
+	echo "start ccci_mdinit"
+	procd_open_instance ccci_mdinit
+	procd_set_param command /usr/bin/ccci_mdinit 0
+	procd_set_param stdout 1
+	procd_set_param stderr 1
+	procd_close_instance
+}
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/LICENSE b/src/telephonyware/3.0/ccci_mdinit/src/LICENSE
new file mode 100644
index 0000000..10f9164
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/LICENSE
@@ -0,0 +1,31 @@
+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.
+
+Copyright  (C) 2021 MediaTek Inc. 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.
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/Makefile b/src/telephonyware/3.0/ccci_mdinit/src/Makefile
new file mode 100644
index 0000000..c848a57
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/Makefile
@@ -0,0 +1,10 @@
+INCLUDES=-I$(STAGING_DIR)/user/include
+LIBS=$(TARGET_LDFLAGS) -lpthread -lccci
+
+all: ccci_mdinit
+
+ccci_mdinit:
+	$(CC) $(CFLAGS) -o $@ env_setting.c magic_pattern.c time_clib_srv.c md_init_fsm.c $(LDFLAGS) $(LIBS)
+
+clean:
+	rm -f ccci_mdinit
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/ccci_mdinit_cfg.h b/src/telephonyware/3.0/ccci_mdinit/src/ccci_mdinit_cfg.h
new file mode 100644
index 0000000..fe6cff0
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/ccci_mdinit_cfg.h
@@ -0,0 +1,142 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2008
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER 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 BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'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 BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   ccci_mdinit.h
+ *
+ * Project:
+ * --------
+ *  
+ *
+ * Description:
+ * ------------
+ *   
+ *
+ * Author:
+ * -------
+ *   
+ *
+ ****************************************************************************/
+
+#ifndef __CCCI_MD_INIT_CFG_H__
+#define __CCCI_MD_INIT_CFG_H__
+
+#define CCCI_TIMEZONE_FILE	"/data/ccci_cfg/timezone"
+#define CCCI_TIME_UPDATE_PORT	"/dev/ccci_ipc_5"
+//----------------debug log define-----------------//
+#define MD_COMM_TAG				"[ccci_mdinit]"
+#include <syslog.h>
+#define DEBUGLEVEL LOG_LEVEL_ERR
+#define DEBUG 1
+
+#ifdef DEBUG
+/*
+ * The maximum log level for messages to be logged to the syslog.
+ * Only messages with a level lower than this will be printed to the console.
+ */
+enum {
+    LOG_LEVEL_ERR,
+    LOG_LEVEL_WARNING,
+    LOG_LEVEL_INFO,
+    LOG_LEVEL_DEBUG,
+};
+#define PRINTF(fmt, ...) syslog(LOG_DEBUG, fmt, ## __VA_ARGS__)
+
+#define LOGD(fmt, ...) \
+do { \
+    if (LOG_LEVEL_DEBUG <= DEBUGLEVEL) \
+        PRINTF(fmt, ##__VA_ARGS__); \
+} while(0)
+
+#define LOGI(fmt, ...) \
+do { \
+    if (LOG_LEVEL_INFO <= DEBUGLEVEL) \
+        PRINTF(fmt, ##__VA_ARGS__); \
+} while(0)
+
+#define LOGW(fmt, ...) \
+do { \
+    if (LOG_LEVEL_WARNING <= DEBUGLEVEL) \
+        PRINTF(fmt, ##__VA_ARGS__); \
+} while(0)
+
+#define LOGE(fmt, ...) \
+do { \
+    if (LOG_LEVEL_ERR <= DEBUGLEVEL) \
+        PRINTF(fmt, ##__VA_ARGS__); \
+} while(0)
+
+#define LOGE_COM(fmt, ...) \
+do { \
+    if (LOG_LEVEL_ERR <= DEBUGLEVEL) \
+        PRINTF(fmt, ##__VA_ARGS__); \
+} while(0)
+
+#else
+
+#ifdef NEED_CTRL_AS_SP
+/* deleted for code size */
+#else
+#define LOGV(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+
+#define LOGD(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+
+#define LOGI(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+
+#define LOGW(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+
+#define LOGE(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+
+#define LOGE_COM(...)	do{ printf(MD_COMM_TAG, __VA_ARGS__); }while(0)
+#endif
+#endif
+
+#ifdef NEED_CTRL_AS_SP
+/* deleted for code size */
+#else
+#define SMSG_DEBUG(fmt, ...) \
+	do{ printf(MD_COMM_TAG fmt, ##__VA_ARGS__); }while(0)
+
+#define SMSG_ERROR(fmt, ...) \
+	do{ printf(MD_COMM_TAG fmt, ##__VA_ARGS__); }while(0)
+
+#define SMSG_INFO(fmt, ...) \
+	do{ printf(MD_COMM_TAG fmt, ##__VA_ARGS__); }while(0)
+#endif
+
+#endif
+
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/env_setting.c b/src/telephonyware/3.0/ccci_mdinit/src/env_setting.c
new file mode 100644
index 0000000..c966e03
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/env_setting.c
@@ -0,0 +1,355 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2008
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER 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 BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'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 BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifdef NEED_CTRL_AS_SP
+#include <cutils/properties.h>
+#include <android/log.h>
+#else
+#include "ccci_mdinit_cfg.h"
+#endif
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include "platform/ccci_intf.h"
+
+/*------------------------------------------*/
+#ifndef NEED_CTRL_AS_SP
+#define PROPERTY_KEY_MAX 64
+#define PROPERTY_VALUE_MAX 64
+#endif
+/* Env variable need to store support       */
+static int ccci_md_env_cfg_folder_init(void)
+{
+	int fd;
+	int has_read;
+	struct stat buf;
+	umask(0007);
+	if (stat("/data/ccci_cfg",&buf)<0) {
+		LOGD("No /data/ccci_cfg dir.\n");
+		if (mkdir("/data/ccci_cfg",0700) < 0) {
+			LOGD("mkdir for ccci_cfg failed.\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int md_env_val_get(char name[], char buf[], int size)
+{
+	int fd;
+	int actual_read;
+	char tmp_buf[64];
+	struct stat stat_buf;
+
+	LOGD("md env r\n");
+	if (ccci_md_env_cfg_folder_init() < 0)
+		return -1;
+
+	snprintf(tmp_buf, sizeof(tmp_buf), "/data/ccci_cfg/%s",name);
+	if (stat(tmp_buf, &stat_buf) < 0)
+		return -1;
+	fd = open(tmp_buf, O_RDONLY, 0600);
+	if(fd < 0) {
+		LOGD("open setting file fail:%d @read for %s\n", errno, tmp_buf);
+		return -1;
+	}
+	actual_read = (int)read(fd, buf, size);
+
+	buf[size - 1] = '\0'; /* Make sure has terminate */
+
+	close(fd);
+	return actual_read;
+}
+
+static int md_env_val_set(char name[], char val[])
+{
+	int fd;
+	int actual_write;
+	char tmp_buf[64];
+	int size;
+
+	LOGD("md env w\n");
+	if (ccci_md_env_cfg_folder_init() < 0)
+		return -1;
+
+	snprintf(tmp_buf, sizeof(tmp_buf), "/data/ccci_cfg/%s",name);
+	fd = open(tmp_buf, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+	if(fd < 0) {
+		LOGD("open setting file fail:%d @write for %s\n", errno, tmp_buf);
+		return -1;
+	}
+	size = strlen(val)+1;
+	actual_write = (int)write(fd, val, size);
+	if (actual_write != size) {
+		LOGD("write %s fail,errno:%d\n", tmp_buf, errno);
+		close(fd);
+		return -2;
+	}
+
+	close(fd);
+	return 0;
+}
+
+
+/*------------------------------------------*/
+/* RAT configure setting */
+/* Bit map defination at AP side            */
+/* 0 | 0 | C | Lf | Lt | W | T | G          */
+#define MD_CAP_ENHANCE		(0x5A<<24)
+#define MD_CAP_GSM		(1<<0)
+#define MD_CAP_TDS_CDMA		(1<<1)
+#define MD_CAP_WCDMA		(1<<2)
+#define MD_CAP_TDD_LTE		(1<<3)
+#define MD_CAP_FDD_LTE		(1<<4)
+#define MD_CAP_CDMA2000		(1<<5)
+#define MD_CAP_MASK		(MD_CAP_GSM|MD_CAP_TDS_CDMA|MD_CAP_WCDMA|MD_CAP_TDD_LTE|MD_CAP_FDD_LTE|MD_CAP_CDMA2000)
+#define MD_CAP_BIT_NUM		(6)
+
+static unsigned int get_capability_bit(char cap_str[])
+{
+	if (cap_str == NULL)
+		return 0;
+	if ((strcmp(cap_str, "LF") == 0) || (strcmp(cap_str, "Lf") == 0) || (strcmp(cap_str, "lf") == 0))
+		return MD_CAP_FDD_LTE;
+	if ((strcmp(cap_str, "LT") == 0) || (strcmp(cap_str, "Lt") == 0) || (strcmp(cap_str, "lt") == 0))
+		return MD_CAP_TDD_LTE;
+	if ((strcmp(cap_str, "W") == 0) || (strcmp(cap_str, "w") == 0))
+		return MD_CAP_WCDMA;
+	if ((strcmp(cap_str, "C") == 0) || (strcmp(cap_str, "c") == 0))
+		return MD_CAP_CDMA2000;
+	if ((strcmp(cap_str, "T") == 0) || (strcmp(cap_str, "t") == 0))
+		return MD_CAP_TDS_CDMA;
+	if ((strcmp(cap_str, "G") == 0) || (strcmp(cap_str, "g") == 0))
+		return MD_CAP_GSM;
+
+	return 0;
+}
+
+#define MAX_CAP_STR_LENGTH	16
+static unsigned int ccci_rat_str_to_bitmap(char str[])
+{
+	char tmp_str[MAX_CAP_STR_LENGTH];
+	int tmp_str_curr_pos = 0;
+	unsigned int capability_bit_map = 0;
+	int str_len;
+	int i;
+
+	if (str == NULL)
+		return 0;
+
+	str_len = strlen(str);
+	for (i = 0; i < str_len; i++) {
+		if (str[i] == ' ')
+			continue;
+		if (str[i] == '\t')
+			continue;
+		if ((str[i] == '/') || (str[i] == '_')) {
+			if (tmp_str_curr_pos) {
+				tmp_str[tmp_str_curr_pos] = 0;
+				capability_bit_map |= get_capability_bit(tmp_str);
+			}
+			tmp_str_curr_pos = 0;
+			continue;
+		}
+		if (tmp_str_curr_pos < (MAX_CAP_STR_LENGTH-1)) {
+			tmp_str[tmp_str_curr_pos] = str[i];
+			tmp_str_curr_pos++;
+		} else
+			break;
+	}
+	if (tmp_str_curr_pos) {
+		tmp_str[tmp_str_curr_pos] = 0;
+		capability_bit_map |= get_capability_bit(tmp_str);
+	}
+
+	return capability_bit_map;
+}
+
+static unsigned int legacy_rat_map[] = {
+	(MD_CAP_FDD_LTE|MD_CAP_TDD_LTE|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ultg */
+	(MD_CAP_FDD_LTE|MD_CAP_TDD_LTE|MD_CAP_WCDMA|MD_CAP_GSM), /* ulwg */
+	(MD_CAP_FDD_LTE|MD_CAP_TDD_LTE|MD_CAP_WCDMA|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ulwtg */
+	(MD_CAP_FDD_LTE|MD_CAP_TDD_LTE|MD_CAP_WCDMA|MD_CAP_CDMA2000|MD_CAP_GSM), /* ulwcg */
+	(MD_CAP_FDD_LTE|MD_CAP_TDD_LTE|MD_CAP_WCDMA|MD_CAP_CDMA2000|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ulwctg */
+	(MD_CAP_TDD_LTE|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ulttg */
+	(MD_CAP_FDD_LTE|MD_CAP_WCDMA|MD_CAP_GSM), /* ulfwg */
+	(MD_CAP_FDD_LTE|MD_CAP_WCDMA|MD_CAP_CDMA2000|MD_CAP_GSM), /* ulfwcg */
+	(MD_CAP_FDD_LTE|MD_CAP_CDMA2000|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ulctg */
+	(MD_CAP_TDD_LTE|MD_CAP_CDMA2000|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ultctg */
+	(MD_CAP_TDD_LTE|MD_CAP_WCDMA||MD_CAP_GSM), /*ultwg */
+	(MD_CAP_TDD_LTE|MD_CAP_WCDMA|MD_CAP_CDMA2000|MD_CAP_GSM), /* ultwcg */
+	(MD_CAP_FDD_LTE|MD_CAP_TDS_CDMA|MD_CAP_GSM), /* ulftg */
+	(MD_CAP_FDD_LTE|MD_CAP_CDMA2000|MD_CAP_TDS_CDMA|MD_CAP_GSM)/* ulfctg */
+};
+
+/* Rat value description           */
+/* 0: invalid                      */
+/* 1: 2g                           */
+/* 2: 3g                           */
+/* 3: wg                           */
+/* 4: tg                           */
+/* 5: lwg                          */
+/* 6: ltg                          */
+/* 7: sglte (phase out)            */
+/* 8~21: legacy ubin wm_id         */
+/* 0x5A000000+xx : true rat bitmap */
+
+static unsigned int legacy_md_support_id_to_rat(int md_support_id)
+{
+	if (md_support_id < 0) /* Invalid case */
+		return 0;
+	if (md_support_id < 8) /* Legacy modem support value */
+		return md_support_id;
+	if (md_support_id <= 21) /* Legacy ubin modem support value */
+		return legacy_rat_map[md_support_id - 8];
+	if ((md_support_id & MD_CAP_ENHANCE) == MD_CAP_ENHANCE)
+		return md_support_id;
+
+	return 0;
+}
+
+unsigned int parse_sys_env_rat_setting(void)
+{
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int retpropget = 0;
+	unsigned int prj_rat = 0;
+	unsigned int lk_rat = 0;
+	unsigned int saved_id_or_rat = 0;
+#ifdef NEED_CTRL_AS_SP
+	retpropget = property_get("ro.mtk_protocol1_rat_config", value, NULL);
+	if (retpropget > 0)
+		prj_rat = ccci_rat_str_to_bitmap(value);
+
+	retpropget = property_get("ro.boot.opt_ps1_rat", value, NULL);
+	if (retpropget > 0)
+		lk_rat = ccci_rat_str_to_bitmap(value);
+#else
+	lk_rat = 0x3F;
+#endif
+	retpropget = md_env_val_get("md_type", value, sizeof(value));
+	if (retpropget > 0)
+		saved_id_or_rat = atoi(value);
+
+	LOGD("get_rat_cfg: 0x%x(@prj), 0x%x(@lk), 0x%x(@store)", prj_rat, lk_rat, saved_id_or_rat);
+
+	/* Priority: persist > ro.boot > ro. */
+	if (saved_id_or_rat > 0)
+		return saved_id_or_rat;
+	if (lk_rat)
+		return lk_rat|MD_CAP_ENHANCE;
+#ifdef NEED_CTRL_AS_SP
+	return prj_rat|MD_CAP_ENHANCE;
+#endif
+}
+
+int get_stored_modem_type_val(int md_id)
+{
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int retpropget = 0;
+	int ret = 0;
+
+	if (md_id != 0)
+		return 0; /* Only support modem 1 */
+
+	retpropget = md_env_val_get("md_type", value, sizeof(value));
+	if (retpropget > 0)
+		ret = legacy_md_support_id_to_rat(atoi(value));
+	else
+		ret = -1;
+
+	LOGD("get_save_modem_type_val: 0x%x", ret);
+
+	return ret;
+}
+
+int store_modem_type_val(int md_id, int new_val)
+{
+	char value[PROPERTY_VALUE_MAX];
+
+	if (md_id != 0)
+		return 0; /* Only support modem 1 */
+	if (new_val == 0)
+		return 0;
+
+	snprintf(value, sizeof(value), "%d", new_val);
+	return md_env_val_set("md_type", value);
+}
+
+int check_lk_load_md_status(int md_id, char buf[], int size)
+{
+	int fd;
+	int inf_buf_size;
+
+	// Because there is no md3 only case, check MD1 enough
+	if (md_id != MD_SYS1)
+		return 0;
+
+	fd = open("/sys/kernel/ccci/lk_md", O_RDONLY);
+	if (fd < 0) {
+		LOGD("Kernel load");
+		return 0;
+	}
+
+	inf_buf_size = read(fd, buf, size);
+	if (inf_buf_size <= 0) {
+		LOGD("LK info read fail:%d", errno);
+		close(fd);
+		return 0;
+	}
+
+	buf[size-1] = '\0'; /* Make sure string has terminate */
+	LOGD("%s(%d)", buf, inf_buf_size);
+	close(fd);
+
+	if (strstr(buf, "LK Load MD:[Disabled]")) {
+		LOGD("LK load modem feature disable\n");
+		return 0;
+	}
+
+	if (strstr(buf, "LK load MD success!"))
+		return 0;
+
+	return -1;
+}
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/magic_pattern.c b/src/telephonyware/3.0/ccci_mdinit/src/magic_pattern.c
new file mode 100644
index 0000000..0cda74e
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/magic_pattern.c
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#ifdef NEED_CTRL_AS_SP
+#include <android/log.h>
+#else
+#include "ccci_mdinit_cfg.h"
+#endif
+
+#define DEV_IOC_MAGIC       		'd'
+#define READ_DEV_DATA       		_IOR(DEV_IOC_MAGIC,  1, unsigned int)
+#define OPEN_DEVINFO_NODE_FAIL		0x1001
+#define READ_DEVINFO_DATA_FAIL		0x1002	
+#define ID_INDEX					12		//HRID
+
+static int byte_reverse(unsigned char *id_ptr){
+	int i = 0;
+	int tmp = 0;
+	
+	for (i=0 ; i<=2;i+=2){
+		tmp = *(id_ptr+i);
+		*(id_ptr+i) = *(id_ptr+i+1);
+		*(id_ptr+i+1) = tmp;
+	}
+	return 0;
+}
+
+static int cross_id_switch(unsigned char *id_1_ptr, unsigned char *id_2_ptr){
+	unsigned char tmp = 0;
+	
+	tmp = *(id_1_ptr+1);
+	*(id_1_ptr+1) = *(id_2_ptr);
+	*(id_2_ptr) = tmp;
+	
+	tmp = *(id_1_ptr+2);
+	*(id_1_ptr+2) = *(id_2_ptr+3);
+	*(id_2_ptr+3) = tmp;
+	
+	return 0;
+}
+
+static int dump_id_data(unsigned int id_1, unsigned int id_2){
+
+	/* ----------------------------------- 	*/
+    /* Dump for debug                		*/
+    /* ----------------------------------- 	*/  
+	SMSG_DEBUG("id_1:0x%x\n", id_1);
+	SMSG_DEBUG("id_2:0x%x\n", id_2);
+
+	return 0;
+}
+
+int compute_random_pattern(unsigned int * p_val){
+
+	int fd = 0;    	
+	int ret = 0;
+	int i = 0;
+	unsigned char tmp;
+	unsigned int id_1 = ID_INDEX;
+	unsigned int id_2 = ID_INDEX + 1;
+	unsigned char* id_1_ptr = (unsigned char *)&id_1;
+	unsigned char* id_2_ptr = (unsigned char *)&id_2;
+	
+    /* =================================== */
+    /* open devinfo driver                 */
+    /* =================================== */    
+    fd = open("/dev/devmap", O_RDONLY, 0);
+    if (fd < 0)
+    {
+        ret = OPEN_DEVINFO_NODE_FAIL;
+        goto _fail;
+    }
+	
+    /* ----------------------------------- 	*/
+    /* Read ID data                   		*/
+    /* ----------------------------------- 	*/   
+	if ((ret = ioctl(fd, READ_DEV_DATA, &id_1)) != 0)
+	{	
+		SMSG_ERROR("get id_1 fail:%d\n", ret);
+		ret = READ_DEVINFO_DATA_FAIL;
+		goto _fail;
+	}
+	
+	if ((ret = ioctl(fd, READ_DEV_DATA, &id_2)) != 0)
+	{	
+		SMSG_ERROR("get id_2 fail:%d\n", ret);
+		ret = READ_DEVINFO_DATA_FAIL;
+		goto _fail;
+	}
+
+	dump_id_data(id_1, id_2);
+
+	/* ----------------------------------- 	*/
+    /* Byte reverse	                		*/
+    /* ----------------------------------- 	*/
+	byte_reverse(id_1_ptr);
+	byte_reverse(id_2_ptr);
+	dump_id_data(id_1, id_2);	
+	
+	/* ----------------------------------- 	*/
+    /* Cross ID Switch               		*/
+    /* ----------------------------------- 	*/
+	cross_id_switch(id_1_ptr, id_2_ptr);
+	dump_id_data(id_1, id_2);
+	
+	/* ----------------------------------- 	*/
+    /* xor ids		               			*/
+    /* ----------------------------------- 	*/
+	*p_val = id_1 = id_1 ^ id_2;
+	SMSG_DEBUG("random pattern:0x%x", id_1);
+	
+_end:
+	close(fd);
+	return 0;  
+  
+_fail:
+	SMSG_ERROR("failure occured!! ret:%d\n", ret);
+	if (fd >= 0)
+		close(fd);
+
+	return -1;
+}
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/md_init_fsm.c b/src/telephonyware/3.0/ccci_mdinit/src/md_init_fsm.c
new file mode 100644
index 0000000..b517d44
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/md_init_fsm.c
@@ -0,0 +1,1755 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2008
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER 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 BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'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 BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifdef NEED_CTRL_AS_SP
+#include <cutils/properties.h>
+#include <android/log.h>
+#endif
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include <time.h>
+#ifdef NEED_CTRL_AS_SP
+#include "libnvram.h"
+#endif
+#include "ccci_intf.h"
+#include "ccci_mdinit_cfg.h"
+#ifdef NEED_CTRL_AS_SP
+#ifndef CONFIG_MTK_BACH
+#include "../../../external/aee/binary/inc/aee.h"
+#else
+#include "platform/aee.h"
+#endif
+#endif
+// for FSD wake_lock not released
+#include <signal.h>
+
+#ifdef NEED_CTRL_AS_SP
+int dl_aee_system_exception(const char *module, const char *path, unsigned int flag, const char* msg, ...);
+#endif
+// NVRAM issue make timeout value as 22s,
+#define MAX_NVRAM_RESTRORE_READY_RETRY_NUM	(44)
+#define MAX_OPEN_PORT_RETRY_NUM			(600)
+
+//--------------structure define-----------------//
+typedef struct
+{
+    unsigned int data[2];
+    unsigned int channel;
+    unsigned int reserved;
+} CCCI_BUFF_T;
+
+/* MD Message, this is for user space deamon use */
+enum {
+	CCCI_MD_MSG_FORCE_STOP_REQUEST = 0xFAF50001,
+	CCCI_MD_MSG_FLIGHT_STOP_REQUEST,
+	CCCI_MD_MSG_FORCE_START_REQUEST,
+	CCCI_MD_MSG_FLIGHT_START_REQUEST,
+	CCCI_MD_MSG_RESET_REQUEST,
+
+	CCCI_MD_MSG_EXCEPTION,
+	CCCI_MD_MSG_SEND_BATTERY_INFO,
+	CCCI_MD_MSG_STORE_NVRAM_MD_TYPE,
+	CCCI_MD_MSG_CFG_UPDATE,
+	CCCI_MD_MSG_RANDOM_PATTERN,
+};
+
+/* MD Status, this is for user space deamon use */
+enum {
+	CCCI_MD_STA_INIT = -1,
+	CCCI_MD_STA_BOOT_READY = 0,
+	CCCI_MD_STA_BOOT_UP,
+	CCCI_MD_STA_RESET,
+	CCCI_MD_STA_STOP,
+	CCCI_MD_STA_FLIGHT_MODE,
+	CCCI_MD_STA_EXCEPTION,
+};
+
+enum {
+	MD_DEBUG_REL_INFO_NOT_READY = 0,
+	MD_IS_DEBUG_VERSION,
+	MD_IS_RELEASE_VERSION
+};
+
+#define USR_CCCI_MD1_CTRL_NAME        "/dev/ccci_monitor"
+#define USR_CCCI_MD3_CTRL_NAME        "/dev/ccci3_monitor"
+
+//----------------maro define-----------------//
+// For rild common
+#define RILD_PROXY_NAME			"ril-proxy"
+#define RILD_PROXY_SERVICE_STATUS	"init.svc.ril-proxy"
+// For MD1
+#define MONITOR_DEV_FOR_MD1		"/dev/ccci_monitor"
+#define MUXD_FOR_MD1_NAME		"gsm0710muxd"
+#define RILD_FOR_MD1_NAME		"ril-daemon-mtk"
+#define MD_LOG_FOR_MD1_NAME		"mdlogger"
+//#define MD_LOG_FOR_MD1_NAME_E	"ecccimdlogger"
+#define MD_LOG_FOR_MD1_NAME_E		"emdlogger1"
+#define FSD_FOR_MD1_NAME		"ccci_fsd"
+#define MD1_INIT_CMD			"0"
+#define MD1_TAG				"ccci_mdinit(1)"
+
+// Common
+#define MD_INIT_OLD_FILE		"/sys/class/BOOT/BOOT/boot/md"
+#define MD_INIT_NEW_FILE		"/sys/kernel/ccci/boot"
+#define BOOT_MODE_FILE			"/sys/class/BOOT/BOOT/boot/boot_mode" // controlled by mtxxxx_boot.c
+#define META_MODE			'1'
+#define FACTORY_MODE		'4'
+#define CCCI_MONITOR_CH			(0xf0000000)
+#define MD_COMM_TAG			"ccci_mdinit(0)"
+#define MD_RESET_WAIT_TIME		"mediatek.debug.md.reset.wait"
+#define MDLOGGER_CAN_RESET		"debug.md.reset"
+
+typedef enum {
+	md_type_invalid = 0,
+	modem_2g = 1,
+	modem_3g,
+	modem_wg,
+	modem_tg,
+	modem_lwg,
+	modem_ltg,
+	modem_sglte,
+	modem_ultg,
+	modem_ulwg,
+	modem_ulwtg,
+	modem_ulwcg,
+	modem_ulwctg,
+	modem_ulttg,
+	modem_ulfwg,
+	modem_ulfwcg,
+	modem_ulctg,
+	modem_ultctg,
+	MAX_IMG_NUM = modem_ultctg /* this enum starts from 1 */
+}modem_type_t;
+
+typedef struct _md_img
+{
+	char file_name[32];
+	int  type;
+}md_img_t;
+
+static char md_img_folder[32] = "/vendor/firmware/";
+static char md_img_cip_folder[32] = "/custom/etc/firmware/";
+
+static md_img_t md1_img_list[] = {
+	{ "modem_1_2g_n.img", modem_2g},
+	{ "modem_1_3g_n.img", modem_3g},
+	{ "modem_1_wg_n.img", modem_wg},
+	{ "modem_1_tg_n.img", modem_tg},
+	{ "modem_1_lwg_n.img", modem_lwg},
+	{ "modem_1_ltg_n.img", modem_ltg},
+	{ "modem_1_sglte_n.img", modem_sglte},
+	{ "modem_1_ultg_n.img", modem_ultg},
+	{ "modem_1_ulwg_n.img", modem_ulwg},
+	{ "modem_1_ulwtg_n.img", modem_ulwtg},
+	{ "modem_1_ulwcg_n.img", modem_ulwcg},
+	{ "modem_1_ulwctg_n.img", modem_ulwctg},
+	{ "modem_1_ulttg_n.img", modem_ulttg},
+	{ "modem_1_ulfwg_n.img", modem_ulfwg},
+	{ "modem_1_ulfwcg_n.img", modem_ulfwcg},
+	{ "modem_1_ulctg_n.img", modem_ulctg},
+	{ "modem_1_ultctg_n.img", modem_ultctg}
+};
+
+static md_img_t *md_img_list;
+static unsigned int img_max_cnt;
+//static md_type_struct *nvram_md_type = NULL;
+
+//----------------variable define-----------------//
+static int  md_ctl_fsm_curr_state = CCCI_MD_STA_INIT; /* Modem Control Finity State Machine global control variable */
+static int  need_silent_reboot = 0; /* This varialbe will set to 1 when modem exception at boot ready state */
+static int  ignore_time_out_msg = 0;
+static int  gotten_md_info = MD_DEBUG_REL_INFO_NOT_READY;
+static int  system_ch_handle = 0;
+static int  mdlogger_cnt = 0;
+static int  md_id = -1;
+static char sys_boot_mode = 0;
+#ifdef NEED_CTRL_AS_SP
+static char muxd_name[PROPERTY_KEY_MAX];
+static char rild_name[PROPERTY_KEY_MAX];
+static char mdlogger_name[PROPERTY_KEY_MAX];
+#else
+#define PROPERTY_KEY_MAX 64
+#define PROPERTY_VALUE_MAX 64
+#endif
+static char fsd_name[PROPERTY_KEY_MAX];
+static char md_boot_name[32];
+//  service property name init.svc.service
+static const char *pre_service_status = "init.svc.";
+#ifdef NEED_CTRL_AS_SP
+static char muxd_service_status[PROPERTY_KEY_MAX];
+static char rild_service_status[PROPERTY_KEY_MAX];
+static char mdlogger_service_status[PROPERTY_KEY_MAX];
+#endif
+static char fsd_service_status[PROPERTY_KEY_MAX];
+
+// service start/stop wait time
+#define MAX_WAIT_FOR_PROPERTY  6000  // wait 6s for service status changed
+
+typedef struct _wait_prop_t
+{
+	char		*prop_name;
+	char		*disr_value;
+} wait_prop_t;
+
+#ifdef NEED_CTRL_AS_SP
+static int rild_generation(void);
+#endif
+
+/* External functin list by env_setting.c */
+extern int compute_random_pattern(unsigned int * p_val);
+extern int get_stored_modem_type_val(int md_id);
+extern int store_modem_type_val(int md_id, int new_val);
+extern unsigned int parse_sys_env_rat_setting(void);
+extern int check_lk_load_md_status(int md_id, char buf[], int size);
+
+#if 1
+enum {
+    PARTIAL_WAKE_LOCK = 1,  // the cpu stays on, but the screen is off
+    FULL_WAKE_LOCK = 2      // the screen is also on
+};
+
+enum {
+    PARTIAL = 0,
+    RELEASE,
+    FD_COUNT
+};
+
+const char * const PATHS[] = {
+    "/sys/power/wake_lock",
+    "/sys/power/wake_unlock",
+};
+
+static int g_fds[FD_COUNT];
+static int initialized;
+static inline int initialize_fds(void);
+
+static inline int initialize_fds(void) {
+    int i;
+    if (initialized == 0) {
+        for (i = 0; i < FD_COUNT; i++) {
+            g_fds[i] = -1;
+            int fd = open(PATHS[i], O_RDWR | O_CLOEXEC);
+            if (fd < 0) {
+                LOGD("open lock fail %s: %s\n", PATHS[i], strerror(errno));
+                goto fail;
+            }
+            g_fds[i] = fd;
+        }
+        initialized = 1;
+    }
+
+    return 0;
+fail:
+    for (i = 0; i < FD_COUNT; i++) {
+        if (g_fds[i] >= 0) {
+            close(g_fds[i]);
+        }
+    }
+    return -1;
+}
+
+static void acquire_wake_lock(int lock, const char* id) {
+    if (initialize_fds()) return;
+
+    ssize_t len = write(g_fds[PARTIAL], id, strlen(id));
+    if (len < 0) {
+        LOGD("acquire wake_lock fail %s: %s\n", id, strerror(errno));
+    }
+}
+
+static void release_wake_lock(const char* id) {
+    if (initialize_fds()) return;
+
+    ssize_t len = write(g_fds[RELEASE], id, strlen(id));
+    if (len < 0) {
+        LOGD("release wake_lock fail %s: %s\n", id, strerror(errno));
+    }
+}
+
+//modem init wake lock
+#define MD_INIT_WAKE_LOCK_NAME "ccci_mdinit"
+#define MD_INIT_WAKE_LOCK() acquire_wake_lock(PARTIAL_WAKE_LOCK, MD_INIT_WAKE_LOCK_NAME)
+#define MD_INIT_WAKE_UNLOCK() release_wake_lock(MD_INIT_WAKE_LOCK_NAME)
+
+#define FSD_WAKE_UNLOCK() release_wake_lock("ccci_fsd")
+
+#endif
+
+
+#ifdef NEED_CTRL_TELEPHONY
+static int check_rild_ee_indication(void)
+{
+	char buf[PROPERTY_VALUE_MAX];
+	int val = 0;
+
+	property_get("persist.ril.ee.delay", buf, "none");
+	if (0 != strcmp(buf, "none")) {
+		val = atoi(buf);
+		LOGD("Wait rild %ds to aware MD EE\n",val);
+		if(0< val && val < 10)
+			return val;
+	}
+	LOGD("Do not notify rild about MD EE\n");
+	return 0;
+}
+#endif
+
+static int check_curret_md_status(int desired)
+{
+	if (md_ctl_fsm_curr_state == desired) {
+		LOGE("status already is %d\n", desired);
+		return 1;
+	}
+	return 0;
+}
+
+static void set_current_md_status(int status)
+{
+	char buf[PROPERTY_VALUE_MAX];
+	char name[50];
+	time_t cur_time;
+	int len;
+
+	md_ctl_fsm_curr_state = status;
+	switch(status){
+	case CCCI_MD_STA_INIT:
+		len = snprintf(buf, sizeof(buf), "init");
+		break;
+	case CCCI_MD_STA_BOOT_READY:
+		len = snprintf(buf, sizeof(buf), "ready");
+		break;
+	case CCCI_MD_STA_BOOT_UP:
+		len = snprintf(buf, sizeof(buf), "bootup");
+		break;
+	case CCCI_MD_STA_RESET:
+		len = snprintf(buf, sizeof(buf), "reset");
+		break;
+	case CCCI_MD_STA_STOP:
+		len = snprintf(buf, sizeof(buf), "stop");
+		break;
+	case CCCI_MD_STA_FLIGHT_MODE:
+		len = snprintf(buf, sizeof(buf), "flightmode");
+		break;
+	case CCCI_MD_STA_EXCEPTION:
+		len = snprintf(buf, sizeof(buf), "exception");
+		break;
+	default:
+		len = snprintf(buf, sizeof(buf), "undefined");
+		break;
+	}
+
+	time(&cur_time);
+
+	snprintf(name, sizeof(name), "mtk.md%d.status",md_id+1);
+	LOGD("set md status:%s=%s \n",name,buf);
+#ifdef NEED_CTRL_AS_SP
+	RLOGI("MD%d set status: %s=%s \n", md_id+1, name, buf);
+	property_set(name,buf);
+#endif
+}
+
+static char get_sys_boot_mode(void)
+{
+	int fd, ret;
+	size_t s;
+	volatile char data[20];
+
+	if (!sys_boot_mode) {
+		fd = open(BOOT_MODE_FILE, O_RDONLY);
+		if (fd < 0) {
+			LOGE("fail to open %s: err_no=%d", BOOT_MODE_FILE, errno);
+			return 0;
+		}
+
+		s = read(fd, (void *)data, sizeof(char) * 3);
+		if (s <= 0) {
+			LOGE("fail to read %s err_no=%d", BOOT_MODE_FILE, errno);
+			sys_boot_mode = '0';
+		} else {
+			sys_boot_mode = data[0];
+		}
+
+		close(fd);
+	}
+	LOGD("system boot Mode: %d\n", sys_boot_mode);
+	return sys_boot_mode;
+}
+
+static int is_factory_mode(void)
+{
+	if (get_sys_boot_mode() == FACTORY_MODE)
+		return 1;
+	else
+		return 0;
+}
+
+static int is_meta_mode(void)
+{
+	int fd, ret;
+	size_t s;
+	volatile char data[20];
+
+	fd = open(BOOT_MODE_FILE, O_RDONLY);
+	if (fd < 0) {
+		LOGE("fail to open %s: err_no=%d", BOOT_MODE_FILE, errno);
+		return 0;
+	}
+
+	s = read(fd, (void *)data, sizeof(char) * 3);
+	if (s <= 0) {
+		LOGE("fail to read %s err_no=%d", BOOT_MODE_FILE, errno);
+		ret = 0;
+	} else {
+		if (data[0] == META_MODE)
+			ret = 1;
+		else
+			ret = 0;
+	}
+
+	close(fd);
+	return ret;
+}
+
+static int get_default_sim_mode(void)
+{
+	int ssw_fd,size;
+	char ssw_default[8];
+	char ssw_default_val=0;
+	LOGD("Begin to set sim mode!\n");
+	ssw_fd = open("/sys/mtk_ssw/mode", O_RDONLY);
+	if (ssw_fd >= 0) {
+		LOGD("/sys/mtk_ssw/mode open OK\n");
+		size = read(ssw_fd, (void *)ssw_default, sizeof(ssw_default));
+		if (size<=0) {
+			LOGD("Can't read ssw default!\n");
+		} else {
+			ssw_default_val = ssw_default[2]-'0';
+			LOGD("ssw default is %d!\n", ssw_default_val);
+		}
+		close(ssw_fd);
+	} else {
+		LOGD("Open mtk_ssw fail!\n");
+	}
+    return ssw_default_val;
+}
+
+/****************************************************************************/
+/* CCCI settings                                                       */
+/*                                                                          */
+/****************************************************************************/
+
+
+
+/****************************************************************************/
+/* modem control message handle function                                                                  */
+/*                                                                                                                           */
+/****************************************************************************/
+
+static void delay_to_reset_md(void)
+{
+#if 0
+    char buf[PROPERTY_VALUE_MAX];
+    int val;
+    property_get(MD_RESET_WAIT_TIME, buf, "none");
+    if (0 != strcmp(buf, "none")) {
+        val = atoi(buf);
+	LOGD("Wait modem %ds to reset md\n",val);
+	if(0< val && val < 10)
+	    sleep(val);
+	else
+	    LOGD("Wait modem time invalid:%s\n", buf);
+    }
+#endif
+}
+
+#ifdef NEED_CTRL_AS_SP
+static int get_nvram_ef_data(int fid, int recsize, void* pdata)
+{
+	F_ID nvram_ef_fid = {0,0,0};
+	int rec_size = 0;
+	int rec_num = 0;
+	bool isread = false;
+	int ret = 0;
+
+	if (pdata == NULL) {
+		LOGE("get_nvram_ef_data: pdata=NULL, fid:%d, recsize:%d\n", fid, recsize);
+		return -1;
+	}
+
+	nvram_ef_fid = NVM_GetFileDesc(fid, &rec_size, &rec_num, isread);
+	if (nvram_ef_fid.iFileDesc < 0) {
+		LOGE("get_nvram_ef_data: Fail to get nvram file descriptor!! fid:%d, errno:0x%x\n", fid, errno);
+		return -1;
+	}
+
+	if (rec_size != read(nvram_ef_fid.iFileDesc, pdata, rec_size)) {
+		LOGE("get_nvram_ef_data: Fail to read nvram file!! fid:%d, errno:0x%x\n", fid, errno);
+		return -1;
+	}
+
+	if (!NVM_CloseFileDesc(nvram_ef_fid)) {
+		LOGE("get_nvram_ef_data: Fail to close nvram file!! fid:%d, errno:0x%x\n", fid, errno);
+	}
+
+	return ret;
+}
+#endif
+#define PROPERTY_WAIT_TIME 10    // 100 ms between polls
+
+/*
+    return: 0: succeeded, 1: maybe has no this property, negative:failed
+*/
+static int wait_for_property(const char *name, const char *desired_value, int waitmsec)
+{
+#ifdef NEED_CTRL_AS_SP
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int maxtimes = waitmsec / PROPERTY_WAIT_TIME;
+	int needretry = 1;
+	int retpropget = 0;
+
+	do {
+		retpropget = property_get(name, value, NULL);
+		if (retpropget > 0) {
+			if (desired_value == NULL || strcmp(value, desired_value) == 0) {
+				LOGI("%s:success(%s=%s), loop:%d\n", __func__, name, desired_value, maxtimes);
+				return 0;
+			}
+		} else if (retpropget == 0) { /* has no this property, needn't try again */
+			LOGI("%s: no property of :%s, loop:%d\n", __func__, name, maxtimes);
+			//return 1; // when phone boot up, service's property is just not created yet, no need to stop
+		} else {  /* property_get return negative, it seems impossible */
+			LOGI("%s: error returned:%d, errno:%d\n", __func__, retpropget, errno);
+		}
+		usleep(PROPERTY_WAIT_TIME * 1000);
+		maxtimes--;
+	} while (maxtimes > 0);
+	if (waitmsec > 0)
+		LOGE("%s:failed, name:%s, desired_value:%s, waitmsec:%d, value:%s\n",
+			__func__, name, desired_value, waitmsec, value);
+
+	return -1;
+#else
+	return 1;
+#endif
+}
+
+static int start_service_verified(const char *service_name, const char*service_status_name, int waitmsec)
+{
+#ifdef NEED_CTRL_AS_SP
+	int succeeded = -1;
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+
+	succeeded = property_get(service_status_name, value, NULL);
+	if (succeeded > 0)
+		LOGI("start_service %s, current state:%s, returned:%d\n", service_status_name, value, succeeded);
+	else if (succeeded == 0)
+		LOGI("start_service %s, but returned 0, maybe has no this property\n", service_status_name);
+	else
+		LOGI("start_service %s, returned:%d\n", service_status_name, succeeded);
+	property_set("ctl.start", service_name);
+	succeeded = wait_for_property(service_status_name, "running", waitmsec);
+	return succeeded;
+#else
+	return 0;
+#endif
+}
+
+static int stop_service_verified(const char *service_name, const char*service_status_name, int waitmsec)
+{
+	int succeeded = -1;
+
+#ifdef NEED_CTRL_AS_SP
+	property_set("ctl.stop", service_name);
+	succeeded = wait_for_property(service_status_name, "stopped", waitmsec);
+#endif
+	return succeeded;
+}
+
+static void check_to_restart_md(void)
+{
+#if 0
+	if (md_id == MD_SYS1 && !is_factory_mode()) {
+		if (rild_generation() == 0) { /* c2k in one case */
+			stop_service_verified(RILD_PROXY_NAME, RILD_PROXY_SERVICE_STATUS, MAX_WAIT_FOR_PROPERTY);
+			LOGD("check_to_restart_md kill ril-proxy, md1 only\n");
+		} else
+			LOGD("ignore kill ril-proxy, fusion\n");
+	}
+	//LOGI("check_to_restart_md:%s not exist\n", the_other_md_status_key);
+#endif
+}
+
+// return 1: ready,  0, not ready
+static int wait_property_ready(wait_prop_t *wp, const int count, const int waitmsec)
+{
+#if 1
+    return 0;
+#else
+	int i;
+	int ready = 0;
+	int watiflag = 0;
+	int bitflag = 0;
+	int maxtimes = waitmsec /PROPERTY_WAIT_TIME;
+	int needtry = 1;
+	wait_prop_t *curwt = NULL;
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int needgetprop = 0;
+
+	if (count > (int)(sizeof(watiflag) * 8)) {
+		LOGI("%s: count > %d, return 0\n", __func__, (8 * sizeof(int)));
+		return ready;
+	}
+
+	if (maxtimes < 1)
+		maxtimes = 1;
+
+	LOGI("%s: count:%d, waitmsec:%d, loop:%d\n", __func__, count, waitmsec, maxtimes);
+	while ((maxtimes-- > 0) && needtry) {
+		curwt = wp;
+		needtry = 0;
+
+		//LOGI("%s watiflag:0x%x\n", __func__, watiflag);
+		for (i=0; i<count; i++) {
+			bitflag = ( 1<< i);
+
+			needgetprop = (!(watiflag & bitflag));
+			if (needgetprop) {
+				if (wait_for_property(curwt->prop_name, curwt->disr_value, 0) >= 0)
+					watiflag |= bitflag;
+				else
+					if (needtry == 0) needtry = 1;
+			}
+
+			if (needgetprop && (maxtimes % 10 == 0)) {
+				LOGI("%s: retry name:%s, disrvalue:%s, loop:%d\n",
+					__func__, curwt->prop_name, curwt->disr_value, maxtimes);
+			}
+			curwt++;
+		}
+
+		// if need to retry, sleep about 100ms
+		if (needtry)
+			usleep(PROPERTY_WAIT_TIME * 1000);
+	}
+
+	if (!needtry){
+		LOGI("%s:Succeeded! count:%d, waitmsec:%d, loop:%d\n", __func__, count, waitmsec, maxtimes);
+		ready = 1;
+	} else {
+		LOGI("%s:Failed! count:%d, waitmsec:%d, loop:%d\n", __func__, count, waitmsec, maxtimes);
+	}
+
+	return ready;
+#endif
+}
+
+static void update_service_name(int fd)
+{
+	if(md_id != 0)
+		return;
+#ifdef NEED_CTRL_AS_SP
+	if (ft_lte_dc_support) {
+		int curr_md_type;
+		int ret;
+
+		ret = ioctl(fd, CCCI_IOC_GET_MD_TYPE, &curr_md_type);
+		if (0 == ret) {
+			if (curr_md_type == modem_sglte) {
+				snprintf(muxd_name, 32, MUXD_FOR_MD1_NAME);// For sglte, in CSFB mode
+				snprintf(rild_name, 32, RILD_FOR_MD1_NAME);// For sglte, in CSFB mode
+			} else {
+				snprintf(muxd_name, 32, MUX_DAEMON_SINGLE);
+				snprintf(rild_name, 32, RIL_DAEMON_SINGLE);
+			}
+			snprintf(muxd_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, muxd_name);
+			snprintf(rild_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, rild_name);
+		} else {
+			LOGD("[Update]get md type fail: %d(%d)\n", errno, ret);
+		}
+	} else {
+		snprintf(muxd_name, 32, MUXD_FOR_MD1_NAME);
+		snprintf(muxd_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, muxd_name);
+		snprintf(rild_name, 32, "%s", RILD_FOR_MD1_NAME);
+
+		snprintf(rild_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, rild_name);
+	}
+	LOGD("Current muxd: %s, rild:%s\n", muxd_name, rild_name);
+#endif
+}
+
+static void stop_all_ccci_up_layer_services(void)
+{
+	
+#ifndef  NEED_CTRL_AS_SP
+	LOGD("stop all up layer service\n");
+	stop_service_verified(fsd_name, fsd_service_status, MAX_WAIT_FOR_PROPERTY);
+	FSD_WAKE_UNLOCK();
+#else
+	int retry= 0;
+	char buf[PROPERTY_VALUE_MAX];
+	wait_prop_t wp[3];
+	int wpcount = 0;
+	int stopped = 0;
+
+	LOGD("stop all up layer service\n");
+
+	stop_service_verified(fsd_name, fsd_service_status, MAX_WAIT_FOR_PROPERTY);
+	FSD_WAKE_UNLOCK();
+	if (!is_factory_mode()) {
+		stop_service_verified(rild_name, rild_service_status, MAX_WAIT_FOR_PROPERTY);
+
+		if(md_id != MD_SYS3){
+			property_set("ctl.stop", muxd_name);
+			wp[wpcount].prop_name = muxd_service_status;
+			wp[wpcount].disr_value ="stopped";
+			wpcount++;
+		}
+	}
+	if(mdlogger_cnt) {
+		while(retry < 6){
+			retry++;
+			property_get(MDLOGGER_CAN_RESET, buf, "0");
+			if (0 != strcmp(buf, "0"))
+				break;
+			usleep(50*1000);
+		}
+		if (retry >= 6)
+			LOGD("MDlogger not set %s\n",MDLOGGER_CAN_RESET);
+		property_set("ctl.stop", mdlogger_name);
+		wp[wpcount].prop_name = mdlogger_service_status;
+		wp[wpcount].disr_value ="stopped";
+		wpcount++;
+
+		mdlogger_cnt = 0;
+	}
+
+	stopped = wait_property_ready(wp, wpcount, MAX_WAIT_FOR_PROPERTY);
+	if (stopped > 0)
+		LOGD("stop all up layer service succeeded!\n");
+	else
+		LOGE("stop all up layer service failed\n");
+#endif
+}
+
+static void start_all_ccci_up_layer_services(void)
+{
+#ifndef NEED_CTRL_AS_SP
+	LOGD("mdlogger && mux is not supported\n");
+#else
+	LOGD("start all ccci up layer services\n");
+
+	if (need_silent_reboot) {
+		LOGD("set ril.mux.report.case 2\n");
+		property_set("ril.mux.report.case", "2"); /* set mux flag here, should before muxd */
+	}
+
+	if(mdlogger_cnt == 0) {
+		// LOGD("start mdlogger\n");
+		start_service_verified(mdlogger_name, mdlogger_service_status, 0);
+		mdlogger_cnt = 1;
+	}
+
+	update_service_name(system_ch_handle);
+	if (!is_factory_mode()) {
+		if(md_id != MD_SYS3) {
+			start_service_verified(muxd_name, muxd_service_status, MAX_WAIT_FOR_PROPERTY);
+		} else {
+			// LOGD("start c2k rild\n");
+			start_service_verified(rild_name, rild_service_status, MAX_WAIT_FOR_PROPERTY);
+		}
+	}
+#endif
+}
+
+static int common_msg_handler(int msg, int resv)
+{
+	int ret = 1;
+	int data = 0;
+	char str[32];
+	int rild_pid, rild_delay;
+	char rild_pid_key[PROPERTY_KEY_MAX] = {0};
+	char rild_pid_value[PROPERTY_VALUE_MAX] = {0};
+	char property_name[50];
+
+	switch (msg) {
+	case CCCI_MD_MSG_SEND_BATTERY_INFO:
+		if(ioctl(system_ch_handle, CCCI_IOC_SEND_BATTERY_INFO, &data))
+			LOGE("send md battery info fail: %d", errno);
+		else
+			LOGD("send md battery info OK");
+		break;
+	case CCCI_MD_MSG_CFG_UPDATE:
+		LOGD("CFG UPDATE: 0x%x(dummy)\n", resv);
+		break;
+	case CCCI_MD_MSG_RANDOM_PATTERN:
+		LOGD("CCCI_MD_MSG_RANDOM_PATTERN\n");
+		compute_random_pattern((unsigned int*) &data);
+		if (0 != ioctl(system_ch_handle, CCCI_IOC_RESET_AP, &data))
+			LOGE("reset_ap_ioctl failed.\n");
+		break;
+	case CCCI_MD_MSG_STORE_NVRAM_MD_TYPE:
+		LOGD("CCCI_MD_MSG_STORE_SIM_MODE\n");
+		ioctl(system_ch_handle, CCCI_IOC_GET_MD_TYPE_SAVING, &data);
+		LOGD("md%d type in kernel(%d)\n", md_id+1, data);
+		if (data == get_stored_modem_type_val(md_id))
+			LOGD("No need to store md type(%d)\n", data);
+		else
+			store_modem_type_val(md_id, data);
+		break;
+	case CCCI_MD_MSG_EXCEPTION:
+		if (check_curret_md_status(CCCI_MD_STA_EXCEPTION))
+			break;
+		LOGD(" CCCI_MD_MSG_EXCEPTION\n");
+		set_current_md_status(CCCI_MD_STA_EXCEPTION);
+		if(mdlogger_cnt == 0) {
+			LOGD("start mdlogger when MD exception happens early\n");
+			//start_service_verified(mdlogger_name, mdlogger_service_status, MAX_WAIT_FOR_PROPERTY);
+			mdlogger_cnt = 1;
+		}
+		need_silent_reboot = 1;
+#ifdef NEED_CTRL_AS_SP
+		if(md_id == MD_SYS3) {
+			/*c2krild will use this "exception" state to decide how to triger NE*/
+			snprintf(property_name, sizeof(property_name), "net.cdma.mdmstat");
+			LOGD("set md3 status:%s=exception \n",property_name);
+			property_set(property_name,"exception");
+		}
+		rild_delay = check_rild_ee_indication();
+		if(rild_delay) {
+			snprintf(rild_pid_key, PROPERTY_KEY_MAX, "ril.pid.%d", md_id+1);
+			if (property_get(rild_pid_key, rild_pid_value, NULL) > 0) {
+				rild_pid = atoi(rild_pid_value);
+				LOGD("get ril pid=%d\n", rild_pid);
+				if(rild_pid > 0) {
+					int val = (SIGUSR2<<16)|(rild_pid&0xFFFF);
+					ret = ioctl(system_ch_handle, CCCI_IOC_SEND_SIGNAL_TO_USER, &val);
+					LOGD("send SIGUSR2 to ril %d/%d\n", ret, errno);
+					sleep(rild_delay);
+				}
+			} else {
+				LOGE("get rild_pid property failed. rild_pid_key=%s\n", rild_pid_key);
+			}
+		}
+#endif
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+	return ret;
+}
+
+/*
+*Return value:
+* 0: unencrypted, unsupported
+* 1: auto encrypt and decrpty on first boot
+* 2: vold trigger_restart_framework after decrpty, fsis norma
+* 3: vold trigger_restart_min_framework and wait decrpty, fs is tmpfs
+* error value: <0
+*/
+static int check_decrypt_ready(void)
+{
+#ifdef NEED_CTRL_AS_SP
+	int ret;
+	char property_val[PROPERTY_VALUE_MAX] = {0};
+	// Check whether is at decrypt state
+	property_get("ro.crypto.state", property_val, NULL);
+	LOGD("ro.crypto.state=%s\n",property_val);
+	if (strcmp(property_val, "") == 0) {
+		LOGD("auto encrypt & decrypt\n");
+		wait_decrypt_done();
+		wait_nvram_ready(1);
+		return 1;
+	} else if (strcmp(property_val, "unencrypted") == 0) {
+		wait_nvram_ready(1);
+		LOGD("unencrypted!!\n");
+		return 0;
+	} else if (strcmp(property_val, "unsupported") == 0) {
+		wait_nvram_ready(1);
+		LOGD("unsupported!!\n");
+		return 0;
+	} else if (strcmp(property_val, "encrypted") == 0) {
+		property_get("ro.crypto.type", property_val, NULL);
+		if (strcmp(property_val, "file") == 0) {
+				wait_nvram_ready(1);
+				LOGD("file/FBE!!\n");
+				return 0;
+		}
+		while(1) {
+			property_get("vold.decrypt", property_val, NULL);
+			if (strcmp(property_val, "trigger_restart_framework") == 0) {
+				LOGD("vold.decrypt:trigger_restart_framework\n");
+				wait_nvram_ready(1);
+				return 2;
+			} else if (strcmp(property_val, "trigger_restart_min_framework") == 0) {
+				LOGD("vold.decrypt:trigger_restart_min_framework!!\n");
+				wait_nvram_ready(2);
+				return 3;
+			}
+			usleep(100*1000);
+		}
+	} else {
+		LOGE("crypto state error %s!!\n", property_val);
+		ret = -1;
+	}
+	return ret;
+#else
+	return 0;
+#endif
+}
+
+typedef enum {
+	MODE_UNKNOWN = -1,	  /* -1 */
+	MODE_IDLE,			  /* 0 */
+	MODE_USB,			   /* 1 */
+	MODE_SD,				/* 2 */
+	MODE_POLLING,		   /* 3 */
+	MODE_WAITSD,			/* 4 */
+} LOGGING_MODE;
+/* MD logger configure file */
+#define MD1_LOGGER_FILE_PATH "/data/mdlog/mdlog1_config"
+#define MDLOGGER_FILE_PATH   "/data/mdl/mdl_config"
+
+static int get_mdlog_boot_mode(int md_id)
+{
+	int fd, ret;
+	unsigned int mdl_mode = 0;
+#ifdef NEED_CTRL_AS_SP
+	char pBuildType[PROPERTY_VALUE_MAX] = {0};
+#endif
+
+	switch(md_id) {
+	case 0:
+		fd = open(MD1_LOGGER_FILE_PATH, O_RDONLY, 0660);
+		if(fd < 0)
+			fd = open(MDLOGGER_FILE_PATH, O_RDONLY, 0660);
+		break;
+	default:
+		LOGE_COM("Open md_id=%d error!\n", md_id);
+		fd = -1;
+		break;
+	}
+	if (fd < 0) {
+		LOGE_COM("Open md_log_config file failed, errno=%d!\n", errno);
+#ifdef NEED_CTRL_AS_SP
+		property_get("ro.build.type", pBuildType, "eng");
+		if (0 == strcmp(pBuildType, "eng"))
+				mdl_mode = MODE_SD;
+		else
+#endif
+				mdl_mode = MODE_IDLE;
+		return mdl_mode;
+	}
+	ret = read(fd, &mdl_mode, sizeof(unsigned int));
+	if (ret != sizeof(unsigned int)) {
+		LOGE_COM("read failed ret=%d, errno=%d!\n", ret, errno);
+#ifdef NEED_CTRL_AS_SP
+		property_get("ro.build.type", pBuildType, "eng");
+		if (0 == strcmp(pBuildType, "eng"))
+				mdl_mode = MODE_SD;
+		else
+#endif
+				mdl_mode = MODE_IDLE;
+	}
+	close(fd);
+	return mdl_mode;
+}
+
+static int get_usp_sbp_setting(int md_id)
+{
+#ifdef NEED_CTRL_AS_SP
+#define MTK_USP_SBP_NAME "persist.mtk_usp_md_sbp_code"
+	char buf[PROPERTY_VALUE_MAX] ={ 0 };
+	int ret;
+	int sbp_code = 0;
+
+	ret = property_get(MTK_USP_SBP_NAME, buf, NULL);
+	if (ret == 0) {
+		LOGI("USP_SBP:%s not exist\n", MTK_USP_SBP_NAME);
+		return 0;
+	}
+	sbp_code = atoi(buf);
+	if (sbp_code < 0) {
+		LOGE("USP_SBP:%s=%s,usp_sbp=%d is a invalide value\n", MTK_USP_SBP_NAME, buf, sbp_code);
+		sbp_code = 0;
+	} else
+		LOGI("USP_SBP:%s=%s,usp_sbp=%d\n", MTK_USP_SBP_NAME, buf, sbp_code);
+
+	return sbp_code;
+#else
+	return 0;
+#endif
+}
+
+// return: 0-fail,  others-setting value
+static unsigned int get_cip_sbp_setting(int md_id)
+{
+#define CIP_SBP_FILE "CIP_MD_SBP"
+	char md_cip_sbp_file[100] = "";
+	int fd, read_len;
+	struct stat sbp_stat;
+	char cip_sbp_value[12] = "";
+	long retl = 0;
+	unsigned int ret = 0;
+	char *endptr = NULL;
+
+	memset(md_cip_sbp_file, 0x0, sizeof(md_cip_sbp_file));
+	strncpy(md_cip_sbp_file, md_img_cip_folder, 99);	// For cip path
+	if (md_id == MD_SYS1) {
+		strncat(md_cip_sbp_file+strlen(md_cip_sbp_file), CIP_SBP_FILE,
+                        99-strlen(md_cip_sbp_file));
+	} else {
+		LOGD("get_cip_sbp_setting, md_id:%d is error!\n", md_id);
+		return 0;
+	}
+
+	umask(0007);
+	if (stat(md_cip_sbp_file, &sbp_stat) < 0) {
+		LOGD("get_cip_sbp_setting, file %s NOT exists!\n", md_cip_sbp_file);
+		return 0;
+	}
+
+	fd = open(md_cip_sbp_file, O_RDONLY, 0660);
+	if(fd < 0) {
+		LOGD("get_cip_sbp_setting, open file %s Fail! err:%d\n", md_cip_sbp_file, errno);
+		return 0;
+	}
+
+	memset(cip_sbp_value, 0x0, sizeof(cip_sbp_value));
+	read_len = (int)read(fd, cip_sbp_value, sizeof(cip_sbp_value));
+	if(read_len < 0) {
+		LOGD("get_cip_sbp_setting, read file %s Fail! err:%d\n", md_cip_sbp_file, errno);
+		close(fd);
+		return 0;
+	}
+	close(fd);
+
+	retl = strtol(cip_sbp_value, &endptr, 0);
+	if (endptr != NULL) {
+		LOGD("get_cip_sbp_setting, Warning!! endptr is not NULL! value:%x\n", *((unsigned int *)endptr));
+	}
+	if (retl > 0) {
+		ret = (unsigned int)(retl & 0xFFFFFFFF);
+		LOGD("get_cip_sbp_setting, get sbp setting:0x%x\n", ret);
+	} else {
+		LOGD("get_cip_sbp_setting, Error!! sbp setting is 0!\n");
+	}
+
+	return ret;
+}
+static int get_nvram_sbp_code(int md_id)
+{
+#ifdef NEED_CTRL_AS_SP
+#define MD_SBP_PATH_FILE "/data/nvram/APCFG/APRDCL/MD_SBP"
+	int getsbpcode = 0;
+	int store_sbp_code = 0;
+	MD_SBP_Struct *nvram_sbp_info = NULL;
+	int md_sbp_lid = -1;
+
+	md_sbp_lid = NVM_GetLIDByName(MD_SBP_PATH_FILE);
+	if (md_sbp_lid < 0) {
+		LOGE("Error!! get sbp lid fail!!!%d\n", md_sbp_lid);
+		goto EXIT_FUN;
+	}
+	nvram_sbp_info = (MD_SBP_Struct *)malloc(sizeof(MD_SBP_Struct));
+	if (nvram_sbp_info == NULL) {
+		LOGD("Error!! malloc md sbp code fail! errno:%d\n", errno);
+		goto EXIT_FUN;
+	}
+	memset((void *)nvram_sbp_info, 0, sizeof(MD_SBP_Struct));
+	getsbpcode = get_nvram_ef_data(md_sbp_lid,	sizeof(MD_SBP_Struct), nvram_sbp_info);
+	if (getsbpcode != 0) {
+		LOGD("Error!! get_nvram_ef_data fail lid=%d,ret:%d\n", md_sbp_lid, getsbpcode);
+		goto EXIT_FUN;
+
+	}
+	if (md_id == MD_SYS2)
+		store_sbp_code = nvram_sbp_info->md2_sbp_code;
+	else
+		store_sbp_code = nvram_sbp_info->md_sbp_code;
+EXIT_FUN:
+	if (nvram_sbp_info) {
+		free(nvram_sbp_info);
+		nvram_sbp_info = NULL;
+	}
+#else
+	int store_sbp_code = 0;
+#endif
+	return store_sbp_code;
+}
+
+static int get_project_sbp_code(int md_id)
+{
+	int sbp_code = 0;
+	//char tmp_buf[10] = {0};
+
+	if (md_id != MD_SYS1) {
+	} else {
+		// get md1 SBP code from ProjectConfig.mk from ccci_lib
+		//if (0 == query_prj_cfg_setting("MTK_MD_SBP_CUSTOM_VALUE", tmp_buf, sizeof(tmp_buf)))
+			//sbp_code = atoi(tmp_buf);
+	}
+	return sbp_code;
+}
+
+/*
+ *  for MD SBP feature, diferent operators use the same md image
+ *  MTK_MD_SBP_CUSTOM_VALUE_ must be definied on ProjectConfig.mk
+ *    0: INVALID value, the project need SBP feature, but value 0 needn't transform to modem
+ *  related files:
+ *    MD_SBP: under /data/nvram/APCFG/APRDCL/, see about CFG_MD_SBP_File.h
+ *      the md_sbp_value of MD_SBP could be assigned by MTK_MD_SBP_CUSTOM_VALUE_ in ProjectConfig.mk
+ *      if MTK_MD_SBP_CUSTOM_VALUE_=0, it means need SBP process flow, but not care ProjectConfig value.
+ *    CIP_MD_SBP: under /custom/etc/firmware/, It is Hexadecimai number string, ex: 0x3
+ *  Rules:
+ *    wwop project use CIP_MD_SBP file, the number transform from CIP_MD_SBP MUST NOT be 0
+ *        MTK_MD_SBP_CUSTOM_VALUE_ SHOULD be defined as 0x0(or 0) in ProjectConfig.mk of wwop project
+ *    in non-wwop project:
+ *      MTK_MD_SBP_CUSTOM_VALUE_ Defined: the MTK_MD_SBP_CUSTOM_VALUE_ should be transfer to md
+ *      MTK_MD_SBP_CUSTOM_VALUE_ Undefined: the value in MD_SBP should be transfer to md
+ *    The sb_code needn't transfer to md from the second boot up time, if the sb_code is not changed from the first boot.
+ */
+static int get_md_sbp_code(int md_id)
+{
+	int sbp_default = 0;
+	int cip_sbp_value = 0;
+	int stored_sbp_code = 0;
+	static int sbpc = 0;
+	int usp_sbp_value;
+
+	/* NOTES:
+	* priority: USP > CIP > ProjectConfig > meta tool
+	* Assume:
+	*    0. uniservice pack property for global device
+	*    1. wwop(CIP) project could not be modified by meta tool
+	*    2. ProjectConfiged project could not be modified by meta tool
+	*    3. meta tool could modified project MUST NOT define MTK_MD_SBP_CUSTOM
+	*/
+	usp_sbp_value =  get_usp_sbp_setting(md_id);
+	if (usp_sbp_value && usp_sbp_value != sbpc)
+		sbpc = usp_sbp_value;
+	/*if static var sbpc has been set, then return directly*/
+	if(sbpc)
+		return sbpc;
+
+	cip_sbp_value = get_cip_sbp_setting(md_id);
+	stored_sbp_code = get_nvram_sbp_code(md_id);
+	sbp_default = get_project_sbp_code(md_id);
+
+	if (stored_sbp_code > 0)
+		sbpc = stored_sbp_code;
+
+	if (sbp_default > 0)
+		sbpc = sbp_default;
+
+	if (cip_sbp_value > 0)
+		sbpc = cip_sbp_value;
+	LOGD("Get: usp_sbp=%d, cip_sbp=%d, project_sbp=%d, nvram_sbp=%d, set sbp=%d\n",
+		usp_sbp_value, cip_sbp_value, sbp_default, stored_sbp_code, sbpc);
+
+	return sbpc;
+}
+
+static int get_md_dbg_dump_flag(int md_id)
+{
+#ifdef NEED_CTRL_AS_SP
+	char buf[PROPERTY_VALUE_MAX] = { '\0' };
+	int ret = -1; /* equal to 0xFFFFFFFF as Uint32 in kernel */
+
+	if (md_id == MD_SYS1)
+		property_get("persist.ccci.md1.dbg_dump", buf, "none");
+	else if (md_id == MD_SYS3)
+		property_get("persist.ccci.md3.dbg_dump", buf, "none");
+
+	if (0 != strcmp(buf, "none"))
+		ret = strtoul(buf, NULL, 16);
+	return ret;
+#else
+	return -1;
+#endif
+}
+
+#define MD_BOOT_MODE_PATH "/proc/device-tree/chosen/atag,boot"
+
+static int get_md_boot_mode(char const * path)
+{
+    int fd;
+
+    if (path == NULL) {
+        return -1;
+    }
+
+    fd = open(path, O_RDONLY);
+    if (fd >= 0)
+    {
+        int buffer[8] = {0};
+        int len = read(fd, &buffer, sizeof(int)*8);
+        LOGI("read boot mode struct len = %d\n", len);
+        if (len > 0) {
+            LOGI("boot mode size = %d, tag = %d, bootMode = %d\n", buffer[0], buffer[1], buffer[2]);
+            close(fd);
+            return buffer[2];
+        }
+        close(fd);
+    }
+    LOGI("read boot mode failed to open %s\n", path);
+    return -errno;
+}
+
+int set_md_boot_env_data(int md_id, int fd)
+{
+	unsigned int data[16] = { 0 };
+
+	data[0] = get_mdlog_boot_mode(md_id);
+	data[1] = get_md_sbp_code(md_id);
+	data[2] = get_md_dbg_dump_flag(md_id);
+	data[3] = get_md_boot_mode(MD_BOOT_MODE_PATH);
+	LOGI("set md boot data:mdl=%d sbp=%d dbg_dump=%d bootMode=%d\n", data[0], data[1], data[2], data[3]);
+	ioctl(fd, CCCI_IOC_SET_BOOT_DATA, &data);
+	return 0;
+}
+
+/****************************************************************************/
+/* initial and main thread                                                                                           */
+/*                                                                                                                           */
+/****************************************************************************/
+static int trigger_modem_to_run(unsigned int monitor_fd, int flight_mode, int first_boot)
+{
+	int fd = 0, ret = 0, curr_md_type = 0;
+	int current_boot_mode = MD_BOOT_MODE_INVALID;
+	char data[20] = {0};
+	char md_id_str[16] = {0};
+
+	LOGD("trigger modem to run! %d %d\n", flight_mode, first_boot);
+	set_current_md_status(CCCI_MD_STA_RESET);
+	if (flight_mode) {
+		wait_for_property("ril.getccci.response", "1", 500);
+		if (!is_meta_mode()) {
+			stop_all_ccci_up_layer_services();
+		}
+	}
+	ret = ioctl(monitor_fd, CCCI_IOC_GET_MD_TYPE, &curr_md_type);
+	if(0 == ret){
+		snprintf(md_id_str, 16, "%d", curr_md_type);
+#ifdef NEED_CTRL_AS_SP
+		property_set("ril.active.md", md_id_str);
+#endif
+	} else {
+		LOGD("[Active MD]get md type fail: %d(%d)\n", errno, ret);
+	}
+
+	if (!first_boot)
+		check_to_restart_md();
+	check_decrypt_ready();
+	set_md_boot_env_data(md_id, monitor_fd);
+	start_service_verified(fsd_name, fsd_service_status, MAX_WAIT_FOR_PROPERTY);
+
+	set_current_md_status(CCCI_MD_STA_BOOT_UP);
+	if (first_boot)
+		ccci_ccb_init_users(md_id);
+	ret = ioctl(monitor_fd, CCCI_IOC_DO_START_MD, NULL);
+	if (ret) {
+		LOGE("Fail to trigger md run, ioctl %d %d\n", ret, errno);
+		perror("");
+		return -1;
+	}
+
+start_service:
+
+#if 0
+	ret = ioctl(monitor_fd, CCCI_IOC_GET_MD_STATE, &current_boot_mode);
+	if (ret < 0) {
+		LOGE("fail to get modem state(%d) %d %d\n", current_boot_mode, ret, errno);
+		return -1;
+	}
+	if (current_boot_mode == MD_STATE_READY) {
+		set_current_md_status(CCCI_MD_STA_BOOT_READY);
+		ccci_ccb_check_users(md_id); // must before we start MDlogger
+		if (!is_meta_mode()) {
+			if (ioctl(monitor_fd, CCCI_IOC_GET_MD_BOOT_MODE, &current_boot_mode) == 0) {
+				if (current_boot_mode != MD_BOOT_MODE_META)
+					start_all_ccci_up_layer_services();
+				else
+					LOGD("boot MD into META mode when system is in normal mode\n");
+			} else {
+				start_all_ccci_up_layer_services();
+			}
+		}
+		need_silent_reboot = 0;
+	} else {
+		LOGE("modem state %d\n", current_boot_mode);
+		return -1;
+	}
+	LOGI("modem boot ready and deamon begin to run!\n");
+#endif
+	return 0;
+}
+
+static int md_image_exist_check(int fd,int md_id)
+{
+	int exist_idx = 0;
+	unsigned int md_type = 0;
+	char md_img_path[100] = "";
+	char md_img_cip_path[100] = "";
+	unsigned int md_img_index = 0;
+	int err = 0;
+	unsigned int md_img_exist[MAX_IMG_NUM] = {0};
+	exist_idx = 0;
+	while (md_img_index < img_max_cnt){
+		memset(md_img_path, '\0', sizeof(md_img_path));
+		strncpy(md_img_path, md_img_folder, 99);	// For default path
+		strncat(md_img_path+strlen(md_img_path), md_img_list[md_img_index].file_name,
+                        99-strlen(md_img_path));
+		strncpy(md_img_cip_path, md_img_cip_folder, 99);	// For CIP path
+		strncat(md_img_cip_path+strlen(md_img_cip_path), md_img_list[md_img_index].file_name,
+                        99-strlen(md_img_cip_path));
+		//LOGD("looking for %s...", md_img_cip_path);
+		if ((err = access(md_img_cip_path, F_OK)) == 0){
+			LOGD("Found %s\n", md_img_list[md_img_index].file_name);
+			md_img_exist[exist_idx] = md_img_list[md_img_index].type;
+			exist_idx++;
+		}else {
+			//LOGD("looking for %s...", md_img_path);
+			if ((err = access(md_img_path, F_OK)) == 0){
+				LOGD("Found %s\n", md_img_list[md_img_index].file_name);
+				md_img_exist[exist_idx] = md_img_list[md_img_index].type;
+				exist_idx++;
+			}
+		}
+		md_img_index++;
+	}
+	LOGD("md_img_exist %d %d %d %d\n", md_img_exist[0], md_img_exist[1], md_img_exist[2], md_img_exist[3]);
+	ioctl(fd, CCCI_IOC_SET_MD_IMG_EXIST, &md_img_exist);
+    return 0;
+}
+
+/*
+*
+* Wait_level
+* 1: only check whether service.nvram_init = "Ready"
+* 2: check service.nvram_init is both "Ready" and "Pre_ready
+*/
+static int wait_nvram_ready(int wait_level)
+{
+#ifdef NEED_CTRL_AS_SP
+#define MAX_NVRAM_RETRY_TIMES 240
+	int retry = 0;
+	int ret = -1;
+	char property_val[PROPERTY_VALUE_MAX] = {0};
+	LOGD("waiting nvram ready! %d\n", retry);
+	while(1){
+		property_get("service.nvram_init", property_val, NULL);
+		if(wait_level == 1 || wait_level == 2){
+			if(strcmp(property_val, "Ready") == 0){
+				ret = 0;
+				break;
+			}
+		}
+		if (wait_level == 2) {
+			if (strcmp(property_val, "Pre_Ready") == 0) {
+				ret = 0;
+				break;
+			}
+		}
+		retry++;
+ 	 	if ((retry % MAX_NVRAM_RETRY_TIMES) == 0) {
+ 	 	 	ret = -1;
+ 	 	 	LOGD("wait service.nvram_init=%s... timeout\n", property_val);
+ 	 	 	break;
+ 	 	}
+		usleep(500*1000);
+	}
+	//when factory restore runs on emmc, modem start to run before nvram restore complete,
+	//and then modem exception happens, so need wait for nvram is ready
+	LOGE("Gotten ret=%d,nvram_init=%s!\n", ret, property_val);
+	if (ret < 0) {
+		LOGE("Get nvram restore ready fail! Warning for nvram!\n");
+		const char *mod = MD_COMM_TAG;
+		if (md_id == 0)
+			mod = MD1_TAG;
+		else if (md_id == 1)
+			mod = MD2_TAG;
+		dl_aee_system_exception(mod, "ccci_mdinit", DB_OPT_FTRACE,
+				"Wait service.nvram_init ready timeout, please ask nvram owner to check!");
+		exit(-0xF1);
+	}
+	return ret;
+#else
+	return 0;
+#endif
+}
+static int wait_decrypt_done(void)
+{
+#ifdef NEED_CTRL_AS_SP
+#define MAX_RETRY_TIMES 120
+	int retry=0;
+	char property_val[PROPERTY_VALUE_MAX] = {0};
+	LOGD("waiting vold.decrypt=trigger_restart_framework\n");
+	property_get("vold.decrypt", property_val, NULL);
+	while (strcmp(property_val, "trigger_restart_framework") != 0) {
+		retry++;
+		if ((retry % MAX_RETRY_TIMES) == 0)
+			LOGD("wait vold.decrypt...,%s\n",property_val);
+		usleep(500*1000);
+		property_get("vold.decrypt", property_val, NULL);
+	}
+	LOGD("wait vold.decrypt=%s done success!\n",property_val);
+#endif
+	return 0;
+}
+
+#if 1//def NEED_CTRL_AS_SP
+extern void* monitor_time_update_thread(void* arg);
+extern int time_srv_init(void);
+#endif
+
+static int get_int_property_val(const char *name, const char *desired_value)
+{
+#ifdef NEED_CTRL_AS_SP
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int retpropget = 0;
+#endif
+	int val;
+
+#ifdef NEED_CTRL_AS_SP
+	retpropget = property_get(name, value, desired_value);
+	if (retpropget > 0)
+		val = atoi(value);
+	else
+#endif
+		val = atoi(desired_value);
+
+	LOGE("get_int_property_val: %s [%d]", name, val);
+	return val;
+}
+
+#ifdef NEED_CTRL_AS_SP
+int rild_generation(void)
+{
+	char value[PROPERTY_VALUE_MAX] = {'\0'};
+	int retpropget = 0;
+	int ril_gen = 0;
+
+	retpropget = property_get("ro.mtk_ril_mode", value, "legacy chip");
+	if ((retpropget > 0) && (strcmp(value, "c6m_1rild") == 0))
+		ril_gen = 1;
+
+	LOGE("rild_generation value: %s [%d]", value, ril_gen);
+	return ril_gen;
+}
+#endif
+
+int main_v2(int argc, char **argv)
+{
+	int ret, fd, tmp=0;
+	ssize_t s;
+	CCCI_BUFF_T buff;
+//	char nvram_init_val[PROPERTY_VALUE_MAX] = {0};
+	char dev_port[32];
+	pthread_t tid;
+	unsigned int monitor_ch;
+	int port_open_retry = MAX_OPEN_PORT_RETRY_NUM;
+	int md_type = 0;
+	char tmp_buf[4];
+	char *lk_info_buf;
+
+	LOGE_COM("md_init ver:2.12\n");
+
+	//Check if input parameter is valid
+	if(argc != 2) {
+		LOGE_COM("[Warning]wrong parameter %d, so use original version!\n", argc);
+		md_id = 0;
+		monitor_ch = CCCI_MONITOR_CH;
+	} else {
+		if(strcmp(argv[1],"0")==0)
+			md_id = 0;
+		else {
+			LOGE_COM("[Error]Invalid md sys id(%d)!\n", md_id);
+			return -1;
+		}
+		monitor_ch = CCCI_MONITOR_CH;
+	}
+
+	lk_info_buf = malloc(4096);
+	if (lk_info_buf == NULL) {
+		LOGE("alloc 4K memory buffer fail\n");
+		return -1;
+	}
+	if (check_lk_load_md_status(md_id, lk_info_buf, 4096) < 0){
+		const char *mod = MD_COMM_TAG;
+		if (wait_for_property("init.svc.debuggerd", "running", 30*1000) == 0)
+			sleep(1);
+#ifdef NEED_CTRL_AS_SP
+		dl_aee_system_exception(mod, "external.ccci_mdinit", 0,
+				"%s", lk_info_buf);
+#endif
+	}
+	free(lk_info_buf);
+	lk_info_buf = NULL;
+
+	set_current_md_status(CCCI_MD_STA_INIT);
+
+	//Configure service and dev port name
+	switch(md_id) {
+	case 0:
+		//snprintf(dev_port, 32, "%s", ccci_get_node_name(USR_CCCI_CTRL, MD_SYS1));
+		snprintf(dev_port, 32, "%s", USR_CCCI_MD1_CTRL_NAME);
+		
+#ifdef NEED_CTRL_AS_SP
+		snprintf(muxd_name, 32, "%s", MUXD_FOR_MD1_NAME);
+		snprintf(rild_name, 32, "%s", RILD_FOR_MD1_NAME);
+		snprintf(mdlogger_name, 32, "%s", MD_LOG_FOR_MD1_NAME_E);
+#endif
+		snprintf(fsd_name, 32, "%s", FSD_FOR_MD1_NAME);
+		md_img_list=md1_img_list;
+		img_max_cnt = sizeof(md1_img_list)/sizeof(md_img_t);
+		break;
+	default:
+		LOGE("[Error]Invalid md sys id: %d\n", md_id+1);
+		return -1;
+	}
+
+#ifdef NEED_CTRL_AS_SP
+	snprintf(muxd_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, muxd_name);
+	snprintf(rild_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, rild_name);
+	snprintf(mdlogger_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, mdlogger_name);
+	snprintf(fsd_service_status, PROPERTY_KEY_MAX, "%s%s", pre_service_status, fsd_name);
+
+	LOGI("[%s][%s][%s][%s] img_max_cnt=%d\n",
+		muxd_service_status,
+		rild_service_status,
+		mdlogger_service_status,
+		fsd_service_status, img_max_cnt);
+#endif
+
+	snprintf(md_boot_name, 32, MD_INIT_NEW_FILE); // <== Using new md boot file
+
+	check_decrypt_ready();
+
+	// Retry to open if dev node attr not ready
+	while(1) {
+		fd = open(dev_port, O_RDWR);
+		if (fd < 0) {
+			port_open_retry--;
+			if(port_open_retry>0) {
+				usleep(10*1000);
+				continue;
+			} else {
+				LOGE("open %s fail: %d\n", dev_port, errno);
+				return -1;
+			}
+		} else {
+			LOGD("%s is opened(%d).\n", dev_port, (MAX_OPEN_PORT_RETRY_NUM-port_open_retry));
+			break;
+		}
+	}
+
+	md_image_exist_check(fd, md_id);
+
+	// Get current MD type and update mux daemon name
+	update_service_name(fd);
+	if(time_srv_init()==0){
+		pthread_create(&tid, NULL, monitor_time_update_thread, NULL);
+	}
+
+	tmp = parse_sys_env_rat_setting();
+	if(ioctl(fd, CCCI_IOC_RELOAD_MD_TYPE, &tmp) != 0)
+		LOGD("update modem type to kernel fail: err=%d", errno);
+
+	ret = trigger_modem_to_run(fd, 0, 1);
+	if (ret < 0)
+		LOGE("boot modem fail!\n");
+
+	if( gotten_md_info == MD_DEBUG_REL_INFO_NOT_READY ){
+		if(0 == ioctl(fd, CCCI_IOC_GET_MD_INFO, &tmp)){
+			gotten_md_info = tmp;
+			if(gotten_md_info == MD_IS_DEBUG_VERSION)
+				LOGD("MD is debug version");
+			else if(gotten_md_info == MD_IS_RELEASE_VERSION)
+				LOGD("MD is release version");
+			else{
+				LOGD("MD version is not ready now");
+				gotten_md_info = MD_DEBUG_REL_INFO_NOT_READY;
+			}
+		}else{
+			LOGD("MD version is unknow: err=%d", errno);
+		}
+	}
+
+	system_ch_handle = fd;
+
+	MD_INIT_WAKE_UNLOCK();
+	/* block on reading CCCI_MONITOR device until a modem reset message is gotten */
+	do {
+		s = read(fd, (void *)&buff, sizeof(buff));
+		if (s<=0) {
+			if(s != -1) {
+				LOGE("read fail ret=%d\n", errno);
+			}
+			continue;
+		} else if (s!= sizeof(buff)) {
+			LOGE("read CCCI data with unexpected size: %d\n", (int)s);
+			continue;
+			//return -1;
+		}
+
+		MD_INIT_WAKE_LOCK();
+		
+		LOGD("buff.data[0] = 0x%08X, data[1] = 0x%08X, channel = %08X, reserved = 0x%08X\n",
+			buff.data[0], buff.data[1], buff.channel, buff.reserved);
+
+		if ( (buff.data[0] == 0xFFFFFFFF) && (buff.channel == monitor_ch) ) { /* Monitor channel message */
+			/* Check common message first */
+			if (common_msg_handler(buff.data[1], buff.reserved)) {
+				MD_INIT_WAKE_UNLOCK();
+				continue;
+			}
+
+			switch (buff.data[1]) {
+			case CCCI_MD_MSG_FORCE_STOP_REQUEST:
+				if (check_curret_md_status(CCCI_MD_STA_STOP))
+					break;
+				if (check_curret_md_status(CCCI_MD_STA_FLIGHT_MODE))
+					break;
+
+				delay_to_reset_md();
+				tmp = 0;
+				ret = ioctl(fd, CCCI_IOC_DO_STOP_MD, &tmp);
+				if (!is_meta_mode()) {
+					stop_all_ccci_up_layer_services();
+				}
+				set_current_md_status(CCCI_MD_STA_STOP);
+				break;
+			case CCCI_MD_MSG_FORCE_START_REQUEST:
+				if (check_curret_md_status(CCCI_MD_STA_BOOT_READY))
+					break;
+
+				trigger_modem_to_run(fd, 0, 0);
+				break;
+
+			case CCCI_MD_MSG_FLIGHT_STOP_REQUEST:
+				if (check_curret_md_status(CCCI_MD_STA_STOP))
+					break;
+				if (check_curret_md_status(CCCI_MD_STA_FLIGHT_MODE))
+					break;
+				set_current_md_status(CCCI_MD_STA_FLIGHT_MODE);
+
+				//RLOGI("MD%d enter flight mode\n", md_id+1);
+				tmp = 1;
+				ret = ioctl(fd, CCCI_IOC_DO_STOP_MD, &tmp);
+				break;
+			case CCCI_MD_MSG_FLIGHT_START_REQUEST:
+				if (check_curret_md_status(CCCI_MD_STA_BOOT_READY))
+					break;
+
+				//RLOGI("MD%d leave flight mode\n", md_id+1);
+				trigger_modem_to_run(fd, 1, 0);
+				break;
+
+			case CCCI_MD_MSG_RESET_REQUEST:
+				delay_to_reset_md();
+				tmp = 0;
+				ret = ioctl(fd, CCCI_IOC_DO_STOP_MD, &tmp);
+				if (!is_meta_mode())
+					stop_all_ccci_up_layer_services();
+				set_current_md_status(CCCI_MD_STA_STOP);
+
+				trigger_modem_to_run(fd, 0, 0);
+				break;
+
+			default:
+				LOGE("Invalid message, should not enter here!!!\n");
+				break;
+			}
+		} else { /* pattern not invalid */
+			LOGE("[Error]Invalid pattern, data[0]:%08x channel:%08x\n", buff.data[0], buff.channel);
+			MD_INIT_WAKE_UNLOCK();
+			continue;
+		}
+		MD_INIT_WAKE_UNLOCK();
+	} while (1);
+
+	system_ch_handle = 0;
+
+	return 0;
+}
+
+static int exit_signal = 0;
+void signal_treatment(int param)
+{
+	LOGD("signal number=%d\n", param);
+	if(param == SIGTERM) {
+	exit(EXIT_SUCCESS);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+    CCCI_VERSION ccci_version = ccci_get_version();
+
+	openlog("ccci_mdinit", LOG_PID, LOG_DAEMON);
+
+    printf("md_init Ver:v2.1, CCCI Ver:%d, ppid=%d, pid=%d\n", ccci_get_version(), getppid(), getpid());
+
+	LOGD("register signal hadler\n");
+	if(signal(SIGHUP, signal_treatment)==SIG_ERR)
+		LOGE("can't catch SIGHUP\n");
+	//if(signal(SIGKILL, signal_treatment)==SIG_ERR)
+		//LOGE("can't catch SIGKILL\n");
+	if(signal(SIGINT, signal_treatment)==SIG_ERR) /*^C == 2*/
+		LOGE("can't catch SIGINT\n");
+	if(signal(SIGUSR1, signal_treatment)==SIG_ERR)
+		LOGE("can't catch SIGUSR1\n");
+	if(signal(SIGUSR2, signal_treatment)==SIG_ERR)
+		LOGE("can't catch SIGUSR2\n");
+	if(signal(SIGTERM, signal_treatment)==SIG_ERR)
+		LOGE("can't catch SIGTERM\n");
+	if(signal(SIGALRM, signal_treatment)==SIG_ERR)
+		LOGE("can't catch SIGALRM\n");
+
+    if (ccci_version == ECCCI_FSM)
+    	main_v2(argc, argv);
+
+	closelog();
+}
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/platform/ccci_intf.h b/src/telephonyware/3.0/ccci_mdinit/src/platform/ccci_intf.h
new file mode 100644
index 0000000..552c32e
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/platform/ccci_intf.h
@@ -0,0 +1,93 @@
+#ifndef __CCCI_INTERFACE_H__
+#define __CCCI_INTERFACE_H__
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef enum {
+    MD_SYS1 = 0,
+    MD_SYS2 = 1,
+    MD_SYS3 = 2,
+    MD_SYS5 = 4,
+} CCCI_MD;
+
+typedef enum {
+    INVALID = 0,
+    CCCI,            /* for 6575/77 */
+    DUAL_CCCI,       /* for 6589/82/72/92/71/80 */
+    ECCCI,           /* for 6595 and later LTE projects */
+    EEMCS,           /* for 6582/92 LTE */
+    EDSDA,           /* for 6595 DSDA (emd_ctl) */
+    ECCCI_FSM,       /* ECCCI with FSM modification, since N0 kernel 3.18/4.4 */
+} CCCI_VERSION;
+
+typedef enum {
+    MD_BOOT_MODE_INVALID = 0,
+    MD_BOOT_MODE_NORMAL,
+    MD_BOOT_MODE_META,
+    MD_BOOT_MODE_MAX,
+} MD_BOOT_MODE;
+
+enum {
+    MD_STATE_INVALID = 0,
+    MD_STATE_BOOTING = 1,
+    MD_STATE_READY = 2,
+    MD_STATE_EXCEPTION = 3
+};
+
+#define USR_CCCI_MD1_CTRL_NAME        "/dev/ccci_monitor"
+#define USR_CCCI_MD3_CTRL_NAME        "/dev/ccci3_monitor"
+
+/**
+ * ccci_get_version - get version of CCCI driver
+ *
+ * RETURNS:
+ * see the defination of CCCI_VERSION
+ */
+static inline CCCI_VERSION ccci_get_version(void)
+{
+    int fd, ret;
+    char ver_str[2];
+    fd = open("/sys/kernel/ccci/version", O_RDONLY);
+    if (fd < 0)
+        return ECCCI;
+    ret = read(fd, ver_str, sizeof(ver_str));
+    close(fd);
+    if (ret < 1)
+        return INVALID;
+    return (CCCI_VERSION) (ver_str[0] - '0');
+}
+
+/************************************* IOCTL command set *************************************/
+#define CCCI_IOC_MAGIC 'C'
+#define CCCI_IOC_MD_RESET                _IO(CCCI_IOC_MAGIC,  0) /* mdlogger META/muxreport */
+#define CCCI_IOC_GET_MD_STATE            _IOR(CCCI_IOC_MAGIC, 1, unsigned int) /* audio */
+#define CCCI_IOC_GET_MD_INFO             _IOR(CCCI_IOC_MAGIC, 8, unsigned int) /* md_init */
+#define CCCI_IOC_DO_STOP_MD              _IO(CCCI_IOC_MAGIC,  12) /* md_init */
+#define CCCI_IOC_DO_START_MD             _IO(CCCI_IOC_MAGIC,  13) /* md_init */
+#define CCCI_IOC_SEND_BATTERY_INFO       _IO(CCCI_IOC_MAGIC,  21) /* md_init */
+#define CCCI_IOC_RELOAD_MD_TYPE          _IO(CCCI_IOC_MAGIC,  25)    /* META  md_init // muxreport */
+#define CCCI_IOC_SET_MD_IMG_EXIST        _IOW(CCCI_IOC_MAGIC, 29, unsigned int)    /* md_init */
+#define CCCI_IOC_GET_MD_IMG_EXIST        _IOR(CCCI_IOC_MAGIC, 30, unsigned int)    /* META */
+#define CCCI_IOC_GET_MD_TYPE             _IOR(CCCI_IOC_MAGIC, 31, unsigned int)    /* RILD */
+#define CCCI_IOC_STORE_MD_TYPE           _IOW(CCCI_IOC_MAGIC, 32, unsigned int)    /* RILD */
+#define CCCI_IOC_GET_MD_TYPE_SAVING      _IOR(CCCI_IOC_MAGIC, 33, unsigned int)    /* META */
+
+#define CCCI_IOC_SEND_SIGNAL_TO_USER     _IOW(CCCI_IOC_MAGIC, 43, unsigned int)    /* md_init */
+#define CCCI_IOC_IGNORE_MD_EXCP          _IO(CCCI_IOC_MAGIC,  44)                  /* RILD */
+#define CCCI_IOC_RESET_MD1_MD3_PCCIF     _IO(CCCI_IOC_MAGIC,  45)                  /* md_init */
+#define CCCI_IOC_RESET_AP                _IOW(CCCI_IOC_MAGIC, 46, unsigned int)    /* md_init */
+/* set MD boot env data before power on MD */
+#define CCCI_IOC_SET_BOOT_DATA           _IOW(CCCI_IOC_MAGIC, 47, unsigned int[16])
+
+#define CCCI_IOC_GET_MD_BOOT_MODE       _IOR(CCCI_IOC_MAGIC, 59, unsigned int) /* md_init */
+
+#define CCCI_IPC_MAGIC 'P'    /* only for IPC user */
+#define CCCI_IPC_UPDATE_TIME        _IO(CCCI_IPC_MAGIC,4)
+#define CCCI_IPC_WAIT_TIME_UPDATE   _IO(CCCI_IPC_MAGIC,5)
+#define CCCI_IPC_UPDATE_TIMEZONE    _IO(CCCI_IPC_MAGIC,6)
+
+#endif /*__CCCI_INTERFACE_H__    */
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/platform/power.h b/src/telephonyware/3.0/ccci_mdinit/src/platform/power.h
new file mode 100644
index 0000000..dc5a3f4
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/platform/power.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HARDWARE_POWER_H
+#define _HARDWARE_POWER_H
+
+#include <stdint.h>
+#ifdef CONFIG_MTK_BACH
+#include <signal.h>
+#endif
+
+#if __cplusplus
+extern "C" {
+#endif
+
+enum {
+    PARTIAL_WAKE_LOCK = 1,  // the cpu stays on, but the screen is off
+    FULL_WAKE_LOCK = 2      // the screen is also on
+};
+
+int acquire_wake_lock(int lock, const char* id);
+int release_wake_lock(const char* id);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HARDWARE_POWER_H
diff --git a/src/telephonyware/3.0/ccci_mdinit/src/time_clib_srv.c b/src/telephonyware/3.0/ccci_mdinit/src/time_clib_srv.c
new file mode 100644
index 0000000..a9d2bfa
--- /dev/null
+++ b/src/telephonyware/3.0/ccci_mdinit/src/time_clib_srv.c
@@ -0,0 +1,181 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2008
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER 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 BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'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 BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   time_clib_srv.c
+ *
+ * Project:
+ * --------
+ *  
+ *
+ * Description:
+ * ------------
+ *   
+ *
+ * Author:
+ * -------
+ *   
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifdef NEED_CTRL_AS_SP
+#include <cutils/properties.h>
+#include <android/log.h>
+#endif
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/time.h>
+#include "platform/ccci_intf.h"
+#include "ccci_mdinit_cfg.h"
+
+//extern int time_monitor_thd_quit;
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+static int ipc_fd;
+
+static int save_timezone(int tz)
+{
+	int fd;
+	int ret;
+  LOGD("save_timezone++\n");
+	fd = open(CCCI_TIMEZONE_FILE, O_CREAT | O_RDWR | O_TRUNC, 0600);
+	if(fd<0) {
+		LOGE("Open time zone setting fail:%d(%d)", fd, errno);
+		return -1;
+	}
+
+	//Update timezone info to file
+	ret = write(fd, &tz, sizeof(int));
+	if(ret != sizeof(int)) {
+		LOGE("Write time zone setting fail:%d(%d)", ret, errno);
+		close(fd);
+		return -2;
+	}
+
+	close(fd);
+	return 0;
+}
+
+int load_timezone(int *tz)
+{
+	int fd;
+	int ret;
+  LOGD("load_timezone++\n");
+	fd = open(CCCI_TIMEZONE_FILE, O_RDONLY, 0600);
+	if(fd<0) {
+		LOGE("Open time zone setting fail(R):%d(%d)", fd, errno);
+		return -1;
+	}
+
+	//Update timezone info to file
+	ret = read(fd, tz, sizeof(int));
+	if(ret != sizeof(int)) {
+		LOGE("Read time zone setting fail(R):%d(%d)", ret, errno);
+		close(fd);
+		return -2;
+	}
+
+	close(fd);
+	return 0;
+}
+
+int time_srv_init(void)
+{
+	struct timezone tz;
+	int    curr_tz;
+	LOGD("time_srv_init++\n");
+	ipc_fd = open(CCCI_TIME_UPDATE_PORT, O_RDWR);
+	if(ipc_fd<0) {
+		LOGE("Open ipc port %d fail", errno);
+		return -1;
+	}
+
+	if(load_timezone(&curr_tz) < 0) {
+		gettimeofday(NULL, &tz);
+		curr_tz = tz.tz_minuteswest;
+	}
+		
+	if(ioctl(ipc_fd, CCCI_IPC_UPDATE_TIMEZONE, curr_tz)<0) {
+		LOGE("Set default tz by ipc port fail(%d)", errno);
+		return -2;
+	}
+	return 0;
+}
+
+void* monitor_time_update_thread(void)
+{
+	struct timezone tz;
+	int    curr_tz;
+	LOGD("monitor_time_update_thread++\n");
+	if(load_timezone(&curr_tz) < 0) {
+		gettimeofday(NULL, &tz);
+		curr_tz = tz.tz_minuteswest;
+	}
+
+	LOGD("Umonitor_time_update_thread begin to run");
+
+	while(1) {
+		pthread_mutex_lock(&mtx);
+
+		if(ioctl(ipc_fd, CCCI_IPC_WAIT_TIME_UPDATE, 0)==0) {
+			gettimeofday(NULL, &tz);
+			if(curr_tz != tz.tz_minuteswest) {
+				curr_tz = tz.tz_minuteswest;
+				save_timezone(curr_tz);
+			}
+
+			if(ioctl(ipc_fd, CCCI_IPC_UPDATE_TIME, curr_tz)<0)
+				LOGE("Update time to md by ipc port fail(%d)", errno);
+		}
+		
+		pthread_mutex_unlock(&mtx);
+	}
+
+	close(ipc_fd);
+	return NULL;
+}
+