initial commit
This commit is contained in:
14
mw/config.mk
Executable file
14
mw/config.mk
Executable file
@@ -0,0 +1,14 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/
|
||||
HEADERS += $(MW_DIR)/*.h
|
||||
|
||||
include $(MW_DIR)/config/config.mk
|
||||
include $(MW_DIR)/dmc/config.mk
|
||||
include $(MW_DIR)/mmc/config.mk
|
||||
include $(MW_DIR)/shutdownmgr/config.mk
|
||||
include $(MW_DIR)/soft_watchdog/config.mk
|
||||
include $(MW_DIR)/tcpclient/config.mk
|
||||
include $(MW_DIR)/tcpserver/config.mk
|
||||
include $(MW_DIR)/storage/config.mk
|
||||
include $(MW_DIR)/unittest/config.mk
|
||||
LIBHV_HEADERS += $(HEADERS)
|
||||
CORE_SRCDIRS += $(SRCDIRS)
|
||||
2
mw/config/config.mk
Executable file
2
mw/config/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
HEADERS += $(MW_DIR)/config/*.h
|
||||
SRCDIRS += $(MW_DIR)/config
|
||||
933
mw/config/mw_config.c
Executable file
933
mw/config/mw_config.c
Executable file
@@ -0,0 +1,933 @@
|
||||
/*****************************************************************************************************************************
|
||||
File name : config.c
|
||||
Module :
|
||||
Author :
|
||||
Copyright :
|
||||
Version : 0.1
|
||||
Created on : 2021-12-30
|
||||
Creator : amir.liang
|
||||
Description :
|
||||
Config read/save/check related
|
||||
*************************************************************************************************************************************/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "mw_config.h"
|
||||
#include "crc32.h"
|
||||
#include "util.h"
|
||||
#include "hbase.h"
|
||||
#include "hmutex.h"
|
||||
#include "hlog.h"
|
||||
#include "hal_interface_flash.h"
|
||||
|
||||
typedef struct{
|
||||
hmutex_t mutex;
|
||||
hmutex_t rom_mutex;
|
||||
mw_read_cb read_cb_f;
|
||||
mw_write_cb write_cb_f;
|
||||
/* Global Configs */
|
||||
Mw_CfgSysPart_t cfg_sys_part;
|
||||
Mw_CfgUserPart_t cfg_user_part;
|
||||
const Mw_CfgSysPart_t sys_part_default;
|
||||
const Mw_CfgUserPart_t user_part_default;
|
||||
/* Configs relative to ROM */
|
||||
uint32_t init_flg;
|
||||
uint8_t start_default;
|
||||
Mw_CfgStorage_Region_e active_region[CFG_STORAGE_REGION_NUM]; // toggle CFG_STORAGE_REGION_MAIN and CFG_STORAGE_REGION_BACK
|
||||
}mw_config;
|
||||
|
||||
static mw_config s_mw_cfg = {
|
||||
.init_flg = 0,
|
||||
.start_default = 0,
|
||||
.sys_part_default=CFG_SYSPART_DEFAULT_TABLE,
|
||||
.user_part_default = CFG_USERPART_DEFAULT_TABLE
|
||||
};
|
||||
|
||||
#define MW_CFG_SIZE_CHECK_COMMON(real_size, type) \
|
||||
if ((real_size) != sizeof(type)) \
|
||||
{ \
|
||||
hloge("Mw cfg checksize[%d]!=(sizeof(%s)=[%lu]), fail.", real_size, #type, sizeof(type)); \
|
||||
return NG; \
|
||||
}
|
||||
#define MW_CFG_ITEM_COPY_COMMON(dst, src, type) (void)memcpy((void *)(dst), (void *)(src), sizeof(type))
|
||||
#define MW_CFG_ITEM_CHECK_SAME(dst, src, type) \
|
||||
if (0 == memcmp(dst, src, sizeof(type))) \
|
||||
{ \
|
||||
return MW_SET_SAME; \
|
||||
}
|
||||
#define MW_CFG_COMMON_SET_FUNC(group, name, dst) \
|
||||
static uint32_t Mw_Cfg_##group##name##Set(void *data, uint32_t size) \
|
||||
{ \
|
||||
Mw_Cfg##group##_##name##_t *info = (Mw_Cfg##group##_##name##_t *)data; \
|
||||
MW_CFG_SIZE_CHECK_COMMON(size, Mw_Cfg##group##_##name##_t); \
|
||||
MW_CFG_ITEM_CHECK_SAME(dst, info, Mw_Cfg##group##_##name##_t); \
|
||||
MW_CFG_ITEM_COPY_COMMON(dst, info, Mw_Cfg##group##_##name##_t); \
|
||||
return OK; \
|
||||
}
|
||||
#define MW_CFG_COMMON_GET_FUNC(group, name, src) \
|
||||
static uint32_t Mw_Cfg_##group##name##Get(void *data, uint32_t size) \
|
||||
{ \
|
||||
MW_CFG_SIZE_CHECK_COMMON(size, Mw_Cfg##group##_##name##_t); \
|
||||
MW_CFG_ITEM_COPY_COMMON(data, src, Mw_Cfg##group##_##name##_t); \
|
||||
return OK; \
|
||||
}
|
||||
#define MW_CFG_COMMON_SET_AND_GET_FUNC(group, name, data) \
|
||||
MW_CFG_COMMON_SET_FUNC(group, name, data) \
|
||||
MW_CFG_COMMON_GET_FUNC(group, name, data)
|
||||
|
||||
#define MW_CFG_COMMON_GROUPSET_FUNC(group, dst) \
|
||||
static uint32_t Mw_Cfg_##group##GroupSet(void *data, uint32_t size) \
|
||||
{ \
|
||||
Mw_Cfg##group##Group_t *info = (Mw_Cfg##group##Group_t *)data; \
|
||||
MW_CFG_SIZE_CHECK_COMMON(size, Mw_Cfg##group##Group_t); \
|
||||
MW_CFG_ITEM_COPY_COMMON(dst, info, Mw_Cfg##group##Group_t); \
|
||||
return OK; \
|
||||
}
|
||||
#define MW_CFG_COMMON_GROUPGET_FUNC(group, src) \
|
||||
static uint32_t Mw_Cfg_##group##GroupGet(void *data, uint32_t size) \
|
||||
{ \
|
||||
MW_CFG_SIZE_CHECK_COMMON(size, Mw_Cfg##group##Group_t); \
|
||||
MW_CFG_ITEM_COPY_COMMON(data, src, Mw_Cfg##group##Group_t); \
|
||||
return OK; \
|
||||
}
|
||||
#define MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(group, data) \
|
||||
MW_CFG_COMMON_GROUPSET_FUNC(group, data) \
|
||||
MW_CFG_COMMON_GROUPGET_FUNC(group, data)
|
||||
|
||||
static uint32_t Mw_Cfg_LoadCfgFromRom(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *p_out, const int32_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hmutex_lock(&s_mw_cfg.mutex);
|
||||
ret = s_mw_cfg.read_cb_f(part, region, p_out, size);
|
||||
if ( ret != size )
|
||||
{
|
||||
hloge("%s fail, part[%d], region[%d] size:%u ret:%u", __func__, part, region, size, ret);
|
||||
}else hlogi("%s cfg to rom part[%d], region[%d] size:%u ret:%u", __func__, part, region, size, ret);
|
||||
hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_WriteCfgToRom(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *p_in, uint16_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hmutex_lock(&s_mw_cfg.mutex);
|
||||
ret = s_mw_cfg.write_cb_f(part, region, p_in, size);
|
||||
if ( ret != size )
|
||||
{
|
||||
hloge("%s fail, part[%d], region[%d] size:%u ret:%u", __func__, part, region, size, ret);
|
||||
}else hlogi("%s cfg to rom part[%d], region[%d] size:%u ret:%u", __func__, part, region, size, ret);
|
||||
hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_TrySave(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *p_in, uint16_t size)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint32_t chksum_data;
|
||||
Mw_CfgHeader_t *p_header = (Mw_CfgHeader_t *)p_in;
|
||||
|
||||
if (CFG_STORAGE_PARTITION_NUM <= part)
|
||||
{
|
||||
hloge("Storage part [%d] error.", part);
|
||||
return NG;
|
||||
}
|
||||
|
||||
ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (OK != ret)
|
||||
{
|
||||
hloge("Take user settings rom mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Calculate checksum */
|
||||
chksum_data = crc32(0, p_in + sizeof(Mw_CfgHeader_t), size - sizeof(Mw_CfgHeader_t));
|
||||
if ( chksum_data == p_header->checksum ){
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hlogi("No save same part[%d] Region[%d] checksum:%X", part, region, p_header->checksum);
|
||||
return OK;
|
||||
}
|
||||
p_header->age++;
|
||||
p_header->total_size = size;
|
||||
p_header->magic = CFG_MAGIC_DEFAULT;
|
||||
p_header->checksum = chksum_data;
|
||||
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
|
||||
ret = Mw_Cfg_WriteCfgToRom(part, region, p_in, size);
|
||||
if (OK != ret)
|
||||
{
|
||||
hloge("Write user settings to rom fail, Ret=%d.", ret);
|
||||
return ret;
|
||||
}
|
||||
hlogi("Configs part[%d] Region[%d] checksum:%X save done.", part, region, p_header->checksum);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t Mw_Cfg_CheckValid(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, const Mw_CfgHeader_t *p_header, const uint16_t size)
|
||||
{
|
||||
uint32_t chksum_data;
|
||||
if(p_header->total_size != size)
|
||||
{
|
||||
hlogw("Configs part[%d] Region[%d] header size not match, header size=%d, real size=%d", part, region, p_header->total_size, size);
|
||||
return 0;
|
||||
}
|
||||
if(p_header->magic != CFG_MAGIC_DEFAULT)
|
||||
{
|
||||
hlogw("Configs part[%d] Region[%d] Profile magic not match",part, region);
|
||||
return 0;
|
||||
}
|
||||
chksum_data = crc32(0, (char *)p_header + sizeof(Mw_CfgHeader_t), p_header->total_size - sizeof(Mw_CfgHeader_t));
|
||||
if(p_header->checksum != chksum_data)
|
||||
{
|
||||
hlogw("total_size[%d] data checksum not match, data chksum=0x%X, real=0x%X", p_header->total_size, p_header->checksum, chksum_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hlogi("Configs part[%d] Region[%d] is valid.", part, region);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *Mw_Cfg_Find_Correct_Cfg(Mw_CfgStorage_Partition_e part, char *main, char *back, uint16_t size)
|
||||
{
|
||||
const Mw_CfgHeader_t *pmain_header = (const Mw_CfgHeader_t *)main;
|
||||
const Mw_CfgHeader_t *pback_header = (const Mw_CfgHeader_t *)back;
|
||||
char *right_cfg = NULL;
|
||||
if ( pmain_header->age > pback_header->age ){
|
||||
if ( Mw_Cfg_CheckValid(part, CFG_STORAGE_REGION_MAIN, pmain_header, size) ) {
|
||||
s_mw_cfg.active_region[part] = CFG_STORAGE_REGION_MAIN;
|
||||
right_cfg = main;
|
||||
} else if ( Mw_Cfg_CheckValid(part, CFG_STORAGE_REGION_BACK, pback_header, size) ) {
|
||||
s_mw_cfg.active_region[part] = CFG_STORAGE_REGION_BACK;
|
||||
right_cfg = back;
|
||||
}
|
||||
} else {
|
||||
if ( Mw_Cfg_CheckValid(part, CFG_STORAGE_REGION_BACK, pmain_header, size) ) {
|
||||
s_mw_cfg.active_region[part] = CFG_STORAGE_REGION_BACK;
|
||||
right_cfg = back;
|
||||
} else if ( Mw_Cfg_CheckValid(part, CFG_STORAGE_REGION_MAIN, pback_header, size) ) {
|
||||
s_mw_cfg.active_region[part] = CFG_STORAGE_REGION_MAIN;
|
||||
right_cfg = main;
|
||||
}
|
||||
}
|
||||
if ( right_cfg ) {
|
||||
hlogi("%s part[%d] Region[%d] size:%u main.age:%u back.age:%u", __func__, part, s_mw_cfg.active_region[part], size, pmain_header->age, pback_header->age);
|
||||
}
|
||||
return right_cfg;
|
||||
}
|
||||
static uint32_t Mw_Cfg_MemoryInit(void)
|
||||
{
|
||||
char *p_main = NULL;
|
||||
char *p_back = NULL;
|
||||
char *p_data = NULL;
|
||||
uint32_t size = 0, i, j;
|
||||
|
||||
char *parts[CFG_STORAGE_PARTITION_NUM][CFG_STORAGE_REGION_NUM] = {NULL};
|
||||
//load data from rom
|
||||
for(i=0; i<CFG_STORAGE_PARTITION_NUM; i++)
|
||||
{
|
||||
for(j=0; j<CFG_STORAGE_REGION_NUM; j++)
|
||||
{
|
||||
switch(i){
|
||||
case CFG_STORAGE_PARTITION_SYS:
|
||||
parts[i][j] = (char *)calloc(1, sizeof(Mw_CfgSysPart_t));
|
||||
Mw_Cfg_LoadCfgFromRom(i, j, parts[i][j], sizeof(Mw_CfgSysPart_t));
|
||||
break;
|
||||
case CFG_STORAGE_PARTITION_USER:
|
||||
parts[i][j] = (char *)calloc(1, sizeof(Mw_CfgUserPart_t));
|
||||
Mw_Cfg_LoadCfgFromRom(i, j, parts[i][j], sizeof(Mw_CfgUserPart_t));
|
||||
break;
|
||||
default:
|
||||
hloge("unsupport partition:%d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0; i<CFG_STORAGE_PARTITION_NUM; i++)
|
||||
{
|
||||
switch(i){
|
||||
case CFG_STORAGE_PARTITION_SYS:
|
||||
p_main = parts[i][CFG_STORAGE_REGION_MAIN];
|
||||
p_back = parts[i][CFG_STORAGE_REGION_BACK];
|
||||
size = sizeof(Mw_CfgSysPart_t);
|
||||
p_data = (void *)&s_mw_cfg.cfg_sys_part;
|
||||
break;
|
||||
case CFG_STORAGE_PARTITION_USER:
|
||||
p_main = parts[i][CFG_STORAGE_REGION_MAIN];
|
||||
p_back = parts[i][CFG_STORAGE_REGION_BACK];
|
||||
size = sizeof(Mw_CfgUserPart_t);
|
||||
p_data = (void *)&s_mw_cfg.cfg_user_part;
|
||||
break;
|
||||
default:
|
||||
hloge("unsupport partition:%d", i);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( size && p_main && p_back){
|
||||
char *cfg = Mw_Cfg_Find_Correct_Cfg(i, p_main, p_back, size);
|
||||
if ( cfg ) {
|
||||
memcpy(p_data, cfg, size);
|
||||
} else {
|
||||
Mw_Cfg_LoadDefault(i);
|
||||
s_mw_cfg.start_default = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for(i=0; i<CFG_STORAGE_PARTITION_NUM; i++)
|
||||
{
|
||||
for(j=0; j<CFG_STORAGE_REGION_NUM; j++)
|
||||
{
|
||||
if ( parts[i][j] ){
|
||||
free(parts[i][j]);
|
||||
parts[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hlogi("Configs memory init done.");
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint8_t Mw_Cfg_IsLoadFromDefault(void)
|
||||
{
|
||||
return s_mw_cfg.start_default;
|
||||
}
|
||||
|
||||
#define MW_CFG_PRINT(...) do { \
|
||||
hlogi(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static uint32_t Mw_Cfg_BaseLicensePrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" License = %s",s_mw_cfg.cfg_sys_part.base_info.license_info.audio_license);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_BaseActiveTimePrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" ActiveTime = %ld",s_mw_cfg.cfg_sys_part.base_info.active_time.active_time);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_BaseFactoryAgingInfoPrint(uint32_t id, char *name)
|
||||
{
|
||||
Mw_CfgBase_FactoryAgingInfo_t *pdata = (Mw_CfgBase_FactoryAgingInfo_t *)&s_mw_cfg.cfg_sys_part.base_info.factory_aging_info;
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" AgingFlag = %d, AgingResultFlag = %d", pdata->aging_flag, pdata->aging_result_flag);
|
||||
MW_CFG_PRINT(" AgingNums = %d, AgingPeriod = %d", pdata->aging_nums, pdata->aging_period);
|
||||
MW_CFG_PRINT(" AgingStartTime = %ld, AgingStopTime = %ld", pdata->aging_start_time, pdata->aging_stop_time);
|
||||
MW_CFG_PRINT(" ErrInfo = %s", pdata->error_info);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_BaseUUIDPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" UUID = %s", s_mw_cfg.cfg_sys_part.base_info.product_uuid.uuid);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_BaseSerialPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Serial = %s", s_mw_cfg.cfg_sys_part.base_info.product_sn.sn);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_SystemWifiPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Enable = %d, SSID = %s, PASS = %s", s_mw_cfg.cfg_sys_part.system_info.wifi_info.enable,
|
||||
s_mw_cfg.cfg_sys_part.system_info.wifi_info.ap_ssid, s_mw_cfg.cfg_sys_part.system_info.wifi_info.ap_password);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_OtherLcdPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Time = %d Brightness = %d", s_mw_cfg.cfg_user_part.other_info.lcd_info.time,
|
||||
s_mw_cfg.cfg_user_part.other_info.lcd_info.brightness);
|
||||
return OK;
|
||||
}
|
||||
static uint32_t Mw_Cfg_OtherQcapPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Qcap = %d", s_mw_cfg.cfg_user_part.other_info.quick_cap.enable);
|
||||
return OK;
|
||||
}
|
||||
static uint32_t Mw_Cfg_CommonCamModePrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Mode = %d SubMode = %d",s_mw_cfg.cfg_user_part.common_info.mode.cam_mode,
|
||||
s_mw_cfg.cfg_user_part.common_info.mode.sub_mode);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_VideoRecord_streamPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" Rec_stream = %d (1:main 2:sub 3:both)",s_mw_cfg.cfg_user_part.video_info.stream.rec_stream);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_VideoRecordSpecPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" RecRes = %d Fps = %d",s_mw_cfg.cfg_user_part.video_info.spec.resolution, s_mw_cfg.cfg_user_part.video_info.spec.fps);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_VideoCodecPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" CodecType = %d (0:h264 1:h265)",s_mw_cfg.cfg_user_part.video_info.codec.main_type);
|
||||
MW_CFG_PRINT(" Sub CodecType = %d (0:h264 1:h265)",s_mw_cfg.cfg_user_part.video_info.codec.sub_type);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t Mw_Cfg_VideoRecordBitratePrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" MainBitrate = %d Mbps, SubBitrate = %d Mbps", s_mw_cfg.cfg_user_part.video_info.bitrate.value[0], s_mw_cfg.cfg_user_part.video_info.bitrate.value[1]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_VideoRecordBrateCtrlPrint(uint32_t id, char *name)
|
||||
{
|
||||
char str[128];
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
uint8_t i, idx = 0;
|
||||
Mw_CfgVideo_BrateCtrl_t *bctrl = &s_mw_cfg.cfg_user_part.video_info.bratectrl;
|
||||
idx += snprintf(str+idx, sizeof(str) - idx, "BrateCtrl: ");
|
||||
for (i=0; i<sizeof(bctrl->value)/sizeof(bctrl->value[0]); i++)
|
||||
{
|
||||
idx += snprintf(str+idx, sizeof(str) - idx, "[%u] ", bctrl->value[i]);
|
||||
}
|
||||
idx += snprintf(str+idx, sizeof(str) - idx, "(note: 1 CBR, 2 VBR, 3 SMART_VBR)");
|
||||
MW_CFG_PRINT(" %s", str);
|
||||
return OK;
|
||||
}
|
||||
static uint32_t Mw_Cfg_PhotoCapcfgPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" SyncEncStart = %d, PicType = %d", s_mw_cfg.cfg_user_part.photo_info.capcfg.syncencstart, s_mw_cfg.cfg_user_part.photo_info.capcfg.pictype);
|
||||
MW_CFG_PRINT(" _strmMsk = %d, CapOnly = %d", s_mw_cfg.cfg_user_part.photo_info.capcfg.strmmsk, s_mw_cfg.cfg_user_part.photo_info.capcfg.caponly);
|
||||
MW_CFG_PRINT(" CapType = %d, LivStop = %d", s_mw_cfg.cfg_user_part.photo_info.capcfg.captype, s_mw_cfg.cfg_user_part.photo_info.capcfg.stopliveview);
|
||||
MW_CFG_PRINT(" CapNum = %d, AebNum = %d", s_mw_cfg.cfg_user_part.photo_info.capcfg.capnum, s_mw_cfg.cfg_user_part.photo_info.capcfg.aebnum);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_AudioEncodePrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" AACbitrate = %d, BitsPerSample = %d", s_mw_cfg.cfg_user_part.audio_info.encode.aac_bitrate, s_mw_cfg.cfg_user_part.audio_info.encode.bits_per_sample);
|
||||
MW_CFG_PRINT(" EnableDMIC = %d, Volumn = %d", s_mw_cfg.cfg_user_part.audio_info.encode.enable_DMIC, s_mw_cfg.cfg_user_part.audio_info.encode.volume);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t Mw_Cfg_ImageAAAPrint(uint32_t id, char *name)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]:", id, name);
|
||||
MW_CFG_PRINT(" ExpMode = %d, Shutter = %d, Iso = %d", s_mw_cfg.cfg_user_part.image_info.aaa.exposure_mode,
|
||||
s_mw_cfg.cfg_user_part.image_info.aaa.shutter, s_mw_cfg.cfg_user_part.image_info.aaa.iso);
|
||||
MW_CFG_PRINT(" ShutterLimit = %f, IsoLimit = %d", s_mw_cfg.cfg_user_part.image_info.aaa.shutter_limit, s_mw_cfg.cfg_user_part.image_info.aaa.iso_limit);
|
||||
MW_CFG_PRINT(" EvBias = %f", s_mw_cfg.cfg_user_part.image_info.aaa.ev_bias);
|
||||
MW_CFG_PRINT(" WbMode = %d, WbTemp = %d", s_mw_cfg.cfg_user_part.image_info.aaa.wb_mode, s_mw_cfg.cfg_user_part.image_info.aaa.wb_temp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, FactoryMode, &s_mw_cfg.cfg_sys_part.base_info.factory_mode);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, ActiveTime, &s_mw_cfg.cfg_sys_part.base_info.active_time);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, FactoryAgingInfo, &s_mw_cfg.cfg_sys_part.base_info.factory_aging_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, License, &s_mw_cfg.cfg_sys_part.base_info.license_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, ProductUUID, &s_mw_cfg.cfg_sys_part.base_info.product_uuid);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Base, ProductSerial, &s_mw_cfg.cfg_sys_part.base_info.product_sn);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Wifi, &s_mw_cfg.cfg_sys_part.system_info.wifi_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Bluetooth, &s_mw_cfg.cfg_sys_part.system_info.bt_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Usb, &s_mw_cfg.cfg_sys_part.system_info.usb_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Sensor, &s_mw_cfg.cfg_sys_part.system_info.sensor_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Battery, &s_mw_cfg.cfg_sys_part.system_info.battery_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Led, &s_mw_cfg.cfg_sys_part.system_info.led_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(System, Button, &s_mw_cfg.cfg_sys_part.system_info.button_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Common, CamMode, &s_mw_cfg.cfg_user_part.common_info.mode);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Video, Record_stream, &s_mw_cfg.cfg_user_part.video_info.stream);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Video, RecordSpec, &s_mw_cfg.cfg_user_part.video_info.spec);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Video, Bitrate, &s_mw_cfg.cfg_user_part.video_info.bitrate);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Video, BrateCtrl, &s_mw_cfg.cfg_user_part.video_info.bratectrl);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Video, Codec, &s_mw_cfg.cfg_user_part.video_info.codec);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Photo, Resolution, &s_mw_cfg.cfg_user_part.photo_info.resolution);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Photo, Capcfg, &s_mw_cfg.cfg_user_part.photo_info.capcfg);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Audio, Encode, &s_mw_cfg.cfg_user_part.audio_info.encode);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Image, Brightness, &s_mw_cfg.cfg_user_part.image_info.brightness);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Image, Sharpness, &s_mw_cfg.cfg_user_part.image_info.sharpness);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Image, Contrast, &s_mw_cfg.cfg_user_part.image_info.contrast);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Image, AAA, &s_mw_cfg.cfg_user_part.image_info.aaa);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Image, AntiFlicker, &s_mw_cfg.cfg_user_part.image_info.anti_flicker);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Other, Lcd, &s_mw_cfg.cfg_user_part.other_info.lcd_info);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(Other, Qcap, &s_mw_cfg.cfg_user_part.other_info.quick_cap);
|
||||
MW_CFG_COMMON_SET_AND_GET_FUNC(App, Gui, &s_mw_cfg.cfg_user_part.app_info.gui);
|
||||
|
||||
static Mw_CfgAccess_t s_Mw_CfgAccess[] =
|
||||
{
|
||||
[CFG_BASE_ID_FACTORY_MODE] = {"CFG_BASE_ID_FACTORY_MODE", Mw_Cfg_BaseFactoryModeSet, Mw_Cfg_BaseFactoryModeGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_FACTORY_MODE].cb_func_list)},
|
||||
[CFG_BASE_ID_ACTIVE_TIME] = {"CFG_BASE_ID_ACTIVE_TIME", Mw_Cfg_BaseActiveTimeSet, Mw_Cfg_BaseActiveTimeGet, Mw_Cfg_BaseActiveTimePrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_ACTIVE_TIME].cb_func_list)},
|
||||
[CFG_BASE_ID_FACTORY_AGING] = {"CFG_BASE_ID_FACTORY_AGING", Mw_Cfg_BaseFactoryAgingInfoSet, Mw_Cfg_BaseFactoryAgingInfoGet, Mw_Cfg_BaseFactoryAgingInfoPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_FACTORY_AGING].cb_func_list)},
|
||||
[CFG_BASE_ID_PRODUCT_UUID] = {"CFG_BASE_ID_PRODUCT_UUID", Mw_Cfg_BaseProductUUIDSet, Mw_Cfg_BaseProductUUIDGet, Mw_Cfg_BaseUUIDPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_PRODUCT_UUID].cb_func_list)},
|
||||
[CFG_BASE_ID_PRODUCT_SERIAL] = {"CFG_BASE_ID_PRODUCT_SERIAL", Mw_Cfg_BaseProductSerialSet, Mw_Cfg_BaseProductSerialGet, Mw_Cfg_BaseSerialPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_PRODUCT_SERIAL].cb_func_list)},
|
||||
[CFG_BASE_ID_LICENSE] = {"CFG_BASE_ID_LICENSE", Mw_Cfg_BaseLicenseSet, Mw_Cfg_BaseLicenseGet, Mw_Cfg_BaseLicensePrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_BASE_ID_LICENSE].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_WIFI] = {"CFG_SYSTEM_ID_WIFI", Mw_Cfg_SystemWifiSet, Mw_Cfg_SystemWifiGet, Mw_Cfg_SystemWifiPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_WIFI].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_BLUETOOTH] = {"CFG_SYSTEM_ID_BLUETOOTH", Mw_Cfg_SystemBluetoothSet, Mw_Cfg_SystemBluetoothGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_BLUETOOTH].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_USB] = {"CFG_SYSTEM_ID_USB", Mw_Cfg_SystemUsbSet, Mw_Cfg_SystemUsbGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_USB].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_SENSOR] = {"CFG_SYSTEM_ID_SENSOR", Mw_Cfg_SystemSensorSet, Mw_Cfg_SystemSensorGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_SENSOR].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_BATTERY] = {"CFG_SYSTEM_ID_BATTERY", Mw_Cfg_SystemBatterySet, Mw_Cfg_SystemBatteryGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_BATTERY].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_LED] = {"CFG_SYSTEM_ID_LED", Mw_Cfg_SystemLedSet, Mw_Cfg_SystemLedGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_LED].cb_func_list)},
|
||||
[CFG_SYSTEM_ID_BUTTON] = {"CFG_SYSTEM_ID_BUTTON", Mw_Cfg_SystemButtonSet, Mw_Cfg_SystemButtonGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_SYSTEM_ID_BUTTON].cb_func_list)},
|
||||
[CFG_COMMON_ID_CAMMODE] = {"CFG_COMMON_ID_CAMMODE", Mw_Cfg_CommonCamModeSet, Mw_Cfg_CommonCamModeGet, Mw_Cfg_CommonCamModePrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_COMMON_ID_CAMMODE].cb_func_list)},
|
||||
[CFG_VIDEO_ID_RECORD_STREAM] = {"CFG_VIDEO_ID_RECORD_STREAM", Mw_Cfg_VideoRecord_streamSet, Mw_Cfg_VideoRecord_streamGet, Mw_Cfg_VideoRecord_streamPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_VIDEO_ID_RECORD_STREAM].cb_func_list)},
|
||||
[CFG_VIDEO_ID_RECORD_SPEC] = {"CFG_VIDEO_ID_RECORD_SPEC", Mw_Cfg_VideoRecordSpecSet, Mw_Cfg_VideoRecordSpecGet, Mw_Cfg_VideoRecordSpecPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_VIDEO_ID_RECORD_SPEC].cb_func_list)},
|
||||
[CFG_VIDEO_ID_BITRATE] = {"CFG_VIDEO_ID_BITRATE", Mw_Cfg_VideoBitrateSet, Mw_Cfg_VideoBitrateGet, Mw_Cfg_VideoRecordBitratePrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_VIDEO_ID_BITRATE].cb_func_list)},
|
||||
[CFG_VIDEO_ID_BRATECTRL] = {"CFG_VIDEO_ID_BRATECTRL", Mw_Cfg_VideoBrateCtrlSet, Mw_Cfg_VideoBrateCtrlGet, Mw_Cfg_VideoRecordBrateCtrlPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_VIDEO_ID_BRATECTRL].cb_func_list)},
|
||||
[CFG_VIDEO_ID_CODEC] = {"CFG_VIDEO_ID_CODEC", Mw_Cfg_VideoCodecSet, Mw_Cfg_VideoCodecGet, Mw_Cfg_VideoCodecPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_VIDEO_ID_CODEC].cb_func_list)},
|
||||
[CFG_PHOTO_ID_RESOLUTION] = {"CFG_PHOTO_ID_RESOLUTION", Mw_Cfg_PhotoResolutionSet, Mw_Cfg_PhotoResolutionGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_PHOTO_ID_RESOLUTION].cb_func_list)},
|
||||
[CFG_PHOTO_ID_CAPCFG] = {"CFG_PHOTO_ID_CAPCFG", Mw_Cfg_PhotoCapcfgSet, Mw_Cfg_PhotoCapcfgGet, Mw_Cfg_PhotoCapcfgPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_PHOTO_ID_CAPCFG].cb_func_list)},
|
||||
[CFG_AUDIO_ID_ENCODE] = {"CFG_AUDIO_ID_ENCODE", Mw_Cfg_AudioEncodeSet, Mw_Cfg_AudioEncodeGet, Mw_Cfg_AudioEncodePrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_AUDIO_ID_ENCODE].cb_func_list)},
|
||||
[CFG_IMAGE_ID_BRIGHTNESS] = {"CFG_IMAGE_ID_BRIGHTNESS", Mw_Cfg_ImageBrightnessSet, Mw_Cfg_ImageBrightnessGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_IMAGE_ID_BRIGHTNESS].cb_func_list)},
|
||||
[CFG_IMAGE_ID_CONTRAST] = {"CFG_IMAGE_ID_CONTRAST", Mw_Cfg_ImageContrastSet, Mw_Cfg_ImageContrastGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_IMAGE_ID_CONTRAST].cb_func_list)},
|
||||
[CFG_IMAGE_ID_SHARPNESS] = {"CFG_IMAGE_ID_SHARPNESS", Mw_Cfg_ImageSharpnessSet, Mw_Cfg_ImageSharpnessGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_IMAGE_ID_SHARPNESS].cb_func_list)},
|
||||
[CFG_IMAGE_ID_AAA] = {"CFG_IMAGE_ID_AAA", Mw_Cfg_ImageAAASet, Mw_Cfg_ImageAAAGet, Mw_Cfg_ImageAAAPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_IMAGE_ID_AAA].cb_func_list)},
|
||||
[CFG_IMAGE_ID_ANTI_FLICKER] = {"CFG_IMAGE_ID_ANTI_FLICKER", Mw_Cfg_ImageAntiFlickerSet, Mw_Cfg_ImageAntiFlickerGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_IMAGE_ID_ANTI_FLICKER].cb_func_list)},
|
||||
[CFG_OTHER_ID_LCD] = {"CFG_OTHER_ID_LCD", Mw_Cfg_OtherLcdSet, Mw_Cfg_OtherLcdGet, Mw_Cfg_OtherLcdPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_OTHER_ID_LCD].cb_func_list)},
|
||||
[CFG_OTHER_ID_QCAP] = {"CFG_OTHER_ID_QCAP", Mw_Cfg_OtherQcapSet, Mw_Cfg_OtherQcapGet, Mw_Cfg_OtherQcapPrint, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_OTHER_ID_QCAP].cb_func_list)},
|
||||
[CFG_APP_ID_GUI] = {"CFG_APP_ID_GUI", Mw_Cfg_AppGuiSet, Mw_Cfg_AppGuiGet, NULL, .cb_func_list=LIST_HEAD_INIT(s_Mw_CfgAccess[CFG_APP_ID_GUI].cb_func_list)},
|
||||
};
|
||||
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Base, &s_mw_cfg.cfg_sys_part.base_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(System, &s_mw_cfg.cfg_sys_part.system_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Common, &s_mw_cfg.cfg_user_part.common_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Video, &s_mw_cfg.cfg_user_part.video_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Photo, &s_mw_cfg.cfg_user_part.photo_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Audio, &s_mw_cfg.cfg_user_part.audio_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Image, &s_mw_cfg.cfg_user_part.image_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(Other, &s_mw_cfg.cfg_user_part.other_info);
|
||||
MW_CFG_COMMON_GROUP_SET_AND_GET_FUNC(App, &s_mw_cfg.cfg_user_part.app_info);
|
||||
|
||||
static Mw_CfgAccess_t s_Mw_CfgGroupAccess[] =
|
||||
{
|
||||
[CFG_GROUP_BASE] = {"CFG_GROUP_BASE", Mw_Cfg_BaseGroupSet, Mw_Cfg_BaseGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_SYSTEM] = {"CFG_GROUP_SYSTEM", Mw_Cfg_SystemGroupSet, Mw_Cfg_SystemGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_COMMON] = {"CFG_GROUP_COMMON", Mw_Cfg_CommonGroupSet, Mw_Cfg_CommonGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_VIDEO] = {"CFG_GROUP_VIDEO", Mw_Cfg_VideoGroupSet, Mw_Cfg_VideoGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_PHOTO] = {"CFG_GROUP_PHOTO", Mw_Cfg_PhotoGroupSet, Mw_Cfg_PhotoGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_AUDIO] = {"CFG_GROUP_AUDIO", Mw_Cfg_AudioGroupSet, Mw_Cfg_AudioGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_IMAGE] = {"CFG_GROUP_IMAGE", Mw_Cfg_ImageGroupSet, Mw_Cfg_ImageGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_OTHER] = {"CFG_GROUP_OTHER", Mw_Cfg_OtherGroupSet, Mw_Cfg_OtherGroupGet, NULL, {NULL}},
|
||||
[CFG_GROUP_APP] = {"CFG_GROUP_APP", Mw_Cfg_AppGroupSet, Mw_Cfg_AppGroupGet, NULL, {NULL}},
|
||||
};
|
||||
|
||||
uint32_t Mw_Cfg_Init(mw_write_cb wb, mw_read_cb rb)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
if(s_mw_cfg.init_flg == 1)
|
||||
{
|
||||
hlogi("Config already inited");
|
||||
return OK;
|
||||
}
|
||||
s_mw_cfg.read_cb_f = rb;
|
||||
s_mw_cfg.write_cb_f = wb;
|
||||
if (CFG_ID_NUM != ARRAY_SIZE(s_Mw_CfgAccess))
|
||||
{
|
||||
hloge("Mw cfg Access items number[%lu] error, not equal to %d!",
|
||||
ARRAY_SIZE(s_Mw_CfgAccess), CFG_ID_NUM);
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (CFG_GROUP_NUM != ARRAY_SIZE(s_Mw_CfgGroupAccess))
|
||||
{
|
||||
hloge("Mw cfg group Access items number[%lu] error, not equal to %d!",
|
||||
ARRAY_SIZE(s_Mw_CfgGroupAccess), CFG_GROUP_NUM);
|
||||
|
||||
return NG;
|
||||
}
|
||||
|
||||
ret = hmutex_init(&s_mw_cfg.mutex);
|
||||
if(ret != 0)
|
||||
{
|
||||
hloge("Mw cfg init mutex create fail[%d].", ret);
|
||||
return NG;
|
||||
}
|
||||
ret = hmutex_init(&s_mw_cfg.rom_mutex);
|
||||
if(ret != 0)
|
||||
{
|
||||
hloge("Mw cfg init rommutex create fail[%d].", ret);
|
||||
return NG;
|
||||
}
|
||||
|
||||
Mw_Cfg_MemoryInit();
|
||||
s_mw_cfg.init_flg = 1;
|
||||
|
||||
hlogi("Configs init done.");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_GetConfig(uint32_t config_id, void *p_out, uint32_t size)
|
||||
{
|
||||
uint32_t ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = Mw_Cfg_GetConfig_NoBlock(config_id, p_out, size);
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_SetConfig(uint32_t config_id, void *p_in, uint32_t size)
|
||||
{
|
||||
uint32_t ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = Mw_Cfg_SetConfig_NoBlock(config_id, p_in, size);
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_GetConfig_NoBlock(uint32_t config_id, void *p_out, uint32_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogd("Mw Cfg get id[%d], size[%d]", config_id, size);
|
||||
|
||||
if ((config_id >= CFG_ID_NUM) || (NULL == p_out) || (0 == size))
|
||||
{
|
||||
hloge("Mw Cfg input error, id=%d, p_in=%p, size=%d.", config_id, p_out, size);
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (NULL != s_Mw_CfgAccess[config_id].get_func)
|
||||
{
|
||||
|
||||
ret = s_Mw_CfgAccess[config_id].get_func(p_out, size);
|
||||
if (0 != ret)
|
||||
{
|
||||
hloge("Call getting function fail, Ret=%d, Id=%d", ret, config_id);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("Get function is NULL, Id=%d, fail.", config_id);
|
||||
return NG;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_SetConfig_NoBlock(uint32_t config_id, void *p_in, uint32_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogi("Mw Cfg set id[%d], size[%d]", config_id, size);
|
||||
|
||||
if ((config_id >= CFG_ID_NUM) || (NULL == p_in) || (0 == size))
|
||||
{
|
||||
hloge("Mw Cfg input error, id=%d, p_in=%p, size=%d.", config_id, p_in, size);
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (NULL != s_Mw_CfgAccess[config_id].set_func)
|
||||
{
|
||||
|
||||
ret = s_Mw_CfgAccess[config_id].set_func(p_in, size);
|
||||
if (0 != ret && MW_SET_SAME != ret)
|
||||
{
|
||||
hloge("Call setting function fail, Ret=%d, Id=%d", ret, config_id);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("Set function is NULL, Id=%d, fail.", config_id);
|
||||
return NG;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_PrintId(uint32_t id)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
uint32_t value[64];
|
||||
if(s_Mw_CfgAccess[id].print_func != NULL)
|
||||
{
|
||||
s_Mw_CfgAccess[id].print_func(id, s_Mw_CfgAccess[id].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = Mw_Cfg_GetConfig(id, (void *)value, sizeof(int));
|
||||
if(0 == ret)
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]............0x%x", id, s_Mw_CfgAccess[id].name, value[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MW_CFG_PRINT("[%d][%s]............Get Failed!( plz check print_func has been set also )", id, s_Mw_CfgAccess[id].name);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_PrintAll(void)
|
||||
{
|
||||
uint32_t i;
|
||||
MW_CFG_PRINT("UserPart Header Version[0x%x] Total Size[%d] Checksum[0x%x]",
|
||||
s_mw_cfg.cfg_user_part.header.version, s_mw_cfg.cfg_user_part.header.total_size, s_mw_cfg.cfg_user_part.header.checksum);
|
||||
MW_CFG_PRINT("SysPart Header Version[0x%x] Total Size[%d] Checksum[0x%x]",
|
||||
s_mw_cfg.cfg_sys_part.header.version, s_mw_cfg.cfg_sys_part.header.total_size, s_mw_cfg.cfg_sys_part.header.checksum);
|
||||
MW_CFG_PRINT("Cfg id max: %d", CFG_ID_NUM);
|
||||
|
||||
for(i=0; i<CFG_ID_NUM; i++)
|
||||
{
|
||||
Mw_Cfg_PrintId(i);
|
||||
}
|
||||
MW_CFG_PRINT("Cfg id max: %d", CFG_ID_NUM);
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_SetCallbackRegister(uint32_t config_id, Mw_CfgSetIdCallback_f cb_func)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogi("Mw Cfg Callback register id[%d]", config_id);
|
||||
|
||||
if ((config_id >= CFG_ID_NUM) || (NULL == cb_func))
|
||||
{
|
||||
hloge("Mw Cfg Callback input error, id=%d, func=%p.", config_id, cb_func);
|
||||
return NG;
|
||||
}
|
||||
|
||||
ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
Mw_CfgSetIdCallback_s *p_cb = (Mw_CfgSetIdCallback_s*)malloc(sizeof(Mw_CfgSetIdCallback_s));
|
||||
list_add_tail(&p_cb->link,&s_Mw_CfgAccess[config_id].cb_func_list);
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_SetCallbackUnregister(uint32_t config_id, Mw_CfgSetIdCallback_f cb_func)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogi("Mw Cfg Callback unregister id[%d]", config_id);
|
||||
|
||||
if ((config_id >= CFG_ID_NUM) || (NULL == cb_func))
|
||||
{
|
||||
hloge("Mw Cfg Callback input error, id=%d, func=%p.", config_id, cb_func);
|
||||
return NG;
|
||||
}
|
||||
|
||||
ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
struct list_head *pos, *n;
|
||||
list_for_each_safe(pos, n, &s_Mw_CfgAccess[config_id].cb_func_list){
|
||||
Mw_CfgSetIdCallback_s* cb = list_entry(pos, Mw_CfgSetIdCallback_s, link);
|
||||
if (cb->cb_func == cb_func){
|
||||
list_del(pos);
|
||||
free(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
hmutex_unlock(&s_mw_cfg.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_GetGroupInfo(Mw_CfgGroup_Type_e group_id, void *p_out, uint32_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogi("Mw Cfg get group id[%d], size[%d]", group_id, size);
|
||||
|
||||
if ((group_id >= CFG_GROUP_NUM) || (NULL == p_out) || (0 == size))
|
||||
{
|
||||
hloge("Mw Cfg input error, id=%d, p_in=%p, size=%d.", group_id, p_out, size);
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (NULL != s_Mw_CfgGroupAccess[group_id].get_func)
|
||||
{
|
||||
ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = s_Mw_CfgGroupAccess[group_id].get_func(p_out, size);
|
||||
if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Call getting function fail, Ret=%d, Id=%d", ret, group_id);
|
||||
return ret;
|
||||
}
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("Get function is NULL, Id=%d, fail.", group_id);
|
||||
return NG;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_SetGroupInfo(Mw_CfgGroup_Type_e group_id, void *p_in, uint32_t size)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hlogi("Mw Cfg set group id[%d], size[%d]", group_id, size);
|
||||
|
||||
if ((group_id >= CFG_GROUP_NUM) || (NULL == p_in) || (0 == size))
|
||||
{
|
||||
hloge("Mw Cfg input error, id=%d, p_in=%p, size=%d.", group_id, p_in, size);
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (NULL != s_Mw_CfgGroupAccess[group_id].set_func)
|
||||
{
|
||||
ret = hmutex_lock(&s_mw_cfg.mutex);
|
||||
if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Take user settings mutex, fail, Ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = s_Mw_CfgGroupAccess[group_id].set_func(p_in, size);
|
||||
if(MW_SET_SAME == ret)
|
||||
{
|
||||
ret = 0; //to avoid warning if same
|
||||
}
|
||||
else if (0 != ret)
|
||||
{
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hloge("Call setting function fail, Ret=%d, Id=%d", ret, group_id);
|
||||
return ret;
|
||||
}
|
||||
(void)hmutex_unlock(&s_mw_cfg.mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("Set function is NULL, Id=%d, fail.", group_id);
|
||||
return NG;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_LoadDefault(Mw_CfgStorage_Partition_e part)
|
||||
{
|
||||
char *data, *default_data;
|
||||
uint16_t size;
|
||||
switch ( part ) {
|
||||
case CFG_STORAGE_PARTITION_USER:
|
||||
data = (char *)&s_mw_cfg.cfg_user_part;
|
||||
size = sizeof(s_mw_cfg.cfg_user_part);
|
||||
default_data = (char *)&s_mw_cfg.user_part_default;
|
||||
break;
|
||||
case CFG_STORAGE_PARTITION_SYS:
|
||||
data = (char *)&s_mw_cfg.cfg_sys_part;
|
||||
size = sizeof(s_mw_cfg.cfg_sys_part);
|
||||
default_data = (char *)&s_mw_cfg.sys_part_default;
|
||||
break;
|
||||
default:
|
||||
hloge("Mw Cfg Undefined storage part[%d]", part);
|
||||
return NG;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(data, default_data, size);
|
||||
hlogi("Configs part [%d] load default.", part);
|
||||
s_mw_cfg.active_region[part] = CFG_STORAGE_REGION_MAIN;
|
||||
Mw_Cfg_TrySave(part, CFG_STORAGE_REGION_MAIN, data, size);
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t Mw_Cfg_Save(Mw_CfgStorage_Partition_e part)
|
||||
{
|
||||
/* Save to ROM (only save main here, back should be saved at init)*/
|
||||
uint32_t ret;
|
||||
char *data;
|
||||
uint16_t size;
|
||||
Mw_CfgStorage_Partition_e active_region = s_mw_cfg.active_region[part] == CFG_STORAGE_REGION_MAIN ? CFG_STORAGE_REGION_BACK : CFG_STORAGE_REGION_MAIN;
|
||||
switch ( part ) {
|
||||
case CFG_STORAGE_PARTITION_USER:
|
||||
data = (char *)&s_mw_cfg.cfg_user_part;
|
||||
size = sizeof(s_mw_cfg.cfg_user_part);
|
||||
break;
|
||||
case CFG_STORAGE_PARTITION_SYS:
|
||||
data = (char *)&s_mw_cfg.cfg_sys_part;
|
||||
size = sizeof(s_mw_cfg.cfg_sys_part);
|
||||
break;
|
||||
default:
|
||||
hloge("Mw Cfg Undefined storage part[%d]", part);
|
||||
return NG;
|
||||
}
|
||||
ret = Mw_Cfg_TrySave(part, active_region, data, size);
|
||||
if ( ret == OK ){
|
||||
s_mw_cfg.active_region[part] = active_region;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* for unit test */
|
||||
uint32_t Mw_Cfg_Destroy(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
hmutex_lock(&s_mw_cfg.mutex);
|
||||
|
||||
for(uint32_t i =0; i<ARRAY_SIZE(s_Mw_CfgAccess);i++){
|
||||
struct list_head *pos, *n;
|
||||
list_for_each_safe(pos, n, &s_Mw_CfgAccess[i].cb_func_list){
|
||||
Mw_CfgSetIdCallback_s* cb = list_entry(pos, Mw_CfgSetIdCallback_s, link);
|
||||
list_del(pos);
|
||||
free(cb);
|
||||
}
|
||||
}
|
||||
hmutex_unlock(&s_mw_cfg.mutex);
|
||||
hlogi("Destroy cfg data part[%d], region[%d]", part, region);
|
||||
ret = Mw_Cfg_Save(part);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************test***************************/
|
||||
// path can be file, return size has been writed
|
||||
|
||||
void Mw_Cfg_Test()
|
||||
{
|
||||
Mw_Cfg_Init(mw_storage_write, mw_storage_read);
|
||||
{
|
||||
Mw_CfgBase_ProductUUID_t product_uuid;
|
||||
Mw_Cfg_GetConfig(CFG_BASE_ID_PRODUCT_UUID, &product_uuid, sizeof(product_uuid));
|
||||
hlogd("read product_uuid:%s", product_uuid.uuid);
|
||||
}
|
||||
|
||||
Mw_Cfg_Destroy(CFG_STORAGE_PARTITION_SYS, CFG_STORAGE_REGION_MAIN);
|
||||
|
||||
}
|
||||
|
||||
276
mw/config/mw_config.h
Executable file
276
mw/config/mw_config.h
Executable file
@@ -0,0 +1,276 @@
|
||||
#ifndef __MW_CONFIG_H__
|
||||
#define __MW_CONFIG_H__
|
||||
#include "mw_config_enum.h"
|
||||
#include "mw_config_struct.h"
|
||||
#include "list.h"
|
||||
#include "mw_storage.h"
|
||||
|
||||
#define CFG_MAGIC_DEFAULT 0xdefa0505
|
||||
#define CFG_ID_NUM CFG_APP_ID_NUMBER
|
||||
#define MW_SET_SAME (0x0000FEFEU)
|
||||
|
||||
#define CFG_DEFAULT_BRATECTRL_TYPE CFG_VIDEO_CODEC_BRATECTRL_TYPE_VBR
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_GROUP_BASE = 0,
|
||||
CFG_GROUP_SYSTEM,
|
||||
CFG_GROUP_COMMON,
|
||||
CFG_GROUP_VIDEO,
|
||||
CFG_GROUP_PHOTO,
|
||||
CFG_GROUP_AUDIO,
|
||||
CFG_GROUP_IMAGE,
|
||||
CFG_GROUP_OTHER,
|
||||
CFG_GROUP_APP,
|
||||
CFG_GROUP_NUM
|
||||
}Mw_CfgGroup_Type_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_BASE_ID_LICENSE = 0,
|
||||
CFG_BASE_ID_FACTORY_MODE,
|
||||
CFG_BASE_ID_ACTIVE_TIME,
|
||||
CFG_BASE_ID_FACTORY_AGING,
|
||||
CFG_BASE_ID_PRODUCT_UUID,
|
||||
CFG_BASE_ID_PRODUCT_SERIAL,
|
||||
CFG_BASE_ID_NUMBER
|
||||
}Mw_CfgBase_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_SYSTEM_ID_WIFI = CFG_BASE_ID_NUMBER,
|
||||
CFG_SYSTEM_ID_BLUETOOTH,
|
||||
CFG_SYSTEM_ID_USB,
|
||||
CFG_SYSTEM_ID_SENSOR,
|
||||
CFG_SYSTEM_ID_BATTERY,
|
||||
CFG_SYSTEM_ID_LED,
|
||||
CFG_SYSTEM_ID_BUTTON,
|
||||
|
||||
CFG_SYSTEM_ID_NUMBER
|
||||
}Mw_CfgSystem_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_COMMON_ID_CAMMODE = CFG_SYSTEM_ID_NUMBER,
|
||||
|
||||
CFG_COMMON_ID_NUMBER
|
||||
}Mw_CfgCommon_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_VIDEO_ID_RECORD_STREAM = CFG_COMMON_ID_NUMBER,
|
||||
CFG_VIDEO_ID_RECORD_SPEC,
|
||||
CFG_VIDEO_ID_BITRATE,
|
||||
CFG_VIDEO_ID_CODEC,
|
||||
CFG_VIDEO_ID_BRATECTRL, // 0 FIX, 1 CBR, 2 VBR, 3 SMART_VBR
|
||||
|
||||
CFG_VIDEO_ID_NUMBER
|
||||
}Mw_CfgVideo_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_PHOTO_ID_RESOLUTION = CFG_VIDEO_ID_NUMBER,
|
||||
CFG_PHOTO_ID_CAPCFG,
|
||||
|
||||
CFG_PHOTO_ID_NUMBER
|
||||
}Mw_CfgPhoto_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_AUDIO_ID_ENCODE = CFG_PHOTO_ID_NUMBER,
|
||||
|
||||
CFG_AUDIO_ID_NUMBER
|
||||
}Mw_CfgAudio_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_IMAGE_ID_BRIGHTNESS = CFG_AUDIO_ID_NUMBER,
|
||||
CFG_IMAGE_ID_CONTRAST,
|
||||
CFG_IMAGE_ID_SHARPNESS,
|
||||
CFG_IMAGE_ID_AAA,
|
||||
CFG_IMAGE_ID_ANTI_FLICKER,
|
||||
|
||||
CFG_IMAGE_ID_NUMBER
|
||||
}Mw_CfgImage_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_OTHER_ID_LCD = CFG_IMAGE_ID_NUMBER,
|
||||
CFG_OTHER_ID_QCAP,
|
||||
|
||||
CFG_OTHER_ID_NUMBER
|
||||
}Mw_CfgOther_ID_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_APP_ID_GUI = CFG_OTHER_ID_NUMBER,
|
||||
|
||||
CFG_APP_ID_NUMBER
|
||||
}Mw_CfgApp_ID_e;
|
||||
|
||||
|
||||
/* default system part setting table */
|
||||
#define CFG_SYSPART_DEFAULT_TABLE \
|
||||
{ \
|
||||
/* header */ \
|
||||
.header.version = 0x00000001, \
|
||||
.header.total_size = 0, \
|
||||
.header.checksum = 0, \
|
||||
\
|
||||
/* base info */ \
|
||||
.base_info.factory_mode.factory_mode = 0, \
|
||||
.base_info.active_time.active_time = 0, \
|
||||
.base_info.product_sn.sn = "INSWWYYNXXXXXX", \
|
||||
.base_info.license_info.audio_license = "default", \
|
||||
\
|
||||
/* system info */ \
|
||||
.system_info.wifi_info.enable = 0, \
|
||||
.system_info.bt_info.enable = 0, \
|
||||
.system_info.usb_info.enable = 0, \
|
||||
.system_info.sensor_info.type = 0, \
|
||||
.system_info.battery_info.percent = 0, \
|
||||
.system_info.led_info.enable = 0, \
|
||||
.system_info.button_info.enable = 0, \
|
||||
\
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_COMMON \
|
||||
{ \
|
||||
.mode.cam_mode = MW_CFG_CAMMODE_VIDEO, \
|
||||
.mode.sub_mode = MW_CFG_CAM_SUBMODE_VID_NORMAL, \
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_VIDEO \
|
||||
{ \
|
||||
.stream.rec_stream = CFG_VIDEO_RECORD_STREAM_BOTH, \
|
||||
.spec.resolution = MW_CFG_VIDEO_RES_3840X2160, \
|
||||
.spec.fps = MW_CFG_VIDEO_FPS_60, \
|
||||
.bitrate.value[0] = 0, /* main stream */ \
|
||||
.bitrate.value[1] = 0, /* sub stream */ \
|
||||
.bratectrl.value = {CFG_DEFAULT_BRATECTRL_TYPE, CFG_DEFAULT_BRATECTRL_TYPE}, /*all default to CBR*/\
|
||||
.codec.main_type = CFG_VIDEO_CODEC_TYPE_H265, \
|
||||
.codec.sub_type = CFG_VIDEO_CODEC_TYPE_H265, \
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_PHOTO \
|
||||
{ \
|
||||
.resolution.val = MW_CFG_CAP_RES_720X1280, \
|
||||
.capcfg.capnum = 1, \
|
||||
.capcfg.aebnum = 1, \
|
||||
.capcfg.strmmsk = 1, \
|
||||
.capcfg.pictype = 8, \
|
||||
.capcfg.syncencstart = 0, \
|
||||
.capcfg.caponly = 0, \
|
||||
.capcfg.captype = 1, \
|
||||
.capcfg.stopliveview = 1, \
|
||||
.capcfg.timelapsemsk = 0, \
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_AUDIO \
|
||||
{ \
|
||||
.encode.bits_per_sample = 16, \
|
||||
.encode.aac_bitrate = 128000, \
|
||||
.encode.volume = 100, \
|
||||
.encode.enable_DMIC = 0, \
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_IMAGE \
|
||||
{ \
|
||||
.brightness.val = 0, \
|
||||
.contrast.val = 0, \
|
||||
.sharpness.val = 0, \
|
||||
.aaa.exposure_mode = MW_CFG_AE_EXPMODE_AUTO, \
|
||||
.aaa.shutter = -1000000, \
|
||||
.aaa.iso = 800, \
|
||||
.aaa.shutter_limit = 0.0, \
|
||||
.aaa.iso_limit = 0, \
|
||||
.aaa.ev_bias = 0.0, \
|
||||
.aaa.wb_mode = MW_CFG_AWB_MODE_AUTO, \
|
||||
.aaa.wb_temp = 2000, \
|
||||
.anti_flicker.value = MW_CFG_AE_FLICKER_AUTO,\
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_OTHER \
|
||||
{ \
|
||||
.lcd_info.time = 30, \
|
||||
.lcd_info.brightness= 100, \
|
||||
.quick_cap.enable = 0, \
|
||||
}
|
||||
|
||||
#define CFG_USERPART_DEFAULT_TABLE_APP \
|
||||
{ \
|
||||
.gui.val = 0, \
|
||||
}
|
||||
|
||||
/* default user part setting table */
|
||||
#define CFG_USERPART_DEFAULT_TABLE \
|
||||
{ \
|
||||
/* header */ \
|
||||
.header.version = 0x00000001, \
|
||||
.header.total_size = 0, \
|
||||
.header.checksum = 0, \
|
||||
\
|
||||
.common_info = CFG_USERPART_DEFAULT_TABLE_COMMON, \
|
||||
\
|
||||
.video_info = CFG_USERPART_DEFAULT_TABLE_VIDEO, \
|
||||
\
|
||||
.photo_info = CFG_USERPART_DEFAULT_TABLE_PHOTO, \
|
||||
\
|
||||
.audio_info = CFG_USERPART_DEFAULT_TABLE_AUDIO,\
|
||||
\
|
||||
.image_info = CFG_USERPART_DEFAULT_TABLE_IMAGE,\
|
||||
\
|
||||
.other_info = CFG_USERPART_DEFAULT_TABLE_OTHER,\
|
||||
\
|
||||
.app_info = CFG_USERPART_DEFAULT_TABLE_APP,\
|
||||
\
|
||||
}
|
||||
|
||||
/*
|
||||
* access structure
|
||||
*/
|
||||
typedef uint32_t (*Mw_CfgAccess_f)(void *data, uint32_t size);
|
||||
typedef uint32_t (*Mw_CfgSetIdCallback_f)(void *data, uint32_t size);
|
||||
typedef uint32_t (*Mw_CfgUpdateCallback_f)(uint32_t id, void *data, uint32_t size);
|
||||
typedef uint32_t (*Mw_CfgPrint_f)(uint32_t id, char *name);
|
||||
|
||||
typedef struct {
|
||||
struct list_head link;
|
||||
Mw_CfgSetIdCallback_f cb_func;
|
||||
}Mw_CfgSetIdCallback_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
Mw_CfgAccess_f set_func;
|
||||
Mw_CfgAccess_f get_func;
|
||||
Mw_CfgPrint_f print_func;
|
||||
struct list_head cb_func_list;
|
||||
}Mw_CfgAccess_t;
|
||||
|
||||
|
||||
|
||||
uint32_t Mw_Cfg_Init(mw_write_cb wb, mw_read_cb rb);
|
||||
uint32_t Mw_Cfg_GetConfig(uint32_t config_id, void *p_out, uint32_t size);
|
||||
uint32_t Mw_Cfg_SetConfig(uint32_t config_id, void *p_in, uint32_t size);
|
||||
uint32_t Mw_Cfg_GetConfig_NoBlock(uint32_t config_id, void *p_out, uint32_t size); //use carefully
|
||||
uint32_t Mw_Cfg_SetConfig_NoBlock(uint32_t config_id, void *p_in, uint32_t size); //use carefully
|
||||
uint32_t Mw_Cfg_SetCallbackRegister(uint32_t config_id, Mw_CfgSetIdCallback_f cb_func);
|
||||
uint32_t Mw_Cfg_SetCallbackUnregister(uint32_t config_id, Mw_CfgSetIdCallback_f cb_func);
|
||||
uint32_t Mw_Cfg_GetGroupInfo(Mw_CfgGroup_Type_e group_id, void *p_out, uint32_t size);
|
||||
uint32_t Mw_Cfg_SetGroupInfo(Mw_CfgGroup_Type_e group_id, void *p_in, uint32_t size);
|
||||
/* TDB: need timer to save config regularly */
|
||||
uint32_t Mw_Cfg_Save(Mw_CfgStorage_Partition_e part);
|
||||
uint32_t Mw_Cfg_LoadDefault(Mw_CfgStorage_Partition_e part);
|
||||
uint8_t Mw_Cfg_IsLoadFromDefault(void);
|
||||
uint32_t Mw_Cfg_PrintAll(void);
|
||||
uint32_t Mw_Cfg_PrintId(uint32_t id);
|
||||
|
||||
|
||||
/* For unit test */
|
||||
uint32_t Mw_Cfg_Destroy(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region);
|
||||
|
||||
|
||||
void Mw_Cfg_Test();
|
||||
|
||||
#endif
|
||||
186
mw/config/mw_config_enum.h
Executable file
186
mw/config/mw_config_enum.h
Executable file
@@ -0,0 +1,186 @@
|
||||
/*************************************************************************
|
||||
File name : enum.h
|
||||
Module : config_manager
|
||||
Author :
|
||||
Copyright :
|
||||
Version : 0.1
|
||||
Created on : 2022-3-21
|
||||
Creator : amir.liang
|
||||
Description :
|
||||
Data enum definitions required by Config.
|
||||
***************************************************************************/
|
||||
#ifndef __MW_CONFIG_ENUM_H__
|
||||
#define __MW_CONFIG_ENUM_H__
|
||||
|
||||
/*
|
||||
* factory mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_FACTORY_TEST = 0,
|
||||
MW_CFG_FACTORY_AGING,
|
||||
MW_CFG_NORAML,
|
||||
MW_CFG_FACTORYMODE_NUM,
|
||||
}Mw_Cfg_FactoryMode_e;
|
||||
|
||||
/*
|
||||
* Cam mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_CAMMODE_VIDEO = 0,
|
||||
MW_CFG_CAMMODE_PHOTO,
|
||||
MW_CFG_CAMMODE_PLAYBACK,
|
||||
|
||||
MW_CFG_CAMMODE_NUM
|
||||
}Mw_Cfg_CamMode_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_CAM_SUBMODE_VID_NORMAL = 0,
|
||||
MW_CFG_CAM_SUBMODE_VID_TIMELAPSE,
|
||||
MW_CFG_CAM_SUBMODE_VID_HDR,
|
||||
MW_CFG_CAM_SUBMODE_VID_BULLETTIME,
|
||||
MW_CFG_CAM_SUBMODE_VID_SLOWMOTION,
|
||||
MW_CFG_CAM_SUBMODE_VID_PURE,
|
||||
MW_CFG_CAM_SUBMODE_VID_TIMESHIFT,
|
||||
MW_CFG_CAM_SUBMODE_VID_LOOPRECORD,
|
||||
MW_CFG_CAM_SUBMODE_VID_FPV,
|
||||
MW_CFG_CAM_SUBMODE_VID_MOVIE,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_VID_IDX_MAX = MW_CFG_CAM_SUBMODE_VID_MOVIE,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_PHO_NORMAL ,
|
||||
MW_CFG_CAM_SUBMODE_PHO_TIMELAPSE,
|
||||
MW_CFG_CAM_SUBMODE_PHO_BURST,
|
||||
MW_CFG_CAM_SUBMODE_PHO_AEB,
|
||||
MW_CFG_CAM_SUBMODE_PHO_HDR,
|
||||
MW_CFG_CAM_SUBMODE_PHO_SUPERNIGHT,
|
||||
MW_CFG_CAM_SUBMODE_PHO_PANO,
|
||||
MW_CFG_CAM_SUBMODE_PHO_STARLAPSE,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_PHO_IDX_MAX = MW_CFG_CAM_SUBMODE_PHO_STARLAPSE,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_USER_0,
|
||||
MW_CFG_CAM_SUBMODE_USER_1,
|
||||
MW_CFG_CAM_SUBMODE_USER_2,
|
||||
MW_CFG_CAM_SUBMODE_USER_3,
|
||||
MW_CFG_CAM_SUBMODE_USER_4,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_USER_IDX_MAX = MW_CFG_CAM_SUBMODE_USER_4,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_LOCAL_PB,
|
||||
|
||||
MW_CFG_CAM_SUBMODE_NUM
|
||||
}Mw_Cfg_CamSubMode_e;
|
||||
|
||||
/*
|
||||
* Sensor
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_SENSOR_ID_GC2083 = 0,
|
||||
MW_CFG_SENSOR_ID_OV02B1B,
|
||||
MW_CFG_SENSOR_ID_NUM
|
||||
}Mw_Cfg_SensorId_e;
|
||||
|
||||
/*
|
||||
* Video
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_VIDEO_RES_1280X720 = 0,
|
||||
MW_CFG_VIDEO_RES_1920X1080,
|
||||
MW_CFG_VIDEO_RES_2560X1440,
|
||||
MW_CFG_VIDEO_RES_3840X2160,
|
||||
MW_CFG_VIDEO_RES_7680X4320,
|
||||
|
||||
MW_CFG_VIDEO_RES_NUM
|
||||
}Mw_Cfg_VideoResolution_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_VIDEO_FPS_10 = 0,
|
||||
MW_CFG_VIDEO_FPS_15,
|
||||
MW_CFG_VIDEO_FPS_20,
|
||||
MW_CFG_VIDEO_FPS_24, //23.975
|
||||
MW_CFG_VIDEO_FPS_25,
|
||||
MW_CFG_VIDEO_FPS_30, //29.97
|
||||
MW_CFG_VIDEO_FPS_50,
|
||||
MW_CFG_VIDEO_FPS_60, //59.94
|
||||
MW_CFG_VIDEO_FPS_120,
|
||||
MW_CFG_VIDEO_FPS_200,
|
||||
MW_CFG_VIDEO_FPS_240,
|
||||
|
||||
MW_CFG_VIDEO_FPS_24T, //24
|
||||
MW_CFG_VIDEO_FPS_30T, //30
|
||||
MW_CFG_VIDEO_FPS_60T, //60
|
||||
|
||||
MW_CFG_VIDEO_FPS_NUM
|
||||
}Mw_Cfg_VideoFps_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_VIDEO_CODEC_TYPE_H264 = 0,
|
||||
CFG_VIDEO_CODEC_TYPE_H265 = 1
|
||||
}Mw_Cfg_VideoCodecType_e;
|
||||
|
||||
//default CBR
|
||||
typedef enum
|
||||
{
|
||||
CFG_VIDEO_CODEC_BRATECTRL_TYPE_VBR = 0, //default
|
||||
CFG_VIDEO_CODEC_BRATECTRL_TYPE_CBR = 1,
|
||||
}Mw_Cfg_VideoBrateCtrlType_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_VIDEO_RECORD_STREAM_MAIN = 0x01,
|
||||
CFG_VIDEO_RECORD_STREAM_SUB = 0x02,
|
||||
CFG_VIDEO_RECORD_STREAM_BOTH = 0x03
|
||||
}Mw_Cfg_VideoRecord_stream_e;
|
||||
|
||||
/*
|
||||
* Photo
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_CAP_RES_320X240 = 0,
|
||||
MW_CFG_CAP_RES_640X480,
|
||||
MW_CFG_CAP_RES_800X480,
|
||||
MW_CFG_CAP_RES_1280X720,
|
||||
MW_CFG_CAP_RES_1920X1080,
|
||||
|
||||
MW_CFG_CAP_RES_240X320 = 10,
|
||||
MW_CFG_CAP_RES_480X640,
|
||||
MW_CFG_CAP_RES_480X800,
|
||||
MW_CFG_CAP_RES_720X1280,
|
||||
MW_CFG_CAP_RES_1080X1920,
|
||||
|
||||
}Mw_Cfg_PhotoResolution_e;
|
||||
|
||||
/*
|
||||
* Image
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_AE_EXPMODE_AUTO, //p
|
||||
MW_CFG_AE_EXPMODE_TV, //S
|
||||
MW_CFG_AE_EXPMODE_SV, //Iso priority
|
||||
MW_CFG_AE_EXPMODE_AV, //A
|
||||
MW_CFG_AE_EXPMODE_ME, //M
|
||||
}Mw_Cfg_AeExpoMode_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_AE_FLICKER_AUTO,
|
||||
MW_CFG_AE_FLICKER_50HZ,
|
||||
MW_CFG_AE_FLICKER_60HZ,
|
||||
}Mw_Cfg_AeAntiFlicker_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MW_CFG_AWB_MODE_AUTO,
|
||||
MW_CFG_AWB_MODE_M,
|
||||
}Mw_Cfg_AwbMode_e;
|
||||
|
||||
#endif
|
||||
398
mw/config/mw_config_struct.h
Executable file
398
mw/config/mw_config_struct.h
Executable file
@@ -0,0 +1,398 @@
|
||||
/*************************************************************************
|
||||
File name : struct.h
|
||||
Module : config_manager
|
||||
Author :
|
||||
Copyright :
|
||||
Version : 0.1
|
||||
Created on : 2022-3-21
|
||||
Creator : amir.liang
|
||||
Description :
|
||||
Data struct definitions required by Config.
|
||||
***************************************************************************/
|
||||
#ifndef __MW_CONFIG_STRUCT_H__
|
||||
#define __MW_CONFIG_STRUCT_H__
|
||||
#include <stdint.h>
|
||||
#define MW_CFG_UUID_LEN (64)
|
||||
#define MW_CFG_SERIAL_LEN (32)
|
||||
#define MW_CFG_SYSMODE_LEN (32)
|
||||
#define MW_CFG_OFFSET_LEN (180)
|
||||
#define MW_CFG_AE_METER_WEIGHT_CNT (96)
|
||||
#define MW_CFG_IP_LEN (16)
|
||||
#define MW_CFG_SSID_LEN (32)
|
||||
#define MW_CFG_PWD_LEN (64)
|
||||
#define MW_CFG_CON_PREFIX_LEN (32)
|
||||
#define MW_CFG_MAX_ID_NUM (10)
|
||||
#define MW_CFG_ID_LEN (64)
|
||||
#define MW_CFG_CCODE_LEN (4)
|
||||
#define MW_CFG_MAX_CHN_NUM (64)
|
||||
#define MW_CFG_BTRC_VER_LEN (32)
|
||||
#define MW_CFG_SENSOR_ID_LEN (16)
|
||||
#define MW_CFG_ENCODE_STREAM_NUM (2)
|
||||
#define MW_CFG_AGING_STRING_LEN (512)
|
||||
/*
|
||||
* Base Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t factory_mode;
|
||||
}Mw_CfgBase_FactoryMode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t active_time;
|
||||
}Mw_CfgBase_ActiveTime_t;
|
||||
|
||||
typedef struct Mw_Aging_Record_Cfg_Info_s
|
||||
{
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint8_t fps;
|
||||
uint8_t encodec;
|
||||
uint16_t bit_rate;
|
||||
} Mw_Aging_Record_Cfg_Info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t aging_flag;
|
||||
uint8_t aging_result_flag;
|
||||
uint16_t aging_nums;
|
||||
uint32_t aging_period;
|
||||
uint64_t aging_start_time;
|
||||
uint64_t aging_stop_time;
|
||||
Mw_Aging_Record_Cfg_Info_t aging_config1;
|
||||
Mw_Aging_Record_Cfg_Info_t aging_config2;
|
||||
Mw_Aging_Record_Cfg_Info_t aging_config3;
|
||||
uint8_t error_info[MW_CFG_AGING_STRING_LEN];
|
||||
} Mw_CfgBase_FactoryAgingInfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t uuid[MW_CFG_UUID_LEN];
|
||||
}Mw_CfgBase_ProductUUID_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t sn[MW_CFG_UUID_LEN];
|
||||
}Mw_CfgBase_ProductSerial_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t audio_license[64];
|
||||
uint8_t recognition_license[128];
|
||||
}Mw_CfgBase_License_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t offset_x;
|
||||
uint32_t offset_y;
|
||||
uint32_t offset_z;
|
||||
|
||||
} Mw_CfgBase_GsensorCalib_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgBase_FactoryMode_t factory_mode;
|
||||
Mw_CfgBase_ActiveTime_t active_time;
|
||||
Mw_CfgBase_FactoryAgingInfo_t factory_aging_info;
|
||||
Mw_CfgBase_ProductUUID_t product_uuid;
|
||||
Mw_CfgBase_ProductSerial_t product_sn;
|
||||
Mw_CfgBase_License_t license_info;
|
||||
Mw_CfgBase_GsensorCalib_t gsensor_calib;
|
||||
uint8_t rsv[64];
|
||||
}Mw_CfgBaseGroup_t;
|
||||
|
||||
/*
|
||||
* System Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
char ap_ssid[32];
|
||||
char ap_password[16];
|
||||
}Mw_CfgSystem_Wifi_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
}Mw_CfgSystem_Bluetooth_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
}Mw_CfgSystem_Usb_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type;
|
||||
}Mw_CfgSystem_Sensor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t percent;
|
||||
}Mw_CfgSystem_Battery_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
}Mw_CfgSystem_Led_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
}Mw_CfgSystem_Button_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgSystem_Wifi_t wifi_info;
|
||||
Mw_CfgSystem_Bluetooth_t bt_info;
|
||||
Mw_CfgSystem_Usb_t usb_info;
|
||||
Mw_CfgSystem_Sensor_t sensor_info;
|
||||
Mw_CfgSystem_Battery_t battery_info;
|
||||
Mw_CfgSystem_Led_t led_info;
|
||||
Mw_CfgSystem_Button_t button_info;
|
||||
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgSystemGroup_t;
|
||||
|
||||
/*
|
||||
* Common Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t cam_mode;
|
||||
uint32_t sub_mode;
|
||||
}Mw_CfgCommon_CamMode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgCommon_CamMode_t mode;
|
||||
uint8_t rsv[64];
|
||||
}Mw_CfgCommonGroup_t;
|
||||
|
||||
/*
|
||||
* Video Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t rec_stream; /* see Mw_Cfg_VideoRecord_stream_e */
|
||||
}Mw_CfgVideo_Record_stream_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t resolution; /* see Mw_Cfg_VideoResolution_e */
|
||||
uint32_t fps; /* see Mw_Cfg_VideoFps_e */
|
||||
}Mw_CfgVideo_RecordSpec_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t value[MW_CFG_ENCODE_STREAM_NUM]; //Mbps
|
||||
}Mw_CfgVideo_Bitrate_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t main_type; /* see Mw_Cfg_VideoCodecType_e */
|
||||
uint32_t sub_type;
|
||||
}Mw_CfgVideo_Codec_t;
|
||||
|
||||
|
||||
typedef struct //birate encode mode: CRB/VRB/SMART_VRB
|
||||
{
|
||||
uint8_t value[MW_CFG_ENCODE_STREAM_NUM]; /* see Mw_Cfg_VideoBrateCtrlType_e */
|
||||
}Mw_CfgVideo_BrateCtrl_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgVideo_Record_stream_t stream;
|
||||
Mw_CfgVideo_RecordSpec_t spec;
|
||||
Mw_CfgVideo_Bitrate_t bitrate;
|
||||
Mw_CfgVideo_BrateCtrl_t bratectrl;
|
||||
Mw_CfgVideo_Codec_t codec;
|
||||
uint8_t rsv[128];
|
||||
} Mw_CfgVideoGroup_t;
|
||||
|
||||
/*
|
||||
* Photo Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t val;
|
||||
}Mw_CfgPhoto_Resolution_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t capnum;
|
||||
uint16_t aebnum; /* should be 0 or the same the CapNum. maximum SVC_STL_MAX_AEB_NUM */
|
||||
uint16_t strmmsk; /* yuv stream mask for CapType = SVC_CAP_TYPE_YUV, or vin mask for CapType = SVC_CAP_TYPE_RAW */
|
||||
uint8_t pictype; /* 0 - normal picture. 1 - video thumbnail. 2 - dump YUV. */
|
||||
uint8_t syncencstart;
|
||||
uint8_t caponly;
|
||||
uint8_t captype; /* SVC_CAP_TYPE_YUV - yuv capture, SVC_CAP_TYPE_RAW - raw capture */
|
||||
uint8_t stopliveview;
|
||||
uint16_t timelapsemsk;
|
||||
uint8_t Rsvd[16];
|
||||
} Mw_CfgPhoto_Capcfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgPhoto_Resolution_t resolution;
|
||||
Mw_CfgPhoto_Capcfg_t capcfg;
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgPhotoGroup_t;
|
||||
|
||||
/*
|
||||
* Audio Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t bits_per_sample;
|
||||
uint32_t aac_bitrate;
|
||||
uint32_t volume;
|
||||
uint32_t enable_DMIC;
|
||||
}Mw_CfgAudio_Encode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgAudio_Encode_t encode;
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgAudioGroup_t;
|
||||
|
||||
/*
|
||||
* Image Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t val;
|
||||
}Mw_CfgImage_Brightness_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t val;
|
||||
}Mw_CfgImage_Contrast_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t val;
|
||||
}Mw_CfgImage_Sharpness_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t exposure_mode;
|
||||
int32_t shutter; //M mode, 1/8000s->-8000000; 120->120000
|
||||
uint32_t iso; //M mode
|
||||
float shutter_limit; //A mode
|
||||
uint32_t iso_limit; //S mode
|
||||
float ev_bias; //P mode
|
||||
uint32_t wb_mode;
|
||||
uint32_t wb_temp; //M mode
|
||||
}Mw_CfgImage_AAA_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t value;
|
||||
}Mw_CfgImage_AntiFlicker_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgImage_Brightness_t brightness;
|
||||
Mw_CfgImage_Contrast_t contrast;
|
||||
Mw_CfgImage_Sharpness_t sharpness;
|
||||
Mw_CfgImage_AAA_t aaa;
|
||||
Mw_CfgImage_AntiFlicker_t anti_flicker;
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgImageGroup_t;
|
||||
|
||||
/*
|
||||
* Other Group
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t time;
|
||||
uint32_t brightness;
|
||||
}Mw_CfgOther_Lcd_t;
|
||||
typedef struct
|
||||
{
|
||||
uint32_t enable;
|
||||
}Mw_CfgOther_Qcap_t;
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgOther_Lcd_t lcd_info;
|
||||
Mw_CfgOther_Qcap_t quick_cap;
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgOtherGroup_t;
|
||||
|
||||
/*
|
||||
* App Group
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t val;
|
||||
}Mw_CfgApp_Gui_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgApp_Gui_t gui;
|
||||
uint8_t rsv[128];
|
||||
}Mw_CfgAppGroup_t;
|
||||
|
||||
/*
|
||||
* ALL
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic;
|
||||
uint16_t version;
|
||||
uint16_t total_size;
|
||||
uint32_t age; //use the max(main.age, back.age) part
|
||||
uint32_t checksum;
|
||||
}Mw_CfgHeader_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgHeader_t header;
|
||||
Mw_CfgBaseGroup_t base_info;
|
||||
Mw_CfgSystemGroup_t system_info;
|
||||
|
||||
}Mw_CfgSysPart_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Mw_CfgHeader_t header;
|
||||
|
||||
Mw_CfgCommonGroup_t common_info;
|
||||
Mw_CfgVideoGroup_t video_info;
|
||||
Mw_CfgPhotoGroup_t photo_info;
|
||||
Mw_CfgAudioGroup_t audio_info;
|
||||
Mw_CfgImageGroup_t image_info;
|
||||
Mw_CfgOtherGroup_t other_info;
|
||||
Mw_CfgAppGroup_t app_info;
|
||||
|
||||
|
||||
uint8_t rsv[256];
|
||||
}Mw_CfgUserPart_t;
|
||||
|
||||
/*
|
||||
* Profile related
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char val[64];
|
||||
} Mw_CfgProfileName_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t valid;
|
||||
Mw_CfgProfileName_t name;
|
||||
|
||||
Mw_CfgCommonGroup_t common_info;
|
||||
Mw_CfgVideoGroup_t video_info;
|
||||
Mw_CfgPhotoGroup_t photo_info;
|
||||
Mw_CfgAudioGroup_t audio_info;
|
||||
Mw_CfgImageGroup_t image_info;
|
||||
uint8_t rsv[256];
|
||||
}Mw_CfgProfileSetting_t;
|
||||
|
||||
#endif
|
||||
114
mw/config/mw_ut_config.c
Executable file
114
mw/config/mw_ut_config.c
Executable file
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************************************************************
|
||||
File name : mw_ut_config.c
|
||||
Module :
|
||||
Author :
|
||||
Copyright :
|
||||
Version : 0.1
|
||||
Created on : 2024-09-07
|
||||
Creator : amir.liang
|
||||
Description :
|
||||
Config for unittest
|
||||
*************************************************************************************************************************************/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "mw_config.h"
|
||||
#include "mw_ut_config.h"
|
||||
|
||||
|
||||
static int32_t init(int32_t argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return Mw_Cfg_Init(mw_storage_write, mw_storage_read);;
|
||||
}
|
||||
|
||||
static int32_t save(int32_t argc, char **argv)
|
||||
{
|
||||
uint32_t part = 0;
|
||||
|
||||
if(argc < 1)
|
||||
{
|
||||
hlogw("Input para not enough!");
|
||||
return NG;
|
||||
}
|
||||
part = atoi(argv[0]);
|
||||
return Mw_Cfg_Save(part);
|
||||
}
|
||||
|
||||
static int32_t print(int32_t argc, char **argv)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
if(argc <= 0)
|
||||
{
|
||||
return Mw_Cfg_PrintAll();
|
||||
}
|
||||
id = atoi(argv[0]);
|
||||
|
||||
return Mw_Cfg_PrintId(id);
|
||||
}
|
||||
|
||||
static int32_t set(int32_t argc, char **argv)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
uint32_t value = 0;
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
hlogw("Input para not enough!");
|
||||
return NG;
|
||||
}
|
||||
id = atoi(argv[0]);
|
||||
value = atoi(argv[1]);
|
||||
return Mw_Cfg_SetConfig((uint32_t)id, (void *)&value, sizeof(int));
|
||||
}
|
||||
|
||||
static int32_t get(int32_t argc, char **argv)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
uint32_t value = 0;
|
||||
uint32_t ret = 0;
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
hlogw("Input para not enough!");
|
||||
return NG;
|
||||
}
|
||||
id = atoi(argv[0]);
|
||||
value = atoi(argv[1]);
|
||||
ret = Mw_Cfg_GetConfig((uint32_t)id, (void *)&value, sizeof(value));
|
||||
if(OK == ret)
|
||||
{
|
||||
hlogi("Get id[%d] success, data:%d", id, value);
|
||||
Mw_Cfg_PrintId(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("Get id[%d] failed", id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t reset(int32_t argc, char **argv)
|
||||
{
|
||||
uint32_t part = 0;
|
||||
|
||||
if(argc < 1)
|
||||
{
|
||||
hlogw("Input para not enough!");
|
||||
return NG;
|
||||
}
|
||||
part = atoi(argv[0]);
|
||||
return Mw_Cfg_LoadDefault(part);
|
||||
}
|
||||
|
||||
unittest_cmd g_ut_cmd_config[UT_CMDCNT_CONFIG] =
|
||||
{
|
||||
DECLAR_UT_CMD(init , NULL, "init", "No Param: Init config"),
|
||||
DECLAR_UT_CMD(print, NULL, "print", "No Param: Print all; [ID]: Print sigle id"),
|
||||
DECLAR_UT_CMD(save, NULL, "save", "[partition]: Save sigle partition"),
|
||||
DECLAR_UT_CMD(reset, NULL, "reset", "[partition]: Reset sigle partition"),
|
||||
DECLAR_UT_CMD(set, NULL, "set", "[id] [value]: Set sigle id(only support int type)"),
|
||||
DECLAR_UT_CMD(get, NULL, "get", "[id] [value]: Get sigle id"),
|
||||
};
|
||||
|
||||
6
mw/config/mw_ut_config.h
Executable file
6
mw/config/mw_ut_config.h
Executable file
@@ -0,0 +1,6 @@
|
||||
#ifndef __MW_UT_CONFIG_H__
|
||||
#define __MW_UT_CONFIG_H__
|
||||
#include "mw_unittest.h"
|
||||
#define UT_CMDCNT_CONFIG (6)
|
||||
extern unittest_cmd g_ut_cmd_config[UT_CMDCNT_CONFIG];
|
||||
#endif
|
||||
2
mw/dmc/config.mk
Executable file
2
mw/dmc/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/dmc
|
||||
FUSION_HEADERS += $(MW_DIR)/dmc/*.h
|
||||
67
mw/media/mw_video.c
Executable file
67
mw/media/mw_video.c
Executable file
@@ -0,0 +1,67 @@
|
||||
/*************************************************
|
||||
File name : mw_video.c
|
||||
Module :
|
||||
Author : amir
|
||||
Version : 0.1
|
||||
Created on : 2024-09-07
|
||||
Description :
|
||||
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
*************************************************/
|
||||
#include "mw_video.h"
|
||||
|
||||
/**
|
||||
* 函数:Video_OpenStream
|
||||
* 声明:uint32_t video_openstream(STREAM_CHANNEL Stream, int32_t Channel)
|
||||
* 功能:打开视频流
|
||||
* 入参:STREAM_CHANNEL Stream, 视频流通道
|
||||
VIDEO_FORMAT Format, 视频格式
|
||||
int32_t Channel, 设备通道号
|
||||
* 出参:无
|
||||
* 返回:函数执行指示, uint32_t代码值
|
||||
* 0 成功
|
||||
* 非0 失败, 错误码
|
||||
*/
|
||||
uint32_t video_openstream(HAL_SENSOR_IDX idx, hal_video_frame_callback cb, HAL_STREAM_CHANNEL stream_chn, const video_attr_st attr)
|
||||
{
|
||||
uint32_t ret = hal_video_init(idx);
|
||||
return ret|hal_video_openstream(idx, cb, stream_chn, attr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 函数:Video_CloseStream
|
||||
* 声明:uint32_t video_close(STREAM_CHANNEL Stream, int32_t Channel)
|
||||
* 功能:关闭视频流
|
||||
* 入参:STREAM_CHANNEL Stream, 视频流通道
|
||||
VIDEO_FORMAT Format, 视频格式
|
||||
int32_t Channel, 设备通道号
|
||||
* 出参:无
|
||||
* 返回:函数执行指示, uint32_t代码值
|
||||
* 0 成功
|
||||
* 非0 失败, 错误码
|
||||
*/
|
||||
uint32_t video_close(hal_video_frame_callback cb)
|
||||
{
|
||||
return hal_video_closestream(cb);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t video_frame_cb(video_frame * frame){
|
||||
hlogi("%s frame:%p", __func__, frame);
|
||||
hv_msleep(2000);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
void mw_video_test(){
|
||||
video_attr_st attr;
|
||||
video_openstream(0, video_frame_cb, 0, attr);
|
||||
hv_sleep(2);
|
||||
video_close(video_frame_cb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
371
mw/media/mw_video.h
Executable file
371
mw/media/mw_video.h
Executable file
@@ -0,0 +1,371 @@
|
||||
#ifndef __MW_VIDEO_H__
|
||||
#define __MW_VIDEO_H__
|
||||
|
||||
//#include <stdint.h>
|
||||
//#include <stdio.h>
|
||||
#include "hal_interface_video.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 数据类型定义
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Video视频流通道常量定义, 适用HAL_Video
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
//1080P 1.2Mbps //720P 0.8Mbps //720P 500kbps
|
||||
VIDEO_3M = 3000,
|
||||
VIDEO_2_5M = 2500,
|
||||
VIDEO_2M = 2000,
|
||||
VIDEO_1_5M = 1500,
|
||||
VIDEO_1_4M = 1400,
|
||||
VIDEO_1_3M = 1300,
|
||||
VIDEO_1_2M = 1200,
|
||||
VIDEO_1_1M = 1100,
|
||||
VIDEO_1M = 1000,
|
||||
VIDEO_900k = 900,
|
||||
VIDEO_800k = 800,
|
||||
VIDEO_700k = 700,
|
||||
VIDEO_600k = 600,
|
||||
VIDEO_500k = 500,
|
||||
VIDEO_400k = 400,
|
||||
VIDEO_300k = 300,
|
||||
VIDEO_200k = 200,
|
||||
VIDEO_100k = 100,
|
||||
} VIDEO_BITRATE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VIDEO_LEVEL_1 = 1, //VIDEO_100K
|
||||
VIDEO_LEVEL_2, //VIDEO_200k
|
||||
VIDEO_LEVEL_3, //VIDEO_300k
|
||||
VIDEO_LEVEL_4, //VIDEO_400k
|
||||
VIDEO_LEVEL_5, //VIDEO_500k
|
||||
VIDEO_LEVEL_6, //VIDEO_600k
|
||||
VIDEO_LEVEL_7, //VIDEO_700k
|
||||
VIDEO_LEVEL_8, //VIDEO_800k
|
||||
VIDEO_LEVEL_9, //VIDEO_900k
|
||||
VIDEO_LEVEL_10, //VIDEO_1M
|
||||
VIDEO_LEVEL_11, //VIDEO_1_1M
|
||||
VIDEO_LEVEL_12, //VIDEO_1_2M
|
||||
VIDEO_LEVEL_13, //VIDEO_1_3M
|
||||
VIDEO_LEVEL_14, //VIDEO_1_4M
|
||||
VIDEO_LEVEL_15, //VIDEO_1_5M
|
||||
VIDEO_LEVEL_16, //VIDEO_2M
|
||||
VIDEO_LEVEL_17, //VIDEO_2_5M
|
||||
VIDEO_LEVEL_18, //VIDEO_3M
|
||||
VIDEO_LEVEL_19,
|
||||
VIDEO_LEVEL_20
|
||||
} VIDEO_BITRATE_LEVEL;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUTO_QUALITY = 0,
|
||||
LOW_QUALITY = 1,
|
||||
MEDIUM_QUALITY,
|
||||
HIGH_QUALITY,
|
||||
} VIDEO_QUALITY_LEVEL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int bitrate;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int videoquality;
|
||||
} VIDEO_QUALITY_INFO;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STREAM_FORM_UNDEF = -1, /**< 未指定 */
|
||||
STREAM_FORM_SINGLE = 0, /**< 使能单路流模式 */
|
||||
STREAM_FORM_PIP_UPPER_LEFT = 1, /**< 双摄使能画中画模式,画中画图像在左上 */
|
||||
STREAM_FORM_PIP_UPPER_RIGHT = 2, /**< 双摄使能画中画模式,画中画图像在右上 */
|
||||
STREAM_FORM_PIP_LOWER_LEFT = 3, /**< 双摄使能画中画模式,画中画图像在左下 */
|
||||
STREAM_FORM_PIP_LOWER_RIGHT = 4, /**< 双摄使能画中画模式,画中画图像在右下 */
|
||||
STREAM_FORM_SPLICE_LEFT = 5, /**< 双摄使能拼接模式,主摄图像在左边 */
|
||||
STREAM_FORM_SPLICE_RIGHT = 6, /**< 双摄使能拼接模式,主摄图像在右边 */
|
||||
STREAM_FORM_SPLICE_ABOVE = 7, /**< 双摄使能拼接模式,主摄图像在上边 */
|
||||
STREAM_FORM_SPLICE_UNDER = 8, /**< 双摄使能拼接模式,主摄图像在下边 */
|
||||
STREAM_FORM_MAX
|
||||
} STREAM_FORM;
|
||||
|
||||
/**
|
||||
* Video视频抗频闪模式常量定义, 适用HAL_Video
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ANTIFLICKER_OFF = 0,
|
||||
ANTIFLICKER_50HZ = 50,
|
||||
ANTIFLICKER_60HZ = 60,
|
||||
} ANTIFLICKER_MODE;
|
||||
|
||||
|
||||
/**
|
||||
* ISP运行模式定义
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ISP_RUNNING_MODE_DAY = 0, // 白天模式
|
||||
ISP_RUNNING_MODE_NIGHT = 1, // 夜视模式
|
||||
ISP_RUNNING_MODE_MAX
|
||||
} ISP_RUNNING_MODE;
|
||||
|
||||
/**
|
||||
* OSD水印切换模式
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LOGO_OSD_SWITCH_OFF = 0, // Logo OSD关闭, 时间戳OSD开启模式
|
||||
TIMESTAMP_OSD_SWITCH_OFF = 1, // Logo OSD开启, 时间戳OSD关闭模式
|
||||
BOTH_SWITCH_OFF = 2, // Logo OSD关闭, 时间戳OSD关闭模式
|
||||
BOTH_SWITCH_ON = 3, // Logo OSD开启, 时间戳OSD开启模式
|
||||
} OSD_SWITCH_MODE;
|
||||
|
||||
|
||||
/**
|
||||
* OSD遮挡切换模式
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
BOTH_COVER_OFF = 0, // COVER OSD都关闭
|
||||
COVERMAIN_ON_COVERSUB_OFF = 1, // Main cover osd 打开, Sub cover osd 关闭
|
||||
COVERMAIN_OFF_COVERSUB_ON = 2, // Main cover osd 关闭, Sub cover osd 打开
|
||||
BOTH_COVER_ON = 3, // COVER OSD都打开
|
||||
} COVER_OSD_SWITCH_MODE;
|
||||
|
||||
/**
|
||||
* OSD遮挡属性
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float Start_Percent_x;
|
||||
float Start_Percent_y;
|
||||
float End_Percent_x;
|
||||
float End_Percent_y;
|
||||
uint32_t Color;
|
||||
} Video_COVER_OSD;
|
||||
|
||||
/**
|
||||
* 视频流属性参数数据结构定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
HAL_VIDEO_FORMAT Format; // 流格式: stream format
|
||||
int32_t nWidth; // resolution width
|
||||
int32_t nHeight; // resolution height
|
||||
int32_t nBitrate; // 码率: Kbit per second
|
||||
//int32_t nFPS; // 帧率: framerate such as 15, 25
|
||||
//int32_t nGOP; // I帧间隔: interval between two key frame = n*fps
|
||||
HAL_STREAM_CHANNEL FS_Chn; //辅流Framesource channel
|
||||
int32_t rectX; //辅流叠加到主流的起始X坐标
|
||||
int32_t rectY; //辅流叠加到主流的起始Y坐标
|
||||
} Aux_Video_Attr_Param;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 视频流属性参数数据结构定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
HAL_STREAM_CHANNEL Stream; // 流通道
|
||||
HAL_VIDEO_FORMAT Format; // 流格式: stream format
|
||||
int32_t nWidth; // resolution width
|
||||
int32_t nHeight; // resolution height
|
||||
int32_t nBitrate; // 码率: Kbit per second
|
||||
int32_t AuxStreamEnable; // 是否开启辅流,以下字段仅在本字段为1时启用
|
||||
HAL_STREAM_CHANNEL FS_Chn; // 主流Framesource channel, Add 2021/03/16
|
||||
Aux_Video_Attr_Param AuxStreamAttr; // 辅流的视频属性, Add 2021/03/16
|
||||
STREAM_FORM StreamForm; // 流形式:单路流,画中画流,拼接流
|
||||
} Video_Attr_Param;
|
||||
|
||||
|
||||
/**
|
||||
* 视频回调参数结构定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *pBuff; //视频数据
|
||||
uint32_t nSize; //数据大小
|
||||
HAL_STREAM_CHANNEL Stream_Chn; //视频流通道
|
||||
HAL_VIDEO_FORMAT Video_Format;//视频格式
|
||||
HAL_FRAME_TYPE Frame_Type; //帧类型
|
||||
uint32_t nFPS; //帧率
|
||||
uint32_t nIR_Mode; //红外模式(0:红外关闭,1:红外开启)
|
||||
uint32_t nWidth; //分辨率宽度
|
||||
uint32_t nHeight; //分辨率高度
|
||||
uint64_t nTimestamp; //时间戳
|
||||
uint32_t Frame_Seq; //帧序号
|
||||
uint64_t nlocal_Time; //本地时间
|
||||
} Video_CallBack_Param;
|
||||
|
||||
/**
|
||||
* motion条件设置
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MOTOR_STOP_STATUS = 0, // 马达转动状态
|
||||
LIGHT_ON_OFF_CHANGE = 1, // 大灯亮灭
|
||||
INVALID_TRIGGER = 3,
|
||||
} MOTION_CONDITION_TYPE;
|
||||
|
||||
/**
|
||||
* 视频回调参数, 函数实现者不能发生阻塞, 否则将引起视频数据断片
|
||||
* 功能:视频数据输出
|
||||
* 入参:Video_CallBack_Param * pVideo_Param, 视频参数
|
||||
* uint32_t nChannel, 设备通道号
|
||||
* 出参:无
|
||||
* 返回:函数执行指示, int32_t代码值
|
||||
* 0 成功
|
||||
* 非0 失败, 错误码
|
||||
*/
|
||||
typedef int32_t(*HAL_Video_Callback)(Video_CallBack_Param * pVideo_Param, uint32_t nChannel);
|
||||
|
||||
|
||||
typedef int32_t(*HAL_Video_Motion_callback)(void *pResult);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// 移动检测跟踪数据类型定义
|
||||
// Motion Detection Tracking
|
||||
|
||||
#define PERM_MAX_ROI 8
|
||||
#define PERM_MAX_RECT 8
|
||||
|
||||
/*
|
||||
* 点的定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t x; /**< 横向的坐标值 */
|
||||
int32_t y; /**< 纵向的坐标值 */
|
||||
} MD_Point;
|
||||
|
||||
/*
|
||||
* 矩形框的定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MD_Point ul; /**< 左上角点坐标 */
|
||||
MD_Point br; /**< 右下角点坐标 */
|
||||
} MD_Rect;
|
||||
|
||||
/*
|
||||
* 周界信息结构体
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MD_Point *p; /**< 周界各个顶点信息,不能有线交叉,最多6个点 */
|
||||
int32_t pcnt; /**< 周界顶点数量 */
|
||||
uint64_t alarm_last_time; /**< 持续报警时间 */
|
||||
} MD_Perm;
|
||||
|
||||
|
||||
/*
|
||||
* 移动跟踪算法参数的结构体
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t move_sense; /** 检测灵敏度 0-5 ascend */
|
||||
int32_t open_flag; /** 总开关: motion detection and motion tracking, 0:close 1:open */
|
||||
int32_t perm_start; /** perm开关, 0:close 1:open */
|
||||
int32_t mt_start; /** motion tracking 开关, 0:close 1:open */
|
||||
|
||||
int32_t permcnt; /** 周界个数 */
|
||||
MD_Perm perms[PERM_MAX_ROI];/** 周界信息 */
|
||||
|
||||
int32_t feedback_motor; /** 电机回馈信息 */
|
||||
int32_t motor_stop; /** 电机停止状态 */
|
||||
} MD_Tracking_Param;
|
||||
|
||||
/*
|
||||
* 移动跟踪算法的输出结构体
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t count; /**< 检测到的矩形框目标个数 */
|
||||
MD_Rect rect[20]; /**< 检测到的目标矩形框 */
|
||||
int32_t dx; /**< 检测到的目标dx */
|
||||
int32_t dy; /**< 检测到的目标dy */
|
||||
int32_t step; /**< 检测到的目标step */
|
||||
int32_t capture_lost; /**< 何种状态下跟踪失效 */
|
||||
int32_t tracking; /**< 是否处于跟踪状态 */
|
||||
uint64_t timeStamp; /**< 时间戳*/
|
||||
|
||||
int32_t ret; /**< 是否出现越界 */
|
||||
int32_t is_alarmed[PERM_MAX_ROI]; /**< 那个周界出现越界 */
|
||||
MD_Rect rects[PERM_MAX_RECT]; /**< 越界物体的矩形信息 */
|
||||
int32_t rectcnt; /**< 越界物体的数量 */
|
||||
} MD_Tracking_Output;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DUAL_CAM_STREAM_MODE_UNDEF = -1, /* 未指定 */
|
||||
DUAL_CAM_STREAM_MODE_SINGLE_MAIN = 0, /*使能单路流,出主摄 */
|
||||
DUAL_CAM_STREAM_MODE_SINGLE_SECOND = 1, /*使能单路流,出辅摄 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_MAIN_UPPER_LEFT = 2, /* 画中画,辅摄小图左上 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_MAIN_UPPER_RIGHT = 3, /*画中画,辅摄小图右上 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_MAIN_LOWER_LEFT = 4, /*画中画,辅摄小图左下 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_MAIN_LOWER_RIGHT = 5, /* 画中画,辅摄小图右下 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_SECOND_UPPER_LEFT = 6, /* 画中画,主摄小图左上 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_SECOND_UPPER_RIGHT = 7, /*画中画,主摄小图右上 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_SECOND_LOWER_LEFT = 8, /*画中画,主摄小图左下 */
|
||||
DUAL_CAM_STREAM_MODE_PIP_SECOND_LOWER_RIGHT = 9, /* 画中画,主摄小图右下 */
|
||||
DUAL_CAM_STREAM_MODE_SPLICE_LEFT = 10, /* 拼接模式,主摄图像在左边 */
|
||||
DUAL_CAM_STREAM_MODE_SPLICE_RIGHT = 11, /* 拼接模式,主摄图像在右边 */
|
||||
DUAL_CAM_STREAM_MODE_SPLICE_ABOVE = 12, /* 拼接模式,主摄图像在上边 */
|
||||
DUAL_CAM_STREAM_MODE_SPLICE_UNDER = 13, /* 拼接模式,主摄图像在下边 */
|
||||
DUAL_CAM_STREAM_MODE_MAX
|
||||
} DUAL_CAM_STREAM_MODE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char weight[15][15]; //各个区域权重[0-8]
|
||||
} ISP_WEIGHT;
|
||||
|
||||
|
||||
// Stream Ops
|
||||
/**
|
||||
* 函数:Video_OpenStream
|
||||
* 声明:int32_t video_openstream(HAL_STREAM_CHANNEL Stream, int32_t Channel)
|
||||
* 功能:打开视频流
|
||||
* 入参:STREAM_CHANNEL Stream, 视频流通道
|
||||
HAL_VIDEO_FORMAT Format, 视频格式
|
||||
int32_t Channel, 设备通道号
|
||||
* 出参:无
|
||||
* 返回:函数执行指示, int32_t代码值
|
||||
* 0 成功
|
||||
* 非0 失败, 错误码
|
||||
*/
|
||||
uint32_t video_openstream(HAL_SENSOR_IDX idx, hal_video_frame_callback cb, HAL_STREAM_CHANNEL stream_chn, const video_attr_st attr);
|
||||
|
||||
/**
|
||||
* 函数:Video_CloseStream
|
||||
* 声明:int32_t video_close(HAL_STREAM_CHANNEL Stream, int32_t Channel)
|
||||
* 功能:关闭视频流
|
||||
* 入参:STREAM_CHANNEL Stream, 视频流通道
|
||||
HAL_VIDEO_FORMAT Format, 视频格式
|
||||
int32_t Channel, 设备通道号
|
||||
* 出参:无
|
||||
* 返回:函数执行指示, int32_t代码值
|
||||
* 0 成功
|
||||
* 非0 失败, 错误码
|
||||
*/
|
||||
uint32_t video_close(hal_video_frame_callback cb);
|
||||
|
||||
void mw_video_test();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __MW_VIDEO_H__ */
|
||||
2
mw/mmc/config.mk
Executable file
2
mw/mmc/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
HEADERS+= $(MW_DIR)/mmc/*.h
|
||||
SRCDIRS+= $(MW_DIR)/mmc
|
||||
152
mw/mmc/mw_mmc.c
Executable file
152
mw/mmc/mw_mmc.c
Executable file
@@ -0,0 +1,152 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "hthread.h"
|
||||
#include "hlog.h"
|
||||
#include "mw_mmc.h"
|
||||
|
||||
typedef struct {
|
||||
hthread_t th[HEVENT_PRIORITY_SIZE]; /* in case of block by one only thread */
|
||||
hloop_t *loop[HEVENT_PRIORITY_SIZE];
|
||||
hmutex_t mutex;
|
||||
uint8_t inited;
|
||||
}mmc;
|
||||
static mmc s_mmc_inst = {0};
|
||||
|
||||
static void mmc_atomic_inc(void *p){
|
||||
kpacket *packet =(kpacket *)p;
|
||||
kpacket_inc(packet);
|
||||
}
|
||||
|
||||
static void mmc_atomic_dec(void *p){
|
||||
kpacket *packet =(kpacket *)p;
|
||||
kpacket_dec(packet);
|
||||
|
||||
}
|
||||
|
||||
static uint32_t mmc_get_type(void *p){
|
||||
kpacket *packet =(kpacket *)p;
|
||||
return packet->tlv.T;
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(mmc_thread){
|
||||
hloop_t *loop = (hloop_t *)userdata;
|
||||
hloop_run(loop);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
uint32_t mmc_pub(kpacket *packet){
|
||||
const uint32_t idx = packet->tlv.T % HEVENT_PRIORITY_SIZE;
|
||||
hloop_t* loop = s_mmc_inst.loop[idx];
|
||||
if ( loop ){
|
||||
hloop_mmc_pub_event(loop, packet);
|
||||
return OK;
|
||||
} else {
|
||||
return NG;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* priority not the same with loop[HEVENT_PRIORITY_SIZE]
|
||||
**/
|
||||
|
||||
uint32_t mmc_sub(uint16_t event, hevent_cb cb, hevent_priority_e priority){
|
||||
const uint32_t idx = event % HEVENT_PRIORITY_SIZE;
|
||||
if (!s_mmc_inst.inited){
|
||||
hmutex_init(&s_mmc_inst.mutex);
|
||||
s_mmc_inst.inited = 1;
|
||||
}
|
||||
|
||||
hmutex_lock(&s_mmc_inst.mutex);
|
||||
hloop_t* loop = s_mmc_inst.loop[idx];
|
||||
hthread_t th = s_mmc_inst.th[idx];
|
||||
if (!th){
|
||||
s_mmc_inst.th[idx]= hthread_create(mmc_thread, loop);
|
||||
}
|
||||
hloop_mmc_sub_event(loop, event, priority, cb);
|
||||
hmutex_unlock(&s_mmc_inst.mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t mmc_init(uint32_t mmc_queue_size){
|
||||
for (uint32_t i = 0; i<sizeof(s_mmc_inst.loop)/sizeof(s_mmc_inst.loop[0]); i++){
|
||||
hloop_t* loop = s_mmc_inst.loop[i] = hloop_new(HLOOP_FLAG_AUTO_FREE);
|
||||
if (!loop){
|
||||
return NG;
|
||||
}
|
||||
hloop_mmc_init(loop, mmc_atomic_inc, mmc_atomic_dec, mmc_get_type, mmc_queue_size);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
uint32_t mmc_deinit(){
|
||||
uint32_t err = 0;
|
||||
for (hevent_priority_e idx = HEVENT_LOWEST_PRIORITY; idx < HEVENT_PRIORITY_SIZE; idx++ )
|
||||
{
|
||||
hloop_t* loop = s_mmc_inst.loop[idx];
|
||||
if ( loop ) {
|
||||
s_mmc_inst.loop[idx] = NULL;
|
||||
hloop_stop(loop);
|
||||
uint64_t start_ms = gettimeofday_ms();
|
||||
if (hthread_join(s_mmc_inst.th[idx]) != 0) {
|
||||
err = ESRCH;
|
||||
hloge("%s hthread_join priority:%d %p", __func__, idx, s_mmc_inst.th[idx]);
|
||||
}else {
|
||||
hlogw("%s %u/%u hthread_join priority:%d %p elapsed:%ul ms", __func__, idx+1, HEVENT_PRIORITY_SIZE, idx, s_mmc_inst.th[idx], gettimeofday_ms() - start_ms);
|
||||
}
|
||||
}else{
|
||||
hloge("%s not init hthread_join priority:%d %p", __func__, idx+1, s_mmc_inst.th[idx]);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void on_mmc_events_low(hevent_t* ev) {
|
||||
kpacket *p = (kpacket*)ev->userdata;
|
||||
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
|
||||
}
|
||||
|
||||
static void on_mmc_events_normal(hevent_t* ev) {
|
||||
kpacket *p = (kpacket*)ev->userdata;
|
||||
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
|
||||
}
|
||||
|
||||
static void on_mmc_events_high(hevent_t* ev) {
|
||||
kpacket *p = (kpacket*)ev->userdata;
|
||||
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
|
||||
}
|
||||
|
||||
|
||||
void mmc_test()
|
||||
{
|
||||
|
||||
#define MMC_EVENT_QUEUE_INIT_SIZE 128
|
||||
enum{
|
||||
EVENT_1,
|
||||
EVENT_2,
|
||||
};
|
||||
mmc_init(MMC_EVENT_QUEUE_INIT_SIZE);
|
||||
mmc_sub(EVENT_1, on_mmc_events_low, HEVENT_LOWEST_PRIORITY);
|
||||
mmc_sub(EVENT_1, on_mmc_events_normal, HEVENT_NORMAL_PRIORITY);
|
||||
mmc_sub(EVENT_1, on_mmc_events_high, HEVENT_HIGHEST_PRIORITY);
|
||||
kpacket *packet = kpacket(EVENT_1, 10);
|
||||
kpacket_put_string(packet, "123456");
|
||||
mmc_pub(packet);
|
||||
kpacket_dec(packet);
|
||||
|
||||
hlogd("%s packet=%p\n", __func__, packet);
|
||||
|
||||
mmc_sub(EVENT_2, on_mmc_events_low, HEVENT_LOWEST_PRIORITY);
|
||||
mmc_sub(EVENT_2, on_mmc_events_normal, HEVENT_NORMAL_PRIORITY);
|
||||
mmc_sub(EVENT_2, on_mmc_events_high, HEVENT_HIGHEST_PRIORITY);
|
||||
packet = kpacket(EVENT_2, 10);
|
||||
kpacket_put_string(packet, "abcdefg");
|
||||
mmc_pub(packet);
|
||||
kpacket_dec(packet);
|
||||
hlogd("%s packet=%p\n", __func__, packet);
|
||||
|
||||
hv_sleep(1);
|
||||
mmc_deinit();
|
||||
}
|
||||
31
mw/mmc/mw_mmc.h
Executable file
31
mw/mmc/mw_mmc.h
Executable file
@@ -0,0 +1,31 @@
|
||||
#ifndef _MMC_H_
|
||||
#define _MMC_H_
|
||||
#include "hloop.h"
|
||||
#include "kpacket.h"
|
||||
|
||||
// subscribe a event
|
||||
// param will be keep, can trans to handler
|
||||
uint32_t mmc_sub(uint16_t event, hevent_cb cb, hevent_priority_e priority);
|
||||
|
||||
|
||||
/*async event
|
||||
packet 会被mmc引用计数+1,然后回调完所有后-1
|
||||
如果, packet在外部异步回调,请在外部增/减引用
|
||||
*/
|
||||
uint32_t mmc_pub(kpacket *packet);
|
||||
|
||||
|
||||
//sync event, call directly, and return
|
||||
//uint32_t mmc_pub_sync(kpacket *packet);
|
||||
|
||||
|
||||
/* init mmc */
|
||||
uint32_t mmc_init(uint32_t mmc_queue_size);
|
||||
|
||||
//deinit mmc
|
||||
uint32_t mmc_deinit();
|
||||
|
||||
void mmc_test();
|
||||
|
||||
|
||||
#endif /* _MMC_H_ */
|
||||
2
mw/shutdownmgr/config.mk
Executable file
2
mw/shutdownmgr/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
HEADERS += $(MW_DIR)/shutdownmgr/*.h
|
||||
SRCDIRS += $(MW_DIR)/shutdownmgr
|
||||
105
mw/shutdownmgr/mw_shutdownmgr.c
Executable file
105
mw/shutdownmgr/mw_shutdownmgr.c
Executable file
@@ -0,0 +1,105 @@
|
||||
|
||||
#include "mw_shutdownmgr.h"
|
||||
#include "htime.h"
|
||||
#include "hthread.h"
|
||||
#include "hbase.h"
|
||||
#include "hlog.h"
|
||||
#include "hmutex.h"
|
||||
|
||||
|
||||
|
||||
typedef struct{
|
||||
hthread_t th;
|
||||
hmutex_t mutex;
|
||||
hsem_t sem;
|
||||
uint8_t exit;
|
||||
struct list_head wakeuplist;
|
||||
}shutdownmgr_s;
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct list_head link;
|
||||
WAKEUP_SOURCE src;
|
||||
uint64_t start_ms;
|
||||
uint64_t expire_ms;
|
||||
}wakeup_src_s;
|
||||
|
||||
static shutdownmgr_s *s_mgr;
|
||||
|
||||
static void start_ms_shutdown();
|
||||
static void *thread_entry(void *param){
|
||||
shutdownmgr_s *mgr = (shutdownmgr_s*)param;
|
||||
hlogd("%s start_ms:%p", __func__, param);
|
||||
for(;;)
|
||||
{
|
||||
{
|
||||
hmutex_lock(&mgr->mutex);
|
||||
struct list_head *pos = NULL, *n = NULL;
|
||||
list_for_each_safe(pos, n, &mgr->wakeuplist) {
|
||||
wakeup_src_s* src = list_entry(pos, wakeup_src_s, link);
|
||||
uint64_t now = gettimeofday_ms();
|
||||
if( now > src->expire_ms) {
|
||||
hlogd("now:%llu src %d expire_msd start_ms: %llu expire_ms:%llu interval: %llu ms", now, src->src, src->start_ms, src->expire_ms, src->expire_ms - src->start_ms);
|
||||
list_del(&src->link);
|
||||
hv_free(src);
|
||||
}//else Whlogd(myLog, "src %d param %d now %ld, expire_ms: %ld", src->src, src->param, clock(), src->expire_ms);
|
||||
}
|
||||
hmutex_unlock(&mgr->mutex);
|
||||
if(list_empty(&mgr->wakeuplist)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
hv_msleep(100);
|
||||
}
|
||||
|
||||
hlogw("%s go to shutdown", __func__);
|
||||
|
||||
//standby();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void shutdownmgr_set(WAKEUP_SOURCE source, uint32_t expire_ms_ms){
|
||||
shutdownmgr_s *mgr;
|
||||
if (!s_mgr ){
|
||||
s_mgr = hv_malloc(sizeof(shutdownmgr_s));
|
||||
INIT_LIST_HEAD(&s_mgr->wakeuplist);
|
||||
hmutex_init(&s_mgr->mutex);
|
||||
s_mgr->th = hthread_create(thread_entry, s_mgr);
|
||||
}
|
||||
mgr = s_mgr;
|
||||
|
||||
hmutex_lock(&mgr->mutex);
|
||||
struct list_head *pos, *n;
|
||||
list_for_each_safe(pos, n, &mgr->wakeuplist)
|
||||
{
|
||||
wakeup_src_s* src = list_entry(pos, wakeup_src_s, link);
|
||||
if(src->src == source) {
|
||||
src->expire_ms = gettimeofday_ms() + expire_ms_ms;
|
||||
hmutex_unlock(&mgr->mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
wakeup_src_s *src = hv_malloc(sizeof(wakeup_src_s));
|
||||
src->src = source;
|
||||
src->start_ms = gettimeofday_ms();
|
||||
src->expire_ms = src->start_ms + expire_ms_ms;
|
||||
list_add_tail(&src->link, &mgr->wakeuplist);
|
||||
hmutex_unlock(&mgr->mutex);
|
||||
|
||||
hloge("addWakeupSource %d now:%llu, after: %llums, expire_ms: %llu", source, gettimeofday_ms(), expire_ms_ms, src->expire_ms);
|
||||
start_ms_shutdown();
|
||||
}
|
||||
|
||||
void start_ms_shutdown()
|
||||
{
|
||||
hlogd("start_ms_shutdown:%s", __func__);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void shutdownmgr_test()
|
||||
{
|
||||
shutdownmgr_set(WAKEUP_DEFAULT, 2*1000);
|
||||
shutdownmgr_set(WAKEUP_USER, 5*1000);
|
||||
shutdownmgr_set(WAKEUP_QRCODE, 8*1000);
|
||||
}
|
||||
48
mw/shutdownmgr/mw_shutdownmgr.h
Executable file
48
mw/shutdownmgr/mw_shutdownmgr.h
Executable file
@@ -0,0 +1,48 @@
|
||||
/*************************************************************************
|
||||
File name : shutdownmgr.h
|
||||
Module : mw
|
||||
Author :
|
||||
Copyright :
|
||||
Version : 0.1
|
||||
Created on : 2022-04-27
|
||||
Creator : amir.liang
|
||||
Description :
|
||||
auto suspend the system if meet the condition
|
||||
用于关机管理
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
***************************************************************************/
|
||||
#ifndef __shutdownmgr_H__
|
||||
#define __shutdownmgr_H__
|
||||
#include <stdint.h>
|
||||
#include "list.h"
|
||||
|
||||
/*
|
||||
* 有source在的时候 禁止自动shutdown的
|
||||
* 所有source超时, 进入关机流程
|
||||
*/
|
||||
typedef enum{
|
||||
WAKEUP_DEFAULT = 0 ,//0
|
||||
WAKEUP_USER ,//1
|
||||
WAKEUP_QRCODE ,//2
|
||||
WAKEUP_WIFI ,//3
|
||||
WAKEUP_KEY ,//4
|
||||
WAKEUP_RING_BUTTON ,//6
|
||||
WAKEUP_HTTP ,//7 add 2 second each http request.
|
||||
WAKEUP_IO ,
|
||||
WAKEUP_HISTORYLIST//never suspend except onstanby or keepalive time out
|
||||
}WAKEUP_SOURCE;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void shutdownmgr_set(WAKEUP_SOURCE source, uint32_t expire_ms);
|
||||
|
||||
|
||||
|
||||
void shutdownmgr_test();
|
||||
|
||||
#endif /* __shutdownmgr_H__ */
|
||||
|
||||
2
mw/soft_watchdog/config.mk
Executable file
2
mw/soft_watchdog/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/soft_watchdog
|
||||
FUSION_HEADERS += $(MW_DIR)/soft_watchdog/*.h
|
||||
193
mw/soft_watchdog/mw_soft_watchdog.c
Executable file
193
mw/soft_watchdog/mw_soft_watchdog.c
Executable file
@@ -0,0 +1,193 @@
|
||||
#include "mw_soft_watchdog.h"
|
||||
#include "list.h"
|
||||
#include "htime.h"
|
||||
#include "hthread.h"
|
||||
#include "hbase.h"
|
||||
#include "hlog.h"
|
||||
#include "hmutex.h"
|
||||
#include "hplatform.h"
|
||||
|
||||
|
||||
#define reboot_delay(miniutes) miniutes
|
||||
|
||||
typedef struct {
|
||||
hsem_t sem;
|
||||
wd_item_s *p_items;
|
||||
uint16_t item_cnt;
|
||||
soft_watchdog_item_fail fail_cb;
|
||||
}sf_wtd_s;
|
||||
|
||||
static sf_wtd_s *s_wtd;
|
||||
|
||||
|
||||
void soft_watchdog_stop(uint32_t item)
|
||||
{
|
||||
if(s_wtd->p_items[item].start_ms != IGNORE) {
|
||||
hlogi("%s item %d IGNORE", __func__, item);
|
||||
s_wtd->p_items[item].start_ms = IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
void soft_watchdog_start(uint32_t item)
|
||||
{
|
||||
if( s_wtd->p_items[item].start_ms > 0 ) {
|
||||
/* already starting */
|
||||
} else {
|
||||
s_wtd->p_items[item].start_ms = gettimeofday_ms();
|
||||
hsem_post(&s_wtd->sem);
|
||||
hlogi("%s %u start_ms %lld", __func__, item, s_wtd->p_items[item].start_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void soft_watchdog_timeout(uint32_t item, uint32_t timeout_ms){
|
||||
s_wtd->p_items[item].start_ms = gettimeofday_ms();
|
||||
s_wtd->p_items[item].timeout_ms = timeout_ms;
|
||||
hsem_post(&s_wtd->sem);
|
||||
}
|
||||
|
||||
//something happen, delay the watchdog some time
|
||||
void soft_watchdog_timeout_all(uint32_t timeout_ms){
|
||||
for(uint32_t i = 0; i < s_wtd->item_cnt; i++){
|
||||
wd_item_s * item = &s_wtd->p_items[i];
|
||||
if (item->timeout_ms >= 0) {
|
||||
item->timeout_ms += timeout_ms;
|
||||
}
|
||||
}
|
||||
hlogi("wd_delay_all timeout_ms = %d", timeout_ms);
|
||||
}
|
||||
|
||||
HTHREAD_ROUTINE(soft_wtd_thread_entry)
|
||||
{
|
||||
hlogd("%s", __func__);
|
||||
hsem_wait(&s_wtd->sem);
|
||||
for(;;) {
|
||||
uint64_t now_ms = gettimeofday_ms();
|
||||
uint64_t expire_ms = (uint64_t)(-1);
|
||||
int32_t expire_item = -1;
|
||||
|
||||
for(uint32_t i = 0; i < s_wtd->item_cnt; i++){
|
||||
wd_item_s * item = &s_wtd->p_items[i];
|
||||
uint64_t item_expire_ms;
|
||||
//hlogd("%d start_ms %d timeout_ms %d now_ms %d",i , item->start_ms, item->timeout_ms, now_ms);
|
||||
if (item->start_ms == IGNORE) {
|
||||
continue;
|
||||
}
|
||||
item_expire_ms = item->start_ms + item->timeout_ms;
|
||||
if( now_ms > item_expire_ms ){
|
||||
hlogd("%d now_ms %llu, timeout_ms %llu timeout-now_ms:%llu", i, now_ms, item_expire_ms, item_expire_ms-now_ms);
|
||||
s_wtd->fail_cb(i);
|
||||
}
|
||||
|
||||
/* 最近的时间 */
|
||||
if ( item_expire_ms < expire_ms ) {
|
||||
expire_ms = item_expire_ms;
|
||||
expire_item = i;
|
||||
}
|
||||
|
||||
}
|
||||
now_ms = gettimeofday_ms();
|
||||
hlogd("%d now_ms %llu, timeout_ms %llu timeout-now_ms:%llu", expire_item, now_ms, expire_ms, expire_ms-now_ms);
|
||||
hsem_wait_for(&s_wtd->sem, expire_ms - now_ms + 1);/* '1' 避免, hsem_wait_for(sem, 0) 又快速循环 */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void soft_watchdog_init(wd_item_s *items, uint32_t item_cnt, soft_watchdog_item_fail fail_cb)
|
||||
{
|
||||
if (!s_wtd){
|
||||
s_wtd = (sf_wtd_s*)hv_malloc(sizeof(sf_wtd_s));
|
||||
hsem_init(&s_wtd->sem, 0);
|
||||
s_wtd->p_items = items;
|
||||
s_wtd->item_cnt = item_cnt;
|
||||
s_wtd->fail_cb = fail_cb;
|
||||
hthread_create(soft_wtd_thread_entry, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************soft_watchdog_test**********************/
|
||||
|
||||
|
||||
typedef enum{
|
||||
WD_None = -1,
|
||||
WD_Sensor_Init = 0, /* Sensor 初始化 */
|
||||
WD_Wifi_Init, /* WIFI 初始化 */
|
||||
WD_Wifi_Associated, /* WIFI 连接 */
|
||||
WD_Wifi_DHCP_IP, /* WIFI 获取IP */
|
||||
WD_Connect_Server, /* 连接服务器 */
|
||||
WD_AP_Wait_Client, /* AP模式 连接 */
|
||||
WD_Suspend, /* 休眠过程 */
|
||||
WD_Max
|
||||
}swd_e;
|
||||
|
||||
typedef struct {
|
||||
swd_e last_fail_idx;
|
||||
uint8_t last_fail_cnt;
|
||||
}swd_last_s;
|
||||
|
||||
static wd_item_s wditem_policy[] =
|
||||
{
|
||||
//WD_Sensor_Init, should call wd_set_ok in 3 seconds after system bootup
|
||||
[WD_Sensor_Init] = { IGNORE, 10*1000, { REBOOT, REBOOT, REBOOT, reboot_delay(2), reboot_delay(10), SHUTDOWN} },
|
||||
|
||||
//WD_Wifi_Init, should init done in 3 seconds after system bootup
|
||||
[WD_Wifi_Init] = { IGNORE, 10*1000, { REBOOT, REBOOT, reboot_delay(1), reboot_delay(2), reboot_delay(3), SHUTDOWN} },
|
||||
//WD_Wifi_Associated, should Associate done in 13 seconds after system bootup
|
||||
[WD_Wifi_Associated] = { IGNORE, 60*1000, { REBOOT, reboot_delay(3), reboot_delay(10), reboot_delay(10), reboot_delay(30), reboot_delay(60)} },
|
||||
//WD_Wifi_DHCP_IP, after enabled should be IGNORE to connect 30 seconds, try 2 times
|
||||
[WD_Wifi_DHCP_IP] = { IGNORE, 30*1000, { REBOOT, reboot_delay(2), reboot_delay(5), reboot_delay(10), reboot_delay(30), reboot_delay(60)} },
|
||||
//WD_Connect_Server, after enabled, 60 seconds should be IGNORE, try 2 times.
|
||||
[WD_Connect_Server] = { IGNORE, 60*1000, { REBOOT, reboot_delay(3), reboot_delay(10), reboot_delay(10), reboot_delay(30), reboot_delay(30)} },
|
||||
//WD_AP_Wait_Client, AP mode, wait client connect, 3minutes timeout_ms, just SUSPEND
|
||||
[WD_AP_Wait_Client] = { IGNORE, 180*1000, { SUSPEND, SUSPEND, SUSPEND, SUSPEND, SUSPEND, SUSPEND} },
|
||||
|
||||
//WD_Suspend
|
||||
[WD_Suspend] = { IGNORE, 60*1000, { REBOOT, REBOOT, REBOOT, REBOOT, REBOOT, REBOOT} }
|
||||
|
||||
};
|
||||
|
||||
static const char* get_item_name(swd_e item)
|
||||
{
|
||||
switch (item) {
|
||||
case WD_Sensor_Init : return NAME(WD_Sensor_Init);
|
||||
case WD_Wifi_Init : return NAME(WD_Wifi_Init);
|
||||
case WD_Wifi_Associated : return NAME(WD_Wifi_Associated);
|
||||
case WD_Wifi_DHCP_IP : return NAME(WD_Wifi_DHCP_IP);
|
||||
case WD_Connect_Server : return NAME(WD_Connect_Server);
|
||||
case WD_AP_Wait_Client : return NAME(WD_AP_Wait_Client);
|
||||
case WD_Suspend : return NAME(WD_Suspend);
|
||||
case WD_None: return NAME(WD_None);
|
||||
case WD_Max: return NAME(WD_Max);
|
||||
}
|
||||
return "None";
|
||||
}
|
||||
|
||||
static swd_last_s swd_last;
|
||||
static void soft_watchdog_fail_cb(uint32_t fail_idx){
|
||||
|
||||
/* 这段主要是要执行对应的action */
|
||||
if(swd_last.last_fail_idx == fail_idx) {
|
||||
swd_last.last_fail_cnt++;
|
||||
}else {
|
||||
swd_last.last_fail_cnt = 1;
|
||||
}
|
||||
if (swd_last.last_fail_cnt >= WD_POLICY_NUMBER) {
|
||||
swd_last.last_fail_cnt = WD_POLICY_NUMBER;
|
||||
}
|
||||
|
||||
uint32_t action = wditem_policy[swd_last.last_fail_idx].action[swd_last.last_fail_cnt - 1];
|
||||
uint8_t failed_info = ((swd_last.last_fail_cnt & 0xF) << 4) | (swd_last.last_fail_idx & 0xF);
|
||||
|
||||
/* save failed_info, 比如保存到mcu去 */
|
||||
hlogw("%s last_fail_idx : %d last_fail_cnt : %u", __func__, swd_last.last_fail_idx, swd_last.last_fail_cnt);
|
||||
}
|
||||
|
||||
void soft_watchdog_test()
|
||||
{
|
||||
|
||||
/* uint8_t failed_info = read 如从mcu读取 */
|
||||
soft_watchdog_init(wditem_policy, ARRAY_SIZE(wditem_policy), soft_watchdog_fail_cb);
|
||||
soft_watchdog_timeout(WD_Wifi_Associated, 5000);
|
||||
}
|
||||
|
||||
53
mw/soft_watchdog/mw_soft_watchdog.h
Executable file
53
mw/soft_watchdog/mw_soft_watchdog.h
Executable file
@@ -0,0 +1,53 @@
|
||||
#ifndef __WATCHDOG_H_INCLUDED__
|
||||
#define __WATCHDOG_H_INCLUDED__
|
||||
|
||||
#include<stdint.h>
|
||||
|
||||
|
||||
|
||||
//some helper definition
|
||||
enum {
|
||||
IGNORE = -1,
|
||||
|
||||
//for action
|
||||
REBOOT = 0,
|
||||
SHUTDOWN = -1,
|
||||
SUSPEND = -2,
|
||||
NOOP = -3,
|
||||
//> 0 means reboot_delay
|
||||
};
|
||||
|
||||
|
||||
#define WD_POLICY_NUMBER (6)
|
||||
#define NAME(_name) #_name
|
||||
|
||||
|
||||
typedef struct{
|
||||
int64_t start_ms; //must be int, monitor start time, IGNORE means IGNORE this item, OK means already OK. other >= 0 value means the start time
|
||||
uint32_t timeout_ms; //if not OK after timeout_ms seconds, do the recovery produce.
|
||||
uint32_t action[WD_POLICY_NUMBER]; //if not IGNORE, ask mcu do action. support retry up to 4 times. support REBOOT/SHUTDOWN/NOOP/reboot_delay
|
||||
}wd_item_s;
|
||||
|
||||
typedef void ( *soft_watchdog_item_fail)(uint32_t fail_idx);
|
||||
|
||||
/* 初始化后,需要 soft_watchdog_start 来开启对应的wtd */
|
||||
void soft_watchdog_init(wd_item_s *items, uint32_t item_cnt, soft_watchdog_item_fail fail_cb);
|
||||
|
||||
|
||||
/* 关闭对应item的看门狗 */
|
||||
void soft_watchdog_stop(uint32_t item);
|
||||
|
||||
/* 打开对应item的看门狗 */
|
||||
void soft_watchdog_start(uint32_t item);
|
||||
|
||||
/* 打开对应item的看门狗 , timeout_ms后将超时 */
|
||||
void soft_watchdog_timeout(uint32_t item, uint32_t timeout_ms);
|
||||
|
||||
/* 比如播放提示音:那么所有已经开始的wtd都要+timeout_ms后超时 */
|
||||
void soft_watchdog_timeout_all(uint32_t timeout_ms);
|
||||
|
||||
|
||||
void soft_watchdog_test();
|
||||
|
||||
|
||||
#endif /* __WATCHDOG_H_INCLUDED__ */
|
||||
2
mw/storage/config.mk
Executable file
2
mw/storage/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/storage
|
||||
FUSION_HEADERS += $(MW_DIR)/storage/*.h
|
||||
27
mw/storage/mw_storage.c
Executable file
27
mw/storage/mw_storage.c
Executable file
@@ -0,0 +1,27 @@
|
||||
#include "mw_storage.h"
|
||||
#include "list.h"
|
||||
#include "htime.h"
|
||||
#include "hthread.h"
|
||||
#include "hbase.h"
|
||||
#include "hlog.h"
|
||||
#include "hmutex.h"
|
||||
#include "hplatform.h"
|
||||
|
||||
|
||||
/*
|
||||
* 直接用mtd或操作flash分区, 加快启动速度
|
||||
**/
|
||||
uint32_t mw_storage_write(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size){
|
||||
|
||||
hloge("%s part:%u, region:%u data:%p size:%u", __func__, part, region, data, max_size);
|
||||
return max_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* 直接用mtd或操作flash分区, 加快启动速度
|
||||
**/
|
||||
// path can be file, return size has been read
|
||||
uint32_t mw_storage_read(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size){
|
||||
hloge("%s part:%u, region:%u data:%p size:%u", __func__, part, region, data, max_size);
|
||||
return max_size;
|
||||
}
|
||||
42
mw/storage/mw_storage.h
Executable file
42
mw/storage/mw_storage.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef __MW_STORAGE_H__
|
||||
#define __MW_STORAGE_H__
|
||||
#include "hal.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_STORAGE_REGION_MAIN = 0, /* For current user settings */
|
||||
CFG_STORAGE_REGION_BACK, /* For backup */
|
||||
|
||||
CFG_STORAGE_REGION_NUM
|
||||
}Mw_CfgStorage_Region_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CFG_STORAGE_PARTITION_SYS = 0, /* For system info setting */
|
||||
CFG_STORAGE_PARTITION_USER = 1, /* For user setting */
|
||||
|
||||
CFG_STORAGE_PARTITION_NUM
|
||||
}Mw_CfgStorage_Partition_e;
|
||||
|
||||
|
||||
/* For user */
|
||||
typedef uint32_t (*mw_read_cb)(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size);
|
||||
typedef uint32_t (*mw_write_cb)(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 数据类型定义
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*flash init interface define,should be implement if needed*/
|
||||
|
||||
// path can be file, return size has been writed
|
||||
uint32_t mw_storage_write(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size);
|
||||
|
||||
// path can be file, return size has been read
|
||||
uint32_t mw_storage_read(Mw_CfgStorage_Partition_e part, Mw_CfgStorage_Region_e region, char *data, uint32_t max_size);
|
||||
|
||||
|
||||
|
||||
#endif /* __MW_STORAGE_H__ */
|
||||
2
mw/tcpclient/config.mk
Executable file
2
mw/tcpclient/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/tcpclient
|
||||
FUSION_HEADERS += $(MW_DIR)/tcpclient/*.h
|
||||
262
mw/tcpclient/mw_tcpclient.c
Executable file
262
mw/tcpclient/mw_tcpclient.c
Executable file
@@ -0,0 +1,262 @@
|
||||
/*************************************************
|
||||
File name : pal_tcpclient.h
|
||||
Module :
|
||||
Author : amir
|
||||
Version : 0.1
|
||||
Created on : 2022-02-07
|
||||
Description :
|
||||
Data structure and function definitions required by the socket interface
|
||||
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
*************************************************/
|
||||
|
||||
#include "hthread.h"
|
||||
#include "mw_tcpclient.h"
|
||||
#include "hlog.h"
|
||||
#include "hbase.h"
|
||||
#include "hsocket.h"
|
||||
#include "hloop.h"
|
||||
#include "hevent.h"
|
||||
|
||||
#define dump_addr(io){\
|
||||
char localaddrstr[SOCKADDR_STRLEN] = {0};\
|
||||
char peeraddrstr[SOCKADDR_STRLEN] = {0};\
|
||||
SOCKADDR_STR(io->localaddr, localaddrstr);\
|
||||
SOCKADDR_STR(io->peeraddr, peeraddrstr);\
|
||||
hlogw("%s %s,%s\n", __func__, localaddrstr, peeraddrstr);}
|
||||
|
||||
|
||||
static void on_close(hio_t* io) {
|
||||
tcpclient *tclient = io->loop->userdata;
|
||||
if (tclient->hio == io){
|
||||
tclient->hio = NULL;
|
||||
}
|
||||
dump_addr(io);
|
||||
}
|
||||
|
||||
static void on_recv(hio_t* io, void* buf, int readbytes) {
|
||||
tcpclient *tclient = io->loop->userdata;
|
||||
iobuffer_appendData(&tclient->read_iobuf, buf, readbytes);
|
||||
tclient->handler.on_unpacket(tclient, &tclient->read_iobuf);
|
||||
}
|
||||
|
||||
static void on_connect(hio_t* io) {
|
||||
tcpclient *tclient = io->loop->userdata;
|
||||
if (tclient->hio) { /*最快的已连接上了, 关闭后面的*/
|
||||
hio_close(io);
|
||||
return;
|
||||
}
|
||||
dump_addr(io);
|
||||
tclient->hio = io;
|
||||
hio_setcb_read(io, on_recv);
|
||||
hio_read_start(io);
|
||||
TLV tlv = {.T = CONN_CONNECTED};
|
||||
tclient->handler.on_packet(tclient, &tlv);
|
||||
}
|
||||
|
||||
void tcpclient_conn(tcpclient *tclient, const char *domain_or_ip, const int port) {
|
||||
hio_t* io = hio_create_socket(tclient->loop, domain_or_ip, port, HIO_TYPE_TCP, HIO_CLIENT_SIDE);
|
||||
if (io == NULL) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
dump_addr(io);
|
||||
tcp_nodelay(hio_fd(io), 1);
|
||||
hio_setcb_connect(io, on_connect);
|
||||
hio_setcb_close(io, on_close);
|
||||
hio_connect(io);
|
||||
TLV tlv = {.T = CONN_STARTED};
|
||||
tclient->handler.on_packet(tclient, &tlv);
|
||||
|
||||
}
|
||||
|
||||
int32_t tcpclient_send(tcpclient *tclient, const char *data, const uint32_t sz){
|
||||
char out_data[MAX_PATH];
|
||||
uint32_t cnt = tclient->handler.on_pack(out_data, sizeof(out_data), data, sz);
|
||||
if ( cnt > 0 ){
|
||||
if (tclient->status != 'E'){
|
||||
hlogd(">>> %s size:%u", __func__, cnt);
|
||||
hio_write(tclient->hio, out_data, cnt);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
static void *tcpclient_tast(void *param)
|
||||
{
|
||||
tcpclient *tclient = (tcpclient *)param;
|
||||
hloge("%s tcpclient:%p loop:%p\n",__func__, param, tclient->loop);
|
||||
tclient->status = 'R';
|
||||
while(tclient->status != 'E'){
|
||||
hloop_run(tclient->loop);
|
||||
}
|
||||
hlogw("%s exit:%p\n",__func__, param);
|
||||
//tclient->handler.on_funcpacket(tclient, CONN_DESTROY);
|
||||
tclient->th = 0;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
tcpclient *tcpclient_init(int stack_size, packet_handler handler){
|
||||
tcpclient *tclient = (tcpclient*)calloc(1, sizeof(tcpclient));
|
||||
tclient->loop = hloop_new(0);
|
||||
tclient->loop->userdata = tclient;
|
||||
tclient->status = 'I';//idle
|
||||
tclient->stack_size = stack_size;
|
||||
tclient->handler = handler;
|
||||
iobuffer_init(&tclient->read_iobuf);
|
||||
tclient->th = hthread_create(tcpclient_tast, (void*)tclient);
|
||||
return tclient;
|
||||
}
|
||||
|
||||
int32_t tcpclient_deinit(tcpclient *tclient){
|
||||
if (tclient)
|
||||
{
|
||||
tclient->status = 'E';
|
||||
hloop_wakeup(tclient->loop);
|
||||
hlogw("%s hloop_free\n",__func__);
|
||||
hloop_free(&tclient->loop);
|
||||
free(tclient);
|
||||
return OK;
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************应用层demo***********************/
|
||||
|
||||
#define DEMO_UART_JSON (1) /* 1. 为了测试string在串口工具显示, 实际要发收TLV*/
|
||||
|
||||
/* 应用层四步
|
||||
**
|
||||
** 一, 声明枚举指令 和 回调函数
|
||||
** 二, 填写 packet_cmd_s 的 s_cmd_list
|
||||
** 三, 发数on_pack, 收数on_unpacket后回调
|
||||
**/
|
||||
|
||||
/* 第一步 */
|
||||
typedef enum {
|
||||
EV_LOGIN = 1000,//=>Server
|
||||
}EV_CMD;
|
||||
|
||||
typedef struct{
|
||||
EV_CMD cmd;
|
||||
uint32_t (*on_cmd)(tcpclient *client, TLV *tlv);
|
||||
}packet_cmd_s;
|
||||
|
||||
static uint32_t on_login(tcpclient *client, TLV *tlv){
|
||||
hloge("%s tlv->T:%u L:%u V:%s", __func__, tlv->T, tlv->L, tlv->V);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 第二步 */
|
||||
static packet_cmd_s s_cmd_list[]={
|
||||
{EV_LOGIN, on_login},
|
||||
};
|
||||
|
||||
static int32_t on_packet(tcpclient *client, void *data){
|
||||
json_pkt packet = {0};
|
||||
char buf[MAX_PATH] = {0};
|
||||
TLV *recv_tlv = (TLV *)data;
|
||||
switch(recv_tlv->T){
|
||||
case CONN_STARTED:
|
||||
break;
|
||||
case CONN_CONNECTING:
|
||||
break;
|
||||
case CONN_CONNECTED:
|
||||
json_pkt_add_int(&packet, "cmd", EV_LOGIN);
|
||||
json_pkt_add_str(&packet, "udid", "my_uuid_is_123456789");
|
||||
json_pkt_add_str(&packet, "wakeup_type", "pir");
|
||||
break;
|
||||
case CONN_SECOND_TICK:
|
||||
break;
|
||||
case CONN_CLOSED:
|
||||
break;
|
||||
case CONN_DESTROY:
|
||||
break;
|
||||
default:
|
||||
for ( uint16_t i=0; i< sizeof(s_cmd_list)/sizeof(s_cmd_list[0]); i++ ){
|
||||
if ( s_cmd_list[i].cmd == recv_tlv->T ){
|
||||
s_cmd_list[i].on_cmd(client, recv_tlv);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
hloge("unknown cmd:%u", recv_tlv->T);
|
||||
break;
|
||||
}
|
||||
|
||||
if (packet.json){
|
||||
char *str = json_pkt_toJson_string(&packet);
|
||||
uint32_t len = 0;
|
||||
if (str && ( len = strlen(str)) > 0 && len + sizeof(TLV) < sizeof(buf)){
|
||||
TLV *send_tlv =(TLV*)buf;
|
||||
send_tlv->T = packet.cmd;
|
||||
send_tlv->L = len;
|
||||
memcpy(send_tlv->V, str, len);
|
||||
tcpclient_send(client, (const char *)send_tlv, sizeof(TLV) + send_tlv->L);
|
||||
free(str);
|
||||
}else {
|
||||
hloge("error json:%p, len:%u", str, len);
|
||||
}
|
||||
json_pkt_reset(&packet);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 第三步 */
|
||||
int32_t on_pack(char *out_data, const uint32_t max_sz, const char *in_data, const uint32_t sz){
|
||||
/* 1. 比如可以在这里对data进行加密 */
|
||||
/* 2. in_data 是TLV */
|
||||
uint32_t cnt = 0;
|
||||
if ( sz < max_sz ){
|
||||
#if DEMO_UART_JSON
|
||||
TLV *tlv =(TLV*)in_data;
|
||||
memcpy(out_data, tlv->V, tlv->L);
|
||||
cnt = tlv->L;
|
||||
#else
|
||||
memcpy(out_data, in_data, sz);
|
||||
cnt = sz;
|
||||
#endif
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int32_t on_unpacket(tcpclient *client, iobuffer *iobuf){ /*TLV*/
|
||||
json_pkt packet = {0};
|
||||
#if DEMO_UART_JSON
|
||||
if (json_pkt_parse(&packet, iobuf->iodata, "cmd") ){
|
||||
char buf[MAX_PATH] = {0};
|
||||
TLV *recv_tlv = (TLV *)buf;
|
||||
recv_tlv->T = packet.cmd;
|
||||
recv_tlv->L = iobuf->size;
|
||||
memcpy(recv_tlv->V, iobuf->iodata, iobuf->size);
|
||||
on_packet(client, recv_tlv);
|
||||
iobuffer_eraseall(iobuf);
|
||||
}
|
||||
#else
|
||||
TLV *tlv =(TLV*)iobuf->iodata;
|
||||
if (json_pkt_parse(&packet, tlv->V, "cmd") ){
|
||||
iobuffer_erase(iobuf, 0, sizeof(TLV)+tlv->L);
|
||||
on_packet(client, &packet);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (packet.json){
|
||||
json_pkt_deinit(&packet);
|
||||
}else{
|
||||
hloge("<< unpack error \\n cannot be found: %s", iobuf->iodata);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void tcpclient_test(){
|
||||
packet_handler handler = {on_packet, on_unpacket, on_pack};
|
||||
tcpclient *client = tcpclient_init(1024, handler);
|
||||
tcpclient_conn(client, "192.168.1.98", 60000);
|
||||
//tcpclient_conn(client, "192.168.1.238", 80);
|
||||
//tcpclient_conn(client, "www.baidu.com", 80);
|
||||
hv_sleep(3);
|
||||
}
|
||||
|
||||
56
mw/tcpclient/mw_tcpclient.h
Executable file
56
mw/tcpclient/mw_tcpclient.h
Executable file
@@ -0,0 +1,56 @@
|
||||
#ifndef __MW_TCPCLIENT_H__
|
||||
#define __MW_TCPCLIENT_H__
|
||||
#include <stdint.h>
|
||||
#include "list.h"
|
||||
#include "kpacket.h"
|
||||
#include "json_packet.h"
|
||||
#include "hloop.h"
|
||||
#include "hbase.h"
|
||||
#include "hthread.h"
|
||||
|
||||
|
||||
|
||||
typedef enum{
|
||||
CONN_STARTED = 1, //1 thread start(note:network ok[connected to AP] to trigger it), opposite DESTROY
|
||||
CONN_CONNECTING, //2
|
||||
CONN_CONNECTED, //3
|
||||
CONN_SECOND_TICK, //4 event to up level
|
||||
CONN_CLOSED, //5
|
||||
CONN_DESTROY, //6 thread end
|
||||
CONN_RESERVED
|
||||
}ConnEvent;
|
||||
|
||||
|
||||
typedef struct tcpclient tcpclient;
|
||||
|
||||
typedef struct{
|
||||
int32_t (*on_packet)(tcpclient *client, void *data); /* 回调 TLV*/
|
||||
int32_t (*on_unpacket)(tcpclient *client, iobuffer *iobuf); /*in: 收到数据进行解包*/
|
||||
int32_t (*on_pack)(char *out_data, const uint32_t max_sz, const char *in_data, const uint32_t sz); /*out:以特定格式打包后以备发出, 与on_unpacket相反*/
|
||||
}packet_handler;
|
||||
|
||||
typedef struct tcpclient{
|
||||
int8_t status;// 'I' idle(initial), 'R' running, 'E' exit
|
||||
hloop_t *loop;
|
||||
int16_t stack_size;
|
||||
iobuffer read_iobuf;
|
||||
hthread_t th;
|
||||
packet_handler handler;
|
||||
hio_t *hio; /*连接的hio, 如果多个则自动选择, 最快那个*/
|
||||
}tcpclient;
|
||||
|
||||
|
||||
tcpclient *tcpclient_init(int stack_size, packet_handler handler);
|
||||
|
||||
/**
|
||||
* 支持多个连接同时发起, 最快连接上的会close掉后面连接的
|
||||
**/
|
||||
void tcpclient_conn(tcpclient *tclient, const char* domain_or_ip, int port);
|
||||
int32_t tcpclient_send(tcpclient *tclient, const char *data, const uint32_t sz);
|
||||
int32_t tcpclient_deinit(tcpclient *tclient);
|
||||
|
||||
|
||||
void tcpclient_test();
|
||||
|
||||
|
||||
#endif /* __MW_TCPCLIENT_H__ */
|
||||
2
mw/tcpserver/config.mk
Executable file
2
mw/tcpserver/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/tcpserver
|
||||
FUSION_HEADERS += $(MW_DIR)/tcpserver/*.h
|
||||
64
mw/tcpserver/mw_tcpserver.c
Executable file
64
mw/tcpserver/mw_tcpserver.c
Executable file
@@ -0,0 +1,64 @@
|
||||
/*************************************************
|
||||
File name : mw_tcpserver.h
|
||||
Module :
|
||||
Author : amir
|
||||
Version : 0.1
|
||||
Created on : 2024-10-10
|
||||
Description :
|
||||
Data structure and function definitions required by the socket interface
|
||||
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
*************************************************/
|
||||
|
||||
#include "hthread.h"
|
||||
#include "mw_tcpserver.h"
|
||||
#include "hlog.h"
|
||||
#include "hbase.h"
|
||||
#include "hsocket.h"
|
||||
#include "hloop.h"
|
||||
#include "hevent.h"
|
||||
|
||||
static void on_close(hio_t* io) {
|
||||
hlogd("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||
}
|
||||
|
||||
static void on_recv(hio_t* io, void* buf, int readbytes) {
|
||||
hlogd("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
|
||||
char localaddrstr[SOCKADDR_STRLEN] = {0};
|
||||
char peeraddrstr[SOCKADDR_STRLEN] = {0};
|
||||
hlogd("[%s] <=> [%s]\n",
|
||||
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
|
||||
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
||||
hlogd("< %.*s", readbytes, (char*)buf);
|
||||
// echo
|
||||
hlogd("> %.*s", readbytes, (char*)buf);
|
||||
hio_write(io, buf, readbytes);
|
||||
}
|
||||
|
||||
static void on_accept(hio_t* io) {
|
||||
hlogd("on_accept connfd=%d\n", hio_fd(io));
|
||||
char localaddrstr[SOCKADDR_STRLEN] = {0};
|
||||
char peeraddrstr[SOCKADDR_STRLEN] = {0};
|
||||
hlogd("accept connfd=%d [%s] <= [%s]\n", hio_fd(io),
|
||||
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
|
||||
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
||||
|
||||
hio_setcb_close(io, on_close);
|
||||
hio_setcb_read(io, on_recv);
|
||||
|
||||
hio_read_start(io);
|
||||
|
||||
}
|
||||
|
||||
void tcpserver_test(){
|
||||
const char* host = "0.0.0.0";
|
||||
int port = 8888;
|
||||
|
||||
hloop_t* loop = hloop_new(0);
|
||||
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
|
||||
hlogd("listenfd=%d\n", hio_fd(listenio));
|
||||
hloop_run(loop);
|
||||
hloop_free(&loop);
|
||||
}
|
||||
|
||||
35
mw/tcpserver/mw_tcpserver.h
Executable file
35
mw/tcpserver/mw_tcpserver.h
Executable file
@@ -0,0 +1,35 @@
|
||||
#ifndef __MW_TCPSERVER__
|
||||
#define __MW_TCPSERVER__
|
||||
#include <stdint.h>
|
||||
#include "list.h"
|
||||
#include "kpacket.h"
|
||||
#include "json_packet.h"
|
||||
#include "hloop.h"
|
||||
#include "hbase.h"
|
||||
#include "hthread.h"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct tcpserver{
|
||||
int8_t status;// 'I' idle(initial), 'R' running, 'E' exit
|
||||
hloop_t *loop;
|
||||
int16_t stack_size;
|
||||
iobuffer read_iobuf;
|
||||
hthread_t th;
|
||||
hio_t *hio; /*连接的hio, 如果多个则自动选择, 最快那个*/
|
||||
}tcpserver;
|
||||
|
||||
|
||||
tcpserver *tcpserver_init(int stack_size);
|
||||
|
||||
/**
|
||||
* 支持多个连接同时发起, 最快连接上的会close掉后面连接的
|
||||
**/
|
||||
int32_t tcpserver_deinit(tcpserver *tclient);
|
||||
|
||||
|
||||
void tcpserver_test();
|
||||
|
||||
|
||||
#endif /* __MW_TCPSERVER__ */
|
||||
2
mw/unittest/config.mk
Executable file
2
mw/unittest/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
CORE_SRCDIRS += $(MW_DIR)/unittest
|
||||
HEADERS += $(MW_DIR)/unittest/*.h
|
||||
99
mw/unittest/mw_unittest.c
Executable file
99
mw/unittest/mw_unittest.c
Executable file
@@ -0,0 +1,99 @@
|
||||
/*************************************************
|
||||
File name : mw_unittest.c
|
||||
Module :
|
||||
Author : amir
|
||||
Version : 0.1
|
||||
Created on : 2023-02-07
|
||||
Description :
|
||||
Data structure and function definitions required by the socket interface
|
||||
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
*************************************************/
|
||||
#include "mw_mmc.h"
|
||||
#include "mw_unittest.h"
|
||||
#include "hlog.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#define INSUT_UNITTEST_SHOWHOW -2
|
||||
|
||||
static int32_t unittest_help(unittest_cmd *cmd_info, uint8_t cmd_cnt)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
if(cmd_info == NULL)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
hlogi("Command List:");
|
||||
for(i=0; i<cmd_cnt; i++)
|
||||
{
|
||||
hlogi(" %s - %s", cmd_info[i].cmd_name, cmd_info[i].cmd_help);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t unittest_run_cmd(unittest_cmd *cmd_info, uint8_t cmd_cnt, int32_t argc, char **argv)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
int32_t rval = 0;
|
||||
if(argc > 0 && argv != NULL)
|
||||
{
|
||||
for(i=0; i<cmd_cnt; i++)
|
||||
{
|
||||
if(strcmp(argv[0], cmd_info[i].cmd_name) == 0)
|
||||
{
|
||||
if(cmd_info[i].exec_func != NULL)
|
||||
{
|
||||
rval = cmd_info[i].exec_func(argc-1, &argv[1]);
|
||||
if(rval == INSUT_UNITTEST_SHOWHOW)
|
||||
{
|
||||
unittest_help(cmd_info, cmd_cnt);
|
||||
}
|
||||
else if(rval != 0)
|
||||
{
|
||||
hloge("Rum cmd fail [ %s ] (0x%x)", argv[0], rval);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
else if(cmd_info[i].next_cmd != NULL)
|
||||
{
|
||||
return unittest_run_cmd(cmd_info[i].next_cmd, cmd_info[i].next_cmd_cnt, argc-1, &argv[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unittest_help(cmd_info, cmd_cnt);
|
||||
return INSUT_UNITTEST_SHOWHOW;
|
||||
}
|
||||
|
||||
int32_t unittest_shell_entry(int32_t argc, char **argv)
|
||||
{
|
||||
unittest_cmd *cmds;
|
||||
uint32_t cnt = unittest_get(&cmds);
|
||||
return unittest_run_cmd(cmds, cnt, argc, argv);
|
||||
}
|
||||
|
||||
void unittest(uint32_t argc, char **argv)
|
||||
{
|
||||
unittest_shell_entry(argc, argv);
|
||||
}
|
||||
|
||||
int32_t unittest_test()
|
||||
{
|
||||
char *args0[]={}; /* print all */
|
||||
unittest_shell_entry(sizeof(args0)/sizeof(char *), args0);
|
||||
|
||||
char *args[]={"device", "gpio", "output", "88", "0"};
|
||||
//char *args[]={"device", "gpio"}; 提示help
|
||||
unittest_shell_entry(sizeof(args)/sizeof(char *), args);
|
||||
|
||||
char *args2[]={"media", "debug"};
|
||||
// char *args2[]={"media"}; 提示help
|
||||
unittest_shell_entry(sizeof(args2)/sizeof(char *), args2);
|
||||
|
||||
char *args3[]={"main", "main"};
|
||||
unittest_shell_entry(sizeof(args3)/sizeof(char *), args3);
|
||||
}
|
||||
|
||||
33
mw/unittest/mw_unittest.h
Executable file
33
mw/unittest/mw_unittest.h
Executable file
@@ -0,0 +1,33 @@
|
||||
#ifndef __MW_UNITTES_H__
|
||||
#define __MW_UNITTES_H__
|
||||
#include <stdint.h>
|
||||
#include "hal.h"
|
||||
|
||||
|
||||
//int32_t unittest_register(AMBA_SHELL_COMMAND_s *pNewCmd);
|
||||
/* unittest_shell_entry
|
||||
** 执行命令行
|
||||
** 将这个函数插到shell回调中
|
||||
*/
|
||||
int32_t unittest_shell_entry(int32_t argc, char **argv);
|
||||
|
||||
/* unittest_file_entry
|
||||
** 执行脚本文件
|
||||
*/
|
||||
int32_t unittest_file_entry(uint8_t file_cnt, char *file_list[]);
|
||||
|
||||
/* unittest_get
|
||||
** 需要由外部的project的unittest_list实现
|
||||
*/
|
||||
int32_t unittest_get(unittest_cmd **cmds);
|
||||
//{
|
||||
// *cmds = unittest_list;
|
||||
// return sizeof(unittest_list)/sizeof(unittest_cmd);
|
||||
//}
|
||||
|
||||
|
||||
void unittest(uint32_t argc, char **argv);
|
||||
|
||||
int32_t unittest_test();
|
||||
|
||||
#endif /* __MW_UNITTES_H__ */
|
||||
Reference in New Issue
Block a user