[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, ¤t_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, ¤t_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;
+}
+