// FIXME: your file license if you have one
#include "OplusProject.h"
#include <android-base/logging.h>
#include <cutils/properties.h>
#include <cinttypes>
#include <sys/types.h>
#include <sys/stat.h>
#include <cmath>
#include <fstream>
#include <log/log.h>
#include <hardware/hardware.h>
#include <iostream>
#include <utils/Errors.h>
#include <string.h>
namespace aidl {
namespace vendor {
namespace oplus {
namespace hardware {
namespace stability {
namespace oplus_project {
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/* param setup */
#define THEIA_NODE_ID_MONITOR_PARAM 1
/* stage porint report*/
#define THEIA_NODE_ID_POWERKEY_REPORT 2
/* cancel wakeup check */
#define THEIA_NODE_ID_BLACK_SWITCH 3
/* cancel sleep check */
#define THEIA_NODE_ID_BRIGHT_SWITCH 4
struct theiaNode {
int32_t index;
char path[128];
};
void convertVector2Array(std::vector<int32_t> in, char* out) {
int size = in.size();
for (int i = 0; i < size; i++) {
out[i] = in.at(i);
}
}
void convertArray2Vector_int32(const char* in, int len, std::vector<int32_t>& out) {
out.clear();
for(int i = 0; i < len; i++) {
out.push_back(in[i]);
}
}
struct theiaNode theiaNodeDataArray[] = {
{ THEIA_NODE_ID_MONITOR_PARAM, "/proc/pwkMonitorParam" },
{ THEIA_NODE_ID_POWERKEY_REPORT, "/proc/theiaPwkReport"},
{ THEIA_NODE_ID_BLACK_SWITCH, "/proc/blackSwitch" },
{ THEIA_NODE_ID_BRIGHT_SWITCH, "/proc/brightSwitch" },
};
static constexpr char PRJ_NAME_PATH[] = "/proc/oplusVersion/prjName";
static constexpr char PRJ_VERSION_PATH[] = "/proc/oplusVersion/prjVersion";
static constexpr char PCB_VERSION_PATH[] = "/proc/oplusVersion/pcbVersion";
static constexpr char OPT_NAME_PATH[] = "/proc/oplusVersion/operatorName";
static constexpr char RF_TYPE_PATH[] = "/proc/oplusVersion/RFType";
static constexpr char MODEM_TYPE_PATH[] = "/proc/oplusVersion/modemType";
static constexpr char SERIAL_ID_PATH[] = "/proc/oplusVersion/serialID";
static constexpr char ENG_VERSION_PATH[] = "/proc/oplusVersion/engVersion";
static constexpr char HUNGTASK_PATH[] = "/proc/sys/kernel/hung_task_kill";
static constexpr char FORCE_REBOOT[] = "/proc/force_reboot";
static constexpr char FTMMODE[] = "/sys/systeminfo/ftmmode";
static constexpr char MT_GPIO[] = "/sys/devices/platform/pinctrl/mt_gpio";
static constexpr char OP_BOOT[] = "/proc/opbootfrom";
static constexpr char OPLUSPOFF_REASON[] = "/sys/pmic_info/poff_reason";
static constexpr char OPLUSPON_REASON[] = "/sys/pmic_info/pon_reason";
static constexpr char OPLUSOCP_STATUS[] = "/sys/pmic_info/ocp_status";
static constexpr char PHOENIX[] = "/proc/phoenix";
static constexpr char SHUTDOWN_DETECT[] = "/proc/shutdown_detect";
static constexpr char POFF_REASON[] = "/sys/power/poff_reason";
static constexpr char PON_REASON[] = "/sys/power/pon_reason";
static constexpr char OCP_REASON[] = "/proc/oplusVersion/ocp";
static constexpr char SAUPWK[] = "/proc/sau_pwknum";
static constexpr char PROC_UFS[] = "/proc/devinfo/ufs";
static constexpr char LINKED_MODULES_PATH[] = "/proc/modules";
static constexpr char MODULES_TO_LOAD_PATH[] = "/vendor/lib/modules/modules.load";
static constexpr char MODULES_BLOCKLIST_PATH[] = "/vendor/lib/modules/modules.blocklist";
static constexpr char MTK_PMIC_MONITOR[] = "/sys/pmic_info/pmic_monitor";
/*Tongyang.Xu@TECH.BSP.Stability add for dram freq show begin*/
static constexpr char QCOM_DRAM_FREQ[] = "/sys/devices/system/cpu/bus_dcvs/DDR/available_frequencies";
static constexpr char MTK_DRAM_FREQ[] = "/sys/kernel/helio-dvfsrc/dvfsrc_opp_table";
/*Tongyang.Xu@TECH.BSP.Stability add for dram freq show end*/
OplusProject::OplusProject() {
ALOGD("OplusProject start");
}
int readInterface(const char *path, int offset, void *buf, int len)
{
int fd = -1;
int ret = -1;
int size = -1;
fd = open(path, O_RDONLY);
if (fd == -1) {
ALOGD("open %s failed! err:%s", path, strerror(errno));
return ret;
}
size = lseek(fd, offset, SEEK_SET);
if (size == -1){
ALOGD("read failed! size:%d", size);
goto end;
}
size = read(fd, buf, len);
if (size == -1){
ALOGD("read no content! size:%d", size);
goto end;
}
ret = size;
end:
if (fd != -1)
close(fd);
return ret;
}
int writeInterface(const char *path, int offset, const char *buf, int len)
{
int fd = -1;
int ret = -1;
int size = -1;
fd = open(path, O_WRONLY);
if (fd == -1) {
ALOGD("open %s failed! err:%s", path, strerror(errno));
return ret;
}
size = lseek(fd, offset, SEEK_SET);
if (size == -1){
ALOGD("lseek failed! size:%d", size);
goto end;
}
size = write(fd, buf, len);
if (size == -1){
ALOGD("write failed! size:%d", size);
goto end;
}
ALOGD("write %d bytes", size);
ret = size;
fsync(fd);
end:
if (fd != -1)
close(fd);
return ret;
}
uint32_t OplusProject::get_int(std::string path){
uint32_t data = 0;
mStability.open(path,std::ios::in);
if(!mStability) {
ALOGE("[OplusProject][%s] get_int: open file %s failed!",__FUNCTION__, path.c_str());
return -1;
}
mStability >> data;
mStability.close();
return data;
}
std::string OplusProject::get_string(std::string path){
std::string data,tmp;
mStability.open(path,std::ios::in);
if(!mStability) {
ALOGE("[OplusProject][%s] get_string: open file %s failed!",__FUNCTION__, path.c_str());
return "NULL"; /* Avoid strlen error */
}
do{
mStability >> tmp;
data += tmp + '\n';
}while(!mStability.eof());
mStability.close();
return data;
}
::ndk::ScopedAStatus OplusProject::get_project(int32_t* _aidl_return) {
uint32_t prjName;
mProject.open(PRJ_NAME_PATH, std::ios::in);
if(!mProject) {
mProject.open(PRJ_VERSION_PATH, std::ios::in);
if(!mProject) {
ALOGE("open file %s and %s failed!", PRJ_NAME_PATH, PRJ_VERSION_PATH);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
}
mProject >> prjName;
mProject.close();
*_aidl_return = prjName;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_pcb_version(int32_t* _aidl_return) {
int32_t pcbversion;
mPcb.open(PCB_VERSION_PATH, std::ios::in);
if(!mPcb) {
ALOGE("open file %s failed!", PCB_VERSION_PATH);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
mPcb >> pcbversion;
mPcb.close();
*_aidl_return = pcbversion;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_serial_ID(std::string* _aidl_return) {
std::string serialID = " ";
mSerial.open(SERIAL_ID_PATH, std::ios::in);
if(!mSerial) {
ALOGE("open file %s failed!", SERIAL_ID_PATH);
*_aidl_return = serialID;
return ndk::ScopedAStatus::ok();
}
mSerial >> serialID;
mSerial.close();
*_aidl_return = serialID;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_operator_name(int32_t* _aidl_return) {
int32_t optname;
mOptname.open(OPT_NAME_PATH, std::ios::in);
if(!mOptname) {
ALOGE("open file %s failed!", OPT_NAME_PATH);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
mOptname >> optname;
mOptname.close();
*_aidl_return = optname;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_rf_type(int32_t* _aidl_return) {
int32_t rftype;
mRf.open(RF_TYPE_PATH, std::ios::in);
if(!mRf) {
mRf.open(MODEM_TYPE_PATH, std::ios::in);
if(!mRf) {
ALOGE("open file %s and %s failed!", RF_TYPE_PATH, MODEM_TYPE_PATH);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
}
mRf >> rftype;
mRf.close();
*_aidl_return = rftype;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_eng_version(int32_t* _aidl_return) {
int32_t engversion;
mEng.open(ENG_VERSION_PATH, std::ios::in);
if(!mEng) {
ALOGE("open file %s failed!", ENG_VERSION_PATH);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
mEng >> engversion;
mEng.close();
*_aidl_return = engversion;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_hungtask(std::string* _aidl_return) {
std::string hungtask = "no_task";
mStability.open(HUNGTASK_PATH, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", HUNGTASK_PATH);
*_aidl_return = hungtask;
return ndk::ScopedAStatus::ok();
}
mStability >> hungtask;
mStability.close();
*_aidl_return = hungtask;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_force_reboot(std::string* _aidl_return) {
std::string forcereboot = "null";
mStability.open(FORCE_REBOOT, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", FORCE_REBOOT);
*_aidl_return = forcereboot;
return ndk::ScopedAStatus::ok();
}
mStability >> forcereboot;
mStability.close();
*_aidl_return = forcereboot;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_ftmmode(int32_t* _aidl_return) {
uint32_t ftm = 0;
mStability.open(FTMMODE, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", FTMMODE);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
mStability >> ftm;
mStability.close();
*_aidl_return = ftm;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_mt_gpio(std::string* _aidl_return) {
std::string gpio = "null";
mStability.open(MT_GPIO, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", MT_GPIO);
*_aidl_return = gpio;
return ndk::ScopedAStatus::ok();
}
mStability >> gpio;
mStability.close();
*_aidl_return = gpio;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_opboot(std::string* _aidl_return) {
std::string opboot = " ";
mStability.open(OP_BOOT, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", OP_BOOT);
*_aidl_return = opboot;
return ndk::ScopedAStatus::ok();
}
mStability >> opboot;
mStability.close();
*_aidl_return = opboot;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::set_opboot(const std::string& opboot, bool* _aidl_return) {
int32_t count = 0;
count = writeInterface(OP_BOOT, 0, (char *)opboot.c_str(), (int)strlen(opboot.c_str()));
ALOGD("write_shd_proc path:%s ,%s", SHUTDOWN_DETECT, opboot.c_str());
if (count == strlen(opboot.c_str())) {
*_aidl_return = true;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
std::string OplusProject::read_line_by_pmic_id(int32_t pmic_id, std::string path) {
std::string data;
if(pmic_id < 0 || pmic_id > 7) {
ALOGE("pmic_id is illegal values:%d", pmic_id);
return "NULL";
}
mPmicNode.open(path,std::ios::in);
if(!mPmicNode) {
ALOGE("Open pmic node failed:%s",path.c_str());
return "NULL";
}
std::string tmp;
while (getline(mPmicNode,tmp)){
//PMIC|0|......
std::string tmppmicid=tmp.substr(5,1);
if (atoi(tmppmicid.c_str()) == pmic_id) {
data = tmp;
mPmicNode.close();
//ALOGE("Read pmic node%s:%s",path.c_str(),data.c_str());
return data;
}
tmp = "";
}
mPmicNode.close();
return "NULL";
}
std::string OplusProject::read_line_for_mtk_pmicmonitor(std::string path) {
std::string data;
mPmicNode.open(path,std::ios::in);
if(!mPmicNode) {
ALOGE("Open pmic node failed:%s",path.c_str());
return "NULL";
}
std::string tmp;
while (getline(mPmicNode,tmp)){
//PMIC|0|......
data=data+tmp+"\n";
/*
std::string tmppmicid=tmp.substr(5,1);
if (atoi(tmppmicid.c_str()) == pmic_id) {
data = tmp;
mPmicNode.close();
//ALOGE("Read pmic node%s:%s",path.c_str(),data.c_str());
return data;
}
*/
tmp = "";
}
mPmicNode.close();
return data;
}
::ndk::ScopedAStatus OplusProject::get_pmic_info(std::string* _aidl_return) {
std::string oplus_mtk_pmic_monitor = " ";
oplus_mtk_pmic_monitor = read_line_for_mtk_pmicmonitor(MTK_PMIC_MONITOR);
if(!strcmp("NULL", oplus_mtk_pmic_monitor.c_str())) {
ALOGE("open file %s failed!", MTK_PMIC_MONITOR);
*_aidl_return = oplus_mtk_pmic_monitor;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = oplus_mtk_pmic_monitor;
return ndk::ScopedAStatus::ok();
}
/*Tongyang.Xu@TECH.BSP.Stability add for dram freq show begin*/
std::string OplusProject::read_line_for_dram_freq(std::string path) {
std::string data;
mDramFreqNode.open(path,std::ios::in);
if(!mDramFreqNode) {
ALOGE("Open dram freq node failed:%s",path.c_str());
return "NULL";
}
std::string tmp;
while (getline(mDramFreqNode,tmp)){
data=data+tmp+"\n";
ALOGE("Read dram freq%s:%s",path.c_str(),data.c_str());
tmp = "";
}
mDramFreqNode.close();
return data;
}
::ndk::ScopedAStatus OplusProject::get_dram_freq(std::string* _aidl_return) {
std::string dram_freq = " ";
#ifdef QCOM_PLATFORM_SUPPORT
dram_freq = read_line_for_dram_freq(QCOM_DRAM_FREQ);
#else // MTK_PLATFORM
dram_freq = read_line_for_dram_freq(MTK_DRAM_FREQ);
#endif
if(!strcmp("NULL", dram_freq.c_str())) {
#ifdef QCOM_PLATFORM_SUPPORT
ALOGE("open file %s failed!", QCOM_DRAM_FREQ);
#else// MTK_PLATFORM
ALOGE("open file %s failed!", MTK_DRAM_FREQ);
#endif
*_aidl_return = dram_freq;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = dram_freq;
return ndk::ScopedAStatus::ok();
}
/*Tongyang.Xu@TECH.BSP.Stability add for dram freq show end*/
::ndk::ScopedAStatus OplusProject::get_opluspoff_reason(int32_t pmic_id, std::string* _aidl_return) {
std::string opluspoff = " ";
opluspoff = read_line_by_pmic_id(pmic_id,OPLUSPOFF_REASON);
if(!strcmp("NULL", opluspoff.c_str())) {
ALOGE("open file %s failed!", OPLUSPOFF_REASON);
*_aidl_return = opluspoff;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = opluspoff;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_opluspon_reason(int32_t pmic_id, std::string* _aidl_return) {
std::string opluspon = " ";
opluspon = read_line_by_pmic_id(pmic_id,OPLUSPON_REASON);
if(!strcmp("NULL", opluspon.c_str())) {
ALOGE("open file %s failed!", OPLUSPON_REASON);
*_aidl_return = opluspon;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = opluspon;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_oplusocp_status(int32_t pmic_id, std::string* _aidl_return) {
std::string ocp_status = " ";
ocp_status = read_line_by_pmic_id(pmic_id,OPLUSOCP_STATUS);
if(!strcmp("NULL", ocp_status.c_str())) {
ALOGE("open file %s failed!", OPLUSOCP_STATUS);
*_aidl_return = ocp_status;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = ocp_status;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_phoenix(std::string* _aidl_return) {
std::string phoenix = " ";
phoenix = get_string(PHOENIX);
if(!strcmp("NULL", phoenix.c_str())) {
ALOGE("open file %s failed!", PHOENIX);
*_aidl_return = phoenix;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = phoenix;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::set_phoenix(const std::string& monitoting_command, bool* _aidl_return) {
int32_t count = 0;
count = writeInterface(PHOENIX, 0, (char *)monitoting_command.c_str(), (int)strlen(monitoting_command.c_str()));
ALOGD("write_phoenix_proc path:%s ,%s", PHOENIX, monitoting_command.c_str());
if (count == strlen(monitoting_command.c_str())) {
*_aidl_return = true;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
::ndk::ScopedAStatus OplusProject::get_shutdown_detect(std::string* _aidl_return) {
std::string shutdown = " ";
shutdown = get_string(SHUTDOWN_DETECT);
if(!strcmp("NULL", shutdown.c_str())) {
ALOGE("open file %s failed!", SHUTDOWN_DETECT);
*_aidl_return = shutdown;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = shutdown;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::set_shutdown_detect(const std::string& shutdown_detect_vaule, bool* _aidl_return) {
int32_t count = 0;
count = writeInterface(SHUTDOWN_DETECT, 0, (char *)shutdown_detect_vaule.c_str(), (int)strlen(shutdown_detect_vaule.c_str()));
ALOGD("write_shd_proc path:%s ,%s", SHUTDOWN_DETECT, shutdown_detect_vaule.c_str());
if (count == strlen(shutdown_detect_vaule.c_str())) {
*_aidl_return = true;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
::ndk::ScopedAStatus OplusProject::get_poff_reason(std::string* _aidl_return) {
std::string poff = " ";
poff = get_string(POFF_REASON);
if(!strcmp("NULL", poff.c_str())) {
ALOGE("open file %s failed!", POFF_REASON);
*_aidl_return = poff;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = poff;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_pon_reason(std::string* _aidl_return) {
std::string pon = " ";
pon = get_string(PON_REASON);
if(!strcmp("NULL", pon.c_str())) {
ALOGE("open file %s failed!", PON_REASON);
*_aidl_return = pon;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = pon;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_ocp(std::string* _aidl_return) {
std::string ocp = " ";
ocp = get_string(OCP_REASON);
if(!strcmp("NULL", ocp.c_str())) {
ALOGE("open file %s failed!", OCP_REASON);
*_aidl_return = ocp;
return ndk::ScopedAStatus::ok();
}
*_aidl_return = ocp;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::get_sau(int32_t* _aidl_return) {
uint32_t sau = 0;
mStability.open(SAUPWK, std::ios::in);
if(!mStability) {
ALOGE("open file %s failed!", SAUPWK);
*_aidl_return = -1;
return ndk::ScopedAStatus::ok();
}
mStability >> sau;
mStability.close();
*_aidl_return = sau;
return ndk::ScopedAStatus::ok();
}
char* get_theia_node_path(int32_t theia_node_id) {
for (int i = 0; i < ARRAY_SIZE(theiaNodeDataArray); i++) {
if (theia_node_id == theiaNodeDataArray[i].index) {
return theiaNodeDataArray[i].path;
}
}
return NULL;
}
::ndk::ScopedAStatus OplusProject::is_ufs_devices (bool* _aidl_return) {
bool result = (!access(PROC_UFS, F_OK) ? true : false);
ALOGD("OplusProject is_ufs_devices:%s", result?"true":"false");
if (true == result) {
*_aidl_return = result;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
::ndk::ScopedAStatus OplusProject::read_theia_node(int32_t theia_node_id, std::string* _aidl_return) {
int len = 256;
char theia_data[len];
std::string data;
int ret_size = 0;
char* path = get_theia_node_path(theia_node_id);
if (path == NULL) {
ALOGD("read_theia_node, get path fail! theia_node_id:%d", theia_node_id);
*_aidl_return = {};
return ndk::ScopedAStatus::ok();
}
memset(theia_data, 0, len);
ret_size = readInterface(path, 0, theia_data, len);
if (ret_size == -1 ) {
ALOGD("read_theia_node, readInterface fail!");
*_aidl_return = {};
return ndk::ScopedAStatus::ok();
}
theia_data[ret_size] = '\0';
data = theia_data;
*_aidl_return = data;
ALOGD("read_theia_proc path:%s ,theia_date:%s", path, theia_data);
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::write_theia_node(int32_t theia_node_id, const std::string& theia_data, bool* _aidl_return) {
bool result = false;
int32_t count = 0;
char* path = get_theia_node_path(theia_node_id);
if (path == NULL) {
ALOGD("write_theia_node, get path fail! theia_node_id:%d", theia_node_id);
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
count = writeInterface(path, 0, (char *)theia_data.c_str(), (int)strlen(theia_data.c_str()));
ALOGD("write_theia_proc path:%s ,theia_date:%s", path, theia_data.c_str());
if (count == strlen(theia_data.c_str())) {
*_aidl_return = true;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
//Hong.Zhang@TECH.BSP.Stability.Aging2.0, 2020/07/17, Add for aging 2.0
#ifdef QCOM_PLATFORM_SUPPORT
static uint64 get_partition_size(const char *part_path) {
FILE *fp = NULL;
uint64 part_size = 0;
fp = fopen(part_path, "r");
if (fp == NULL) {
ALOGE("open file %s failed", part_path);
goto out;
}
fseek(fp, 0L, SEEK_END);
part_size = ftell(fp);
fclose(fp);
out:
return part_size;
}
static uint64 getAgingDataTypeStartOffset(const char *part_path, aging_data_type d_type) {
uint64 offset = 0;
uint64 p_size = 0;
aging_partition_type p_type = DDR;
if (part_path == NULL) {
ALOGE("getAgingDataTypeStartOffset:Invaild Parameters, exit\n");
goto out;
}
p_size = get_partition_size(part_path);
if (!strncmp(part_path, OPLUS_RESERVE1_PATH, strlen(OPLUS_RESERVE1_PATH))) {
p_type = AGING_RESERVERD;
}
switch (p_type) {
case DDR:
if (p_size <= AGING_INFO_OR_LOG_SAVE_RESERVED_SIZE) {
ALOGE("Partition size[0x%llx] for data type[%d] is too small, but reserved from 0x%x is overflow\n", \
p_size, d_type, AGING_INFO_OR_LOG_SAVE_RESERVED_SIZE);
break;
}
if (d_type == BOOT_CONTROL_INFO) {
offset = p_size - BOOT_CONTROL_HEADER_START_BOTTOM_OFFSET;
} else if (d_type == DUMP_LOG) {
if (DUMP_INFO_START_BOTTOM_OFFSET > 0x0) {
offset = p_size - DUMP_INFO_START_BOTTOM_OFFSET;
} else {
ALOGE("Partition size[0x%llx] for data type[%d] is too small, but reserved from 0x%lx is overflow\n", \
p_size, d_type, DUMP_INFO_START_BOTTOM_OFFSET);
}
} else if (d_type == APP_INFO) {
if (AGING_APP_INFO_START_BOTTOM_OFFSET > 0x0) {
offset = p_size - AGING_APP_INFO_START_BOTTOM_OFFSET;
} else {
ALOGE("Partition size[0x%llx] for data type[%d] is too small, but reserved from 0x%lx is overflow\n", \
p_size, d_type, AGING_APP_INFO_START_BOTTOM_OFFSET);
}
}
break;
case AGING_RESERVERD:
if (d_type == BOOT_CONTROL_INFO) {
//do nothing now, reserved for future use;
} else if (d_type == APP_INFO) {
//do nothing now, reserved for future use;
}
break;
default:
ALOGD("Other partition type[%d], use the default offset\n", p_type);
break;
}
ALOGD("getAgingDataTypeStartOffset: part size: 0x%llx,offset[type %d]:0x%llx\n",p_size, d_type, offset);
out:
return offset;
}
static char getCurrentDumpCount() {
int count = 0;
char info = 0x0;
char info_return[2] = {0};
int readLen=sizeof(char);
int info_i = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, dump_reason_count);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, &info, readLen);
//recorrect the current dump log location;
if (count == readLen) {
info_i = atoi(&info);
info_i = (info_i + MAX_DUMP_AGING_RECORD - 1) % MAX_SBL_LOG_RECORD;
}
snprintf(info_return, sizeof(info_return), "%d", info_i);
info = info_return[0];
return info;
}
static int getCurrDumpInfo(char* info) {
char currDumpPos = getCurrentDumpCount();
int count = 0;
int currDumpLen = 0x0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, DUMP_LOG);
offset += currDumpPos*MAX_AGING_DUMP_INFO_TOTAL_LENGTH;
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, MAX_AGING_DUMP_INFO_TOTAL_LENGTH);
*(info + MAX_AGING_DUMP_INFO_TOTAL_LENGTH) = '\0';
if (count == MAX_AGING_DUMP_INFO_TOTAL_LENGTH
&& !strncmp(info, VALID_STR, DUMP_INFO_VALID_PREFIX_LEN)) {
currDumpLen = strlen(info);
}
return currDumpLen;
}
/* Control info */
std::vector<int32_t> readAgingtestControlInfo() {
char* info = new char[BOOT_CONTROL_FULL_HEADER_ROUND_SIZE];
memset(info, 0, BOOT_CONTROL_FULL_HEADER_ROUND_SIZE);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, BOOT_CONTROL_FULL_HEADER_ROUND_SIZE);
ALOGD("readAgingtestControlInfo read full control info, count:%d, path:%s", count, DEFAULT_CONTROL_INFO_PART_PATH);
std::vector<int32_t> tmp(BOOT_CONTROL_FULL_HEADER_ROUND_SIZE);
if (count == BOOT_CONTROL_FULL_HEADER_ROUND_SIZE) {
convertArray2Vector_int32(info, BOOT_CONTROL_FULL_HEADER_ROUND_SIZE, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestControlInfo(char* data, uint32_t length) {
int count = 0;
if (length != BOOT_CONTROL_FULL_HEADER_ROUND_SIZE) {
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, length);
ALOGD("readAgingtestControlInfo save full control info, count:%d, path:%s", count, DEFAULT_CONTROL_INFO_PART_PATH);
}
return count > 0;
}
/* memtest support info */
std::vector<int32_t> readAgingtestMemtestSupportInfo() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, mem_test_support);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
/* aginginfo magic */
std::vector<int32_t> readAgingtestMagicInfo() {
int readLen = sizeof(uint8);
char* tempInfo = new char[MAGIC_LENGTH];
char* info = new char[readLen];
memset(tempInfo, 0, MAGIC_LENGTH);
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, magic);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, tempInfo, MAGIC_LENGTH);
ALOGD("readAgingtestMagicInfo read CON_INFO info, count:%d", count);
std::vector<int32_t> tmp(readLen);
if (count == MAGIC_LENGTH) {
if (!strncmp(tempInfo, "CON_INFO", MAGIC_LENGTH)) {
info[0]=0x1;
}
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
delete []tempInfo;
return tmp;
}
bool saveAgingtestMagicInfo(char* data, uint32_t length) { //data[0] is old control info state;
int count = 0;
if (length != sizeof(uint8) || (*data == 0x1) || ((*data != 0x0) && (*data != 0x1))) { //aging test control info is set, don't set again
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
int writeLen = sizeof(boot_control_and_result_info);
char* info = new char[writeLen];
memset(info, 0, writeLen);
//Initialization magic info;
strncpy(info,"CON_INFO",MAGIC_LENGTH);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, writeLen);
ALOGD("saveAgingtestMagicInfo Reintialize control&result structure, count:%d", count);
delete []info;
}
return count > 0;
}
/* agingtest flag */
std::vector<int32_t> readAgingtestFlagInfo() {
char* info = new char[MAGIC_LENGTH];
memset(info, 0, MAGIC_LENGTH);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, aging_running);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, MAGIC_LENGTH);
ALOGD("readAgingtestFlagInfo read agingtest flag, count:%d", count);
std::vector<int32_t> tmp(MAGIC_LENGTH);
if (count == MAGIC_LENGTH) {
convertArray2Vector_int32(info, MAGIC_LENGTH, tmp);
}
delete []info;
return tmp;
}
bool saveOrClearAgingtestFlagInfo(char* data, uint32_t length) {
int count = 0;
bool clear = 0;
if ((length == 1) && (*data == 1)) {
clear = 1;
} else if (length != MAGIC_LENGTH) {
return 0;
}
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, aging_running);
if (clear == 1) {
char* info = new char[MAGIC_LENGTH];
memset(info, 0, MAGIC_LENGTH);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, MAGIC_LENGTH);
ALOGD("saveOrClearAgingtestFlagInfo: clear agingtest flag, count:%d", count);
delete []info;
} else {
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, length);
ALOGD("saveOrClearAgingtestFlagInfo: save agingtest flag, count:%d", count);
}
return count > 0;
}
/* memtest enable flag */
std::vector<int32_t> readAgingtestMemtestEnableFlag() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, mem_test_enable);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestMemtestEnableFlag enable flag:0x%x", info[0]);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestMemtestEnableFlag(char* data, uint32_t length) {
int count = 0;
if (length != sizeof(uint8)) {
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, mem_test_enable);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, length);
ALOGD("saveAgingtestMemtestEnableFlag offset:0x%llx, enable flag:0x%x", offset, *data);
}
return count > 0;
}
/* stage info */
std::vector<int32_t> readAgingtestStageInfo() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, stage);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestStageInfo stage:%d", info[0]);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool clearAgingtestStageInfo(char* data, uint32_t length) {
int count = 0;
if (length != sizeof(uint8)) {
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, stage);
*data = 0x0; //always set to 0;
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, length);
ALOGD("clearAgingtestStageInfo count=%d, length:%d, offset:0x%llx", count, length, offset);
}
return count > 0;
}
/* memtest result info */
std::vector<int32_t> readAgingtestMemtestResultInfo() {
int startBit = offsetof(boot_control_and_result_info, mem_test_sbl_result);
int endBit = offsetof(boot_control_and_result_info, mem_test_flash_result);
int readLen = (endBit - startBit + 1);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += startBit;
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestMemtestResultInfo count=%d, readLen:%d", count, readLen);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool clearAgingtestMemtestResultInfo(char* data, uint32_t length) {
int count = 0;
if ((length != 1) || (*data != 1)) {
return 0;
}
int startBit = offsetof(boot_control_and_result_info, mem_test_sbl_result);
int endBit = offsetof(boot_control_and_result_info, mem_test_flash_result);
int readLen = (endBit - startBit + 1);
char* info = new char[readLen];
memset(info, 0, readLen);
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += startBit;
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("clearAgingtestMemtestResultInfo: clear count=%d", count);
delete []info;
return count > 0;
}
/* dump count info */
std::vector<int32_t> readAgingtestDumpCountInfo() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
info[0] = getCurrentDumpCount();
std::vector<int32_t> tmp(readLen);
convertArray2Vector_int32(info, readLen, tmp);
delete []info;
return tmp;
}
/* boot abnormal info */
std::vector<int32_t> readAgingtestBootAbnormalInfo() {
const int readLen = sizeof(boot_abnormal_info);
char* info = new char[readLen];
char* infoData = new char[AGING_MAX_ERR_TYPE * 2];
int bootFatalIndex = 0;
int i = 0;
boot_abnormal_info *boot_fatal_info = NULL;
int count = 0;
memset(info, 0, readLen);
memset(infoData, 0, (AGING_MAX_ERR_TYPE * 2));
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, b_abnormal_info);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
if ((count > 0) && (count <= sizeof(boot_abnormal_info)) && (count == readLen)) {
boot_fatal_info = (boot_abnormal_info *)info;
if (boot_fatal_info->fatal_err_flag & (1ULL << boot_fatal_info->last_err_type)) {
//Set the latest err type;
infoData[bootFatalIndex] = boot_fatal_info->last_err_type;
bootFatalIndex++;
infoData[bootFatalIndex] = boot_fatal_info->err_count[boot_fatal_info->last_err_type];
bootFatalIndex++;
for(i = 0; i < AGING_MAX_ERR_TYPE; i++) {
if (i == boot_fatal_info->last_err_type) {
continue;
} else if ( boot_fatal_info->fatal_err_flag & (1ULL << i)) {
infoData[bootFatalIndex] = i;
bootFatalIndex++;
infoData[bootFatalIndex] = boot_fatal_info->err_count[i];
bootFatalIndex++;
}
}
} else {
ALOGD("readAgingtestBootAbnormalInfo: No boot abnormal info");
}
}
if (bootFatalIndex == 0)
bootFatalIndex++; // if no fatal error return one byte data
std::vector<int32_t> tmp(bootFatalIndex);
convertArray2Vector_int32(infoData, bootFatalIndex, tmp);
delete []info;
delete []infoData;
return tmp;
}
bool clearAgingtestBootAbnormalInfo(char* data, uint32_t length) {
int count = 0;
if ((length != 1) || (*data != 0)) {
return 0;
}
int readLen = sizeof(boot_abnormal_info);
char* info = new char[readLen];
memset(info, 0, readLen);
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, BOOT_CONTROL_INFO);
offset += offsetof(boot_control_and_result_info, b_abnormal_info);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("clearAgingtestBootAbnormalInfo: clear count=%d", count);
delete []info;
return count > 0;
}
/* dump info */
std::vector<int32_t> readAgingtestCurrDumpInfo() {
char* info = new char[MAX_AGING_DUMP_INFO_TOTAL_LENGTH];
memset(info, 0, MAX_AGING_DUMP_INFO_TOTAL_LENGTH);
int currDumpLen = getCurrDumpInfo(info);
ALOGD("readAgingtestCurrDumpInfo: curr dump len=%d", currDumpLen);
std::vector<int32_t> tmp(currDumpLen);
if (currDumpLen > 0) {
convertArray2Vector_int32(info, currDumpLen, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestCurrDumpVersionInfo(char* data, uint32_t length) {
int count = 0;
char* info = new char[MAX_AGING_DUMP_INFO_TOTAL_LENGTH];
int writeLen = length;
char currDumpPos = getCurrentDumpCount();
memset(info, 0, MAX_AGING_DUMP_INFO_TOTAL_LENGTH);
int currDumpLen = getCurrDumpInfo(info);
if (strstr(info, DUMP_VERSION_STR)) {
//version have updated, return directly
delete []info;
return 1;
}
delete []info;
if (length > (MAX_AGING_DUMP_INFO_TOTAL_LENGTH - currDumpLen - DUMP_VERSION_PREFIX_LEN))
writeLen = (MAX_AGING_DUMP_INFO_TOTAL_LENGTH - currDumpLen - DUMP_VERSION_PREFIX_LEN);
if (currDumpLen > 0 ) {
uint32 offset = (uint32)getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, DUMP_LOG);
if ((MAX_AGING_DUMP_INFO_TOTAL_LENGTH > UINT_MAX / currDumpPos) && (currDumpLen > UINT_MAX - (currDumpPos * MAX_AGING_DUMP_INFO_TOTAL_LENGTH))) {
offset += (currDumpPos * MAX_AGING_DUMP_INFO_TOTAL_LENGTH + currDumpLen);
} else {
return false;
}
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, DUMP_VERSION_STR, DUMP_VERSION_PREFIX_LEN);
if (offset > UINT_MAX - DUMP_VERSION_PREFIX_LEN) {
offset += DUMP_VERSION_PREFIX_LEN;
} else {
return false;
}
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, writeLen);
}
return count > 0;
}
/* full dump format
<count> \n //2 byte
<record 1> \n
<record 2> \n
.........
*/
std::vector<int32_t> readAgingtestFullDumpInfo() {
char* info = new char[MAX_AGING_DUMP_INFO_FULL_LENGTH];
char* targetInfo = NULL;
int tmpLen = 0;
int recordLen = 0;
char currDumpPos = getCurrentDumpCount();
int dumpCount = 0;
int count = 0;
memset(info, 0, MAX_AGING_DUMP_INFO_FULL_LENGTH);
uint64 baseOffset=getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, DUMP_LOG);
uint64 offset = baseOffset + currDumpPos*MAX_AGING_DUMP_INFO_TOTAL_LENGTH;
targetInfo = (info + 2);
for (int i=0; i < MAX_DUMP_AGING_RECORD; i++) {
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, targetInfo, MAX_AGING_DUMP_INFO_TOTAL_LENGTH);
if (count == MAX_AGING_DUMP_INFO_TOTAL_LENGTH ) {
if (!strncmp(targetInfo, VALID_STR, DUMP_INFO_VALID_PREFIX_LEN)) {
dumpCount+=1;
*(targetInfo + MAX_AGING_DUMP_INFO_TOTAL_LENGTH) = '\0';
recordLen = strlen(targetInfo);
targetInfo+=recordLen;
*(targetInfo) = '\n';
targetInfo++;
} else {
break; // no more dump, break;
}
}
currDumpPos = (currDumpPos + MAX_DUMP_AGING_RECORD -1) % MAX_DUMP_AGING_RECORD;
offset = baseOffset + currDumpPos*MAX_AGING_DUMP_INFO_TOTAL_LENGTH;
}
if (dumpCount <= 9) {
info[0] = '0' + dumpCount;
}
info[1] = '\n';
tmpLen = (targetInfo - info);
ALOGD("readAgingtestFullDumpInfo tmpLen=%d, dumpCount:%d", tmpLen, dumpCount);
std::vector<int32_t> tmp(tmpLen);
convertArray2Vector_int32(info, tmpLen, tmp);
delete []info;
return tmp;
}
/* app info */
std::vector<int32_t> readAgingtestAppInfo() {
int readLen = sizeof(app_aging_info);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestAppInfo count=%d, offset=0x%llx", count, offset);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestAppInfo(char* data, uint32_t length) {
int count = 0;
if (length != sizeof(app_aging_info)) {
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, data, length);
ALOGD("saveAgingtestAppInfo offset:0x%llx, length:%d", offset, length);
}
return count > 0;
}
/* app magic info */
std::vector<int32_t> readAgingtestAppMagicInfo() {
int readLen = sizeof(uint8);
char* tempInfo = new char[MAGIC_LENGTH];
char* info = new char[readLen];
memset(tempInfo, 0, MAGIC_LENGTH);
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, magic);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, tempInfo, MAGIC_LENGTH);
std::vector<int32_t> tmp(readLen);
if (count == MAGIC_LENGTH) {
if (!strncmp(tempInfo, "AGE_TEST", MAGIC_LENGTH)) {
info[0]=0x1;
}
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
delete []tempInfo;
return tmp;
}
bool saveAgingtestAppMagicInfo(char* data, uint32_t length) { //data[0] is old app magic flag state;
int count = 0;
if (length != sizeof(uint8) || (*data == 0x1)) { //app magic flag is set, don't set again
return 0;
} else {
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
int writeLen = sizeof(app_aging_info);
char* info = new char[writeLen];
memset(info, 0, writeLen);
//Initialization magic info;
strncpy(info, "AGE_TEST", MAGIC_LENGTH);
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, writeLen);
delete []info;
}
return count > 0;
}
/* full agingtest count */
std::vector<int32_t> readAgingtestedFullCountInfo() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, aging_full_test_count);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestedPartCountInfo offset:0x%llx, part count:%d", offset, info[0]);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestedFullCountInfo(char* data, uint32_t length) { //data[0],1:set, 0:clear
int count = 0;
if (length != sizeof(uint8)) {
return 0;
} else {
char info = 0x0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, aging_full_test_count);
if(*data != 0) {
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, &info, 1);
if(count == 1 && info < MAX_AGING_TEST_COUNT) {
info+=1;
} else if (info == MAX_AGING_TEST_COUNT) {
return 1;
}
}
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, &info, 1);
ALOGD("saveAgingtestedPartCountInfo offset:0x%llx, full count:%d", offset, info);
}
return count > 0;
}
/* part agingtest count */
std::vector<int32_t> readAgingtestedPartCountInfo() {
int readLen = sizeof(uint8);
char* info = new char[readLen];
memset(info, 0, readLen);
int count = 0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, aging_part_test_count);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
ALOGD("readAgingtestedPartCountInfo offset:0x%llx, part count:%d", offset, info[0]);
std::vector<int32_t> tmp(readLen);
if (count == readLen) {
convertArray2Vector_int32(info, readLen, tmp);
}
delete []info;
return tmp;
}
bool saveAgingtestedPartCountInfo(char* data, uint32_t length) { //data[0],1:set, 0:clear
int count = 0;
if (length != sizeof(uint8)) {
return 0;
} else {
char info = 0x0;
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, aging_part_test_count);
if(*data != 0) {
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, &info, 1);
if(count == 1 && info < MAX_AGING_TEST_COUNT) {
info+=1;
} else if (info == MAX_AGING_TEST_COUNT) {
return 1;
}
}
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, &info, 1);
ALOGD("saveAgingtestedPartCountInfo offset:0x%llx, part count:%d", offset, info);
}
return count > 0;
}
/* App fatal err */
std::vector<int32_t> readAgingtestAppFatalInfo() {
int readLen = sizeof(fatal_aging_flag);
char* info = new char[readLen];
char* infoData = new char[MAX_FATAL_FLAG_TYPE * 2];
int fatalIndex = 0;
int i = 0;
fatal_aging_flag *app_fatal_info = NULL;
int count = 0;
memset(info, 0, readLen);
memset(infoData, 0, (MAX_FATAL_FLAG_TYPE * 2));
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, fatal_flag);
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, readLen);
if (count == readLen) {
app_fatal_info = (fatal_aging_flag *)info;
for (i = 0; i < MAX_FATAL_FLAG_TYPE; i++) {
if ( app_fatal_info->fatal_flag & (1ULL << i)) {
infoData[fatalIndex] = i;
fatalIndex++;
infoData[fatalIndex] = app_fatal_info->fatal_count[i];
fatalIndex++;
}
}
}
if (fatalIndex == 0)
fatalIndex++; // if no fatal error return one byte data
ALOGD("readAgingtestAppFatalInfo fatalIndex:%d\n", fatalIndex);
std::vector<int32_t> tmp(fatalIndex);
convertArray2Vector_int32(infoData, fatalIndex, tmp);
delete []info;
delete []infoData;
return tmp;
}
bool saveAgingtestAppFatalInfo(char* data, uint32_t length) { //data[0],1:set, 0:clear
int count = 0;
if ( length == 0 || ((length == 1) && (*data !=0))) {
return 0;
} else {
int i = 0;
int index = 0;
uint8 countValue = 0;
int len = sizeof(fatal_aging_flag);
char* info = new char[len];
fatal_aging_flag *app_fatal_info = NULL;
memset(info, 0, len);
uint64 offset = getAgingDataTypeStartOffset(DEFAULT_CONTROL_INFO_PART_PATH, APP_INFO);
offset += offsetof(app_aging_info, fatal_flag);
if ((length == 1) && (*data == 0)) { //clear all app fatal flag
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, len);
} else {
if ( length >= 2 && ((*data == 0) || (*data == 1))) {
count = readInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, len);
app_fatal_info = (fatal_aging_flag *)info;
for (i = 1; i <= (length -1)/2; i++) {
index = (int)*(data+ 2*i - 1);
countValue = *(data + 2*i);
if (*data == 0x1 ) {
//set
app_fatal_info->fatal_flag |= (1ULL << index);
if ( app_fatal_info->fatal_count[index] + countValue < MAX_ERR_COUNT) {
app_fatal_info->fatal_count[index] += countValue;
} else {
app_fatal_info->fatal_count[index] = MAX_ERR_COUNT;
}
} else {
//clear
app_fatal_info->fatal_flag &= ~(1ULL << index );
app_fatal_info->fatal_count[index] = 0;
}
}
//update
count = writeInterface(DEFAULT_CONTROL_INFO_PART_PATH, offset, info, len);
}
}
delete []info;
}
return count > 0;
}
#endif
//end
::ndk::ScopedAStatus OplusProject::readAgingData(int32_t type, std::vector<int32_t>* _aidl_return) {
ALOGD("readAgingData type = %d", type);
switch(type) {
//Hong.Zhang@TECH.BSP.Stability.Aging2.0, 2020/07/17, Add for aging 2.0
#ifdef QCOM_PLATFORM_SUPPORT
case ACTION_GET_SET_AGINGTEST_CONTROL_INFO: {
std::vector<int32_t> agingControlInfo = readAgingtestControlInfo();
*_aidl_return = agingControlInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_AGINGTEST_MEMTEST_SUPPORT_INFO: {
std::vector<int32_t> agingMemtestSupportInfo = readAgingtestMemtestSupportInfo();
*_aidl_return = agingMemtestSupportInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_MAGIC_FLAG: {
std::vector<int32_t> agingMagicInfo = readAgingtestMagicInfo();
*_aidl_return = agingMagicInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_FLAG_INFO: {
std::vector<int32_t> agingFlagInfo = readAgingtestFlagInfo();
*_aidl_return = agingFlagInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_MEMTEST_ENABLE_INFO: {
std::vector<int32_t> agingMemtestEnableInfo = readAgingtestMemtestEnableFlag();
*_aidl_return = agingMemtestEnableInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_STAGE_INFO: {
std::vector<int32_t> agingStageInfo = readAgingtestStageInfo();
*_aidl_return = agingStageInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_MEMTEST_RESULT_INFO: {
std::vector<int32_t> agingMemtestResultInfo = readAgingtestMemtestResultInfo();
*_aidl_return = agingMemtestResultInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_AGINGTEST_DUMP_CURRENT_COUNT: {
std::vector<int32_t> agingDumpCountInfo = readAgingtestDumpCountInfo();
*_aidl_return = agingDumpCountInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_ABNORMAL_INFO: {
std::vector<int32_t> agingBootAbnormalInfo = readAgingtestBootAbnormalInfo();
*_aidl_return = agingBootAbnormalInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_APP_INFO: {
std::vector<int32_t> agingAppInfo = readAgingtestAppInfo();
*_aidl_return = agingAppInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_APP_MAGIC_FLAG: {
std::vector<int32_t> agingAppMagicInfo = readAgingtestAppMagicInfo();
*_aidl_return = agingAppMagicInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_APP_FULL_TESTCOUNT: {
std::vector<int32_t> agingAppFullCountInfo = readAgingtestedFullCountInfo();
*_aidl_return = agingAppFullCountInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_APP_PART_TESTCOUNT: {
std::vector<int32_t> agingAppPartCountInfo = readAgingtestedPartCountInfo();
*_aidl_return = agingAppPartCountInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_AGINGTEST_LASTEST_DUMP_INFO: {
std::vector<int32_t> agingAppCurrDumpInfo = readAgingtestCurrDumpInfo();
*_aidl_return = agingAppCurrDumpInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_AGINGTEST_FULL_DUMP_INFO: {
std::vector<int32_t> agingAppFullDumpInfo = readAgingtestFullDumpInfo();
*_aidl_return = agingAppFullDumpInfo;
return ndk::ScopedAStatus::ok();
}
case ACTION_GET_SET_AGINGTEST_APP_FATAL_FLAG_INFO: {
std::vector<int32_t> agingAppFatalInfo = readAgingtestAppFatalInfo();
*_aidl_return = agingAppFatalInfo;
return ndk::ScopedAStatus::ok();
}
#endif
//end
default:
break;
}
*_aidl_return = {};
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::saveAgingData(int32_t type, const std::vector<int32_t>& saveAgingData, int32_t length, bool* _aidl_return) {
bool result = false;
if (saveAgingData.empty()) {
ALOGE("invalid saveAgingData");
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
ALOGD("saveAgingData type = %d, length = %d, size = %zu", type, length, saveAgingData.size());
if (length != saveAgingData.size() || length > 4096) {
ALOGE("data size error");
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
char* data = new char[saveAgingData.size()];
memset(data, 0, saveAgingData.size());
convertVector2Array(saveAgingData, data);
switch (type) {
//Hong.Zhang@TECH.BSP.Stability.Aging2.0, 2020/07/17, Add for aging 2.0
#ifdef QCOM_PLATFORM_SUPPORT
case ACTION_GET_SET_AGINGTEST_CONTROL_INFO: {
result = saveAgingtestControlInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_MAGIC_FLAG: {
result = saveAgingtestMagicInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_FLAG_INFO: {
result = saveOrClearAgingtestFlagInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_MEMTEST_ENABLE_INFO: {
result = saveAgingtestMemtestEnableFlag(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_STAGE_INFO: {
result = clearAgingtestStageInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_MEMTEST_RESULT_INFO: {
result = clearAgingtestMemtestResultInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_ABNORMAL_INFO: {
result = clearAgingtestBootAbnormalInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_APP_INFO: {
result = saveAgingtestAppInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_APP_MAGIC_FLAG: {
result = saveAgingtestAppMagicInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_APP_FULL_TESTCOUNT: {
result = saveAgingtestedFullCountInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_APP_PART_TESTCOUNT: {
result = saveAgingtestedPartCountInfo(data, length);
break;
}
case ACTION_SET_AGINGTEST_VERSION_TO_DUMP_INFO: {
result = saveAgingtestCurrDumpVersionInfo(data, length);
break;
}
case ACTION_GET_SET_AGINGTEST_APP_FATAL_FLAG_INFO: {
result = saveAgingtestAppFatalInfo(data, length);
break;
}
#endif
//End
default:
break;
}
delete[] data;
if (true == result) {
*_aidl_return = true;
return ndk::ScopedAStatus::ok();
} else {
*_aidl_return = false;
return ndk::ScopedAStatus::ok();
}
}
std::string miscReadModuleRelatedFile(const char* path)
{
std::string data;
int32_t count = 0;
int length = 4096;
char *buf_data = new char[length];
int32_t offset = 0;
while (1) {
memset(buf_data, 0, length-1);
count = readInterface(path, offset, buf_data, length-1);
if (count < 0) {
data.clear();
break;
}
buf_data[count] = '\0';
if (count == 0)
break;
data.append(buf_data);
offset += count;
}
delete []buf_data;
return data;
}
::ndk::ScopedAStatus OplusProject::miscReadLinkedModules(std::string* _aidl_return)
{
std::string data;
data = miscReadModuleRelatedFile(LINKED_MODULES_PATH);
*_aidl_return = data;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::miscModule2Load(std::string* _aidl_return)
{
std::string data;
data = miscReadModuleRelatedFile(MODULES_TO_LOAD_PATH);
*_aidl_return = data;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OplusProject::miscModuleBlocklist(std::string* _aidl_return)
{
std::string data;
data = miscReadModuleRelatedFile(MODULES_BLOCKLIST_PATH);
*_aidl_return = data;
return ndk::ScopedAStatus::ok();
}
} // namespace oplus_project
} // namespace stability
} // namespace hardware
} // namespace oplus
} // namespace vendor
} // namespace aidl
解释readAgingtestBootAbnormalInfo这个函数