Commit c16cb140 authored by Mark Stevens's avatar Mark Stevens
Browse files

update from duco/rk312x_20160510 on rockchip-5.1.0_r5 branches

parent 5b9defe8
......@@ -13,7 +13,7 @@
# limitations under the License.
LOCAL_PATH := $(call my-dir)
prebuilt_stdcxx_PATH := prebuilts/ndk/current/sources/cxx-stl/
include $(CLEAR_VARS)
......@@ -39,6 +39,7 @@ LOCAL_SRC_FILES := \
asn1_decoder.cpp \
verifier.cpp \
adb_install.cpp \
rkimage.cpp \
fuse_sdcard_provider.c
LOCAL_MODULE := recovery
......@@ -52,6 +53,15 @@ endif
RECOVERY_API_VERSION := 3
RECOVERY_FSTAB_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
LOCAL_CFLAGS += -D_FILE_OFFSET_BITS=64
LOCAL_C_INCLUDES := \
$(prebuilt_stdcxx_PATH)/gnu-libstdc++/include\
$(prebuilt_stdcxx_PATH)/gnu-libstdc++/libs/armeabi-v7a/include\
bionic \
bionic/libstdc++/include \
$(LOCAL_PATH)/rkupdate
LOCAL_CPPFLAGS += -fexceptions -frtti
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_STATIC_LIBRARIES := \
......@@ -69,9 +79,23 @@ LOCAL_STATIC_LIBRARIES := \
libcutils \
liblog \
libselinux \
librkupdate\
libext2_uuid\
librkrsa\
libgnustl_static\
libstdc++ \
libutils \
libm \
libc
libc \
libedify \
libapplypatch \
librsa \
libcrc32 \
librk_emmcutils
ifeq ($(RECOVERY_AUTO_USB_UPDATE), true)
LOCAL_CFLAGS += -DUSE_AUTO_USB_UPDATE
endif
ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_CFLAGS += -DUSE_EXT4
......@@ -79,18 +103,59 @@ ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_STATIC_LIBRARIES += libext4_utils_static libz
endif
ifeq ($(RECOVERY_UPDATEIMG_RSA_CHECK), true)
$(warning recovery use updateimg rsa check!)
LOCAL_CFLAGS += -DUSE_RSA_CHECK
else
$(warning recovery use updateimg crc32 check!)
endif
ifeq ($(RECOVERY_BOARD_ID), true)
$(warning recovery use board id!)
LOCAL_CFLAGS += -DUSE_BOARD_ID
LOCAL_STATIC_LIBRARIES += libboard_id_recovery libxml2_recovery
else
$(warning recovery not use board id!)
endif
ifeq ($(RECOVERY_WITH_RADICAL_UPDATE), true)
$(warning recovery with radical_update!)
LOCAL_CFLAGS += -DUSE_RADICAL_UPDATE
LOCAL_STATIC_LIBRARIES += libradical_update_recovery libxml2_recovery
LOCAL_C_INCLUDES += $(LOCAL_PATH)/radical_update/inc
else
$(warning recovery without radical_update!)
endif
# LOCAL_CFLAGS += -E
ifeq ($(strip $(TARGET_BOARD_HARDWARE)),rk30board)
LOCAL_CFLAGS += -DTARGET_RK30
endif
ifeq ($(strip $(TARGET_BOARD_HARDWARE)),rk2928board)
LOCAL_CFLAGS += -DTARGET_RK30
endif
ifeq ($(strip $(TARGET_BOARD_PLATFORM)),rk3368)
LOCAL_CFLAGS += -DTARGET_RK3368
endif
ifeq ($(strip $(TARGET_BOARD_PLATFORM)),rk3188)
LOCAL_CFLAGS += -DTARGET_RK3188
endif
# This binary is in the recovery ramdisk, which is otherwise a copy of root.
# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
# a (redundant) copy of the binary in /system/bin for user builds.
# TODO: Build the ramdisk image in a more principled way.
LOCAL_MODULE_TAGS := eng
ifeq ($(TARGET_RECOVERY_UI_LIB),)
#ifeq ($(TARGET_RECOVERY_UI_LIB),)
LOCAL_SRC_FILES += default_device.cpp
else
LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
endif
#else
# LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
#endif
LOCAL_CFLAGS += -fpermissive
LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_C_INCLUDES += external/openssl/include
......@@ -134,4 +199,14 @@ include $(LOCAL_PATH)/minui/Android.mk \
$(LOCAL_PATH)/edify/Android.mk \
$(LOCAL_PATH)/uncrypt/Android.mk \
$(LOCAL_PATH)/updater/Android.mk \
$(LOCAL_PATH)/applypatch/Android.mk
$(LOCAL_PATH)/emmcutils/Android.mk \
$(LOCAL_PATH)/applypatch/Android.mk \
$(LOCAL_PATH)/rsa/Android.mk \
$(LOCAL_PATH)/crc/Android.mk \
$(LOCAL_PATH)/board_id/Android.mk \
$(LOCAL_PATH)/libxml2/Android.mk \
$(LOCAL_PATH)/radical_update/Android.mk \
$(LOCAL_PATH)/rkupdate/stl/Android.mk \
$(LOCAL_PATH)/rkupdate/rsa/Android.mk \
$(LOCAL_PATH)/rkupdate/update/Android.mk
......@@ -115,7 +115,7 @@ apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) {
break;
}
}
result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false);
result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false, 0);
break;
}
......
......@@ -19,7 +19,7 @@ LOCAL_SRC_FILES := applypatch.c bspatch.c freecache.c imgpatch.c utils.c
LOCAL_MODULE := libapplypatch
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += external/bzip2 external/zlib bootable/recovery
LOCAL_STATIC_LIBRARIES += libmtdutils libmincrypt libbz libz
LOCAL_STATIC_LIBRARIES += libmtdutils libmincrypt libbz libz librk_emmcutils
include $(BUILD_STATIC_LIBRARY)
......@@ -27,8 +27,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.c
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz librk_emmcutils
LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
......@@ -40,7 +40,7 @@ LOCAL_MODULE := applypatch_static
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz librk_emmcutils
LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
......
......@@ -30,6 +30,8 @@
#include "applypatch.h"
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"
#include "emmcutils/rk_emmcutils.h"
#include "mtdutils/rk29.h"
static int LoadPartitionContents(const char* filename, FileContents* file);
static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token);
......@@ -126,17 +128,24 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
const char* magic = strtok(copy, ":");
enum PartitionType type;
int emmcEnabled = getEmmcState();
char temp[64];
if (strcmp(magic, "MTD") == 0) {
if (strcmp(magic, "MTD") == 0 && emmcEnabled == 0) {
type = MTD;
} else if (strcmp(magic, "EMMC") == 0) {
} else if (strcmp(magic, "EMMC") == 0 || emmcEnabled == 1) {
type = EMMC;
} else {
printf("LoadPartitionContents called with bad filename (%s)\n",
filename);
return -1;
}
const char* partition = strtok(NULL, ":");
if(emmcEnabled) {
transformPath(partition, temp);
partition = temp;
}
int i;
int colons = 0;
......@@ -227,7 +236,9 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
break;
case EMMC:
read = fread(p, 1, next, dev);
//modify by mmk@rock-chips.com
read = rk29_fread(p, 1, next, dev);
//read = fread(p, 1, next, dev);
break;
}
if (next != read) {
......@@ -354,15 +365,23 @@ int WriteToPartition(unsigned char* data, size_t len,
const char* magic = strtok(copy, ":");
enum PartitionType type;
if (strcmp(magic, "MTD") == 0) {
int emmcEnabled = getEmmcState();
char temp[64];
if (strcmp(magic, "MTD") == 0 && emmcEnabled == 0) {
type = MTD;
} else if (strcmp(magic, "EMMC") == 0) {
} else if (strcmp(magic, "EMMC") == 0 || emmcEnabled == 1) {
type = EMMC;
} else {
printf("WriteToPartition called with bad target (%s)\n", target);
return -1;
}
const char* partition = strtok(NULL, ":");
if(emmcEnabled) {
transformPath(partition, temp);
partition = temp;
}
if (partition == NULL) {
printf("bad partition target name \"%s\"\n", target);
......
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
board_id_ctrl.c \
custom.c \
parse_cust_xml.c \
parse_device_xml.c \
restore.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../libxml2/include \
$(LOCAL_PATH)/..
LOCAL_MODULE := libboard_id_recovery
# LOCAL_CFLAGS += -E
include $(BUILD_STATIC_LIBRARY)
/*
* board_id_ctrl.c
*
* Created on: 2013-4-27
* Author: mmk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include "board_id_ctrl.h"
#include "common.h"
// #include "custom_log.h"
static int sCtrlFd = -1;
int board_id_open_device(void)
{
if (sCtrlFd < 0)
{
sCtrlFd = open("/dev/board_id_misc", O_RDWR);
if(sCtrlFd < 0)
{
E("error=%s.", strerror(errno));
return -1;
}
}
D("success to open board_id_misc");
return 0;
}
int board_id_close_device(void)
{
D("enter.");
if(sCtrlFd >= 0)
{
close(sCtrlFd);
sCtrlFd = -1;
}
return 0;
}
int board_id_get_locale_region(enum type_devices type, char *country_area, char *locale_language, char *locale_region, char *country_geo, char *timezone, char *user_define)
{
int result = 0;
struct area_id_name area_select;
if(type != DEVICE_TYPE_AREA)
{
E("type = %d, error", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_AREA_ID, &area_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
D("tid=%d, bid=%d, area=\"%s\", locale=\"%s\", region=\"%s\", timezone=\"%s\".",
area_select.type,
area_select.id,
area_select.country_area,
area_select.locale_language,
area_select.locale_region,
area_select.timezone);
strcpy(country_area, area_select.country_area);
strcpy(locale_language, area_select.locale_language);
strcpy(locale_region, area_select.locale_region);
strcpy(country_geo, area_select.country_geo);
strcpy(timezone, area_select.timezone);
strcpy(user_define, area_select.user_define);
return result;
error:
strcpy(country_area, "United_States");
strcpy(locale_language, "en");
strcpy(locale_region, "US");
strcpy(country_geo, "no");
strcpy(timezone, "Atlantic/Azores");
strcpy(user_define, "no");
return result;
}
int board_id_get_operator_name(enum type_devices type, char *locale_region, char *operator_name)
{
int result = 0;
struct operator_id_name operator_select;
if(type != DEVICE_TYPE_OPERATOR)
{
E("type = %d is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_OPERATOR_ID, &operator_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
strcpy(operator_name, operator_select.operator_name);
strcpy(locale_region, operator_select.locale_region);
return result;
error:
strcpy(operator_name, "CHINA_MOBILE");
strcpy(locale_region, "CN");
return result;
}
int board_id_get_reserve_name(enum type_devices type, char *locale_region, char *reserve_name)
{
int result = 0;
struct reserve_id_name reserve_select;
if(type != DEVICE_TYPE_RESERVE)
{
E("type = %d is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_RESERVE_ID, &reserve_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
strcpy(reserve_name, reserve_select.reserve_name);
strcpy(locale_region, reserve_select.locale_region);
return result;
error:
strcpy(reserve_name, "no");
strcpy(locale_region, "CN");
return result;
}
int board_id_get_device_name(enum type_devices type, char *type_name, char *dev_name)
{
int result = 0;
struct device_id_name device_selected_temp;
int ioctl_cmd_temp = BOARD_ID_IOCTL_READ_TP_ID;
if((type < DEVICE_TYPE_TP) || (type >= DEVICE_NUM_TYPES))
{
E("type = %d is error.", type);
goto error;
}
switch(type)
{
case DEVICE_TYPE_TP:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_TP_ID;
break;
case DEVICE_TYPE_LCD:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_LCD_ID;
break;
case DEVICE_TYPE_KEY:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_KEY_ID;
break;
case DEVICE_TYPE_CODEC:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_CODEC_ID;
break;
case DEVICE_TYPE_WIFI:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_WIFI_ID;
break;
case DEVICE_TYPE_BT:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_BT_ID;
break;
case DEVICE_TYPE_GPS:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_GPS_ID;
break;
case DEVICE_TYPE_FM:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_FM_ID;
break;
case DEVICE_TYPE_MODEM:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_MODEM_ID;
break;
case DEVICE_TYPE_DDR:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_DDR_ID;
break;
case DEVICE_TYPE_FLASH:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_FLASH_ID;
break;
case DEVICE_TYPE_HDMI:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_HDMI_ID;
break;
case DEVICE_TYPE_BATTERY:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_BATTERY_ID;
break;
case DEVICE_TYPE_CHARGE:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_CHARGE_ID;
break;
case DEVICE_TYPE_BACKLIGHT:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_BACKLIGHT_ID;
break;
case DEVICE_TYPE_HEADSET:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_HEADSET_ID;
break;
case DEVICE_TYPE_MICPHONE:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_MICPHONE_ID;
break;
case DEVICE_TYPE_SPEAKER:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SPEAKER_ID;
break;
case DEVICE_TYPE_VIBRATOR:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_VIBRATOR_ID;
break;
case DEVICE_TYPE_TV:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_TV_ID;
break;
case DEVICE_TYPE_ECHIP:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_ECHIP_ID;
break;
case DEVICE_TYPE_PMIC:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_PMIC_ID;
break;
case DEVICE_TYPE_REGULATOR:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_REGULATOR_ID;
break;
case DEVICE_TYPE_RTC:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_RTC_ID;
break;
case DEVICE_TYPE_CAMERA_FRONT:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_CAMERA_FRONT_ID;
break;
case DEVICE_TYPE_CAMERA_BACK:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_CAMERA_BACK_ID;
break;
case DEVICE_TYPE_ANGLE:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_ANGLE_ID;
break;
case DEVICE_TYPE_ACCEL:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_ACCEL_ID;
break;
case DEVICE_TYPE_COMPASS:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_COMPASS_ID;
break;
case DEVICE_TYPE_GYRO:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_GYRO_ID;
break;
case DEVICE_TYPE_LIGHT:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_LIGHT_ID;
break;
case DEVICE_TYPE_PROXIMITY:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_PROXIMITY_ID;
break;
case DEVICE_TYPE_TEMPERATURE:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_TEMPERATURE_ID;
break;
case DEVICE_TYPE_PRESSURE:
ioctl_cmd_temp = BOARD_ID_IOCTL_READ_SENSOR_PRESSURE_ID;
break;
default:
D("type = %d, is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, ioctl_cmd_temp, &device_selected_temp) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
D("tid=%d, bid=%d, type=\"%s\", dev=\"%s\", desc=\"%s\"",
device_selected_temp.type,
device_selected_temp.id,
device_selected_temp.type_name,
device_selected_temp.dev_name,
device_selected_temp.description);
strcpy(type_name, device_selected_temp.type_name);
strcpy(dev_name, device_selected_temp.dev_name);
return result;
error:
strcpy(type_name, "gps");
strcpy(dev_name, "no_gps");
return result;
};
int board_id_get_locale_region_by_id(enum type_devices type, char *id, char *country_area, char *locale_language, char *locale_region, char *country_geo, char *timezone, char *user_define)
{
int result = 0;
struct area_id_name area_last_select;
if(!id)
{
E("id is null");
goto error;
}
area_last_select.type = type;
area_last_select.id = id[type];
if(type != DEVICE_TYPE_AREA)
{
E("type = %d is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_AREA_NAME_BY_ID, &area_last_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
if((area_last_select.id != (int)id[type]) || (area_last_select.type != (int)type))
{
E("type=%d,%d,id=%d,%d", area_last_select.type, type, area_last_select.id, id[type]);
result = -1;
goto error;
}
strcpy(country_area, area_last_select.country_area);
strcpy(locale_language, area_last_select.locale_language);
strcpy(locale_region, area_last_select.locale_region);
strcpy(country_geo, area_last_select.country_geo);
strcpy(timezone, area_last_select.timezone);
strcpy(user_define, area_last_select.user_define);
return result;
error:
strcpy(country_area, "United_States");
strcpy(locale_language, "en");
strcpy(locale_region, "US");
strcpy(country_geo, "no");
strcpy(timezone, "Atlantic/Azores");
strcpy(user_define, "no");
return result;
}
int board_id_get_operator_name_by_id(enum type_devices type, char *id, char *locale_region, char *operator_name)
{
int result = 0;
struct operator_id_name operator_last_select;
if(!id)
{
E("id is null.");
goto error;
}
operator_last_select.type = type;
operator_last_select.id = ((id[type] << 8) | id[type+1]);
if(type != DEVICE_TYPE_OPERATOR)
{
E("type = %d is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_OPERATOR_NAME_BY_ID, &operator_last_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
if((operator_last_select.id != (int)((id[type] << 8) | id[type+1])) || (operator_last_select.type != (int)type))
{
E("type = %d, %d; id=%d, %d", operator_last_select.type, type, operator_last_select.id, ((id[type] << 8) | id[type+1]));
result = -1;
goto error;
}
strcpy(operator_name, operator_last_select.operator_name);
strcpy(locale_region, operator_last_select.locale_region);
return result;
error:
strcpy(operator_name, "CHINA_MOBILE");
strcpy(locale_region, "CN");
return result;
}
int board_id_get_reserve_name_by_id(enum type_devices type, char *id, char *locale_region, char *reserve_name)
{
int result = 0;
struct reserve_id_name reserve_last_select;
if(!id)
{
E("id is null");
goto error;
}
reserve_last_select.type = type;
reserve_last_select.id = id[type];
if(type != DEVICE_TYPE_RESERVE)
{
E("type = %d is error.", type);
goto error;
}
if ( 0 > ioctl(sCtrlFd, BOARD_ID_IOCTL_READ_RESERVE_NAME_BY_ID, &reserve_last_select) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
if((reserve_last_select.id != (int)id[type]) || (reserve_last_select.type != (int)type))
{
E("type=%d,%d; id=%d,%d", reserve_last_select.type, type, reserve_last_select.id, id[type]);
result = -1;
goto error;
}
strcpy(reserve_name, reserve_last_select.reserve_name);
strcpy(locale_region, reserve_last_select.locale_region);
return result;
error:
strcpy(reserve_name, "no");
strcpy(locale_region, "CN");
return result;
}
int board_id_get_device_name_by_id(enum type_devices type, char *id, char *type_name, char *dev_name)
{
int result = 0;
struct device_id_name device_selected_temp;
if(!id)
{
D("id is null");
goto error;
}
device_selected_temp.type = type;
device_selected_temp.id = id[type];
if((type < DEVICE_TYPE_TP) || (type >= DEVICE_NUM_TYPES))
{
E("unexpected 'type' = %d.", type);
goto error;
}
int ioctl_cmd_temp = BOARD_ID_IOCTL_READ_DEVICE_NAME_BY_ID;
if ( 0 > ioctl(sCtrlFd, ioctl_cmd_temp, &device_selected_temp) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
if((device_selected_temp.type != (int)type) || (device_selected_temp.id != (int)id[type]) )
{
E("type=%d,%d,id=%d,%d", device_selected_temp.type, type, device_selected_temp.id, id[type]);
result = -1;
goto error;
}
D("id=%d, device_id=%d, dev_name=%s, type=%d, type_name=%s",
device_selected_temp.id,
device_selected_temp.device_id,
device_selected_temp.dev_name,
device_selected_temp.type,
device_selected_temp.type_name);
strcpy(type_name, device_selected_temp.type_name);
strcpy(dev_name, device_selected_temp.dev_name);
return result;
error:
strcpy(type_name, "gps");
strcpy(dev_name, "no_gps");
return result;
}
int board_id_get(char *id)
{
int result = 0;
int ioctl_cmd_temp = BOARD_ID_IOCTL_READ_VENDOR_DATA;
if(!id)
{
E("id is null.");
goto error;
}
if ( 0 > ioctl(sCtrlFd, ioctl_cmd_temp, id) )
{
E("fail to ioctl, error = %s.", strerror(errno));
result = -1;
goto error;
}
return result;
error:
strcpy(id, "123456789");
return result;
}
/*
* board_id_ctrl.h
*
* Created on: 2013-4-27
* Author: mmk
*/
#ifndef BOARD_ID_CTRL_H_
#define BOARD_ID_CTRL_H_
#include <sys/ioctl.h>
enum type_devices{
DEVICE_TYPE_NULL = 0x0,
DEVICE_TYPE_SUM = 0x20,
DEVICE_TYPE_AREA = 0x24, //
DEVICE_TYPE_OPERATOR = 0x25,
DEVICE_TYPE_OPERATOR2 = 0x26,
DEVICE_TYPE_RESERVE = 0x27,
DEVICE_TYPE_STATUS = 0x28,
DEVICE_TYPE_TP = 0x29, //one byte size
DEVICE_TYPE_LCD,
DEVICE_TYPE_KEY,
DEVICE_TYPE_CODEC,
DEVICE_TYPE_WIFI,
DEVICE_TYPE_BT,
DEVICE_TYPE_GPS,
DEVICE_TYPE_FM,
DEVICE_TYPE_MODEM,
DEVICE_TYPE_DDR,
DEVICE_TYPE_FLASH,
DEVICE_TYPE_HDMI,
DEVICE_TYPE_BATTERY,
DEVICE_TYPE_CHARGE,
DEVICE_TYPE_BACKLIGHT,
DEVICE_TYPE_HEADSET,
DEVICE_TYPE_MICPHONE,
DEVICE_TYPE_SPEAKER,
DEVICE_TYPE_VIBRATOR,
DEVICE_TYPE_TV,
DEVICE_TYPE_ECHIP, //30
DEVICE_TYPE_HUB,
DEVICE_TYPE_TPAD,
DEVICE_TYPE_PMIC,
DEVICE_TYPE_REGULATOR,
DEVICE_TYPE_RTC,
DEVICE_TYPE_CAMERA_FRONT,
DEVICE_TYPE_CAMERA_BACK, //35
DEVICE_TYPE_ANGLE,
DEVICE_TYPE_ACCEL,
DEVICE_TYPE_COMPASS,
DEVICE_TYPE_GYRO,
DEVICE_TYPE_LIGHT,
DEVICE_TYPE_PROXIMITY,
DEVICE_TYPE_TEMPERATURE,
DEVICE_TYPE_PRESSURE,
DEVICE_NUM_TYPES,
};
enum id_language{
LANGUAGE_ID_NULL,
LANGUAGE_ID_EN,// 英文
LANGUAGE_ID_EN_US,// 英文 (美国)
LANGUAGE_ID_AR,// 阿拉伯文
LANGUAGE_ID_AR_AE,// 阿拉伯文 (阿拉伯联合酋长国)
LANGUAGE_ID_AR_BH,// 阿拉伯文 (巴林)
LANGUAGE_ID_AR_DZ,// 阿拉伯文 (阿尔及利亚)
LANGUAGE_ID_AR_EG,// 阿拉伯文 (埃及)
LANGUAGE_ID_AR_IQ,// 阿拉伯文 (伊拉克)
LANGUAGE_ID_AR_JO,// 阿拉伯文 (约旦)
LANGUAGE_ID_AR_KW,// 阿拉伯文 (科威特)
LANGUAGE_ID_AR_LB,// 阿拉伯文 (黎巴嫩)
LANGUAGE_ID_AR_LY,// 阿拉伯文 (利比亚)
LANGUAGE_ID_AR_MA,// 阿拉伯文 (摩洛哥)
LANGUAGE_ID_AR_OM,// 阿拉伯文 (阿曼)
LANGUAGE_ID_AR_QA,// 阿拉伯文 (卡塔尔)
LANGUAGE_ID_AR_SA,// 阿拉伯文 (沙特阿拉伯)
LANGUAGE_ID_AR_SD,// 阿拉伯文 (苏丹)
LANGUAGE_ID_AR_SY,// 阿拉伯文 (叙利亚)
LANGUAGE_ID_AR_TN,// 阿拉伯文 (突尼斯)
LANGUAGE_ID_AR_YE,// 阿拉伯文 (也门)
LANGUAGE_ID_BE,// 白俄罗斯文
LANGUAGE_ID_BE_BY,// 白俄罗斯文 (白俄罗斯)
LANGUAGE_ID_BG,// 保加利亚文
LANGUAGE_ID_BG_BG,// 保加利亚文 (保加利亚)
LANGUAGE_ID_CA,// 加泰罗尼亚文
LANGUAGE_ID_CA_ES,// 加泰罗尼亚文 (西班牙)
LANGUAGE_ID_CA_ES_EURO,// 加泰罗尼亚文 (西班牙,EURO)
LANGUAGE_ID_CS,// 捷克文
LANGUAGE_ID_CS_CZ,// 捷克文 (捷克共和国)
LANGUAGE_ID_DA,// 丹麦文
LANGUAGE_ID_DA_DK,// 丹麦文 (丹麦)
LANGUAGE_ID_DE,// 德文
LANGUAGE_ID_DE_AT,// 德文 (奥地利)
LANGUAGE_ID_DE_AT_EURO,// 德文 (奥地利,EURO)
LANGUAGE_ID_DE_CH,// 德文 (瑞士)
LANGUAGE_ID_DE_DE,// 德文 (德国)
LANGUAGE_ID_DE_DE_EURO,// 德文 (德国,EURO)
LANGUAGE_ID_DE_LU,// 德文 (卢森堡)
LANGUAGE_ID_DE_LU_EURO,// 德文 (卢森堡,EURO)
LANGUAGE_ID_EL,// 希腊文
LANGUAGE_ID_EL_GR,// 希腊文 (希腊)
LANGUAGE_ID_EN_AU,// 英文 (澳大利亚)
LANGUAGE_ID_EN_CA,// 英文 (加拿大)
LANGUAGE_ID_EN_GB,// 英文 (英国)
LANGUAGE_ID_EN_IE,// 英文 (爱尔兰)
LANGUAGE_ID_EN_IE_EURO,// 英文 (爱尔兰,EURO)
LANGUAGE_ID_EN_NZ,// 英文 (新西兰)
LANGUAGE_ID_EN_ZA,// 英文 (南非)
LANGUAGE_ID_ES,// 西班牙文
LANGUAGE_ID_ES_BO,// 西班牙文 (玻利维亚)
LANGUAGE_ID_ES_AR,// 西班牙文 (阿根廷)
LANGUAGE_ID_ES_CL,// 西班牙文 (智利)
LANGUAGE_ID_ES_CO,// 西班牙文 (哥伦比亚)
LANGUAGE_ID_ES_CR,// 西班牙文 (哥斯达黎加)
LANGUAGE_ID_ES_DO,// 西班牙文 (多米尼加共和国)
LANGUAGE_ID_ES_EC,// 西班牙文 (厄瓜多尔)
LANGUAGE_ID_ES_ES,// 西班牙文 (西班牙)
LANGUAGE_ID_ES_ES_EURO,// 西班牙文 (西班牙,EURO)
LANGUAGE_ID_ES_GT,// 西班牙文 (危地马拉)
LANGUAGE_ID_ES_HN,// 西班牙文 (洪都拉斯)
LANGUAGE_ID_ES_MX,// 西班牙文 (墨西哥)
LANGUAGE_ID_ES_NI,// 西班牙文 (尼加拉瓜)
LANGUAGE_ID_ET,// 爱沙尼亚文
LANGUAGE_ID_ES_PA,// 西班牙文 (巴拿马)
LANGUAGE_ID_ES_PE,// 西班牙文 (秘鲁)
LANGUAGE_ID_ES_PR,// 西班牙文 (波多黎哥)
LANGUAGE_ID_ES_PY,// 西班牙文 (巴拉圭)
LANGUAGE_ID_ES_SV,// 西班牙文 (萨尔瓦多)
LANGUAGE_ID_ES_UY,// 西班牙文 (乌拉圭)
LANGUAGE_ID_ES_VE,// 西班牙文 (委内瑞拉)
LANGUAGE_ID_ET_EE,// 爱沙尼亚文 (爱沙尼亚)
LANGUAGE_ID_FI,// 芬兰文
LANGUAGE_ID_FI_FI,// 芬兰文 (芬兰)
LANGUAGE_ID_FI_FI_EURO,// 芬兰文 (芬兰,EURO)
LANGUAGE_ID_FR,// 法文
LANGUAGE_ID_FR_BE,// 法文 (比利时)
LANGUAGE_ID_FR_BE_EURO,// 法文 (比利时,EURO)
LANGUAGE_ID_FR_CA,// 法文 (加拿大)
LANGUAGE_ID_FR_CH,// 法文 (瑞士)
LANGUAGE_ID_FR_FR,// 法文 (法国)
LANGUAGE_ID_FR_FR_EURO,// 法文 (法国,EURO)
LANGUAGE_ID_FR_LU,// 法文 (卢森堡)
LANGUAGE_ID_FR_LU_EURO,// 法文 (卢森堡,EURO)
LANGUAGE_ID_HR,// 克罗地亚文
LANGUAGE_ID_HR_HR,// 克罗地亚文 (克罗地亚)
LANGUAGE_ID_HU,// 匈牙利文
LANGUAGE_ID_HU_HU,// 匈牙利文 (匈牙利)
LANGUAGE_ID_IS,// 冰岛文
LANGUAGE_ID_IS_IS,// 冰岛文 (冰岛)
LANGUAGE_ID_IT,// 意大利文
LANGUAGE_ID_IT_CH,// 意大利文 (瑞士)
LANGUAGE_ID_IT_IT,// 意大利文 (意大利)
LANGUAGE_ID_IT_IT_EURO,// 意大利文 (意大利,EURO)
LANGUAGE_ID_IW,// 希伯来文
LANGUAGE_ID_IW_IL,// 希伯来文 (以色列)
LANGUAGE_ID_JA,// 日文
LANGUAGE_ID_JA_JP,// 日文 (日本)
LANGUAGE_ID_KO,// 朝鲜文
LANGUAGE_ID_KO_KR,// 朝鲜文 (南朝鲜)
LANGUAGE_ID_LT,// 立陶宛文
LANGUAGE_ID_LT_LT,// 立陶宛文 (立陶宛)
LANGUAGE_ID_LV,// 拉托维亚文(列托)
LANGUAGE_ID_LV_LV,// 拉托维亚文(列托) (拉脱维亚)
LANGUAGE_ID_MK,// 马其顿文
LANGUAGE_ID_MK_MK,// 马其顿文 (马其顿王国)
LANGUAGE_ID_NL,// 荷兰文
LANGUAGE_ID_NL_BE,// 荷兰文 (比利时)
LANGUAGE_ID_NL_BE_EURO,// 荷兰文 (比利时,EURO)
LANGUAGE_ID_NL_NL,// 荷兰文 (荷兰)
LANGUAGE_ID_NL_NL_EURO,// 荷兰文 (荷兰,EURO)
LANGUAGE_ID_NO,// 挪威文
LANGUAGE_ID_NO_NO,// 挪威文 (挪威)
LANGUAGE_ID_NO_NO_NY,// 挪威文 (挪威,NYNORSK)
LANGUAGE_ID_PL,// 波兰文
LANGUAGE_ID_PL_PL,// 波兰文 (波兰)
LANGUAGE_ID_PT,// 葡萄牙文
LANGUAGE_ID_PT_BR,// 葡萄牙文 (巴西)
LANGUAGE_ID_PT_PT,// 葡萄牙文 (葡萄牙)
LANGUAGE_ID_PT_PT_EURO,// 葡萄牙文 (葡萄牙,EURO)
LANGUAGE_ID_RO,// 罗马尼亚文
LANGUAGE_ID_RO_RO,// 罗马尼亚文 (罗马尼亚)
LANGUAGE_ID_RU,// 俄文
LANGUAGE_ID_RU_RU,// 俄文 (俄罗斯)
LANGUAGE_ID_SH,// 塞波尼斯-克罗地亚文
LANGUAGE_ID_SH_YU,// 塞波尼斯-克罗地亚文 (南斯拉夫)
LANGUAGE_ID_SK,// 斯洛伐克文
LANGUAGE_ID_SK_SK,// 斯洛伐克文 (斯洛伐克)
LANGUAGE_ID_SL,// 斯洛文尼亚文
LANGUAGE_ID_SL_SI,// 斯洛文尼亚文 (斯洛文尼亚)
LANGUAGE_ID_SQ,// 阿尔巴尼亚文
LANGUAGE_ID_SQ_AL,// 阿尔巴尼亚文 (阿尔巴尼亚)
LANGUAGE_ID_SR,// 塞尔维亚文
LANGUAGE_ID_SR_YU,// 塞尔维亚文 (南斯拉夫)
LANGUAGE_ID_SV,// 瑞典文
LANGUAGE_ID_SV_SE,// 瑞典文 (瑞典)
LANGUAGE_ID_TH,// 泰文
LANGUAGE_ID_TH_TH,// 泰文 (泰国)
LANGUAGE_ID_TR,// 土耳其文
LANGUAGE_ID_TR_TR,// 土耳其文 (土耳其)
LANGUAGE_ID_UK,// 乌克兰文
LANGUAGE_ID_UK_UA,// 乌克兰文 (乌克兰)
LANGUAGE_ID_ZH,// 中文
LANGUAGE_ID_ZH_CN,// 中文 (中国)
LANGUAGE_ID_ZH_HK,// 中文 (香港)
LANGUAGE_ID_ZH_TW,// 中文 (台湾)
LANGUAGE_ID_NUMS,
};
struct area_id_name{
int type;
int id;
char country_area[32]; //country or area name such as china
char locale_language[4]; //locale language name such as zh
char locale_region[8]; //locale region name such as CN
char country_geo[20]; //country geographical position such as asia
char timezone[32]; //time zone such as Asia/Shanghai
char user_define[20]; //user-defined name such as A10,A12,A13
};
struct operator_id_name{
int type; //type
int id;
char operator_name[20]; //operator name such as CHINA MOBILE
char locale_region[8]; //area name such as CN
};
struct reserve_id_name{
int type; //type
int id;
char reserve_name[20]; //reserve name
char locale_region[20];
};
struct device_id_name{
char type; //device type
char id; //board id
char type_name[14];
char driver_name[16];
char dev_name[16]; //name
char description[30]; // description
unsigned short device_id;//device_id and only one
//short select; // 1:device is selected 0:not
};
#define BOARD_ID_IOCTL_BASE 'b'
//#define BOARD_ID_IOCTL_READ_ALL _IOWR(BOARD_ID_IOCTL_BASE, 0x00, struct board_id_private_data)
//#define BOARD_ID_IOCTL_WRITE_ALL _IOWR(BOARD_ID_IOCTL_BASE, 0x30, struct board_id_private_data)
#define BOARD_ID_IOCTL_READ_AREA_ID _IOR(BOARD_ID_IOCTL_BASE, 0x80, struct area_id_name)
#define BOARD_ID_IOCTL_READ_OPERATOR_ID _IOR(BOARD_ID_IOCTL_BASE, 0x81, struct operator_id_name)
#define BOARD_ID_IOCTL_READ_RESERVE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x82, struct reserve_id_name)
#define BOARD_ID_IOCTL_READ_AREA_NAME_BY_ID _IOWR(BOARD_ID_IOCTL_BASE, 0x70, struct area_id_name)
#define BOARD_ID_IOCTL_READ_OPERATOR_NAME_BY_ID _IOWR(BOARD_ID_IOCTL_BASE, 0x71, struct operator_id_name)
#define BOARD_ID_IOCTL_READ_RESERVE_NAME_BY_ID _IOWR(BOARD_ID_IOCTL_BASE, 0x72, struct reserve_id_name)
#define BOARD_ID_IOCTL_READ_DEVICE_NAME_BY_ID _IOWR(BOARD_ID_IOCTL_BASE, 0x73, struct device_id_name)
#define BOARD_ID_IOCTL_READ_TP_ID _IOR(BOARD_ID_IOCTL_BASE, 0x01, struct device_id_name)
#define BOARD_ID_IOCTL_READ_LCD_ID _IOR(BOARD_ID_IOCTL_BASE, 0x02, struct device_id_name)
#define BOARD_ID_IOCTL_READ_KEY_ID _IOR(BOARD_ID_IOCTL_BASE, 0x03, struct device_id_name)
#define BOARD_ID_IOCTL_READ_CODEC_ID _IOR(BOARD_ID_IOCTL_BASE, 0x04, struct device_id_name)
#define BOARD_ID_IOCTL_READ_WIFI_ID _IOR(BOARD_ID_IOCTL_BASE, 0x05, struct device_id_name)
#define BOARD_ID_IOCTL_READ_BT_ID _IOR(BOARD_ID_IOCTL_BASE, 0x06, struct device_id_name)
#define BOARD_ID_IOCTL_READ_GPS_ID _IOR(BOARD_ID_IOCTL_BASE, 0x07, struct device_id_name)
#define BOARD_ID_IOCTL_READ_FM_ID _IOR(BOARD_ID_IOCTL_BASE, 0x08, struct device_id_name)
#define BOARD_ID_IOCTL_READ_MODEM_ID _IOR(BOARD_ID_IOCTL_BASE, 0x09, struct device_id_name)
#define BOARD_ID_IOCTL_READ_DDR_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0a, struct device_id_name)
#define BOARD_ID_IOCTL_READ_FLASH_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0b, struct device_id_name)
#define BOARD_ID_IOCTL_READ_HDMI_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0c, struct device_id_name)
#define BOARD_ID_IOCTL_READ_BATTERY_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0d, struct device_id_name)
#define BOARD_ID_IOCTL_READ_CHARGE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0e, struct device_id_name)
#define BOARD_ID_IOCTL_READ_BACKLIGHT_ID _IOR(BOARD_ID_IOCTL_BASE, 0x0f, struct device_id_name)
#define BOARD_ID_IOCTL_READ_HEADSET_ID _IOR(BOARD_ID_IOCTL_BASE, 0x10, struct device_id_name)
#define BOARD_ID_IOCTL_READ_MICPHONE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x11, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SPEAKER_ID _IOR(BOARD_ID_IOCTL_BASE, 0x12, struct device_id_name)
#define BOARD_ID_IOCTL_READ_VIBRATOR_ID _IOR(BOARD_ID_IOCTL_BASE, 0x13, struct device_id_name)
#define BOARD_ID_IOCTL_READ_TV_ID _IOR(BOARD_ID_IOCTL_BASE, 0x14, struct device_id_name)
#define BOARD_ID_IOCTL_READ_ECHIP_ID _IOR(BOARD_ID_IOCTL_BASE, 0x15, struct device_id_name)
#define BOARD_ID_IOCTL_READ_HUB_ID _IOR(BOARD_ID_IOCTL_BASE, 0x16, struct device_id_name)
#define BOARD_ID_IOCTL_READ_TPAD_ID _IOR(BOARD_ID_IOCTL_BASE, 0x17, struct device_id_name)
#define BOARD_ID_IOCTL_READ_PMIC_ID _IOR(BOARD_ID_IOCTL_BASE, 0x20, struct device_id_name)
#define BOARD_ID_IOCTL_READ_REGULATOR_ID _IOR(BOARD_ID_IOCTL_BASE, 0x21, struct device_id_name)
#define BOARD_ID_IOCTL_READ_RTC_ID _IOR(BOARD_ID_IOCTL_BASE, 0x22, struct device_id_name)
#define BOARD_ID_IOCTL_READ_CAMERA_FRONT_ID _IOR(BOARD_ID_IOCTL_BASE, 0x23, struct device_id_name)
#define BOARD_ID_IOCTL_READ_CAMERA_BACK_ID _IOR(BOARD_ID_IOCTL_BASE, 0x24, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_ANGLE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x25, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_ACCEL_ID _IOR(BOARD_ID_IOCTL_BASE, 0x26, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_COMPASS_ID _IOR(BOARD_ID_IOCTL_BASE, 0x27, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_GYRO_ID _IOR(BOARD_ID_IOCTL_BASE, 0x28, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_LIGHT_ID _IOR(BOARD_ID_IOCTL_BASE, 0x29, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_PROXIMITY_ID _IOR(BOARD_ID_IOCTL_BASE, 0x2A, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_TEMPERATURE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x2B, struct device_id_name)
#define BOARD_ID_IOCTL_READ_SENSOR_PRESSURE_ID _IOR(BOARD_ID_IOCTL_BASE, 0x2C, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_AREA_ID _IOW(BOARD_ID_IOCTL_BASE, 0x90, struct area_id_name)
#define BOARD_ID_IOCTL_WRITE_OPERATOR_ID _IOW(BOARD_ID_IOCTL_BASE, 0x91, struct operator_id_name)
#define BOARD_ID_IOCTL_WRITE_RESERVE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x92, struct reserve_id_name)
#define BOARD_ID_IOCTL_WRITE_TP_ID _IOW(BOARD_ID_IOCTL_BASE, 0x31, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_LCD_ID _IOW(BOARD_ID_IOCTL_BASE, 0x32, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_KEY_ID _IOW(BOARD_ID_IOCTL_BASE, 0x33, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_CODEC_ID _IOW(BOARD_ID_IOCTL_BASE, 0x34, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_WIFI_ID _IOW(BOARD_ID_IOCTL_BASE, 0x35, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_BT_ID _IOW(BOARD_ID_IOCTL_BASE, 0x36, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_GPS_ID _IOW(BOARD_ID_IOCTL_BASE, 0x37, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_FM_ID _IOW(BOARD_ID_IOCTL_BASE, 0x38, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_MODEM_ID _IOW(BOARD_ID_IOCTL_BASE, 0x39, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_DDR_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3a, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_FLASH_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3b, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_HDMI_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3c, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_BATTERY_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3d, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_CHARGE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3e, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_BACKLIGHT_ID _IOW(BOARD_ID_IOCTL_BASE, 0x3f, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_HEADSET_ID _IOW(BOARD_ID_IOCTL_BASE, 0x40, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_MICPHONE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x41, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SPEAKER_ID _IOW(BOARD_ID_IOCTL_BASE, 0x42, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_VIBRATOR_ID _IOW(BOARD_ID_IOCTL_BASE, 0x43, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_TV_ID _IOW(BOARD_ID_IOCTL_BASE, 0x44, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_ECHIP_ID _IOW(BOARD_ID_IOCTL_BASE, 0x45, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_HUB_ID _IOW(BOARD_ID_IOCTL_BASE, 0x46, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_TPAD_ID _IOW(BOARD_ID_IOCTL_BASE, 0x47, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_PMIC_ID _IOW(BOARD_ID_IOCTL_BASE, 0x50, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_REGULATOR_ID _IOW(BOARD_ID_IOCTL_BASE, 0x51, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_RTC_ID _IOW(BOARD_ID_IOCTL_BASE, 0x52, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_CAMERA_FRONT_ID _IOW(BOARD_ID_IOCTL_BASE, 0x53, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_CAMERA_BACK_ID _IOW(BOARD_ID_IOCTL_BASE, 0x54, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_ANGLE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x55, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_ACCEL_ID _IOW(BOARD_ID_IOCTL_BASE, 0x56, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_COMPASS_ID _IOW(BOARD_ID_IOCTL_BASE, 0x57, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_GYRO_ID _IOW(BOARD_ID_IOCTL_BASE, 0x58, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_LIGHT_ID _IOW(BOARD_ID_IOCTL_BASE, 0x59, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_PROXIMITY_ID _IOW(BOARD_ID_IOCTL_BASE, 0x5A, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_TEMPERATURE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x5B, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_SENSOR_PRESSURE_ID _IOW(BOARD_ID_IOCTL_BASE, 0x5C, struct device_id_name)
#define BOARD_ID_IOCTL_WRITE_AREA_FLASH _IOW(BOARD_ID_IOCTL_BASE, 0x60, struct area_id_name)
#define BOARD_ID_IOCTL_WRITE_DEVICE_FLASH _IOW(BOARD_ID_IOCTL_BASE, 0x61, struct device_id_name)
#define BOARD_ID_IOCTL_READ_STATUS _IOR(BOARD_ID_IOCTL_BASE, 0x62, char)
#define BOARD_ID_IOCTL_READ_VENDOR_DATA _IOR(BOARD_ID_IOCTL_BASE, 0x63, char[DEVICE_NUM_TYPES])
int board_id_open_device(void);
int board_id_close_device(void);
int board_id_get_locale_region(enum type_devices type, char *country_area, char *locale_language, char *locale_region, char *country_geo, char *timezone, char *user_define);
int board_id_get_operator_name(enum type_devices type, char *locale_region, char *operator_name);
int board_id_get_reserve_name(enum type_devices type, char *locale_region, char *reserve_name);
int board_id_get_device_name(enum type_devices type, char *type_name, char *dev_name);
int board_id_get_locale_region_by_id(enum type_devices type, char *id, char *country_area, char *locale_language, char *locale_region, char *country_geo, char *timezone, char *user_define);
int board_id_get_operator_name_by_id(enum type_devices type, char *id, char *locale_region, char *operator_name);
int board_id_get_reserve_name_by_id(enum type_devices type, char *id, char *locale_region, char *reserve_name);
int board_id_get_device_name_by_id(enum type_devices type, char *id, char *type_name, char *dev_name);
int board_id_get(char *id);
#endif /* BOARD_ID_CTRL_H_ */
/*
* custom.c
*
* Created on: 2013-4-27
* Author: mmk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "parse_xml.h"
#include "board_id_ctrl.h"
#include "common.h"
static int run(const char *filename, char *const argv[])
{
struct stat s;
int status;
pid_t pid;
if (stat(filename, &s) != 0) {
E("cannot find '%s'", filename);
return -1;
}
pid = fork();
if (pid == 0) {
setpgid(0, getpid());
/* execute */
execv(filename, argv);
E("can't execv %s (%s)", filename, strerror(errno) );
/* exit */
_exit(0);
}
if (pid < 0) {
E("failed to fork and start '%s'", filename);
return -1;
}
if (-1 == waitpid(pid, &status, WCONTINUED | WUNTRACED)) {
E("wait for child error");
return -1;
}
D("executed '%s' return %d", filename, WEXITSTATUS(status) );
return 0;
}
static int setProp(char *name, char *value) {
char buf[128];
char *cmd[6];
uint length;
memset(buf, 0, sizeof(buf));
sprintf(buf, "/%s/d", name); // "/<pattern>/d" : sed 的查找删除行 命令.
cmd[0] = "/sbin/busybox";
cmd[1] = "sed";
cmd[2] = "-i";
cmd[3] = buf;
cmd[4] = "system/build.prop";
cmd[5] = NULL;
D("%s %s %s %s %s ", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
run(cmd[0], cmd);
FILE *f = fopen("system/build.prop", "a"); // "a" : append.
if(f == NULL) {
E("fial to open system/build.prop, err : %s.", strerror(errno) );
return -1;
}
memset(buf, 0, sizeof(buf));
sprintf(buf, "\n%s=%s", name, value);
length = strlen(name) + strlen(value) + 2;
//fseek(f, 0, SEEK_END);
if(length != fwrite(buf, 1, length, f)) {
E("write prop error =============");
fclose(f);
return -1;
}
I("success to set property.");
fclose(f);
return 0;
}
void customHandler(char *command, int argc, char **argv) {
char *cmd[10];
char *str;
char *str1;
char str3[128];
if(!strcmp(command, "cp") || !strcmp(command, "CP")) {
str = strrchr(argv[1], '/');
str1 = strndup(argv[1], str - argv[1]);
strcpy(str3, "cust/backup/");
strcat(str3, str1);
D("to mkdir '%s'.", str3);
//mkdir des target
cmd[0] = "/sbin/busybox";
cmd[1] = "mkdir";
cmd[2] = "-p";
cmd[3] = str3;
cmd[4] = NULL;
run(cmd[0], cmd);
//backup des target. 实际上备份 fw_in_cur_ota_ver.
cmd[1] = "cp";
cmd[2] = "-a"; // .! : -a, --archive : same as -dR --preserve=all
cmd[3] = argv[1];
cmd[4] = str3;
cmd[5] = NULL;
run(cmd[0], cmd);
//cp src to des
cmd[3] = argv[0];
cmd[4] = argv[1];
cmd[5] = NULL;
run(cmd[0], cmd);
//chmod des
cmd[1] = "chmod";
cmd[2] = argv[2];
cmd[3] = argv[1];
cmd[4] = NULL;
run(cmd[0], cmd);
free(str1);
}else if(!strcmp(command, "rm") || !strcmp(command, "RM")) {
str = strrchr(argv[0], '/');
str1 = strndup(argv[0], str - argv[0]);
strcpy(str3, "cust/backup/");
strcat(str3, str1);
D("to mkdir '%s'.", str3);
//mkdir des target
cmd[0] = "/sbin/busybox";
cmd[1] = "mkdir";
cmd[2] = "-p";
cmd[3] = str3;
cmd[4] = NULL;
run(cmd[0], cmd);
//backup src target
cmd[1] = "cp";
cmd[2] = "-a";
cmd[3] = argv[0];
cmd[4] = str3;
cmd[5] = NULL;
run(cmd[0], cmd);
//rm src
cmd[1] = "rm";
cmd[2] = argv[0];
cmd[3] = NULL;
run(cmd[0], cmd);
free(str1);
}else if(!strcmp(command, "set") || !strcmp(command, "SET")) {
setProp(argv[0], argv[1]);
}
}
int saveBoardIdToFile(char *board_id) {
FILE *fp_id;
fp_id = fopen("cust/last_board_id", "w");
if(fp_id == NULL) {
E("fial to open file last_board_id; err : %s.", strerror(errno) );
return -1;
}
uint length = DEVICE_NUM_TYPES;
D("length:%d", length);
uint i;
for(i = 0; i < length; i++) {
D("board-id: %d.", *(board_id+i));
}
if(1 != fwrite(&length, 4, 1, fp_id)) {
E("fail to write length, err : %s.", strerror(errno) );
fclose(fp_id);
return -1;
}
if(length != fwrite(board_id, 1, length, fp_id)) {
E("fail to write board id, err = %s.", strerror(errno) );
fclose(fp_id);
return -1;
}
I("save board id success!");
fclose(fp_id);
return 0;
}
int backupProp() {
char *cmd[10];
cmd[0] = "/sbin/busybox";
cmd[1] = "mkdir";
cmd[2] = "-p";
cmd[3] = "cust/backup/system";
cmd[4] = NULL;
run(cmd[0], cmd);
cmd[1] = "cp";
cmd[2] = "-a";
cmd[3] = "system/build.prop";
cmd[4] = "cust/backup/system/build.prop";
cmd[5] = NULL;
run(cmd[0], cmd);
I("backup build.prop complete!");
return 0;
}
int custom() {
char area[32];
char language[32];
char local[32];
char geo[32];
char timezone[32];
char user_define[32];
char operator[32];
char reserve[32];
FILE *fp_area;
I("*********** start custom ***************");
board_id_open_device();
//get language from ioctrl
memset(area, 0, sizeof(area));
memset(language, 0, sizeof(language));
memset(local, 0, sizeof(local));
memset(geo, 0, sizeof(geo));
memset(timezone, 0, sizeof(timezone));
memset(user_define, 0, sizeof(user_define));
memset(operator, 0, sizeof(operator));
memset(reserve, 0, sizeof(reserve));
board_id_get_operator_name(DEVICE_TYPE_OPERATOR, local, operator);
board_id_get_reserve_name(DEVICE_TYPE_RESERVE, local, reserve);
board_id_get_locale_region(DEVICE_TYPE_AREA, area, language, local, geo, timezone, user_define);
D("get area form ioctrl: area=%s, language=%s, local=%s, timezone=%s, operator=%s, reserve=%s",
area,
language,
local,
timezone,
operator,
reserve);
fp_area = fopen("/cust/cust.xml", "r");
if(fp_area == NULL) {
E("fial to open area.xml, err : %s!", strerror(errno) );
board_id_close_device();
return -1;
}
//must backup build.prop first. .R : 定制操作中, /system/build.prop 将以 line 为单位被修改.
backupProp();
// .KP : 在解析 /cust/cust.xml 的流程中, 同时完成对应的 定制化 (custom) 处理. 这里使用策略回调的形式.
if(parse_area(fp_area, area, local, language, operator, reserve, customHandler)) {
E("=============> parse area.xml error <===========");
fclose(fp_area);
board_id_close_device();
return -1;
}
fclose(fp_area);
//get devices from ioctrl
int i;
char type[32];
char dev[32];
FILE *fp_device;
fp_device = fopen("/cust/device.xml", "r");
if(fp_device == NULL) {
E("fail to open device.xml, err : %s!", strerror(errno) );
board_id_close_device();
return -1;
}
/* 循环地, 从内核获取 所有 设备的 字串形态的 type 和 dev_name. */
for(i = DEVICE_TYPE_TP; i < DEVICE_NUM_TYPES; i++) {
memset(type, 0, sizeof(type));
memset(dev, 0, sizeof(dev));
if(board_id_get_device_name(i, type, dev)) {
E("===========> get device info error <===========");
fclose(fp_device);
board_id_close_device();
return -1;
}
D("get device info from ioctrl: type=%s, dev=%s ", type, dev);
// .KP : 在解析 /cust/devicie.xml 的流程中, 同时完成对应的 定制化 (custom) 处理,
if(parse_device(fp_device, dev, type, customHandler)) {
E("===========> parse device.xml error <==========");
fclose(fp_device);
board_id_close_device();
return -1;
}
}
char board_id[DEVICE_NUM_TYPES];
memset(board_id, 0, sizeof(board_id));
board_id_get(board_id);
if(saveBoardIdToFile(board_id)) {
E("save board id to file error! ");
fclose(fp_device);
board_id_close_device();
return -1;
}
fclose(fp_device);
board_id_close_device();
return 0;
}
/*
* custom.h
*
* Created on: 2013-4-27
* Author: mmk
*/
#ifndef CUSTOM_H_
#define CUSTOM_H_
int custom();
#endif /* CUSTOM_H_ */
/*
* xml_helper.c
*
* Created on: 2013-4-27
* Author: mmk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "parse_xml.h"
#include "libxml/parser.h"
#include "libxml/tree.h"
#include "libxml/xpath.h"
#include "libxml/SAX2.h"
#include "libxml/xmlstring.h"
#include "common.h"
extern void customHandler(char *command, int argc, char **argv);
static volatile bool gIfMatch = false;
static xmlChar *gArea;
static xmlChar *gLocal;
static xmlChar *gLanguage;
static xmlChar *gOperator;
static xmlChar *gReserve;
static handlerFun gHandlerFun;
static xmlChar* getAttrValueByName(xmlChar *name, int attrNum, const xmlChar **attributes) {
LOGV("getAttrValueByName: attr Num %d \n", attrNum);
int i;
for(i = 0; i < attrNum; i++) {
LOGV("attrname = %s\n", attributes[i*5]);
if(!xmlStrcmp(attributes[i*5], name)) {
const xmlChar* str = xmlStrchr(attributes[i*5 + 3], '"');
xmlChar* ret = xmlStrndup(attributes[i*5 + 3], str - attributes[i*5 + 3]);
LOGV("value = %s \n", ret);
return ret;
}
}
return NULL;
}
static int attrCmp(xmlChar *attr, xmlChar *value) {
if(attr == NULL && value == NULL) {
return 0;
}
if(attr != NULL && value == NULL) {
return -1;
}
if(attr == NULL && value != NULL) {
return 0;
}
LOGV("attrcmp: attr=%s, value=%s \n", attr, value);
if(*attr == '!') {
if(!xmlStrcmp(attr + 1, value)) {
return -1;
}
}else {
if(xmlStrcmp(attr, value)) {
return -1;
}
}
return 0;
}
static void cust_OnStartElementNs( void *ctx,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI,
int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar **attributes)
{
xmlChar *attr1 = NULL;
xmlChar *attr2 = NULL;
xmlChar *attr3 = NULL;
xmlChar *attr4 = NULL;
xmlChar *attr5 = NULL;
char odex_path[128];
char *odex_argv[1];
LOGV("start element tag: %s, attr number %d, default attr num %d, gIfMatch=%d \n",
localname, nb_attributes, nb_defaulted, gIfMatch);
if(!xmlStrcmp(localname, BAD_CAST "if")) {
attr1 = getAttrValueByName(BAD_CAST "language", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "region", nb_attributes, attributes);
attr3 = getAttrValueByName(BAD_CAST "operator", nb_attributes, attributes);
attr4 = getAttrValueByName(BAD_CAST "reserve", nb_attributes, attributes);
attr5 = getAttrValueByName(BAD_CAST "area", nb_attributes, attributes);
gIfMatch = true;
if(attrCmp(attr1, gLanguage)) {
gIfMatch = false;
}
if(attrCmp(attr2, gLocal)) {
gIfMatch = false;
}
if(attrCmp(attr3, gOperator)) {
gIfMatch = false;
}
if(attrCmp(attr4, gReserve)) {
gIfMatch = false;
}
if(attrCmp(attr5, gArea)) {
gIfMatch = false;
}
if(gIfMatch) {
LOGI("==========> catch a cust condition\n");
}
}else if(!xmlStrcmp(localname, BAD_CAST "cp") || !xmlStrcmp(localname, BAD_CAST "CP")) {
if(gIfMatch) {
// do copy
attr1 = getAttrValueByName(BAD_CAST "src", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "des", nb_attributes, attributes);
attr3 = getAttrValueByName(BAD_CAST "mode", nb_attributes, attributes);
LOGD("cp %s %s %s\n", attr1, attr2, attr3);
char* argv[3];
argv[0] = (char *)attr1;
argv[1] = (char *)attr2;
argv[2] = (char *)attr3;
gHandlerFun((char *)localname, 3, argv);
//rm odex file
if(strstr(argv[1], "system/app/") != NULL && strstr(argv[1], "apk") != NULL) {
char *tmp = strstr(argv[1], "apk");
memset(odex_path, 0, sizeof(odex_path));
strncpy(odex_path, argv[1], tmp - argv[1]);
strcat(odex_path, "odex");
LOGD("rm %s\n", odex_path);
odex_argv[0] = odex_path;
customHandler("rm", 1, odex_argv);
}
}
}else if(!xmlStrcmp(localname, BAD_CAST "rm") || !xmlStrcmp(localname, BAD_CAST "RM")) {
if(gIfMatch) {
// do remove
attr1 = getAttrValueByName(BAD_CAST "src", nb_attributes, attributes);
LOGD("rm %s \n", attr1);
char *argv[1];
argv[0] = (char *)attr1;
gHandlerFun((char *)localname, 1, argv);
//rm odex file
if(strstr(argv[0], "system/app/") != NULL && strstr(argv[0], "apk") != NULL) {
char *tmp = strstr(argv[0], "apk");
memset(odex_path, 0, sizeof(odex_path));
strncpy(odex_path, argv[0], tmp - argv[0]);
strcat(odex_path, "odex");
LOGD("rm %s\n", odex_path);
odex_argv[0] = odex_path;
gHandlerFun("rm", 1, odex_argv);
}
}
}else if(!xmlStrcmp(localname, BAD_CAST "set") || !xmlStrcmp(localname, BAD_CAST "SET")) {
if(gIfMatch) {
// do remove
attr1 = getAttrValueByName(BAD_CAST "name", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "value", nb_attributes, attributes);
LOGD("set %s=%s \n", attr1, attr2);
char *argv[2];
argv[0] = (char *)attr1;
argv[1] = (char *)attr2;
gHandlerFun((char *)localname, 2, argv);
}
}
if(attr1 != NULL) {
xmlFree(attr1);
}
if(attr2 != NULL) {
xmlFree(attr2);
}
if(attr3 != NULL) {
xmlFree(attr3);
}
if(attr4 != NULL) {
xmlFree(attr4);
}
if(attr5 != NULL) {
xmlFree(attr5);
}
}
static void cust_OnEndElementNs(
void* ctx,
const xmlChar* localname,
const xmlChar* prefix,
const xmlChar* URI )
{
LOGV("end element tag: %s \n", localname);
if(!xmlStrcmp(localname, BAD_CAST "if")) {
gIfMatch = false;
}
}
static void cust_OnCharacters(void *ctx, const xmlChar *ch, int len)
{
}
int parse_area(FILE *f,
char *area,
char *local,
char *language,
char *operator,
char *reserve,
handlerFun handler)
{
int readcount;
char chunk[1024];
gArea = (xmlChar*)area;
gLocal = BAD_CAST local;
gLanguage = BAD_CAST language;
gOperator = BAD_CAST operator;
gReserve = BAD_CAST reserve;
gHandlerFun = handler;
gIfMatch = false;
xmlInitParser();
xmlSAXHandler SAXHander;
memset(&SAXHander, 0, sizeof(xmlSAXHandler));
SAXHander.initialized = XML_SAX2_MAGIC;
SAXHander.startElementNs = cust_OnStartElementNs;
SAXHander.endElementNs = cust_OnEndElementNs;
SAXHander.characters = cust_OnCharacters;
fseek(f, 0, SEEK_SET);
readcount = fread(chunk, 1, 4, f);
xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(&SAXHander, NULL, chunk, readcount, NULL);
while ((readcount = fread(chunk, 1, sizeof(chunk), f)) > 0)
{
if(xmlParseChunk(ctxt, chunk, readcount, 0))
{
xmlParserError(ctxt, "xmlParseChunk");
return 1;
}
}
xmlParseChunk(ctxt, chunk, 0, 1);
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
return 0;
}
/*
* parse_device.c
*
* Created on: 2013-5-8
* Author: mmk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "parse_xml.h"
#include "libxml/parser.h"
#include "libxml/tree.h"
#include "libxml/xpath.h"
#include "libxml/SAX2.h"
#include "libxml/xmlstring.h"
#include "common.h"
static bool gIfMatch = false;
/* 当前机器上, 当前定制处理的设备实例机器类型的字串标识. 诸如 type="tp" dev="Goodix-TS"; 用来匹配 device.xml 中的对应 element. */
static xmlChar *gDev;
static xmlChar *gType;
/**
* 根据 device.xml 的内容, 具体完成定制操作的策略回调函数.
* 对于 custom 操作, 是 custom.c, customHandler().
* 对于 restore 操作, 是 restore.c, restoreHandler().
*/
static handlerFun gHandlerFun;
static xmlChar* getAttrValueByName(xmlChar *name, int attrNum, const xmlChar **attributes) {
LOGV("getAttrValueByName: attr Num %d \n", attrNum);
int i;
for(i = 0; i < attrNum; i++) {
LOGV("attrname = %s\n", attributes[i*5]);
if(!xmlStrcmp(attributes[i*5], name)) {
const xmlChar* str = xmlStrchr(attributes[i*5 + 3], '"');
xmlChar* ret = xmlStrndup(attributes[i*5 + 3], str - attributes[i*5 + 3]);
LOGV("value = %s \n", ret);
return ret;
}
}
return NULL;
}
static int attrCmp(xmlChar *attr, xmlChar *value) {
if(attr == NULL && value == NULL) {
return 0;
}
if(attr != NULL && value == NULL) {
return -1;
}
if(attr == NULL && value != NULL) {
return 0;
}
LOGV("attrcmp: attr=%s, value=%s \n", attr, value);
if(*attr == '!') {
if(!xmlStrcmp(attr + 1, value)) {
return -1;
}
}else {
if(xmlStrcmp(attr, value)) {
return -1;
}
}
return 0;
}
static void device_OnStartElementNs(
void *ctx,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI,
int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar **attributes)
{
xmlChar *attr1 = NULL;
xmlChar *attr2 = NULL;
xmlChar *attr3 = NULL;
if(!xmlStrcmp(localname, BAD_CAST "if")) {
attr1 = getAttrValueByName(BAD_CAST "type", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "dev", nb_attributes, attributes);
gIfMatch = true;
if(attrCmp(attr1, gType)) {
gIfMatch = false;
}
if(attrCmp(attr2, gDev)) {
gIfMatch = false;
}
if(gIfMatch) {
LOGE("==========> catch a device condition\n");
}
}else if(!xmlStrcmp(localname, BAD_CAST "cp") || !xmlStrcmp(localname, BAD_CAST "CP")) {
if(gIfMatch) {
// do copy
attr1 = getAttrValueByName(BAD_CAST "src", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "des", nb_attributes, attributes);
attr3 = getAttrValueByName(BAD_CAST "mode", nb_attributes, attributes);
LOGD("cp %s %s %s\n", attr1, attr2, attr3);
char *argv[3];
argv[0] = (char *)attr1;
argv[1] = (char *)attr2;
argv[2] = (char *)attr3;
gHandlerFun((char *)localname, 3, argv);
}
}else if(!xmlStrcmp(localname, BAD_CAST "rm") || !xmlStrcmp(localname, BAD_CAST "RM")) {
if(gIfMatch) {
// do remove
attr1 = getAttrValueByName(BAD_CAST "src", nb_attributes, attributes);
LOGD("rm %s \n", attr1);
char *argv[1];
argv[0] = (char *)attr1;
gHandlerFun((char *)localname, 1, argv);
}
}else if(!xmlStrcmp(localname, BAD_CAST "set") || !xmlStrcmp(localname, BAD_CAST "SET")) {
if(gIfMatch) {
// do set
attr1 = getAttrValueByName(BAD_CAST "name", nb_attributes, attributes);
attr2 = getAttrValueByName(BAD_CAST "value", nb_attributes, attributes);
LOGD("set %s=%s \n", attr1, attr2);
char *argv[2];
argv[0] = (char *)attr1;
argv[1] = (char *)attr2;
gHandlerFun((char *)localname, 2, argv);
}
}
if(attr1 != NULL) {
xmlFree(attr1);
}
if(attr2 != NULL) {
xmlFree(attr2);
}
if(attr3 != NULL) {
xmlFree(attr3);
}
}
static void device_OnEndElementNs(
void* ctx,
const xmlChar* localname,
const xmlChar* prefix,
const xmlChar* URI )
{
LOGV("end element tag: %s \n", localname);
if(!xmlStrcmp(localname, BAD_CAST "if")) {
gIfMatch = false;
}
}
static void device_OnCharacters(void *ctx, const xmlChar *ch, int len)
{
}
int parse_device(FILE *f, char *dev, char *type, handlerFun handler)
{
int readcount;
char chunk[1024];
gDev = BAD_CAST dev;
gType = BAD_CAST type;
gHandlerFun = handler;
gIfMatch = false;
xmlInitParser();
xmlSAXHandler SAXHander;
memset(&SAXHander, 0, sizeof(xmlSAXHandler));
SAXHander.initialized = XML_SAX2_MAGIC;
SAXHander.startElementNs = device_OnStartElementNs;
SAXHander.endElementNs = device_OnEndElementNs;
SAXHander.characters = device_OnCharacters;
fseek(f, 0, SEEK_SET);
readcount = fread(chunk, 1, 4, f);
xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(&SAXHander, NULL, chunk, readcount, NULL);
while ((readcount = fread(chunk, 1, sizeof(chunk), f)) > 0)
{
if(xmlParseChunk(ctxt, chunk, readcount, 0))
{
xmlParserError(ctxt, "xmlParseChunk");
return 1;
}
}
xmlParseChunk(ctxt, chunk, 0, 1);
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
return 0;
}
/*
* xml_helper.h
*
* Created on: 2013-4-27
* Author: mmk
*/
#ifndef XML_HELPER_H_
#define XML_HELPER_H_
typedef void (*handlerFun) (char *command, int argc, char **argv);
int parse_area(FILE *f,
char *area,
char *local,
char *language,
char *operator,
char *reserve,
handlerFun handler);
int parse_device(FILE *f, char *dev, char *type, handlerFun handler);
#endif /* XML_HELPER_H_ */
/*
* restore.c
*
* Created on: 2013-5-8
* Author: mmk
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "parse_xml.h"
#include "board_id_ctrl.h"
#include "common.h"
static int run(const char *filename, char *const argv[])
{
struct stat s;
int status;
pid_t pid;
if (stat(filename, &s) != 0) {
E("cannot find '%s', err : %s", filename, strerror(errno) );
return -1;
}
pid = fork();
if (pid == 0) {
setpgid(0, getpid());
/* execute */
execv(filename, argv);
LOGE("can't run %s (%s)\n", filename, strerror(errno));
/* exit */
_exit(0);
}
if (pid < 0) {
LOGE("failed to fork and start '%s'\n", filename);
return -1;
}
if (-1 == waitpid(pid, &status, WCONTINUED | WUNTRACED)) {
LOGD("wait for child error\n");
return -1;
}
LOGI("executed '%s' return %d\n", filename, WEXITSTATUS(status));
return 0;
}
void restoreHandler(char *command, int argc, char **argv) {
char *cmd[10];
char *str;
char *str1;
char str3[128];
if(!strcmp(command, "cp") || !strcmp(command, "CP")) {
strcpy(str3, "cust/backup/");
strcat(str3, argv[1]);
//rm des target
cmd[0] = "/sbin/busybox";
cmd[1] = "rm";
cmd[2] = argv[1];
cmd[3] = NULL;
run(cmd[0], cmd);
//recover from backup
cmd[1] = "cp";
cmd[2] = "-a";
cmd[3] = str3;
cmd[4] = argv[1];
cmd[5] = NULL;
run(cmd[0], cmd);
}else if(!strcmp(command, "rm") || !strcmp(command, "RM")) {
strcpy(str3, "cust/backup/");
strcat(str3, argv[0]);
//recovery from backup
cmd[0] = "/sbin/busybox";
cmd[1] = "cp";
cmd[2] = "-a";
cmd[3] = str3;
cmd[4] = argv[0];
cmd[5] = NULL;
run(cmd[0], cmd);
}
}
char *readBoardIdFromFile() {
FILE *fp_id;
char *result;
fp_id = fopen("cust/last_board_id", "r");
if(fp_id == NULL) {
E("fial to open last_board_id, err : %s.", strerror(errno) );
return NULL;
}
int length;
if(1 != fread(&length, 4, 1, fp_id)) {
E("fail to read board id length, err : %s.", strerror(errno) );
fclose(fp_id);
return NULL;
}
D("length:%d", length);
result = malloc(length);
memset(result, 0, length);
if(length != fread(result, 1, length, fp_id)) {
E("fail to read board id, err : %s.", strerror(errno) );
free(result);
fclose(fp_id);
return NULL;
}
int i;
for(i = 0; i < length; i++) {
D("board-id: %d", *(result+i));
}
fclose(fp_id);
return result;
}
int cleanBackup() {
char *cmd[10];
cmd[0] = "/sbin/busybox";
cmd[1] = "rm";
cmd[2] = "-rf";
cmd[3] = "cust/backup/";
cmd[4] = NULL;
run(cmd[0], cmd);
cmd[3] = "cust/last_board_id";
run(cmd[0], cmd);
I("clean backup files complete!");
return 0;
}
int recoverProp() {
char *cmd[10];
cmd[0] = "/sbin/busybox";
cmd[1] = "cp";
cmd[2] = "-a";
cmd[3] = "cust/backup/system/build.prop";
cmd[4] = "system/build.prop";
cmd[5] = NULL;
run(cmd[0], cmd);
I("recover build.prop complete!");
return 0;
}
int restore() {
char *board_id;
printf("************* BOARD_ID version 0.92 ******************\n");
printf("************* start restore **************************\n");
board_id_open_device();
board_id = readBoardIdFromFile();
if(board_id == NULL) {
E("no find last board id, so not restore....");
board_id_close_device();
return 0;
}
//restore
char area[32];
char language[32];
char local[32];
char geo[32];
char timezone[32];
char user_define[32];
char operator[32];
char reserve[32];
FILE *fp_area;
//get language from ioctrl
memset(area, 0, sizeof(area));
memset(language, 0, sizeof(language));
memset(local, 0, sizeof(local));
memset(geo, 0, sizeof(geo));
memset(timezone, 0, sizeof(timezone));
memset(user_define, 0, sizeof(user_define));
memset(operator, 0, sizeof(operator));
memset(reserve, 0, sizeof(reserve));
board_id_get_operator_name_by_id(DEVICE_TYPE_OPERATOR, board_id, local, operator);
board_id_get_reserve_name_by_id(DEVICE_TYPE_RESERVE, board_id, local, reserve);
board_id_get_locale_region_by_id(DEVICE_TYPE_AREA, board_id, area, language, local, geo, timezone, user_define);
D("get area form ioctrl: area=%s, language=%s, local=%s, timezone=%s, operator=%s, reserve=%s",
area,
language,
local,
timezone,
operator,
reserve);
fp_area = fopen("/cust/cust.xml", "r");
if(fp_area == NULL) {
E("fail to open area.xml. err : %s.", strerror(errno) );
free(board_id);
board_id_close_device();
return -1;
}
if(parse_area(fp_area, area, local, language, operator, reserve, restoreHandler)) {
E("=============> parse area.xml error <===========");
fclose(fp_area);
free(board_id);
board_id_close_device();
return -1;
}
fclose(fp_area);
//get devices from ioctrl
int i;
char type[32];
char dev[32];
FILE *fp_device;
fp_device = fopen("/cust/device.xml", "r");
if(fp_device == NULL) {
E("fail to open device.xml, err : %s.", strerror(errno) );
free(board_id);
board_id_close_device();
return -1;
}
for(i = DEVICE_TYPE_TP; i < DEVICE_NUM_TYPES; i++) {
memset(type, 0, sizeof(type));
memset(dev, 0, sizeof(dev));
if(board_id_get_device_name_by_id(i, board_id, type, dev)) {
E("===========> get device info error <===========");
fclose(fp_device);
free(board_id);
board_id_close_device();
return -1;
}
D("get device info from ioctrl: type=%s, dev=%s ", type, dev);
if(parse_device(fp_device, dev, type, restoreHandler)) {
E("===========> parse device.xml error <==========");
fclose(fp_device);
free(board_id);
board_id_close_device();
return -1;
}
}
/* ָ֮ǰ /system/build.prop ota 汾. */
recoverProp();
cleanBackup();
free(board_id);
fclose(fp_device);
board_id_close_device();
return 0;
}
/*
* restore.h
*
* Created on: 2013-5-8
* Author: mmk
*/
#ifndef RESTORE_H_
#define RESTORE_H_
int restore();
#endif /* RESTORE_H_ */
......@@ -19,6 +19,7 @@
#include "common.h"
#include "mtdutils/mtdutils.h"
#include "roots.h"
#include "mtdutils/rk29.h"
#include <errno.h>
#include <stdio.h>
......@@ -31,6 +32,8 @@ static int set_bootloader_message_mtd(const struct bootloader_message *in, const
static int get_bootloader_message_block(struct bootloader_message *out, const Volume* v);
static int set_bootloader_message_block(const struct bootloader_message *in, const Volume* v);
static int get_bootloader_message_block_rk29(struct bootloader_message *out, const Volume* v);
static int set_bootloader_message_block_rk29(const struct bootloader_message *in, const Volume* v);
int get_bootloader_message(struct bootloader_message *out) {
Volume* v = volume_for_path("/misc");
if (v == NULL) {
......@@ -38,9 +41,14 @@ int get_bootloader_message(struct bootloader_message *out) {
return -1;
}
if (strcmp(v->fs_type, "mtd") == 0) {
#ifdef TARGET_RK3188
return get_bootloader_message_block_rk29(out, v);
#else
return get_bootloader_message_mtd(out, v);
#endif
} else if (strcmp(v->fs_type, "emmc") == 0) {
return get_bootloader_message_block(out, v);
return get_bootloader_message_block_rk29(out, v);
//return get_bootloader_message_block(out, v);
}
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
......@@ -53,9 +61,14 @@ int set_bootloader_message(const struct bootloader_message *in) {
return -1;
}
if (strcmp(v->fs_type, "mtd") == 0) {
#ifdef TARGET_RK3188
return set_bootloader_message_block_rk29(in, v);
#else
return set_bootloader_message_mtd(in, v);
#endif
} else if (strcmp(v->fs_type, "emmc") == 0) {
return set_bootloader_message_block(in, v);
return set_bootloader_message_block_rk29(in, v);
//return set_bootloader_message_block(in, v);
}
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
......@@ -169,7 +182,8 @@ static int get_bootloader_message_block(struct bootloader_message *out,
return -1;
}
struct bootloader_message temp;
int count = fread(&temp, sizeof(temp), 1, f);
int count = rk29_fread(&temp, sizeof(temp), 1, f);
//int count = fread(&temp, sizeof(temp), 1, f);
if (count != 1) {
LOGE("Failed reading %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
......@@ -185,12 +199,14 @@ static int get_bootloader_message_block(struct bootloader_message *out,
static int set_bootloader_message_block(const struct bootloader_message *in,
const Volume* v) {
wait_for_device(v->blk_device);
FILE* f = fopen(v->blk_device, "wb");
FILE* f = fopen(v->blk_device, "wb+");
//FILE* f = fopen(v->blk_device, "wb");
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
}
int count = fwrite(in, sizeof(*in), 1, f);
int count = rk29_fwrite(in, sizeof(*in), 1, f);
//int count = fwrite(in, sizeof(*in), 1, f);
if (count != 1) {
LOGE("Failed writing %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
......@@ -201,3 +217,84 @@ static int set_bootloader_message_block(const struct bootloader_message *in,
}
return 0;
}
// ------------------------------------
// for misc partitions on rk29 devices
// ------------------------------------
static int get_bootloader_message_block_rk29(struct bootloader_message *out,
const Volume* v) {
FILE* f = NULL;
#ifdef TARGET_RK3188
if (strcmp(v->fs_type, "emmc") == 0){
f = fopen(v->blk_device, "rb");
}else{
f = fopen("/dev/block/rknand_misc", "rb");
}
#else
f = fopen(v->blk_device, "rb");
#endif
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
}
const ssize_t size =READ_SIZE * MISC_PAGES;
char data[size];
int count = rk29_fread(data, size, 1, f);
if (count != 1) {
LOGE("Failed reading %s\n(%s)\n", v->blk_device, strerror(errno));
fclose(f);
return -1;
}
if (fclose(f) != 0) {
LOGE("Failed closing %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
}
memcpy(out, &data[READ_SIZE * MISC_COMMAND_PAGE], sizeof(*out));
return 0;
}
static int set_bootloader_message_block_rk29(const struct bootloader_message *in,
const Volume* v) {
FILE* f = NULL;
#ifdef TARGET_RK3188
if (strcmp(v->fs_type, "emmc") == 0){
f = fopen(v->blk_device, "wb+");
}else{
f = fopen("/dev/block/rknand_misc", "wb+");
}
#else
f = fopen(v->blk_device, "wb+");
#endif
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
}
const ssize_t size =WRITE_SIZE * MISC_PAGES;
char data[size];
memset(data,0,size);
memcpy(&data[WRITE_SIZE * MISC_COMMAND_PAGE], in, sizeof(*in));
int count = rk29_fwrite(data, size, 1, f);
if (count != 1) {
LOGE("Failed writing %s\n(%s)\n", v->blk_device, strerror(errno));
fclose(f);
return -1;
}
fflush(f);
if (fclose(f) != 0) {
LOGE("Failed closing %s\n(%s)\n", v->blk_device, strerror(errno));
return -1;
}
return 0;
}
......@@ -19,28 +19,183 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LOGE(...) ui_print("E:" __VA_ARGS__)
#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
// #define LOGE(...) ui_print("E:" __VA_ARGS__)
#if 0
#define LOGV(...) fprintf(stdout, "V:" __VA_ARGS__)
#define LOGD(...) fprintf(stdout, "D:" __VA_ARGS__)
#define LOGE(fmt, args...)\
{\
ui_print("E:" fmt, ## args);\
fprintf(stdout, "E/ [File] : %s; [Line] : %d; [Func] : %s; " fmt, __FILE__, __LINE__, __FUNCTION__, ## args);\
}
#define E(fmt, args...) LOGE(fmt "\n", ## args)
// #define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
#define LOGW(fmt, args...)\
{ fprintf(stdout, "W/ [File] : %s; [Line] : %d; [Func] : %s; " fmt, __FILE__, __LINE__, __FUNCTION__, ## args); }
#define W(fmt, args...) LOGW(fmt "\n", ## args)
// #define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
#define LOGI(fmt, args...)\
{ \
fprintf(stdout, "I/ [File] : %s; [Line] : %d; [Func] : %s; " fmt, __FILE__, __LINE__, __FUNCTION__, ## args); \
}
#define I(fmt, args...) LOGI(fmt "\n", ## args)
#define ENABLE_DEBUG_LOG
#ifdef ENABLE_DEBUG_LOG
// #define LOGD(...) fprintf(stdout, "D:" __VA_ARGS__)
#define LOGD(fmt, args...)\
{ fprintf(stdout, "D/ [File] : %s; [Line] : %d; [Func] : %s; " fmt, __FILE__, __LINE__, __FUNCTION__, ## args); }
#ifdef D
#undef D
#endif
#define D(fmt, args...) LOGD(fmt "\n", ## args)
#else
#define LOGV(...) do {} while (0)
#define LOGD(...) do {} while (0)
#endif
#define ENABLE_VERBOSE_LOG
#ifdef ENABLE_VERBOSE_LOG
// #define LOGV(...) fprintf(stdout, "V:" __VA_ARGS__)
#define LOGV(fmt, args...)\
{ fprintf(stdout, "V/ [File] : %s; [Line] : %d; [Func] : %s; " fmt, __FILE__, __LINE__, __FUNCTION__, ## args); }
#define V(fmt, args...) LOGV(fmt "\n", ## args)
#else
#define LOGV(...) do {} while (0)
#endif
/**
* 调用函数, 并检查返回值, 根据返回值决定是否跳转到指定的错误处理代码.
* @param functionCall
* 对特定函数的调用, 该函数的返回值必须是 表征 成功 or err 的 整型数.
* 这里, 被调用函数 "必须" 是被定义为 "返回 0 表示操作成功".
* @param result
* 用于记录函数返回的 error code 的 整型变量, 通常是 "ret" or "result" 等.
* @param label
* 若函数返回错误, 程序将要跳转到的 错误处理处的 标号, 通常就是 "EXIT".
*/
#define CHECK_FUNC_CALL(functionCall, result, label) \
{\
if ( 0 != ( (result) = (functionCall) ) )\
{\
E("Function call returned error : " #result " = %d.", result);\
goto label;\
}\
}
/**
* 在特定条件下, 判定 error 发生, 对变量 'retVar' 设置 'errCode',
* Log 输出对应的 Error Caution, 然后跳转 'label' 指定的代码处执行.
* @param msg
* 纯字串形式的提示信息.
* @param retVar
* 标识函数执行状态或者结果的变量, 将被设置具体的 Error Code.
* 通常是 'ret' or 'result'.
* @param errCode
* 表征特定 error 的常数标识, 通常是 宏的形态.
* @param label
* 程序将要跳转到的错误处理代码的标号, 通常就是 'EXIT'.
* @param args...
* 对应 'msgFmt' 实参中 '%s', '%d', ... 等 转换说明符 的具体可变长实参.
*/
#define SET_ERROR_AND_JUMP(msgFmt, retVar, errCode, label, args...) \
{\
E("To set '" #retVar "' to %d('" #errCode "') : " msgFmt, (errCode), ## args);\
(retVar) = (errCode);\
goto label;\
}
/**
* 返回指定数组中的元素个数.
* @param array
* 有效的数组实例标识符.
*/
#define ELEMENT_NUM(array) ( sizeof(array) / sizeof(array[0]) )
/*-------------------------------------------------------*/
/** 使用 D(), 以十进制的形式打印变量 'var' 的 value. */
#define D_DEC(var) \
{ \
long long num = (var); \
D(#var " = %lld.", num); \
}
/** 使用 D(), 以十六进制的形式打印变量 'var' 的 value. */
#define D_HEX(var) \
{ \
long long num = (var); \
D(#var " = 0x%llx.", num); \
}
/** 使用 D(), 以十六进制的形式 打印指针类型变量 'ptr' 的 value. */
#define D_PTR(ptr) D(#ptr " = %p.", ptr);
/** 使用 D(), 打印 char 字串. */
#define D_STR(pStr) \
{\
if ( NULL == pStr )\
{\
D(#pStr" = NULL.");\
}\
else\
{\
D(#pStr" = '%s'.", pStr);\
}\
}
/**
* 在 'pIndentsBuf' 指向的 buf 中, 从头插入 'indentNum' 个 '\t' 字符(缩进), 并跟上一个 '\0'.
* 通常 pIndentsBuf 指向一个 16 字节的 buffer.
*/
inline static void setIndents(char* pIndentsBuf, unsigned char indentNum)
{
unsigned char i = 0;
const unsigned char MAX_NUM_OF_INDENT = 16 - sizeof('\0');
if ( indentNum > MAX_NUM_OF_INDENT )
{
indentNum = MAX_NUM_OF_INDENT;
}
*pIndentsBuf = '\0';
for ( i = 0; i < indentNum; i++ )
{
strcat(pIndentsBuf, "\t");
}
*(pIndentsBuf + indentNum) = '\0';
}
/*---------------------------------------------------------------------------*/
#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)
typedef struct fstab_rec Volume;
/*-------------------------------------------------------*/
typedef unsigned char boolean;
#ifdef TRUE
#undef TRUE
#endif
#define TRUE ( (boolean)(1) )
#ifdef FALSE
#undef FALSE
#endif
#define FALSE ( (boolean)(0) )
/*-------------------------------------------------------*/
#define RU_PARTITION_MOUNT_PATH "/radical_update"
#define SYSTEM_PARTITION_MOUNT_PATH "/system"
// fopen a file, mounting volumes and making parent dirs as necessary.
FILE* fopen_path(const char *path, const char *mode);
......
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ifeq "$(TARGET_ARCH)" "arm64"
LOCAL_PREBUILT_LIBS :=lib64/libcrc32.a
else ifeq "$(TARGET_ARCH)" "arm"
LOCAL_PREBUILT_LIBS :=lib/libcrc32.a
endif
include $(BUILD_MULTI_PREBUILT)
File added
File added
......@@ -318,6 +318,34 @@ Value* GreaterThanIntFn(const char* name, State* state,
return LessThanIntFn(name, state, 2, temp);
}
Value* PickNumFromStringFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc != 1) {
free(state->errmsg);
state->errmsg = strdup("pick_num expects 1 arguments");
return NULL;
}
char* targetString;
if (ReadArgs(state, argv, 1, &targetString) < 0) return NULL;
char* result = NULL;
int length = strlen(targetString);
result = (char*)malloc(length + 1);
memset((void*)result, 0, length + 1);
char* cur = targetString;
char* to = result;
while(*cur != '\0') {
if(*cur >= '0' && *cur <= '9') {
*to = *cur;
to++;
}
cur++;
}
return StringValue(result);
}
Value* Literal(const char* name, State* state, int argc, Expr* argv[]) {
return StringValue(strdup(name));
}
......@@ -390,6 +418,7 @@ void RegisterBuiltins() {
RegisterFunction("less_than_int", LessThanIntFn);
RegisterFunction("greater_than_int", GreaterThanIntFn);
RegisterFunction("pick_num", PickNumFromStringFn);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment