blob: 392429781a92e4ac47e4b683b6aaf5506191d3df [file] [log] [blame]
/*
* mbtk_device_info.c
*
* MBTK device partition information utils.
*
*/
/******************************************************************************
EDIT HISTORY FOR FILE
WHEN WHO WHAT,WHERE,WHY
-------- -------- -------------------------------------------------------
2024/2/27 LiuBin Initial version
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
#include "mbtk_type.h"
#include "mbtk_log.h"
#include "mbtk_str.h"
#include "mbtk_mtd.h"
#include "mbtk_device.h"
/*
* MBTK_DEVICE_INFO_ITEM_BASIC - mbtk_device_info_basic_t
* MBTK_DEVICE_INFO_ITEM_FOTA - mbtk_device_info_fota_t
* MBTK_DEVICE_INFO_ITEM_MODEM - mbtk_device_info_modem_t
* MBTK_DEVICE_INFO_ITEM_LOG - mbtk_device_info_log_t
*/
int mbtk_dev_info_read(mbtk_device_info_item_enum item_type, void *item_ptr, int item_size)
{
int fd, len, i;
mbtk_device_info_header_t info_header;
memset(&info_header, 0, sizeof(mbtk_device_info_header_t));
mbtk_partition_info_t *partition_info = mbtk_partition_get();
if(partition_info == NULL) {
LOGE("mbtk_partition_get() fail.");
return -1;
}
i = 0;
char dev[32] = {0};
while(i < MBTK_PARTITION_NUM_MAX) {
if(partition_info[i].used && strcmp(partition_info[i].name, MBTK_DEVICE_INFO_PARTITION_NAME) == 0) {
snprintf(dev, 32, "/dev/%s", partition_info[i].dev);
LOGD("%s -> %s", partition_info[i].name, dev);
break;
}
i++;
}
if(strlen(dev) == 0) {
LOGE("DEV is null.");
return -1;
}
fd = open(dev, O_RDONLY);
if (fd < 0) {
LOGE("Fatal error: can't open device_info %s\n", dev);
return -1;
}
len = read(fd, &info_header, sizeof(mbtk_device_info_header_t));
if (len != sizeof(mbtk_device_info_header_t)) {
LOGE("Fatal error: read %d bytes(expect %d)\n", len, sizeof(mbtk_device_info_header_t));
close(fd);
goto fail;
}
if(info_header.tag != MBTK_DEVICE_INFO_PARTITION_TAG) {
LOGE("TAG error : %08x", info_header.tag);
goto fail;
}
LOGD("Dev info version : %d, Item count:%d", info_header.version, info_header.item_count);
if(info_header.item_header[item_type].addr == 0) {
LOGE("No found item : %d", item_type);
goto fail;
}
lseek(fd, info_header.item_header[item_type].addr, SEEK_SET);
switch(item_type) {
case MBTK_DEVICE_INFO_ITEM_BASIC:
{
if(item_ptr == NULL || item_size != sizeof(mbtk_device_info_basic_t)) {
LOGE("ARG error:item-%d, item_size-%d", item_type, item_size);
goto fail;
}
mbtk_device_info_basic_t *basic_ptr = (mbtk_device_info_basic_t*)item_ptr;
basic_ptr->version = (mbtk_device_info_version_enum)info_header.version;
if(basic_ptr->version == DEV_INFO_VERSION_V1) {
if (read(fd, &(basic_ptr->basic.v1), sizeof(mbtk_device_info_basic_v1_t)) !=
sizeof(mbtk_device_info_basic_v1_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
} else {
if (read(fd, &(basic_ptr->basic.v2), sizeof(mbtk_device_info_basic_v2_t)) !=
sizeof(mbtk_device_info_basic_v2_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
}
break;
}
case MBTK_DEVICE_INFO_ITEM_FOTA:
{
if(item_ptr == NULL || item_size != sizeof(mbtk_device_info_fota_t)) {
LOGE("ARG error:item-%d, item_size-%d", item_type, item_size);
goto fail;
}
mbtk_device_info_fota_t *fota_ptr = (mbtk_device_info_fota_t*)item_ptr;
fota_ptr->version = (mbtk_device_info_version_enum)info_header.version;
if(fota_ptr->version == DEV_INFO_VERSION_V1) {
if (read(fd, &(fota_ptr->fota.v1), sizeof(mbtk_device_info_fota_v1_t)) !=
sizeof(mbtk_device_info_fota_v1_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
} else {
if (read(fd, &(fota_ptr->fota.v2), sizeof(mbtk_device_info_fota_v2_t)) !=
sizeof(mbtk_device_info_fota_v2_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
}
break;
}
case MBTK_DEVICE_INFO_ITEM_MODEM:
{
if(item_ptr == NULL || item_size != sizeof(mbtk_device_info_modem_t)) {
LOGE("ARG error:item-%d, item_size-%d", item_type, item_size);
goto fail;
}
mbtk_device_info_modem_t *modem_ptr = (mbtk_device_info_modem_t*)item_ptr;
modem_ptr->version = (mbtk_device_info_version_enum)info_header.version;
if(modem_ptr->version == DEV_INFO_VERSION_V1) {
if (read(fd, &(modem_ptr->modem.v1), sizeof(mbtk_device_info_modem_v1_t)) !=
sizeof(mbtk_device_info_modem_v1_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
} else {
if (read(fd, &(modem_ptr->modem.v2), sizeof(mbtk_device_info_modem_v2_t)) !=
sizeof(mbtk_device_info_modem_v2_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
}
break;
}
case MBTK_DEVICE_INFO_ITEM_LOG:
{
if(item_ptr == NULL || item_size != sizeof(mbtk_device_info_log_t)) {
LOGE("ARG error:item-%d, item_size-%d", item_type, item_size);
goto fail;
}
mbtk_device_info_log_t *log_ptr = (mbtk_device_info_log_t*)item_ptr;
log_ptr->version = (mbtk_device_info_version_enum)info_header.version;
if(log_ptr->version == DEV_INFO_VERSION_V1) {
if (read(fd, &(log_ptr->log.v1), sizeof(mbtk_device_info_log_v1_t)) !=
sizeof(mbtk_device_info_log_v1_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
} else {
if (read(fd, &(log_ptr->log.v2), sizeof(mbtk_device_info_log_v2_t)) !=
sizeof(mbtk_device_info_log_v2_t)) {
LOGE("Read fail:%d", errno);
goto fail;
}
}
break;
}
default:
{
LOGE("Item type[%d] error.", item_type);
goto fail;
}
}
close(fd);
return 0;
fail:
close(fd);
return -1;
}
int mbtk_dev_info_write(mbtk_device_info_item_enum item_type, void *item_ptr, int item_size)
{
if(item_ptr == NULL) {
LOGE("ARG error.");
return -1;
}
mbtk_partition_info_t info;
memset(&info, 0x0, sizeof(mbtk_partition_info_t));
if(mbtk_partition_get_by_name(MBTK_DEVICE_INFO_PARTITION_NAME, &info)) {
LOGE("mbtk_partition_get_by_name() fail.");
return -1;
}
LOGD("device_info name : %s, dev : %s, addr : %08x, size : %08x, erase_size : %08x", info.name,
info.dev, info.partition_start, info.partition_size, info.erase_size);
if(info.erase_size <= 0 || info.partition_size <= 0) {
LOGE("partition info error.");
return -1;
}
int fd = open(info.dev, O_RDWR);
if (fd < 0) {
LOGE("Fatal error: can't open device_info %s\n", info.dev);
return -1;
}
char *mtd_buff = (char*)malloc(info.erase_size);
if(mtd_buff == NULL) {
LOGE("malloc() failed\n");
return -1;
}
memset(mtd_buff, 0xFF, info.erase_size);
int len = read(fd, mtd_buff, info.erase_size);
if (len != info.erase_size) {
LOGE("Fatal error: read %d[%d] bytes(expect %d)\n", len, errno, info.erase_size);
goto fail;
}
struct erase_info_user mtdEraseInfo;
if (lseek(fd, 0, SEEK_SET) < 0)
{
LOGE("seek failed\n");
return -1;
}
mtdEraseInfo.length = info.partition_size;
mtdEraseInfo.start = 0;
ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
ioctl(fd, MEMERASE, &mtdEraseInfo);
mbtk_device_info_header_t *info_header = (mbtk_device_info_header_t*)mtd_buff;
switch(item_type) {
case MBTK_DEVICE_INFO_ITEM_BASIC:
{
if(item_size != sizeof(mbtk_device_info_basic_t)) {
LOGE("item_size != sizeof(mbtk_device_info_basic_t)\n\r");
goto fail;
}
mbtk_device_info_basic_t *basic_ptr = (mbtk_device_info_basic_t*)item_ptr;
if(info_header->version != basic_ptr->version) {
LOGE("basic version error.");
goto fail;
}
if(basic_ptr->version == DEV_INFO_VERSION_V1) {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(basic_ptr->basic.v1),
sizeof(mbtk_device_info_basic_v1_t));
} else {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(basic_ptr->basic.v2),
sizeof(mbtk_device_info_basic_v2_t));
}
break;
}
case MBTK_DEVICE_INFO_ITEM_FOTA:
{
if(item_size != sizeof(mbtk_device_info_fota_t)) {
LOGE("item_size != sizeof(mbtk_device_info_fota_t)\n\r");
goto fail;
}
mbtk_device_info_fota_t *fota_ptr = (mbtk_device_info_fota_t*)item_ptr;
if(info_header->version != fota_ptr->version) {
LOGE("fota version error.");
goto fail;
}
if(fota_ptr->version == DEV_INFO_VERSION_V1) {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(fota_ptr->fota.v1),
sizeof(mbtk_device_info_fota_v1_t));
} else {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(fota_ptr->fota.v2),
sizeof(mbtk_device_info_fota_v2_t));
}
break;
}
case MBTK_DEVICE_INFO_ITEM_MODEM:
{
if(item_size != sizeof(mbtk_device_info_modem_t)) {
LOGE("item_size != sizeof(mbtk_device_info_modem_t)\n\r");
goto fail;
}
mbtk_device_info_modem_t *modem_ptr = (mbtk_device_info_modem_t*)item_ptr;
if(info_header->version != modem_ptr->version) {
LOGE("modem version error.");
goto fail;
}
if(modem_ptr->version == DEV_INFO_VERSION_V1) {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(modem_ptr->modem.v1),
sizeof(mbtk_device_info_modem_v1_t));
} else {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(modem_ptr->modem.v2),
sizeof(mbtk_device_info_modem_v2_t));
}
break;
}
case MBTK_DEVICE_INFO_ITEM_LOG:
{
if(item_size != sizeof(mbtk_device_info_log_t)) {
LOGE("item_size != sizeof(mbtk_device_info_log_t)\n\r");
goto fail;
}
mbtk_device_info_log_t *log_ptr = (mbtk_device_info_log_t*)item_ptr;
if(info_header->version != log_ptr->version) {
LOGE("log version error.");
goto fail;
}
if(log_ptr->version == DEV_INFO_VERSION_V1) {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(log_ptr->log.v1),
sizeof(mbtk_device_info_log_v1_t));
} else {
memcpy(mtd_buff + info_header->item_header[item_type].addr, &(log_ptr->log.v2),
sizeof(mbtk_device_info_log_v2_t));
}
break;
}
default:
{
LOGE("Item type[%d] error.\n\r", item_type);
goto fail;
}
}
lseek(fd, 0, SEEK_SET);
if (write(fd, mtd_buff, info.erase_size) != info.erase_size) {
LOGE("Write fail:%d", errno);
goto fail;
}
if(mtd_buff) {
free(mtd_buff);
}
close(fd);
return 0;
fail:
close(fd);
return -1;
}
int mbtk_dev_info_revision_get(char *revision_out, char *revision_in, char *project_cust, char *band_area,
char* build_time)
{
mbtk_device_info_basic_t info_basic;
memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
int result = mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_BASIC, &info_basic, sizeof(mbtk_device_info_basic_t));
if(result) {
LOGE("mbtk_dev_info_read(BASIC) fail.");
return -1;
}
mbtk_device_info_modem_t info_modem;
memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
result = mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, &info_modem, sizeof(mbtk_device_info_modem_t));
if(result) {
LOGE("mbtk_dev_info_read(MODEM) fail.");
return -1;
}
mbtk_modem_band_area_enum modem_band_area = MBTK_MODEM_BAND_AREA_ALL;
if(info_basic.version == DEV_INFO_VERSION_V1) {
if(strlen((char*)info_basic.basic.v1.revision_out) > 0) {
memcpy(revision_out, info_basic.basic.v1.revision_out, strlen((char*)info_basic.basic.v1.revision_out));
}
if(strlen((char*)info_basic.basic.v1.revision_in) > 0) {
memcpy(revision_in, info_basic.basic.v1.revision_in, strlen((char*)info_basic.basic.v1.revision_in));
}
if(strlen((char*)info_basic.basic.v1.project_cust) > 0) {
memcpy(project_cust, info_basic.basic.v1.project_cust, strlen((char*)info_basic.basic.v1.project_cust));
}
if(strlen((char*)info_basic.basic.v1.build_time) > 0) {
memcpy(build_time, info_basic.basic.v1.build_time, strlen((char*)info_basic.basic.v1.build_time));
}
modem_band_area = info_modem.modem.v1.band_area;
} else {
if(strlen((char*)info_basic.basic.v2.revision_out) > 0) {
memcpy(revision_out, info_basic.basic.v2.revision_out, strlen((char*)info_basic.basic.v2.revision_out));
}
if(strlen((char*)info_basic.basic.v2.revision_in) > 0) {
memcpy(revision_in, info_basic.basic.v2.revision_in, strlen((char*)info_basic.basic.v2.revision_in));
}
if(strlen((char*)info_basic.basic.v2.project_cust) > 0) {
memcpy(project_cust, info_basic.basic.v2.project_cust, strlen((char*)info_basic.basic.v2.project_cust));
}
if(strlen((char*)info_basic.basic.v2.build_time) > 0) {
memcpy(build_time, info_basic.basic.v2.build_time, strlen((char*)info_basic.basic.v2.build_time));
}
modem_band_area = info_modem.modem.v2.band_area;
}
switch(modem_band_area) {
case MBTK_MODEM_BAND_AREA_CN:
memcpy(band_area, "CN", 2);
break;
case MBTK_MODEM_BAND_AREA_EU:
memcpy(band_area, "EU", 2);
break;
case MBTK_MODEM_BAND_AREA_SA:
memcpy(band_area, "SA", 2);
break;
default:
memcpy(band_area, "DEF", 3);
break;
}
return 0;
}