Files
TAIXIN/sdk/app/recorder/recorder_viidure.c

5403 lines
168 KiB
C
Raw Normal View History

#include <csi_config.h>
#include "csi_kernel.h"
#include "typesdef.h"
#include "event.h"
#include "list.h"
#include "dev.h"
#include "devid.h"
#include "jpgdef.h"
#include "syscfg.h"
#include "stdio.h"
#include "sys_config.h"
#include "basic_include.h"
#include "file_process.h"
#include "recorder_viidure.h"
#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/sockets.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/etharp.h"
#include "lwip/ip.h"
#include "lwip/snmp.h"
#include "lwip/tcpip.h"
#include "netif/ethernet.h"
#include "netif/ethernetif.h"
#include "osal/irq.h"
#include "osal/string.h"
#include "osal/mutex.h"
#include "osal/sleep.h"
#include "hal/vpp.h"
#include "hal/isp.h"
#include "sys/time.h"
#include "cjson/cJSON.h"
#include "osal/msgqueue.h"
#include "osal/timer.h"
#include "fs/fatfs/osal_file.h"
#include "dev/csi/hgdvp.h"
#include "dev/jpg/hgjpg.h"
#include "lib/net/http/http.h"
#include "lib/net/eloop/eloop.h"
#include "lib/umac/ieee80211.h"
#include "lib/video/dvp/jpeg/jpg.h"
#include "video_app/file_thumb.h"
#include "video_app_h264_msi.h"
#include "video_app/file_common_api.h"
#include "audio_msi/audio_adc.h"
#include "audio_media_ctrl/audio_code_ctrl.h"
#include "loop_record_moudle/loop_record_moudle.h"
#include "sysevt_usb/sysevt_usb.h"
#ifndef RECORDER_MODE
#define RECORDER_MODE 0
#endif
struct msi *mp4_encode_msi2_init(const char *mp4_msi_name, uint8_t srcID, uint8_t filter_type, uint8_t rec_time,
uint32_t audio_encode, struct file_process *file_process, uint8_t mode);
struct msi *avi_encode_msi2_init(const char *avi_msi_name, uint8_t srcID, uint8_t filter_type, uint8_t rec_time,
uint32_t audio_encode, struct file_process *file_process, uint8_t mode);
static struct os_work recorder_wk;
static int itemcfg_save(uint8_t type);
uint8_t get_mipi_video_status(void);
uint8_t get_mipi2_video_status(void);
uint8_t get_usb_video_status(void);
void rec_lock_file(char *file_name, char *file_path);
static void itemcfg_handle(void);
#if RECORDER_MODE == 0
//由于发现,录风者似乎不支持动态修改传输方式udp和tcp
//切换完毕后,需要返回app,再出图才可以切换方式
//如果传输方式不变,是可以动态切换的
#endif
//需要与items_list中设置分辨的一致才行
static const int http_dpi[][2] = {
{1280, 720}, // 720P
{1920, 1080}, // 1080P
{2560, 1440}, // 2K
{3840, 2160}, // 4K
{7680, 4320}, // 8K
};
#define addWeb(web, url, type,reponse,queue) { url,type,(reponse),queue }
/******************************************************************************
* app的功能 *
* *
******************************************************************************/
// 结构体申请空间函数
#ifdef MORE_SRAM
#define STREAM_LIBC_MALLOC os_malloc_psram
#define STREAM_LIBC_FREE os_free_psram
#define STREAM_LIBC_ZALLOC os_zalloc_psram
#else
#define STREAM_LIBC_MALLOC os_malloc
#define STREAM_LIBC_FREE os_free
#define STREAM_LIBC_ZALLOC os_zalloc
#endif
// data申请空间函数
#define STREAM_MALLOC av_psram_malloc
#define STREAM_FREE av_psram_free
#define STREAM_ZALLOC av_psram_zalloc
// 消息推送端口
#define PUSH_MESSAGE_PORT 60000
// 开启后SD剩余容量小于 SD_FREE_SIZE_MIN 则推送SD卡满消息
#define SD_FREE_SIZE_EN 0
#define SD_FREE_SIZE_MIN 0
// 停车监控相册
#define PARKING_MOR_ALBUM_EN 0
// APP 锁存功能开关
#define APP_LOCK_VIDEO_EN 0
// 多目
#define MULTI_CAMERA_EN 1
#define MIPI 0
#define USB 1
#define MP4 0
#define AVI 1
#define CAM_MASK_SINGLE ( 1 << 0 ) // 单目
#define CAM_MASK_FRONT ( 1 << 1 )
#define CAM_MASK_INTERIOR ( 1 << 2 )
#define CAM_MASK_BACK ( 1 << 3 )
// 常用组合
#define CAM_ALL (CAM_MASK_FRONT | CAM_MASK_BACK | CAM_MASK_INTERIOR)
#define CAM_FRONT_BACK (CAM_MASK_FRONT | CAM_MASK_BACK)
#define CAM_FRONT_INTERIOR (CAM_MASK_FRONT | CAM_MASK_INTERIOR)
// 组合配置
#define CAM_MASK_ENABLE CAM_MASK_SINGLE
static struct cam_cfg *g_cam_configs = NULL;
// 镜头配置表
static const struct cam_cfg g_cam_configs_f[] = {
[0] = {
.msi = NULL,
.msi_name = "rec",
.src_msi = NULL,
.src_msi_name = AUTO_H264,
.aac_msi = NULL,
.srcID = FRAMEBUFF_SOURCE_CAMERA0,
.filter_type = FSTYPE_H264_VPP_DATA0,
.mode = 0,
.mask = CAM_MASK_SINGLE,
.type = MP4,
.src_type = MIPI,
.rec_path = REC_PATH,
.img_path = IMG_PATH,
.enable = 0,
.media = {
.rtsp_url = "h264?0",
.tran_mode = "tcp",
},
.file_process = {
.loop = NULL,
.rec_path = REC_PATH,
.ext_name = MP4_EXTENSION_NAME,
.create_file = rec_create_file,
.loop_free = rec_loop_free,
.lock_file = rec_lock_file,
.frame_time = 0
},
.create_func = mp4_encode_msi2_init,
.get_status = get_mipi_video_status
},
[1] = {
.msi = NULL,
.msi_name = "rec_front",
.src_msi = NULL,
.src_msi_name = AUTO_H264,
.aac_msi = NULL,
.srcID = FRAMEBUFF_SOURCE_CAMERA0,
.filter_type = FSTYPE_H264_VPP_DATA0,
.mode = 0,
.mask = CAM_MASK_FRONT,
.type = MP4,
.src_type = MIPI,
.rec_path = RECA_PATH,
.img_path = IMGA_PATH,
.enable = 0,
.media = {
.rtsp_url = "h264?0",
.tran_mode = "tcp",
},
.file_process = {
.loop = NULL,
.rec_path = RECA_PATH,
.ext_name = MP4_EXTENSION_NAME,
.create_file = rec_create_file,
.loop_free = rec_loop_free,
.lock_file = rec_lock_file,
.frame_time = 0
},
.create_func = mp4_encode_msi2_init,
.get_status = get_mipi_video_status
},
[2] = {
.msi = NULL,
.msi_name = "rec_int",
.src_msi = NULL,
.src_msi_name = AUTO_H264,
.aac_msi = NULL,
.srcID = FRAMEBUFF_SOURCE_NONE,
.filter_type = FSTYPE_H264_VPP_DATA1,
.mode = 0,
.mask = CAM_MASK_INTERIOR,
.type = MP4,
.src_type = MIPI,
.rec_path = RECB_PATH,
.img_path = IMGB_PATH,
.enable = 0,
.media = {
.rtsp_url = "h264?1",
.tran_mode = "tcp",
},
.file_process = {
.loop = NULL,
.rec_path = RECB_PATH,
.ext_name = MP4_EXTENSION_NAME,
.create_file = rec_create_file,
.loop_free = rec_loop_free,
.lock_file = rec_lock_file,
.frame_time = 0
},
.create_func = mp4_encode_msi2_init,
.get_status = get_mipi2_video_status
},
[3] = {
.msi = NULL,
.msi_name = "rec_rear",
.src_msi = NULL,
.src_msi_name = ROUTE_USB,
.aac_msi = NULL,
.srcID = 0,
.filter_type = (uint8_t) ~0,
.mode = 0,
.mask = CAM_MASK_BACK,
.type = AVI,
.src_type = USB,
.rec_path = RECC_PATH,
.img_path = IMGC_PATH,
.enable = 0,
.media = {
.rtsp_url = "custom?route-usb",
.tran_mode = "tcp",
},
.file_process = {
.loop = NULL,
.rec_path = RECC_PATH,
.ext_name = AVI_EXTENSION_NAME,
.create_file = rec_create_file,
.loop_free = rec_loop_free,
.lock_file = rec_lock_file,
.frame_time = 0
},
.create_func = avi_encode_msi2_init,
.get_status = get_usb_video_status
}
};
#define REC_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
// 镜头配置数量
#define CAMERAS_CONFIG_COUNT REC_ARRAY_SIZE(g_cam_configs_f)
// 配置项数量
#define ITEMS_CONFIG_COUNT REC_ARRAY_SIZE(items_cfg_f)
#define ITEM_MAX_NUM 8
typedef enum {
ITEM_ENABLE,
ITEM_DISABLE
}ItemEnable;
struct items_config;
static struct items_config *items_cfg = NULL;
typedef void (*param_handler_t)(struct items_config *item, uint8_t value, struct httpClient *httpClient);
typedef struct {
const char *name;
const uint8_t default_value;
const ItemEnable enable;
const param_handler_t handler;
const char *items_list[ITEM_MAX_NUM];
} config_item_t;
struct items_config {
uint8_t value;
const config_item_t *const_item;
};
#define ITEMS_CONFIG_INIT(_name, _default_value, _value, _enable, _handler, ...) \
{ \
.value = (_value), \
.const_item = &(const config_item_t) { \
.name = (_name), \
.default_value = (_default_value), \
.enable = (_enable), \
.handler = (_handler), \
.items_list = {__VA_ARGS__} \
} \
}
typedef enum {
SET_ITEMS_VALUE,
GET_ITEMS_VALUE,
GET_ITEMS_DEFAULT_VALUE,
GET_ITEMS_ENABLE
} ItemsProcessType;
static void set_default(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_mic(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rec_resolution(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rec_split_duration(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_encodec(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_speaker(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_gsr_sensitivity(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rec(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_language(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_timelapse_rate(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_park_record_time(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_park_gsr_sensitivity(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_light_fre(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rear_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_wdr(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_parking_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_parking_monitor(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_voice_control(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_screen_standby(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_auto_poweroff(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_adas(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_boot_sound(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_video_flip(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_video_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_key_tone(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_hour_type(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_time_format(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_ev(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_ir_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_speed_unit(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_wb(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_anti_shake(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_fast_record(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_denoise(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_auto_record(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_image_size(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_delay_shot(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_continue_shot(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_interior_record(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_shot_timelapse_rate(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_shot_timelapse_time(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_video_flip_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_five_g_wifi(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_gps_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_speed_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rear_flip(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_summer_timer(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_screen_brightness(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_sound_indicator(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_gps_data(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_vi_lowfps_rec(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_coordinate_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_inside_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_status_light(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_osd_option(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_wifi_channel(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_fill_light(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_screensaver(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_front_rotate(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_hdr(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_wifi_boot_starter(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_screen_saver_type(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_work_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_frame_zoom(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_rotate(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_motion_detect(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_image_quality(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_beauty(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_file_format(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_video_frame_rate(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_fov(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_video_watermark(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_motion_detect_rec_duration(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_record_light(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_motion_detect_sensitivity(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_sharpness(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_brightness(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_contrast(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_saturation(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_color(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_tv_video_out(struct items_config *item, uint8_t value, struct httpClient *httpClient);
// static void set_interval_shot(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static void set_switchcam(struct items_config *item, uint8_t value, struct httpClient *httpClient);
static const struct items_config items_cfg_f[] = {
/* 功能名 默认值 当前值 使能 执行函数 功能选项 */
ITEMS_CONFIG_INIT("mic", 1, 1, ITEM_ENABLE, set_mic,
"off", "on"), // 录像声音
ITEMS_CONFIG_INIT("osd", 1, 1, ITEM_ENABLE, set_osd,
"off", "on"), // 时间水印
ITEMS_CONFIG_INIT("rec_resolution", 0, 0, ITEM_ENABLE, set_rec_resolution,
"2K", "4K"), // 录像分辨率
ITEMS_CONFIG_INIT("rec_split_duration", 1, 1, ITEM_ENABLE, set_rec_split_duration,
"off", "1MIN", "2MIN", "3MIN"), // 录像文件时长
ITEMS_CONFIG_INIT("encodec", 0, 0, ITEM_DISABLE, set_encodec,
"h.264", "h.265"), // 视频编码格式
ITEMS_CONFIG_INIT("speaker", 0, 0, ITEM_DISABLE, set_speaker,
"off", "lowest", "lower", "low", "middle", "high", "very high"), // 扬声器音量
ITEMS_CONFIG_INIT("gsr_sensitivity", 2, 2, ITEM_ENABLE, set_gsr_sensitivity,
"off", "lowest", "lower", "low", "middle", "high"), // 碰撞感应灵敏度
ITEMS_CONFIG_INIT("rec", 0, 0, ITEM_DISABLE, set_rec,
"off", "on"), // 录像开关,只记录状态,不使能
ITEMS_CONFIG_INIT("language", 1, 1, ITEM_ENABLE, set_language,
"en_US", "zh_CN", "zh_CHT", "ja", "ko", "ru", "fr", "de"), // 记录仪语言
ITEMS_CONFIG_INIT("timelapse_rate", 0, 0, ITEM_ENABLE, set_timelapse_rate,
"off", "1fps", "2fps", "5fps"), // 缩时录影帧率
ITEMS_CONFIG_INIT("park_record_time", 0, 0, ITEM_ENABLE, set_park_record_time,
"off", "12hour", "24hour", "48hour"), // 停车监控时长
ITEMS_CONFIG_INIT("park_gsr_sensitivity", 0, 0, ITEM_ENABLE, set_park_gsr_sensitivity,
"off", "lowest", "lower", "low", "middle", "high"), // 停车监控碰撞感应
ITEMS_CONFIG_INIT("light_fre", 0, 0, ITEM_ENABLE, set_light_fre,
"50HZ", "60HZ"), // 光源频率
ITEMS_CONFIG_INIT("rear_mirror", 0, 0, ITEM_DISABLE, set_rear_mirror,
"off", "on"), // 后路镜像
ITEMS_CONFIG_INIT("wdr", 0, 0, ITEM_DISABLE, set_wdr,
"off", "on"), // 宽动态
ITEMS_CONFIG_INIT("parking_mode", 0, 0, ITEM_DISABLE, set_parking_mode,
"off", "timelapse", "normrec"), // 停车监控模式
ITEMS_CONFIG_INIT("parking_monitor", 0, 0, ITEM_DISABLE, set_parking_monitor,
"off", "on"), // 停车监控开关
ITEMS_CONFIG_INIT("voice_control", 0, 0, ITEM_DISABLE, set_voice_control,
"off", "on"), // 声控开关
ITEMS_CONFIG_INIT("screen_standby", 0, 0, ITEM_ENABLE, set_screen_standby,
"off", "1MIN", "2MIN", "3MIN"), // 自动息屏时间
ITEMS_CONFIG_INIT("auto_poweroff", 0, 0, ITEM_ENABLE, set_auto_poweroff,
"off", "1H", "12H"), // 延时关机时间
ITEMS_CONFIG_INIT("adas", 0, 0, ITEM_DISABLE, set_adas,
"off", "on"), // 驾驶辅助
ITEMS_CONFIG_INIT("boot_sound", 0, 0, ITEM_DISABLE, set_boot_sound,
"off", "on"), // 开机启动音
ITEMS_CONFIG_INIT("video_flip", 0, 0, ITEM_DISABLE, set_video_flip,
"off", "on"), // 视频垂直翻转
ITEMS_CONFIG_INIT("video_mirror", 0, 0, ITEM_DISABLE, set_video_mirror,
"off", "on"), // 视频水平镜像
ITEMS_CONFIG_INIT("key_tone", 0, 0, ITEM_ENABLE, set_key_tone,
"off", "on"), // 按键音
ITEMS_CONFIG_INIT("hour_type", 0, 0, ITEM_DISABLE, set_hour_type,
"off", "on"), // 24 小时制
ITEMS_CONFIG_INIT("time_format", 0, 0, ITEM_DISABLE, set_time_format,
"yyyy-MM-dd", "yyyy/MM/dd"), // 时间格式
ITEMS_CONFIG_INIT("ev", 0, 0, ITEM_DISABLE, set_ev,
"-1", "0", "1"), // 曝光补偿
ITEMS_CONFIG_INIT("ir_mode", 0, 0, ITEM_DISABLE, set_ir_mode,
"auto", "manual"), // 红外模式
ITEMS_CONFIG_INIT("speed_unit", 0, 0, ITEM_DISABLE, set_speed_unit,
"km/h", "mph"), // 速度单位
ITEMS_CONFIG_INIT("wb", 0, 0, ITEM_DISABLE, set_wb,
"off", "on"), // 白平衡
ITEMS_CONFIG_INIT("anti_shake", 0, 0, ITEM_DISABLE, set_anti_shake,
"off", "on"), // 防抖
ITEMS_CONFIG_INIT("fast_record", 0, 0, ITEM_DISABLE, set_fast_record,
"off", "2x", "4x", "6x"), // 快速录像
ITEMS_CONFIG_INIT("denoise", 0, 0, ITEM_DISABLE, set_denoise,
"off", "on"), // 图像降噪
ITEMS_CONFIG_INIT("auto_record", 0, 0, ITEM_DISABLE, set_auto_record,
"off", "on"), // 强制录像
ITEMS_CONFIG_INIT("image_size", 0, 0, ITEM_ENABLE, set_image_size,
"720P", "1080P", "2K", "4K", "8K"), // 拍照分辨率
ITEMS_CONFIG_INIT("delay_shot", 0, 0, ITEM_DISABLE, set_delay_shot,
"off", "2s", "10s"), // 延迟拍照
ITEMS_CONFIG_INIT("continue_shot", 0, 0, ITEM_ENABLE, set_continue_shot,
"off", "2", "10"), // 连拍张数
ITEMS_CONFIG_INIT("interior_record", 0, 0, ITEM_DISABLE, set_interior_record,
"off", "on"), // 车内录像
ITEMS_CONFIG_INIT("shot_timelapse_rate", 0, 0, ITEM_DISABLE, set_shot_timelapse_rate,
"off", "2s", "10s"), // 拍照缩时间隔
ITEMS_CONFIG_INIT("shot_timelapse_time", 0, 0, ITEM_DISABLE, set_shot_timelapse_time,
"off", "2s", "10s"), // 拍照缩时间长
ITEMS_CONFIG_INIT("video_flip_mirror", 0, 0, ITEM_ENABLE, set_video_flip_mirror,
"off", "on"), // 图像翻转
ITEMS_CONFIG_INIT("five_g_wifi", 0, 0, ITEM_DISABLE, set_five_g_wifi,
"off", "on"), // 5GWiFi
ITEMS_CONFIG_INIT("gps_osd", 0, 0, ITEM_DISABLE, set_gps_osd,
"off", "on"), // GPS 水印
ITEMS_CONFIG_INIT("speed_osd", 0, 0, ITEM_DISABLE, set_speed_osd,
"off", "on"), // 速度水印
ITEMS_CONFIG_INIT("rear_flip", 0, 0, ITEM_DISABLE, set_rear_flip,
"off", "on"), // 后路翻转
ITEMS_CONFIG_INIT("summer_timer", 0, 0, ITEM_DISABLE, set_summer_timer,
"off", "on"), // 夏令时
ITEMS_CONFIG_INIT("screen_brightness", 0, 0, ITEM_DISABLE, set_screen_brightness,
"off", "low", "middle", "high", "very high"), // 屏幕亮度
ITEMS_CONFIG_INIT("sound_indicator", 0, 0, ITEM_DISABLE, set_sound_indicator,
"off", "on"), // 提示音
ITEMS_CONFIG_INIT("gps_data", 0, 0, ITEM_DISABLE, set_gps_data,
"off", "on"), // GPS 数据
// ITEMS_CONFIG_INIT("vi_lowfps_rec", 0, 0, ITEM_DISABLE, set_vi_lowfps_rec,
// "1hour", "2hour", "4hour"), // 缩时录像时长
ITEMS_CONFIG_INIT("coordinate_osd", 0, 0, ITEM_DISABLE, set_coordinate_osd,
"off", "on"), // 经纬度水印
ITEMS_CONFIG_INIT("inside_mirror", 0, 0, ITEM_DISABLE, set_inside_mirror,
"off", "on"), // 车内镜像
ITEMS_CONFIG_INIT("status_light", 0, 0, ITEM_DISABLE, set_status_light,
"off", "on"), // 状态灯
ITEMS_CONFIG_INIT("osd_option", 0, 0, ITEM_DISABLE, set_osd_option,
"off", "on", "logo&date", "logo&model&date&time"), // 视频水印选项
ITEMS_CONFIG_INIT("wifi_channel", 0, 0, ITEM_DISABLE, set_wifi_channel,
"0", "1", "2"), // WiFi 信道
ITEMS_CONFIG_INIT("fill_light", 0, 0, ITEM_DISABLE, set_fill_light,
"off", "on"), // 补光
ITEMS_CONFIG_INIT("screensaver", 0, 0, ITEM_DISABLE, set_screensaver,
"off", "on"), // 屏幕保护
ITEMS_CONFIG_INIT("front_rotate", 0, 0, ITEM_DISABLE, set_front_rotate,
"off", "on", "auto"), // 前路旋转
ITEMS_CONFIG_INIT("hdr", 0, 0, ITEM_DISABLE, set_hdr,
"off", "on"), // 高动态
ITEMS_CONFIG_INIT("wifi_boot_starter", 0, 0, ITEM_DISABLE, set_wifi_boot_starter,
"off", "on"), // 开机启动 WiFi
ITEMS_CONFIG_INIT("screen_saver_type", 0, 0, ITEM_DISABLE, set_screen_saver_type,
"screen_off", "screen_saver_on"), // 屏保类型
ITEMS_CONFIG_INIT("work_mode", 0, 0, ITEM_DISABLE, set_work_mode,
"record", "capture", "delaycapture", "intervalcapture", "continuouscapture", "slowrecord", "looprecord", "timelapserecord"), // 预览多模式切换
ITEMS_CONFIG_INIT("frame_zoom", 0, 0, ITEM_DISABLE, set_frame_zoom,
"1x", "2x", "3x"), // 预览画面缩放切换
ITEMS_CONFIG_INIT("rotate", 0, 0, ITEM_DISABLE, set_rotate,
"off", "on", "auto"), // 图像旋转
ITEMS_CONFIG_INIT("motion_detect", 0, 0, ITEM_DISABLE, set_motion_detect,
"off", "on"), // 移动侦测
// ITEMS_CONFIG_INIT("image_quality", 0, 0, ITEM_DISABLE, set_image_quality,
// "off", "on"), // 拍照质量
// ITEMS_CONFIG_INIT("beauty", 0, 0, ITEM_DISABLE, set_beauty,
// "off", "on"), // 美颜
ITEMS_CONFIG_INIT("file_format", 0, 0, ITEM_DISABLE, set_file_format,
"MP4", "AVI"), // 录像格式
// ITEMS_CONFIG_INIT("video_frame_rate", 0, 0, ITEM_DISABLE, set_video_frame_rate,
// "30", "60"), // 视频帧率
// ITEMS_CONFIG_INIT("fov", 0, 0, ITEM_DISABLE, set_fov,
// "wide", "middle", "narrow"), // 视角
// ITEMS_CONFIG_INIT("video_watermark", 0, 0, ITEM_DISABLE, set_video_watermark,
// "off", "on"), // 视频水印
// ITEMS_CONFIG_INIT("motion_detect_rec_duration", 0, 0, ITEM_DISABLE, set_motion_detect_rec_duration,
// "off", "12hour", "24hour"), // 移动侦测录像时间
// ITEMS_CONFIG_INIT("record_light", 0, 0, ITEM_DISABLE, set_record_light,
// "off", "on"), // 录像警示灯
// ITEMS_CONFIG_INIT("motion_detect_sensitivity", 0, 0, ITEM_DISABLE, set_motion_detect_sensitivity,
// "off", "low", "middle", "high"), // 移动侦测灵敏度
// ITEMS_CONFIG_INIT("sharpness", 0, 0, ITEM_DISABLE, set_sharpness,
// "off", "low", "middle", "high"), // 锐度
// ITEMS_CONFIG_INIT("brightness", 0, 0, ITEM_DISABLE, set_brightness,
// "off", "low", "middle", "high"), // 亮度
// ITEMS_CONFIG_INIT("contrast", 0, 0, ITEM_DISABLE, set_contrast,
// "off", "low", "middle", "high"), // 对比度
// ITEMS_CONFIG_INIT("saturation", 0, 0, ITEM_DISABLE, set_saturation,
// "off", "low", "middle", "high"), // 饱和度
// ITEMS_CONFIG_INIT("color", 0, 0, ITEM_DISABLE, set_color,
// "default", "mono", "sepia", "cool", "warm", "vivid"), // 色彩
// ITEMS_CONFIG_INIT("tv_video_out", 0, 0, ITEM_DISABLE, set_tv_video_out,
// "NTSC", "PAL"), // TV 模式
// ITEMS_CONFIG_INIT("interval_shot", 0, 0, ITEM_DISABLE, set_interval_shot,
// "2s", "5s"), // 间隔拍照
ITEMS_CONFIG_INIT("switchcam", 0, 0, ITEM_DISABLE, set_switchcam,
NULL), // 切换摄像头,记录状态,不使能
ITEMS_CONFIG_INIT("timezone", 0, 0, ITEM_DISABLE, NULL,
NULL), // 时区,记录状态,不使能
ITEMS_CONFIG_INIT("saveflag", 0, 0, ITEM_DISABLE, NULL,
NULL), // 保存状态标志位,记录状态,不使能
ITEMS_CONFIG_INIT("lockvideo", 0, 0, ITEM_DISABLE, NULL,
NULL), // 锁存,记录状态,不使能
ITEMS_CONFIG_INIT("cameranum", 0, 0, ITEM_DISABLE, NULL,
NULL), // 镜头数量,记录状态,不使能
};
int get_items_counts(int num) {
int count = 0;
if(num < ITEMS_CONFIG_COUNT) {
while((count < ITEM_MAX_NUM) && (items_cfg[num].const_item->items_list[count] != NULL)) {
count++;
}
return count;
}
return 0;
}
int items_value_process(const char* name, uint8_t value, ItemsProcessType type) {
int name_len = 0;
int items_cfg_len = 0;
if(items_cfg == NULL)
return -1;
for (int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
name_len = strlen(name);
items_cfg_len = strlen(items_cfg[i].const_item->name);
if (strncmp(items_cfg[i].const_item->name, name, (name_len > items_cfg_len) ? name_len : items_cfg_len) == 0) {
switch (type)
{
case SET_ITEMS_VALUE:
items_cfg[i].value = value;
break;
case GET_ITEMS_VALUE:
return items_cfg[i].value;
break;
case GET_ITEMS_DEFAULT_VALUE:
return items_cfg[i].const_item->default_value;
break;
case GET_ITEMS_ENABLE:
return items_cfg[i].const_item->enable;
break;
default:
os_printf("Invalid items process type\r\n");
return -1;
}
return 0;
}
}
os_printf("Invalid config name: %s\r\n", name);
return -1;
}
static char *remove_prefix(char *filepath)
{
if (!filepath)
return NULL;
char* slash = strchr(filepath, '/');
if(slash == NULL)
{
slash = filepath;
}
else
{
slash++;
}
char* underscore = strchr(filepath, '_');
if (underscore)
{
if(os_strstr(slash, SOS_PREFIX))
{
os_memmove(slash, underscore + 1, strlen(underscore) + 1);
}
}
return filepath;
}
static char* remove_suffix(char* filepath)
{
if(!filepath)
return NULL;
char* underscore = strrchr(filepath, '_');
char* dot = strrchr(filepath, '.');
if(underscore && dot && underscore < dot)
{
if(os_strstr(underscore, FRONT_SUFFIX) || os_strstr(underscore, BACK_SUFFIX) || os_strstr(underscore, INTER_SUFFIX))
{
os_memmove(underscore, dot, strlen(dot) + 1);
}
}
return filepath;
}
static void http_reponse_getproductinfo(struct httpClient *httpClient);
static void http_reponse_settimezone(struct httpClient *httpClient);
static void http_reponse_setsystime(struct httpClient *httpClient);
static void http_reponse_getmediainfo(struct httpClient *httpClient);
static void http_reponse_getdeviceattr(struct httpClient *httpClient);
static void http_reponse_getparamvalue(struct httpClient *httpClient);
static void http_reponse_capability(struct httpClient *httpClient);
static void http_reponse_getparamitems_all(struct httpClient *httpClient);
static void http_reponse_getsdinfo(struct httpClient *httpClient);
static void http_reponse_getbatteryinfo(struct httpClient *httpClient);
static void http_reponse_getadasitems(struct httpClient *httpClient);
static void http_reponse_getstorageinfo(struct httpClient *httpClient);
static void http_reponse_lockvideo(struct httpClient *httpClient);
static void http_reponse_getlockvideostatus(struct httpClient *httpClient);
static void http_reponse_setting(struct httpClient *httpClient);
static void http_reponse_setparamvalue(struct httpClient *httpClient);
static void http_reponse_enterrecorder(struct httpClient *httpClient);
static void http_reponse_exitrecorder(struct httpClient *httpClient);
static void http_reponse_getrecduration(struct httpClient *httpClient);
static void http_reponse_getadasvalue(struct httpClient *httpClient);
static void http_reponse_playback(struct httpClient *httpClient);
static void http_reponse_getfilelist(struct httpClient *httpClient);
static void http_reponse_thumbnail(struct httpClient *httpClient);
static void http_reponse_setwifi(struct httpClient *httpClient);
static void http_reponse_reset(struct httpClient *httpClient);
static void http_reponse_sdformat(struct httpClient *httpClient);
static void http_reponse_wifireboot(struct httpClient *httpClient);
static void http_reponse_video(struct httpClient *httpClient);
static void http_reponse_event(struct httpClient *httpClient);
static void http_reponse_deletefile(struct httpClient *httpClient);
static void http_reponse_snapshot(struct httpClient *httpClient);
static void http_reponse_rec(struct httpClient *httpClient);
static void http_getparamvalue_rec(struct httpClient *httpClient);
static const struct url getweb[] =
{
addWeb(web, "app/getproductinfo", 1, http_reponse_getproductinfo, NULL),
addWeb(web, "app/settimezone?timezone=", 2, http_reponse_settimezone, NULL),
addWeb(web, "app/setsystime?date=", 2, http_reponse_setsystime, NULL),
addWeb(web, "app/getmediainfo", 1, http_reponse_getmediainfo, NULL),
addWeb(web, "app/getdeviceattr", 1, http_reponse_getdeviceattr, NULL),
addWeb(web, "app/getparamvalue?", 2, http_reponse_getparamvalue, NULL),
addWeb(web, "app/getparamitems?param=all", 1, http_reponse_getparamitems_all, NULL),
addWeb(web, "app/getsdinfo", 1, http_reponse_getsdinfo, NULL),
addWeb(web, "app/getbatteryinfo", 1, http_reponse_getbatteryinfo, NULL),
addWeb(web, "app/capability", 1, http_reponse_capability, NULL),
addWeb(web, "app/lockvideo", 1, http_reponse_lockvideo, NULL),
addWeb(web, "app/getlockvideostatus", 1, http_reponse_getlockvideostatus, NULL),
addWeb(web, "app/getstorageinfo", 1, http_reponse_getstorageinfo, NULL),
addWeb(web, "app/setting?", 2, http_reponse_setting, NULL),
addWeb(web, "app/setparamvalue?", 2, http_reponse_setparamvalue, NULL),
addWeb(web, "app/enterrecorder", 1, http_reponse_enterrecorder, NULL),
addWeb(web, "app/exitrecorder", 1, http_reponse_exitrecorder, NULL),
addWeb(web, "app/getrecduration", 1, http_reponse_getrecduration, NULL),
addWeb(web, "app/snapshot", 1, http_reponse_snapshot, NULL),
addWeb(web, "app/playback", 2, http_reponse_playback, NULL),
addWeb(web, "app/getfilelist", 1, http_reponse_getfilelist, NULL),
addWeb(web, "app/getthumbnail?file=", 2, http_reponse_thumbnail, NULL),
addWeb(web, "app/setwifi?", 2, http_reponse_setwifi, NULL),
addWeb(web, "app/reset", 1, http_reponse_reset, NULL),
addWeb(web, "app/sdformat", 2, http_reponse_sdformat, NULL),
addWeb(web, "app/wifireboot", 1, http_reponse_wifireboot, NULL),
addWeb(web, "LOOP/", 2, http_reponse_video, NULL),
addWeb(web, "EVENT/", 2, http_reponse_event, NULL),
addWeb(web, "EMR/", 2, http_reponse_video, NULL),
addWeb(web, "PARK/", 2, http_reponse_video, NULL),
addWeb(web, "app/deletefile?file=", 2, http_reponse_deletefile, NULL),
addWeb(web, "app/getadasitems", 2, http_reponse_getadasitems, NULL),
addWeb(web, "app/getadasvalue", 2, http_reponse_getadasvalue, NULL),
//搜索到url为NULL代表结束
addWeb(web, NULL, 1, http_send_error, NULL),
};
static uint32_t json_setsuccess(cJSON **root2, char **post_content)
{
*root2 = cJSON_CreateObject();
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddStringToObject(*root2, "info", "success.");
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_reponse_success(struct httpClient *httpClient)
{
if(httpClient == NULL)
{
return;
}
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_setsuccess(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static uint32_t json_setunsupport(cJSON **root2, char **post_content)
{
*root2 = cJSON_CreateObject();
cJSON_AddNumberToObject(*root2, "result", 98);
cJSON_AddStringToObject(*root2, "info", "unsupport.");
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_reponse_unsupport(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_setunsupport(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static uint32_t json_batteryinfo(cJSON **root2, char **post_content2)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "capacity", 100);
cJSON_AddNumberToObject(root, "charge", 1); // 0:未充电 1:充电中
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content2 = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_getbatteryinfo(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_batteryinfo(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static uint32_t json_productinfo(cJSON **root2, char **post_content2)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
cJSON_AddStringToObject(root, "model", "recorder");
cJSON_AddStringToObject(root, "company", "taixin");
cJSON_AddStringToObject(root, "soc", "taixin");
cJSON_AddStringToObject(root, "sp", "taixin");
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content2 = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_getproductinfo(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_productinfo(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static uint32_t json_deviceattr(cJSON **root2, char **post_content)
{
cJSON *root = NULL;
char ssid[32] = {0};
char mac[13] = {0};
os_sprintf(ssid, "%s", sys_cfgs.ssid);
os_sprintf(mac, "%02X%02X%02X%02X%02X%02X", sys_cfgs.mac[0], sys_cfgs.mac[1], sys_cfgs.mac[2], sys_cfgs.mac[3], sys_cfgs.mac[4], sys_cfgs.mac[5]);
// 进入录风者默认是主摄出图
items_value_process("switchcam", 0, SET_ITEMS_VALUE);
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
cJSON_AddStringToObject(root, "uuid", mac);
cJSON_AddStringToObject(root, "softver", "v0.0.8");
cJSON_AddStringToObject(root, "otaver", "v1.20260119.0");
cJSON_AddStringToObject(root, "hwver", "v1.2");
cJSON_AddStringToObject(root, "ssid", ssid);
cJSON_AddStringToObject(root, "bssid", mac);
cJSON_AddNumberToObject(root, "camnum", items_value_process("cameranum", 0, GET_ITEMS_VALUE));
cJSON_AddNumberToObject(root, "curcamid", items_value_process("switchcam", 0, GET_ITEMS_VALUE));
cJSON_AddNumberToObject(root, "wifireboot", 0);
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_reponse_getdeviceattr(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_deviceattr(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
void rec_lock_file(char *file_name, char *file_path)
{
#if APP_LOCK_VIDEO_EN
if(file_name == NULL || file_path == NULL)
{
os_printf("file_name or file_path is NULL\r\n");
return;
}
uint8_t video_num = items_value_process("lockvideo", 0, GET_ITEMS_VALUE);
if(video_num)
{
int res = 0;
char new_file_path[64];
char *last_slash = os_strrchr(file_path, '/');
int front_len = last_slash - file_path;
os_snprintf(new_file_path, sizeof(new_file_path), "%.*s/%s%s", front_len, file_path, SOS_PREFIX, file_name);
res = osal_rename(file_path, new_file_path);
if(res != FR_OK) {
os_printf("lock %s failed, res: %d\r\n", file_path, res);
} else {
os_printf("lock success, rename file %s to %s\r\n", file_path, new_file_path);
osal_fchmod(new_file_path, AM_RDO, AM_RDO);
}
items_value_process("lockvideo", --video_num, SET_ITEMS_VALUE);
}
#endif
}
/* 以下为新的多目录卡接口 */
void open_audio(void)
{
#if AUDIO_EN
os_printf("%s\n", __FUNCTION__);
struct msi *aac_msi = NULL;
AUENC_INIT auenc_init;
uint8_t aac_init = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi && !g_cam_configs[i].aac_msi)
{
if(g_cam_configs[i].type == MP4)
{
if(!aac_init)
{
auenc_init.destroy_self = 0;
auenc_init.src_msi = get_auadc_msi(AUSYS_AUAD);
aac_msi = audio_encode_init(AAC_ENC, audio_adc_get_samplerate(AUSYS_AUAD), &auenc_init);
}
if(aac_msi)
{
aac_init = 1;
g_cam_configs[i].aac_msi = aac_msi;
audio_code_add_output(g_cam_configs[i].aac_msi, g_cam_configs[i].msi->name);
}
}
else if(g_cam_configs[i].type == AVI)
{
g_cam_configs[i].aac_msi = NULL;
auadc_msi_add_output(AUSYS_AUAD, g_cam_configs[i].msi->name);
}
}
}
#endif
}
void close_audio(void)
{
#if AUDIO_EN
os_printf("%s\n", __FUNCTION__);
struct msi *aac_msi = NULL;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi)
{
if(g_cam_configs[i].aac_msi && g_cam_configs[i].type == MP4)
{
audio_code_del_output(g_cam_configs[i].aac_msi, g_cam_configs[i].msi->name);
aac_msi = g_cam_configs[i].aac_msi;
g_cam_configs[i].aac_msi = NULL;
}
else if(g_cam_configs[i].type == AVI)
{
auadc_msi_del_output(AUSYS_AUAD, g_cam_configs[i].msi->name);
}
}
}
if(aac_msi)
{
audio_encode_deinit(aac_msi);
aac_msi = NULL;
}
#endif
}
void open_rec(void)
{
os_printf("%s\n", __FUNCTION__);
#if APP_LOCK_VIDEO_EN
items_value_process("lockvideo", 0, SET_ITEMS_VALUE);
#endif
int rec_split_duration = items_value_process("rec_split_duration", 0, GET_ITEMS_VALUE);
int mic_status = items_value_process("mic", 0, GET_ITEMS_VALUE);
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if((g_cam_configs[i].mask & CAM_MASK_ENABLE) && g_cam_configs[i].enable && !g_cam_configs[i].msi)
{
if(!g_cam_configs[i].src_msi)
{
g_cam_configs[i].src_msi = msi_find(g_cam_configs[i].src_msi_name, 1);
if(g_cam_configs[i].src_msi)
{
_os_printf("open src msi: %s success\r\n", g_cam_configs[i].src_msi_name);
g_cam_configs[i].msi = g_cam_configs[i].create_func(g_cam_configs[i].msi_name, g_cam_configs[i].srcID,
g_cam_configs[i].filter_type,
rec_split_duration, mic_status,
&g_cam_configs[i].file_process, g_cam_configs[i].mode);
if(g_cam_configs[i].msi)
{
_os_printf("open msi: %s success\r\n", g_cam_configs[i].msi->name);
msi_add_output(g_cam_configs[i].src_msi, NULL, g_cam_configs[i].msi->name);
}
else
{
_os_printf("open msi: %s fail\r\n", g_cam_configs[i].msi_name);
msi_put(g_cam_configs[i].src_msi);
g_cam_configs[i].src_msi = NULL;
}
}
}
}
}
if(mic_status)
{
open_audio();
}
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi)
{
msi_do_cmd(g_cam_configs[i].msi, MSI_CMD_MEDIA_CTRL, MSI_MEDIA_CTRL_RECORD_START, 0);
}
}
}
void close_rec(void)
{
os_printf("%s\n", __FUNCTION__);
close_audio();
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi)
{
if(g_cam_configs[i].src_msi)
{
msi_del_output(g_cam_configs[i].src_msi, NULL, g_cam_configs[i].msi->name);
msi_destroy(g_cam_configs[i].msi);
g_cam_configs[i].msi = NULL;
msi_put(g_cam_configs[i].src_msi);
g_cam_configs[i].src_msi = NULL;
}
_os_printf("close msi: %s, src msi: %s\r\n", g_cam_configs[i].msi_name, g_cam_configs[i].src_msi_name);
}
}
}
/* 下面为旧版 MP4 录卡接口,需要先在 g_cam_configs 配置为单目模式且为 MP4 才能使用该接口 */
struct msi *mp4_msi = NULL;
struct msi *h264_msi = NULL;
static struct msi *aac_msi = NULL;
int open_h264_msi(void)
{
os_printf("%s\r\n", __FUNCTION__);
if((CAM_MASK_SINGLE & CAM_MASK_ENABLE) && (g_cam_configs[0].mask & CAM_MASK_ENABLE) && g_cam_configs[0].type == MP4 && g_cam_configs[0].enable)
{
open_rec();
mp4_msi = g_cam_configs[0].msi;
h264_msi = g_cam_configs[0].src_msi;
aac_msi = g_cam_configs[0].aac_msi;
return 1;
}
_os_printf("g_cam_configs config err\r\n");
return 0;
}
int close_h264_msi(void)
{
os_printf("%s\r\n", __FUNCTION__);
close_rec();
return 0;
}
static int open_aac_msi(void)
{
os_printf("%s\r\n", __FUNCTION__);
open_audio();
return 0;
}
static int close_aac_msi(void)
{
os_printf("%s\r\n", __FUNCTION__);
close_audio();
return 0;
}
int recorder_sd_start(void)
{
msi_do_cmd(mp4_msi, MSI_CMD_MEDIA_CTRL, MSI_MEDIA_CTRL_RECORD_START, 0);
return 0;
}
void close_record(void)
{
close_h264_msi();
close_aac_msi();
}
void open_record(void)
{
open_h264_msi();
open_aac_msi();
recorder_sd_start();
}
static uint8_t rec_get_running_status(uint8_t *has_msi)
{
uint8_t rec_status = 1;
uint32_t rec_status_g = 0;
*has_msi = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi)
{
*has_msi = 1;
msi_do_cmd(g_cam_configs[i].msi, MSI_CMD_GET_RUNNING, (uint32_t)&rec_status_g, 0);
rec_status &= rec_status_g ? 1 : 0;
}
}
return *has_msi ? rec_status : 0;
}
/* 以第一个 type 类型的录卡时间为准 */
static uint32_t rec_get_duration(uint8_t type)
{
uint32_t rec_second = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi && g_cam_configs[i].type == type)
{
msi_do_cmd(g_cam_configs[i].msi, MSI_CMD_MEDIA_CTRL, MSI_MEDIA_CTRL_GET_RECTIME, (uint32_t)&rec_second);
return rec_second;
}
}
return 0;
}
extern uint8_t get_fat_isready();
static uint32_t json_rec_status(cJSON **root2, char **post_content)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
uint8_t rec_status = 0;
uint8_t sd_status = 0;
uint8_t has_msi = 0;
#if FS_EN
sd_status = get_fat_isready();
#endif
if (sd_status == 0)
{
rec_status = 0;
}
else
{
rec_status = rec_get_running_status(&has_msi);
if (has_msi && !rec_status)
{
close_rec();
}
}
items_value_process("rec", rec_status, SET_ITEMS_VALUE);
cJSON_AddNumberToObject(root, "value", rec_status);
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_getparamvalue_rec(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_rec_status(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static void http_getparamvalue_car_plate(struct httpClient *httpClient)
{
http_reponse_unsupport(httpClient);
}
static uint32_t json_all_status(cJSON **root2, char **post_content)
{
cJSON *root = NULL;
cJSON *item = NULL;
*root2 = cJSON_CreateObject();
// 创建info数组
root = cJSON_CreateArray();
// 遍历配置项,创建数组元素
for (int i = 0; i < ITEMS_CONFIG_COUNT; i++)
{
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
{
item = cJSON_CreateObject();
cJSON_AddStringToObject(item, "name", items_cfg[i].const_item->name);
cJSON_AddNumberToObject(item, "value", items_cfg[i].value);
cJSON_AddItemToArray(root, item);
}
}
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_getparamvalue_all(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_all_status(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static void http_reponse_getparamvalue(struct httpClient *httpClient)
{
char *param_start, *params;
int param_size = 0;
// 查找参数字符串起始位置
param_start = strstr(httpClient->pattern, "param=");
if(param_start) {
param_start += strlen("param=");
}
if(param_start == NULL) {
os_printf("%s: %d, request error\r\n", __FUNCTION__, __LINE__);
closeRes(httpClient);
return;
}
param_size = strlen(param_start);
params = STREAM_LIBC_MALLOC(param_size + 1);
if (params == NULL) {
os_printf("FUNCTION:%s Line:%d, STREAM_LIBC_MALLOC failed\r\n", __FUNCTION__, __LINE__);
return;
}
strncpy(params, param_start, param_size);
params[param_size] = '\0';
// 根据param值调用对应函数
if (strcmp(params, "rec") == 0) {
http_getparamvalue_rec(httpClient);
}
else if (strcmp(params, "car_plate") == 0) {
// 车牌识别 不支持
http_getparamvalue_car_plate(httpClient);
}
else if (strcmp(params, "all") == 0) {
http_getparamvalue_all(httpClient);
}
else {
closeRes(httpClient);
os_printf("Unknown parameter: %s\r\n", params);
}
STREAM_LIBC_FREE(params);
}
static uint32_t json_mediainfo(cJSON **root2, char **post_content2)
{
char *ip8;
cJSON *root = NULL;
char rtsp_path[100];
char path_for_file[32];
ip8 = (char*)&sys_cfgs.ipaddr;
uint8_t video_num = items_value_process("switchcam", 0, GET_ITEMS_VALUE);
uint8_t camera_num = items_value_process("cameranum", 0, GET_ITEMS_VALUE);
//设置超过范围,则直接配置第一个摄像头
if(video_num >= camera_num)
{
video_num = 0;
}
struct media_s *media = NULL;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if((g_cam_configs[i].mask & CAM_MASK_ENABLE) && g_cam_configs[i].enable)
{
if(video_num == 0)
{
media = &g_cam_configs[i].media;
break;
}
video_num--;
}
}
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
if(media)
{
memset(rtsp_path, 0, sizeof(rtsp_path));
memset(path_for_file, 0, sizeof(path_for_file));
snprintf(path_for_file, sizeof(path_for_file), "%s", media->rtsp_url);
snprintf(rtsp_path, sizeof(rtsp_path), "rtsp://%d.%d.%d.%d/%s", ip8[0], ip8[1], ip8[2], ip8[3], path_for_file);
cJSON_AddStringToObject(root, "rtsp", rtsp_path);
cJSON_AddStringToObject(root, "transport", media->tran_mode);
cJSON_AddNumberToObject(*root2, "result", 0);
}
else
{
_os_printf("media is null\n");
cJSON_AddNumberToObject(*root2, "result", 99);
}
cJSON_AddNumberToObject(root, "port", PUSH_MESSAGE_PORT);
cJSON_AddNumberToObject(root, "rectime", 1);
cJSON_AddItemToObject(*root2, "info", root);
*post_content2 = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_getmediainfo(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_mediainfo(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
uint32_t json_capability(cJSON **root2, char **post_content2)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
if(PARKING_MOR_ALBUM_EN) {
if(APP_LOCK_VIDEO_EN) {
cJSON_AddStringToObject(root, "value", "000101000000010");
} else {
cJSON_AddStringToObject(root, "value", "000001000000010");
}
} else {
if(APP_LOCK_VIDEO_EN) {
cJSON_AddStringToObject(root, "value", "001100000000010");
} else {
cJSON_AddStringToObject(root, "value", "001000000000010");
}
}
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content2 = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_capability(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_capability(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static void http_reponse_settimezone(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
int timezone;
timezone = atoi(httpClient->pattern);
items_value_process("timezone", timezone, SET_ITEMS_VALUE);
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_setsuccess(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
time_t timeToSeconds(const char* timeStr)
{
struct tm tm = {0};
int year, month, day, hour, minute, second;
uint8_t ret = 0;
// 解析时间字符串
ret = sscanf(timeStr, "%4d%2d%2d%2d%2d%2d",
&year, &month, &day, &hour, &minute, &second);
if(ret != 6)
{
return 0;
}
// 设置tm结构体
tm.tm_year = year - 1900; // 年份是从1900开始的
tm.tm_mon = month - 1; // 月份是0-11
tm.tm_mday = day;
tm.tm_hour = hour;
tm.tm_min = minute;
tm.tm_sec = second;
tm.tm_isdst = -1; // 让系统自动判断夏令时
// 转换为时间戳(秒数)
time_t timestamp = mktime(&tm);
return timestamp;
}
static void http_reponse_setsystime(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
int timezone = 0;
uint64_t time = 0;
struct timezone tz = {0};
struct timeval ptimeval;
time = timeToSeconds(httpClient->pattern);
if(time == 0)
{
_os_printf("params error: %s\r\n", httpClient->pattern);
closeRes(httpClient);
return;
}
ptimeval.tv_sec = time;
ptimeval.tv_usec = 0;
timezone = items_value_process("timezone", 0, GET_ITEMS_VALUE);
tz.tz_minuteswest = -timezone * 60;
tz.tz_dsttime = 0;
_os_printf("set rtc time: %s\ttimezone: %d\r\n", httpClient->pattern, timezone);
settimeofday(&ptimeval, &tz);
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_setsuccess(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static void http_reponse_enterrecorder(struct httpClient *httpClient)
{
// 进入录风者界面后开始录像,可根据需要修改
if(items_value_process("rec" , 0, GET_ITEMS_ENABLE) == ITEM_ENABLE) {
if(items_value_process("rec", 0, GET_ITEMS_DEFAULT_VALUE)) {
open_rec();
items_value_process("rec", 1, SET_ITEMS_VALUE);
}
}
http_reponse_success(httpClient);
}
static void http_reponse_exitrecorder(struct httpClient *httpClient)
{
int saveflag = 0;
saveflag = items_value_process("saveflag", 0, GET_ITEMS_VALUE);
if(saveflag) {
itemcfg_save(1);
saveflag = 0;
items_value_process("saveflag", saveflag, SET_ITEMS_VALUE);
}
http_reponse_success(httpClient);
}
static uint32_t json_recduration(cJSON **root2, char **post_content)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
uint32_t rec_second = 0;
// 默认以第一个镜头的录像时间作为当前录卡的持续时间
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].msi)
{
rec_second = rec_get_duration(g_cam_configs[i].type);
break;
}
}
cJSON_AddNumberToObject(root, "duration", rec_second);
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_reponse_getrecduration(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_recduration(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
static void http_reponse_playback(struct httpClient *httpClient)
{
char *params;
// 查找参数字符串起始位置
params = strstr(httpClient->pattern, "param=");
if(params) {
params += strlen("param=");
}
// 根据param值调用对应函数
if (strcmp(params, "enter") == 0) {
_os_printf("playback enter\r\n");
}
else if (strcmp(params, "exit") == 0) {
_os_printf("playback exit\r\n");
// 退出回放界面后打开录像,可根据需要修改
// open_rec();
// items_value_process("rec", 1, SET_ITEMS_VALUE);
}
else {
_os_printf("unknown parameter: %s\n", params);
closeRes(httpClient);
return;
}
http_reponse_success(httpClient);
}
static void http_reponse_getadasitems(struct httpClient *httpClient)
{
http_reponse_unsupport(httpClient);
}
static void http_reponse_getadasvalue(struct httpClient *httpClient)
{
http_reponse_unsupport(httpClient);
}
static void http_reponse_lockvideo(struct httpClient *httpClient)
{
#if APP_LOCK_VIDEO_EN
if (items_value_process("lockvideo", 0, GET_ITEMS_VALUE)) {
items_value_process("lockvideo", 0, SET_ITEMS_VALUE);
} else {
uint8_t video_num = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if((g_cam_configs[i].mask & CAM_MASK_ENABLE) && g_cam_configs[i].msi)
{
video_num++;
}
}
items_value_process("lockvideo", video_num, SET_ITEMS_VALUE);
}
http_reponse_success(httpClient);
#else
http_reponse_unsupport(httpClient);
#endif
}
static uint32_t json_lockvideostatus(cJSON **root2, char **post_content2)
{
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "status", items_value_process("lockvideo", 0, GET_ITEMS_VALUE));
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content2 = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_getlockvideostatus(struct httpClient *httpClient)
{
#if APP_LOCK_VIDEO_EN
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_lockvideostatus(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
#else
http_reponse_unsupport(httpClient);
#endif
}
static void http_reponse_getstorageinfo(struct httpClient *httpClient)
{
http_reponse_unsupport(httpClient);
}
static void http_reponse_setting(struct httpClient *httpClient)
{
char *params;
// 查找参数字符串起始位置
params = strstr(httpClient->pattern, "param=");
if(params) {
params += strlen("param=");
}
// 根据param值调用对应函数
if (strcmp(params, "enter") == 0) {
_os_printf("setting enter\r\n");
}
else if (strcmp(params, "exit") == 0) {
int saveflag = 0;
saveflag = items_value_process("saveflag", 0, GET_ITEMS_VALUE);
if(saveflag) {
itemcfg_save(1);
saveflag = 0;
items_value_process("saveflag", saveflag, SET_ITEMS_VALUE);
}
_os_printf("setting exit\r\n");
// 退出设置界面后打开录像,可根据需要修改
// open_rec();
// items_value_process("rec", 1, SET_ITEMS_VALUE);
}
else {
_os_printf("Unknown parameter: %s\n", params);
closeRes(httpClient);
return;
}
http_reponse_success(httpClient);
}
static void set_rec(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像
if(value == 0)
{
// 关闭录像
_os_printf("rec close\r\n");
close_rec();
}
else if(value == 1)
{
// 打开录像
_os_printf("rec open\r\n");
open_rec();
}
else
{
_os_printf("set rec error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_default(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
item->value = value;
http_reponse_success(httpClient);
}
static void set_mic(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像声音
if(value == 0)
{
// 关闭录像声音
_os_printf("mic close\r\n");
}
else if(value == 1)
{
// 打开录像声音
_os_printf("mic open\r\n");
}
else
{
_os_printf("set mic error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 时间水印
if(value == 0)
{
// 关闭时间水印
_os_printf("set osd close\r\n");
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
vpp_set_watermark0_enable(vpp_dev,value);
// vpp_set_watermark1_enable(vpp_dev,value);
}
else if(value == 1)
{
// 打开时间水印
_os_printf("set osd open\r\n");
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
vpp_set_watermark0_enable(vpp_dev,value);
// vpp_set_watermark1_enable(vpp_dev,value);
}
else
{
_os_printf("set osd error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_rec_resolution(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像分辨率
if(value == 0)
{
// 2K
_os_printf("set rec resolution 2K\r\n");
}
else if(value == 1)
{
// 4K
_os_printf("set rec resolution 4K\r\n");
}
else
{
_os_printf("set mic error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_rec_split_duration(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像文件时长 {"off", "1MIN", "2MIN", "3MIN"}
switch(value)
{
case 0:
_os_printf("set rec split duration off\r\n");
break;
case 1:
_os_printf("set rec split duration 1MIN\r\n");
break;
case 2:
_os_printf("set rec split duration 2MIN\r\n");
break;
case 3:
_os_printf("set rec split duration 3MIN\r\n");
break;
default:
_os_printf("set rec split duration error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_encodec(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像编码器 {"h264", "h265"}
if(value == 0)
{
_os_printf("set encodec h264\r\n");
}
else if(value == 1)
{
_os_printf("set encodec h265\r\n");
}
else
{
_os_printf("set encodec error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_speaker(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 扬声器音量 {"off", "lowest", "lower", "low", "middle", "high", "very high"}
switch(value)
{
case 0:
_os_printf("set speaker off\r\n");
break;
case 1:
_os_printf("set speaker lowest\r\n");
break;
case 2:
_os_printf("set speaker lower\r\n");
break;
case 3:
_os_printf("set speaker low\r\n");
break;
case 4:
_os_printf("set speaker middle\r\n");
break;
case 5:
_os_printf("set speaker high\r\n");
break;
case 6:
_os_printf("set speaker very high\r\n");
break;
default:
_os_printf("set speaker error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_gsr_sensitivity(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 碰撞感应 {"off", "lowest", "lower", "low", "middle", "high"}
switch(value)
{
case 0:
_os_printf("set gsr sensitivity off\r\n");
break;
case 1:
_os_printf("set gsr sensitivity lowest\r\n");
break;
case 2:
_os_printf("set gsr sensitivity lower\r\n");
break;
case 3:
_os_printf("set gsr sensitivity low\r\n");
break;
case 4:
_os_printf("set gsr sensitivity middle\r\n");
break;
case 5:
_os_printf("set gsr sensitivity high\r\n");
break;
default:
_os_printf("set gsr sensitivity error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_language(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 记录仪语言 {"en_US", "zh_CN", "zh_CHT", "ja", "ko", "ru", "fr", "de"}
switch(value)
{
case 0:
_os_printf("set language en_US\r\n");
break;
case 1:
_os_printf("set language zh_CN\r\n");
break;
case 2:
_os_printf("set language zh_CHT\r\n");
break;
case 3:
_os_printf("set language ja\r\n");
break;
case 4:
_os_printf("set language ko\r\n");
break;
case 5:
_os_printf("set language ru\r\n");
break;
case 6:
_os_printf("set language fr\r\n");
break;
case 7:
_os_printf("set language de\r\n");
break;
default:
_os_printf("set language error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_timelapse_rate(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 缩时录影帧率 {"off", "1fps", "2fps", "5fps"}
switch(value)
{
case 0:
_os_printf("set timelapse rate off\r\n");
break;
case 1:
_os_printf("set timelapse rate 1fps\r\n");
break;
case 2:
_os_printf("set timelapse rate 2fps\r\n");
break;
case 3:
_os_printf("set timelapse rate 5fps\r\n");
break;
default:
_os_printf("set timelapse rate off error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_park_record_time(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 停车监控时长 {"off", "12hour", "24hour", "48hour"}
switch(value)
{
case 0:
_os_printf("set park record time off\r\n");
break;
case 1:
_os_printf("set park record time 12hour\r\n");
break;
case 2:
_os_printf("set park record time 24hour\r\n");
break;
case 3:
_os_printf("set park record time 48hour\r\n");
break;
default:
_os_printf("set park record time error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_park_gsr_sensitivity(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 停车监控碰撞感应 {"off", "lowest", "lower", "low", "middle", "high"}
switch(value)
{
case 0:
_os_printf("set park gsr sensitivity off\r\n");
break;
case 1:
_os_printf("set park gsr sensitivity lowest\r\n");
break;
case 2:
_os_printf("set park gsr sensitivity lower\r\n");
break;
case 3:
_os_printf("set park gsr sensitivity low\r\n");
break;
case 4:
_os_printf("set park gsr sensitivity middle\r\n");
break;
case 5:
_os_printf("set park gsr sensitivity high\r\n");
break;
default:
_os_printf("set park gsr sensitivity error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_light_fre(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 光源频率 {"50HZ", "60HZ"}
if(value == 0)
{
// 50HZ
_os_printf("set light fre 50HZ\r\n");
}
else if(value == 1)
{
// 60HZ
_os_printf("set light fre 60HZ\r\n");
}
else
{
_os_printf("set light fre error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_rear_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 后路镜像
if(value == 0)
{
// 50HZ
_os_printf("set rear_mirror off\r\n");
}
else if(value == 1)
{
// 60HZ
_os_printf("set rear_mirror on\r\n");
}
else
{
_os_printf("set rear_mirror error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_wdr(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 宽动态
if(value == 0)
{
// 关闭WDR
_os_printf("set wdr off\r\n");
}
else if(value == 1)
{
// 打开WDR
_os_printf("set wdr on\r\n");
}
else
{
_os_printf("set wdr error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_parking_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 停车监控模式 {"off", "timelapse", "normrec"}
switch(value)
{
case 0:
_os_printf("set parking_mode off\r\n");
break;
case 1:
_os_printf("set parking_mode timelapse\r\n");
break;
case 2:
_os_printf("set parking_mode normrec\r\n");
break;
default:
_os_printf("set parking_mode error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_parking_monitor(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 停车监控开关
if(value == 0)
{
// 关闭停车监控
_os_printf("set parking_monitor off\r\n");
}
else if(value == 1)
{
// 打开停车监控
_os_printf("set parking_monitor on\r\n");
}
else
{
_os_printf("set parking_monitor error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_voice_control(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 声控开关
if(value == 0)
{
// 关闭声控
_os_printf("set voice control off\r\n");
}
else if(value == 1)
{
// 打开声控
_os_printf("set voice control on\r\n");
}
else
{
_os_printf("set voice control error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_screen_standby(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 自动息屏时间 {"off", "1MIN", "2MIN", "3MIN"}
switch(value)
{
case 0:
_os_printf("set screen standby off\r\n");
break;
case 1:
_os_printf("set screen standby 1MIN\r\n");
break;
case 2:
_os_printf("set screen standby 2MIN\r\n");
break;
case 3:
_os_printf("set screen standby 3MIN\r\n");
break;
default:
_os_printf("set screen standby error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_auto_poweroff(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 延时关机时间 {"off", "1MIN", "2MIN", "3MIN"}
switch(value)
{
case 0:
_os_printf("set auto poweroff off\r\n");
break;
case 1:
_os_printf("set auto poweroff 1MIN\r\n");
break;
case 2:
_os_printf("set auto poweroff 2MIN\r\n");
break;
case 3:
_os_printf("set auto poweroff 3MIN\r\n");
break;
default:
_os_printf("set auto poweroff error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_adas(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 驾驶辅助
if(value == 0)
{
// 关闭驾驶辅助
_os_printf("set adas off\r\n");
}
else if(value == 1)
{
// 打开驾驶辅助
_os_printf("set adas on\r\n");
}
else
{
_os_printf("set adas error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_boot_sound(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 开机启动音
if(value == 0)
{
// 关闭开机启动音
_os_printf("set boot sound off\r\n");
}
else if(value == 1)
{
// 打开机启动音
_os_printf("set boot sound on\r\n");
}
else
{
_os_printf("set boot sound error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_video_flip(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 视频垂直镜像
if(value == 0)
{
// 关闭垂直镜像
_os_printf("set video flip off\r\n");
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_reverse_enable(isp, 0, SENSOR_TYPE_MASTER);
}
else if(value == 1)
{
// 打开垂直镜像
_os_printf("set video flip on\r\n");
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_reverse_enable(isp, 1, SENSOR_TYPE_MASTER);
}
else
{
_os_printf("set video flip error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_video_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 视频水平镜像
if(value == 0)
{
// 关闭视频镜像
_os_printf("set video mirror off\r\n");
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_mirror_enable(isp, 0, SENSOR_TYPE_MASTER);
}
else if(value == 1)
{
// 打开视频镜像
_os_printf("set video mirror on\r\n");
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_mirror_enable(isp, 1, SENSOR_TYPE_MASTER);
}
else
{
_os_printf("set video mirror error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_key_tone(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 按键音
if(value == 0)
{
// 关闭按键音
_os_printf("set key tone off\r\n");
}
else if(value == 1)
{
// 打开按键音
_os_printf("set key tone on\r\n");
}
else
{
_os_printf("set key tone error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_hour_type(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 24小时制
if(value == 0)
{
// 关闭24小时制
_os_printf("set 24hour type off\r\n");
}
else if(value == 1)
{
// 打开24小时制
_os_printf("set 24hour type on\r\n");
}
else
{
_os_printf("set 24hour type error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_time_format(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 时间格式
if(value == 0)
{
// yyyy-MM-dd
_os_printf("set time format yyyy-MM-dd\r\n");
}
else if(value == 1)
{
// yyyy/MM/dd
_os_printf("set time format yyyy/MM/dd\r\n");
}
else
{
_os_printf("set time format error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_ev(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 曝光补偿 {"-1", "0", "1"},
switch(value)
{
case 0:
_os_printf("set ev -1\r\n");
break;
case 1:
_os_printf("set ev 0\r\n");
break;
case 2:
_os_printf("set ev 1\r\n");
break;
default:
_os_printf("set ev error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_ir_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 红外模式 {"auto", "manual"}
if(value == 0)
{
// 自动
_os_printf("set ir mode auto\r\n");
}
else if(value == 1)
{
// 手动
_os_printf("set ir mode manual\r\n");
}
else
{
_os_printf("set ir mode error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_speed_unit(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 速度单位 {"km/h", "mph"}
if(value == 0)
{
// km/h
_os_printf("set speed unit km/h\r\n");
}
else if(value == 1)
{
// mph
_os_printf("set speed unit mph\r\n");
}
else
{
_os_printf("set speed unit error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_wb(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 白平衡 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set wb off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set wb on\r\n");
}
else
{
_os_printf("set wb error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_anti_shake(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 防抖 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set anti shake off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set anti shake on\r\n");
}
else
{
_os_printf("set anti shake error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_fast_record(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 快速录像 {"off", "2x", "4x", "6x"}
switch(value)
{
case 0:
// off
_os_printf("set fast record off\r\n");
break;
case 1:
// 2x
_os_printf("set fast record 2x\r\n");
break;
case 2:
// 4x
_os_printf("set fast record 4x\r\n");
break;
case 3:
// 6x
_os_printf("set fast record 6x\r\n");
break;
default:
_os_printf("set fast record error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_denoise(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 图像降噪 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set denoise off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set denoise on\r\n");
}
else
{
_os_printf("set denoise error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_auto_record(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 自动录像 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set auto record off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set auto record on\r\n");
}
else
{
_os_printf("set auto record error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_image_size(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 拍照分辨率 {"720P", "1080P", "2K", "4K", "8K"}
switch(value)
{
case 0:
// 720P
_os_printf("set image size 720P\r\n");
break;
case 1:
// 1080P
_os_printf("set image size 1080P\r\n");
break;
case 2:
// 2K
_os_printf("set image size 2K\r\n");
break;
case 3:
// 4K
_os_printf("set image size 4K\r\n");
break;
case 4:
// 8K
_os_printf("set image size 8K\r\n");
break;
default:
_os_printf("set image size error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_delay_shot(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 延时拍照 {"off", "2s", "10s"}
switch(value)
{
case 0:
// off
_os_printf("set delay shot off\r\n");
break;
case 1:
// 2s
_os_printf("set delay shot 2s\r\n");
break;
case 2:
// 10s
_os_printf("set delay shot 10s\r\n");
break;
default:
_os_printf("set delay shot error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_continue_shot(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 连拍张数 {"off", "2", "10"}
switch(value)
{
case 0:
// off
_os_printf("set continue shot off\r\n");
break;
case 1:
// 2
_os_printf("set continue shot 2\r\n");
break;
case 2:
// 10
_os_printf("set continue shot 10\r\n");
break;
default:
_os_printf("set continue shot error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_interior_record(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 车内录像 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set interior record off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set interior record on\r\n");
}
else
{
_os_printf("set interior record error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_shot_timelapse_rate(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 拍照缩时间隔 {"off", "2s", "10s"}
switch(value)
{
case 0:
// off
_os_printf("set shot timelapse rate off\r\n");
break;
case 1:
// 2s
_os_printf("set shot timelapse rate 2s\r\n");
break;
case 2:
// 10s
_os_printf("set shot timelapse rate 10s\r\n");
break;
default:
_os_printf("set shot timelapse rate error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_shot_timelapse_time(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 拍照缩时间长 {"off", "2s", "10s"}
switch(value)
{
case 0:
// off
_os_printf("set shot timelapse rate off\r\n");
break;
case 1:
// 2s
_os_printf("set shot timelapse rate 2s\r\n");
break;
case 2:
// 10s
_os_printf("set shot timelapse rate 10s\r\n");
break;
default:
_os_printf("set shot timelapse rate error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_video_flip_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 图像翻转 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set video flip mirror off\r\n");
// 关闭垂直镜像
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_reverse_enable(isp, 0, SENSOR_TYPE_MASTER);
isp_mirror_enable(isp, 0, SENSOR_TYPE_MASTER);
}
else if(value == 1)
{
// on
_os_printf("set video flip mirror on\r\n");
struct isp_device *isp = (struct isp_device *)dev_get(HG_ISP_DEVID);
isp_reverse_enable(isp, 1, SENSOR_TYPE_MASTER);
isp_mirror_enable(isp, 1, SENSOR_TYPE_MASTER);
}
else
{
_os_printf("set video flip mirror error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_five_g_wifi(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 5G WiFi {"off", "on"}
if(value == 0)
{
// off
_os_printf("set five g wifi off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set five g wifi on\r\n");
}
else
{
_os_printf("set five g wifi error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_gps_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// GPS 水印 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set gps osd off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set gps osd on\r\n");
}
else
{
_os_printf("set gps osd error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_speed_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 速度水印 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set speed osd off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set speed osd on\r\n");
}
else
{
_os_printf("set speed osd error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_rear_flip(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 后路翻转 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set rear flip off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set rear flip on\r\n");
}
else
{
_os_printf("set rear flip error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_summer_timer(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 夏令时 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set summer timer off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set summer timer on\r\n");
}
else
{
_os_printf("set summer timer error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_screen_brightness(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 屏幕亮度 {"off", "low", "middle", "high", "very high"}
switch(value)
{
case 0:
// off
_os_printf("set screen brightness off\r\n");
break;
case 1:
// low
_os_printf("set screen brightness low\r\n");
break;
case 2:
// middle
_os_printf("set screen brightness middle\r\n");
break;
case 3:
// high
_os_printf("set screen brightness high\r\n");
break;
case 4:
// very high
_os_printf("set screen brightness very high\r\n");
break;
default:
_os_printf("set screen brightness error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_sound_indicator(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 提示音 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set sound indicator off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set sound indicator on\r\n");
}
else
{
_os_printf("set sound indicator error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_gps_data(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// GPS 数据 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set gps data off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set gps data on\r\n");
}
else
{
_os_printf("set gps data error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_coordinate_osd(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 经纬度水印 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set coordinate osd off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set coordinate osd on\r\n");
}
else
{
_os_printf("set coordinate osd error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_inside_mirror(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 车内镜像 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set inside mirror off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set inside mirror on\r\n");
}
else
{
_os_printf("set inside mirror error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_status_light(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 状态灯 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set status light off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set status light on\r\n");
}
else
{
_os_printf("set status light error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_osd_option(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 视频水印选项 {"off", "on", "logo&date", "logo&model&date&time"}
switch(value)
{
case 0:
// off
_os_printf("set osd option off\r\n");
break;
case 1:
// on
_os_printf("set osd option on\r\n");
break;
case 2:
// logo&date
_os_printf("set osd option logo&date\r\n");
break;
case 3:
// logo&model&date&time
_os_printf("set osd option logo&model&date&time\r\n");
break;
default:
_os_printf("set osd option error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_wifi_channel(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// wifi 信道 {"0", 1", "2"}
switch(value)
{
case 0:
// 0
_os_printf("set wifi channel 0\r\n");
break;
case 1:
// 1
_os_printf("set wifi channel 1\r\n");
break;
case 2:
// 2
_os_printf("set wifi channel 2\r\n");
break;
default:
_os_printf("set wifi channel error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_fill_light(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 补光 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set fill light off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set fill light on\r\n");
}
else
{
_os_printf("set fill light error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_screensaver(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 屏保 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set screensaver off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set screensaver on\r\n");
}
else
{
_os_printf("set screensaver error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_front_rotate(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 前路旋转 {"off", "on", "auto"}
switch(value)
{
case 0:
// off
_os_printf("set front rotate off\r\n");
break;
case 1:
// on
_os_printf("set front rotate on\r\n");
break;
case 2:
// auto
_os_printf("set front rotate auto\r\n");
break;
default:
_os_printf("set front rotate error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_hdr(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 高动态 {"off", "on"}
if(value == 0)
{
// off
_os_printf("set hdr off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set hdr on\r\n");
}
else
{
_os_printf("set hdr error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_wifi_boot_starter(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 开机启动 WiFi {"off", "on"}
if(value == 0)
{
// off
_os_printf("set wifi boot starter off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set wifi boot starter on\r\n");
}
else
{
_os_printf("set wifi boot starter error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_screen_saver_type(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 屏保类型 {"screen_off", "screen_saver_on"}
if(value == 0)
{
// off
_os_printf("set screen saver type off\r\n");
}
else if(value == 1)
{
// on
_os_printf("set screen saver type on\r\n");
}
else
{
_os_printf("set screen saver type error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_work_mode(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 预览多模式切换 {"record", "capture", "delaycapture", "intervalcapture",
// "continuouscapture", "slowrecord", "looprecord", "timelapserecord"}
switch(value)
{
case 0:
// record
_os_printf("set work mode record\r\n");
break;
case 1:
// capture
_os_printf("set work mode capture\r\n");
break;
case 2:
// delaycapture
_os_printf("set work mode delaycapture\r\n");
break;
case 3:
// intervalcapture
_os_printf("set work mode intervalcapture\r\n");
break;
case 4:
// continuouscapture
_os_printf("set work mode continuouscapture\r\n");
break;
case 5:
// slowrecord
_os_printf("set work mode slowrecord\r\n");
break;
case 6:
// looprecord
_os_printf("set work mode looprecord\r\n");
break;
case 7:
// timelapserecord
_os_printf("set work mode timelapserecord\r\n");
break;
default:
_os_printf("set work mode error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_frame_zoom(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 预览画面缩放切换 {"1x", "2x", "3x"}
switch(value)
{
case 0:
// 1x
_os_printf("set frame zoom 1x\r\n");
break;
case 1:
// 2x
_os_printf("set frame zoom 2x\r\n");
break;
case 2:
// 3x
_os_printf("set frame zoom 3x\r\n");
break;
default:
_os_printf("set frame zoom error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_rotate(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 图像旋转 {"off", "on", "auto"}
switch(value)
{
case 0:
// off
_os_printf("set rotate off\r\n");
break;
case 1:
// on
_os_printf("set rotate on\r\n");
break;
case 2:
// auto
_os_printf("set rotate auto\r\n");
break;
default:
_os_printf("set rotate error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static os_timer_t md_timer;
static uint32_t md_last_cnt = 0;
static uint8_t md_enabled = 0;
static uint8_t md_recording = 0;
static uint16_t md_no_motion_ticks = 0;
#define MD_NO_MOTION_TIMEOUT 10
static void md_timer_cb(void *arg)
{
extern volatile uint32_t vpp_md_cnt;
if (!md_enabled) return;
if (vpp_md_cnt != md_last_cnt) {
md_last_cnt = vpp_md_cnt;
md_no_motion_ticks = 0;
if (!md_recording) {
_os_printf("[MD] Motion detected! Starting recording...\r\n");
open_record();
md_recording = 1;
}
} else {
if (md_recording) {
md_no_motion_ticks++;
if (md_no_motion_ticks >= MD_NO_MOTION_TIMEOUT) {
_os_printf("[MD] No motion for %d sec. Stopping recording.\r\n",
MD_NO_MOTION_TIMEOUT / 2);
close_record();
md_recording = 0;
md_no_motion_ticks = 0;
}
}
}
}
static void set_motion_detect(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
if (value == 0) {
if (md_enabled) {
os_timer_stop(&md_timer);
os_timer_del(&md_timer);
if (md_recording) {
close_record();
md_recording = 0;
}
md_enabled = 0;
}
_os_printf("set motion detect off\r\n");
}
else if (value == 1) {
if (!md_enabled) {
md_last_cnt = 0;
md_no_motion_ticks = 0;
md_recording = 0;
os_timer_init(&md_timer, md_timer_cb, OS_TIMER_MODE_PERIODIC, NULL);
os_timer_start(&md_timer, 500);
md_enabled = 1;
}
_os_printf("set motion detect on\r\n");
}
else {
_os_printf("set motion detect error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_file_format(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 录像格式 {"MP4", "AVI"}
switch(value)
{
case 0:
// MP4
_os_printf("set file fromat mp4\r\n");
break;
case 1:
// AVI
_os_printf("set file fromat avi\r\n");
break;
default:
_os_printf("set file fromat error!!!\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void set_switchcam(struct items_config *item, uint8_t value, struct httpClient *httpClient)
{
// 镜头切换 前 中 后 画中画
switch(value)
{
case 0:
_os_printf("switch cam 0\r\n");
break;
case 1:
_os_printf("switch cam 1\r\n");
break;
case 2:
_os_printf("switch cam 2\r\n");
break;
default:
_os_printf("switch cam error\r\n");
closeRes(httpClient);
return;
}
item->value = value;
http_reponse_success(httpClient);
}
static void http_reponse_setparamvalue(struct httpClient *httpClient)
{
char *param_start, *param_end, *params, *value_str;
int param_size = 0;
uint8_t value = 0;
// 查找参数字符串起始位置
param_start = strstr(httpClient->pattern, "param=");
if(param_start) {
param_start += strlen("param=");
}
param_end = strchr(httpClient->pattern, '&');
value_str = strstr(httpClient->pattern, "value=");
if(value_str) {
value_str += strlen("value=");
}
if(param_start == NULL || param_end == NULL || value_str == NULL) {
os_printf("%s: %d, request error\r\n", __FUNCTION__, __LINE__);
closeRes(httpClient);
return;
}
param_size = param_end - param_start;
params = STREAM_LIBC_MALLOC(param_size + 1);
if (params == NULL) {
os_printf("%s: %d, malloc failed\r\n", __FUNCTION__, __LINE__);
closeRes(httpClient);
return;
}
strncpy(params, param_start, param_size);
params[param_size] = '\0';
// 转换为整数
value = (uint8_t)atoi(value_str);
// 在参数表中查找对应的处理函数
for (int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
int items_cfg_len = strlen(items_cfg[i].const_item->name);
if (strncmp(items_cfg[i].const_item->name, params, (items_cfg_len > param_size) ? items_cfg_len : param_size) == 0) {
if(items_cfg[i].const_item->handler != NULL) {
items_cfg[i].const_item->handler(&items_cfg[i], value, httpClient);
if(strncmp(items_cfg[i].const_item->name, "rec", items_cfg_len) != 0 && items_cfg[i].const_item->enable == ITEM_ENABLE)
items_value_process("saveflag", 1, SET_ITEMS_VALUE);
} else {
closeRes(httpClient);
}
STREAM_LIBC_FREE(params);
return;
}
}
// 未找到
_os_printf("Unknown parameter: %s\r\n", params);
closeRes(httpClient);
STREAM_LIBC_FREE(params);
}
void send_chunk_dynamic(int fd, const char* data, uint16_t data_len) {
uint16_t len = data_len + 32;
char *chunk_buffer = STREAM_LIBC_MALLOC(len);
if(chunk_buffer == NULL)
{
os_printf("chunk_buffer STREAM_LIBC_MALLOC fail\r\n");
return;
}
int chunk_len = os_snprintf(chunk_buffer, len - 1, "%x\r\n%s\r\n", data_len, data);
send(fd, chunk_buffer, chunk_len, 0);
STREAM_LIBC_FREE(chunk_buffer);
}
static int get_extension_string(int fd, const char *search_dir, const char *extension_name, const char *prefix)
{
int file_count = 0;
char send_buffer[256];
char path[64];
char filename_suffix[32];
const char *suffix = NULL;
uint8_t extension_name_len = strlen(extension_name);
uint8_t type = (os_strcmp(prefix, EVENT_PREFIX) == 0) ? 1 :
(os_strcmp(prefix, LOOP_PREFIX) == 0) ? 2 :
(os_strcmp(prefix, EMR_PREFIX) == 0) ? 3 : 4;
if(os_strcmp(search_dir, REC_PATH) == 0 || os_strcmp(search_dir, IMG_PATH) == 0) {
suffix = NULL;
}
else if(os_strcmp(search_dir, RECA_PATH) == 0 || os_strcmp(search_dir, IMGA_PATH) == 0) {
suffix = FRONT_SUFFIX;
} else if(os_strcmp(search_dir, RECB_PATH) == 0 || os_strcmp(search_dir, IMGB_PATH) == 0) {
suffix = INTER_SUFFIX;
} else if(os_strcmp(search_dir, RECC_PATH) == 0 || os_strcmp(search_dir, IMGC_PATH) == 0) {
suffix = BACK_SUFFIX;
}
FILINFO *fil;
void *dir = osal_opendir((char *) search_dir);
if (dir)
{
do
{
fil = osal_readdir(dir);
if(!fil) break;
if(fil->fname[0] == 0) break;
if (fil->fname[0] == '.') continue;
if (osal_dirent_isdir(fil) && (type == 2 || type == 3 || type == 4))
{
snprintf(path, sizeof(path), "%s/%s", search_dir, fil->fname);
void *subdir = osal_opendir(path);
// 第二层遍历:获取子目录中的文件
FILINFO *sub_fil;
if (subdir)
{
do
{
sub_fil = osal_readdir(subdir);
if(!sub_fil) break;
if(sub_fil->fname[0] == 0) break;
if (sub_fil->fname[0] == '.') continue;
if (osal_dirent_isdir(sub_fil))
continue;
char *filename = osal_dirent_name(sub_fil);
uint32_t filesize = osal_dirent_size(sub_fil);
uint8_t filename_len = strlen(filename);
if(type == 3) {
if(os_strstr(filename, SOS_PREFIX) == NULL)
continue;
} else {
if(os_strstr(filename, SOS_PREFIX) != NULL)
continue;
}
// 检查后缀名是否匹配
uint8_t extension_filename[16];
// 进行全部转换成大写
if (filename_len > extension_name_len)
{
for (uint8_t i = 0; i < extension_name_len; i++)
{
extension_filename[i] = toupper(filename[filename_len - extension_name_len + i]);
}
// 后缀名匹配
if (memcmp(extension_name, extension_filename, extension_name_len) == 0)
{
if(suffix)
{
os_snprintf(filename_suffix, sizeof(filename_suffix), "%.*s%s%s", filename_len - extension_name_len, filename, suffix, extension_name);
os_snprintf(send_buffer, sizeof(send_buffer), "%s{\"name\":\"%s/%s\",\"size\":%d,\"createtimestr\":\"%.14s\",\"type\":%d}",
(file_count++ > 0) ? "," : "",
prefix,
filename_suffix,
filesize / 1024,
filename,
2);
}
else
{
os_snprintf(send_buffer, sizeof(send_buffer), "%s{\"name\":\"%s/%s\",\"size\":%d,\"createtimestr\":\"%.14s\",\"type\":%d}",
(file_count++ > 0) ? "," : "",
prefix,
filename,
filesize / 1024,
filename,
2);
}
// 发送数据
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
}
}
} while(sub_fil);
osal_closedir(subdir);
}
}
else if(!osal_dirent_isdir(fil) && (type == 1))
{
char *filename = osal_dirent_name(fil);
uint32_t filesize = osal_dirent_size(fil);
uint8_t filename_len = strlen(filename);
// 检查后缀名是否匹配
uint8_t extension_filename[16];
// 进行全部转换成大写
if (filename_len > extension_name_len)
{
for (uint8_t i = 0; i < extension_name_len; i++)
{
extension_filename[i] = toupper(filename[filename_len - extension_name_len + i]);
}
// 后缀名匹配
if (memcmp(extension_name, extension_filename, extension_name_len) == 0)
{
if(suffix)
{
os_snprintf(filename_suffix, sizeof(filename_suffix), "%.*s%s%s", filename_len - extension_name_len, filename, suffix, extension_name);
os_snprintf(send_buffer, sizeof(send_buffer), "%s{\"name\":\"%s/%s\",\"size\":%d,\"createtimestr\":\"%.14s\",\"type\":%d}",
(file_count++ > 0) ? "," : "",
prefix,
filename_suffix,
filesize / 1024,
filename,
1);
}
else
{
os_snprintf(send_buffer, sizeof(send_buffer), "%s{\"name\":\"%s/%s\",\"size\":%d,\"createtimestr\":\"%.14s\",\"type\":%d}",
(file_count++ > 0) ? "," : "",
prefix,
filename,
filesize / 1024,
filename,
1);
}
// 发送数据
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
}
}
}
} while (fil);
osal_closedir(dir);
}
return file_count;
}
static void stream_response(int fd)
{
int video_count = 0;
int photo_count = 0;
int sos_count = 0;
int park_count = 0;
int last_count = 0;
char send_buffer[256];
// 创建HTTP响应头
snprintf(send_buffer, sizeof(send_buffer),
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Type: application/json\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n");
send(fd, send_buffer, strlen(send_buffer), 0);
// 获取视频
os_snprintf(send_buffer, sizeof(send_buffer), "{\"result\":0,\"info\":[{\"folder\":\"%s\",\"files\":[", LOOP_PREFIX);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].mask & CAM_MASK_ENABLE)
{
if(last_count != video_count)
{
send_chunk_dynamic(fd, ",", strlen(","));
last_count += video_count;
}
video_count += get_extension_string(fd, g_cam_configs[i].rec_path, g_cam_configs[i].file_process.ext_name, LOOP_PREFIX);
}
}
// 获取照片
os_snprintf(send_buffer, sizeof(send_buffer), "],\"count\":%d},{\"folder\":\"%s\",\"files\":[", video_count, EVENT_PREFIX);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
last_count = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].mask & CAM_MASK_ENABLE)
{
if(last_count != photo_count)
{
send_chunk_dynamic(fd, ",", strlen(","));
last_count += photo_count;
}
photo_count += get_extension_string(fd, g_cam_configs[i].img_path, JPG_EXTENSION_NAME, EVENT_PREFIX);
}
}
// 紧急事件
os_snprintf(send_buffer, sizeof(send_buffer), "],\"count\":%d},{\"folder\":\"%s\",\"files\":[", photo_count, EMR_PREFIX);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
last_count = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].mask & CAM_MASK_ENABLE)
{
if(last_count != sos_count)
{
send_chunk_dynamic(fd, ",", strlen(","));
last_count += sos_count;
}
sos_count += get_extension_string(fd, g_cam_configs[i].rec_path, g_cam_configs[i].file_process.ext_name, EMR_PREFIX);
}
}
if(PARKING_MOR_ALBUM_EN) {
os_snprintf(send_buffer, sizeof(send_buffer), "],\"count\":%d},{\"folder\":\"%s\",\"files\":[", sos_count, PARK_PREFIX);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
last_count = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].mask & CAM_MASK_ENABLE)
{
if(last_count != park_count)
{
send_chunk_dynamic(fd, ",", strlen(","));
last_count += park_count;
}
park_count += get_extension_string(fd, PARK_PATH, g_cam_configs[i].file_process.ext_name, PARK_PREFIX);
}
}
os_snprintf(send_buffer, sizeof(send_buffer), "],\"count\":%d}]}", park_count);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
} else {
os_snprintf(send_buffer, sizeof(send_buffer), "],\"count\":%d}]}", sos_count);
send_chunk_dynamic(fd, send_buffer, strlen(send_buffer));
}
// 发送分块结束标记
send_chunk_dynamic(fd, "", 0); // 0长度块表示结束
}
static void http_reponse_getfilelist(struct httpClient *httpClient)
{
int fd = httpClient->fdClient;
stream_response(fd);
closeRes(httpClient);
}
static void http_reponse_thumbnail(struct httpClient *httpClient)
{
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
char *filepath = httpClient->pattern;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "image/jpeg");
#if APP_LOCK_VIDEO_EN
if(strstr(filepath, EMR_PREFIX))
{
filepath = remove_prefix(filepath);
if(filepath == NULL)
{
os_printf("%s remove_prefix err\r\n", __FUNCTION__);
closeRes(httpClient);
return;
}
}
#endif
char *filename = remove_suffix(filepath);
if(filename == NULL)
{
os_printf("%s remove_suffix err\r\n", __FUNCTION__);
closeRes(httpClient);
return;
}
// 获取缩略图
post_content = (char *)jpg_file_read(filename, 1, (int32_t*)&sendlen);
os_printf("post_content:%x, sendlen:%d\r\n", post_content, sendlen);
http_header_send(head, httpIndex.Length, sendlen, fd);
if (post_content)
{
send(fd, post_content, sendlen, 0);
jpg_file_free(post_content);
}
closeRes(httpClient);
}
static int32 set_wifi_ssid(const char *ssid)
{
uint8_t ifidx = (sys_cfgs.wifi_mode == WIFI_MODE_APSTA ? WIFI_MODE_STA : sys_cfgs.wifi_mode);
os_memset(sys_cfgs.bssid, 0, 6);
os_strncpy(sys_cfgs.ssid, ssid, SSID_MAX_LEN);
ieee80211_conf_set_bssid(ifidx, NULL);
if (os_strlen(sys_cfgs.passwd) > 0) {
wpa_passphrase(sys_cfgs.ssid, (char*)sys_cfgs.passwd, sys_cfgs.psk);
}
ieee80211_conf_set_ssid(ifidx, sys_cfgs.ssid);
ieee80211_conf_set_psk(ifidx, sys_cfgs.psk);
os_printf("set new ssid:%s\r\n", sys_cfgs.ssid);
syscfg_save();
return 0;
}
static int32 set_wifi_passwd(char *passwd)
{
uint8_t ifidx = (sys_cfgs.wifi_mode == WIFI_MODE_APSTA ? WIFI_MODE_STA : sys_cfgs.wifi_mode);
os_strncpy(sys_cfgs.passwd, passwd, PASSWD_MAX_LEN);
wpa_passphrase(sys_cfgs.ssid, (char*)sys_cfgs.passwd, sys_cfgs.psk);
ieee80211_conf_set_psk(ifidx, sys_cfgs.psk);
ieee80211_conf_set_passwd(ifidx, (char*)sys_cfgs.passwd);
os_printf("set new key:%s\r\n", sys_cfgs.passwd);
syscfg_save();
return 0;
}
static void http_reponse_setwifi(struct httpClient *httpClient)
{
char *equal_pos;
char value[64];
equal_pos = strchr(httpClient->pattern, '=');
if(equal_pos == NULL)
{
os_printf("params format error\r\n", __FUNCTION__, __LINE__);
closeRes(httpClient);
return;
}
os_strncpy(value, equal_pos + 1, sizeof(value));
if (os_strstr(httpClient->pattern, "wifissid")) {
os_printf("set wifi ssid: %s\r\n", value);
http_reponse_success(httpClient);
os_sleep_ms(500);
set_wifi_ssid(value);
}
else if (os_strstr(httpClient->pattern, "wifipwd")) {
os_printf("set wifi pwd: %s\r\n",value);
// psk need 8 bytes at less
if (os_strlen(value) < 8) {
os_printf("psk need 8 bytes at less\r\n");
closeRes(httpClient);
return;
}
http_reponse_success(httpClient);
os_sleep_ms(500);
set_wifi_passwd(value);
}
else {
os_printf("unknown params: %s\r\n", httpClient->pattern);
closeRes(httpClient);
return;
}
}
static void http_reponse_reset(struct httpClient *httpClient)
{
for (int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
items_cfg[i].value = items_cfg[i].const_item->default_value;
}
itemcfg_save(0);
itemcfg_handle(); // 重新加载配置
char ssid_default[SSID_MAX_LEN + 1];
char passwd_default[PASSWD_MAX_LEN + 1];
os_snprintf(ssid_default, SSID_MAX_LEN, WIFI_SSID_PREFIX"%02X%02X%02X", sys_cfgs.mac[3], sys_cfgs.mac[4], sys_cfgs.mac[5]);
os_strcpy(passwd_default, WIFI_PASSWD_DEFAULT);
set_wifi_ssid(ssid_default);
set_wifi_passwd(passwd_default);
struct vpp_device *vpp_dev;
vpp_dev = (struct vpp_device *)dev_get(HG_VPP_DEVID);
vpp_set_watermark0_enable(vpp_dev, 1);
http_reponse_success(httpClient);
}
extern bool fatfs_register();
extern void fatfs_unregister();
static void http_reponse_sdformat(struct httpClient *httpClient)
{
#if FS_EN
FRESULT res;
uint8_t *work = STREAM_LIBC_MALLOC(4096);
ASSERT(work);
fatfs_unregister();
res = f_mkfs("0:", FM_ANY, 0, work, 4096);
STREAM_LIBC_FREE(work);
if (res)
{
os_printf("SD format failed, res:%d\r\n",res);
closeRes(httpClient);
return;
}
fatfs_register();
http_reponse_success(httpClient);
#else
closeRes(httpClient);
#endif
}
static void http_reponse_wifireboot(struct httpClient *httpClient)
{
http_reponse_unsupport(httpClient);
}
static void http_reponse_video(struct httpClient *httpClient)
{
uint32_t sendlen = 0;
char path[64];
char range_buf[64];
uint32_t read_len;
struct httpresp *head = NULL;
F_FILE *fp = NULL;
uint8_t *tmp_buf = NULL;
int res = 0;
int fd = httpClient->fdClient;
uint32_t offset_start = 0;
uint32_t offset_end = 0;
uint32_t remain_len = 0;
uint8_t flag = 0;
uint8_t file_type = 0;
struct httpEntry *next = httpClient->http_request;
char *filepath = httpClient->pattern;
int type = (strncmp(next->value, "/" LOOP_PREFIX, strlen("/" LOOP_PREFIX)) == 0) ? 2 :
(strncmp(next->value, "/" EMR_PREFIX, strlen("/" EMR_PREFIX)) == 0) ? 3 :
(strncmp(next->value, "/" PARK_PREFIX, strlen("/" PARK_PREFIX)) == 0) ? 4 : 0;
if(os_strstr(httpClient->pattern, BACK_SUFFIX))
{
file_type = 2;
}
else
{
file_type = 1;
}
_os_printf("file_type: %d\r\n", file_type);
if(type == 0)
{
_os_printf("type error\r\n");
goto reponse_video_end;
}
gen_video_path(filepath, path, sizeof(path));
fp = osal_fopen((const char*)path, "rb");
if(!fp)
{
os_printf("open file failed\r\n");
head = http_create_reply(404, "Not Found");
http_add_header(head, httpIndex.Connection, "close");
http_header_send(head, httpIndex.Length, 0, fd);
goto reponse_video_end;
}
sendlen = osal_fsize(fp);
offset_start = 0;
offset_end = sendlen;
while(next)
{
if(strcmp(next->key, "Range") == 0)
{
uint32_t start = 0;
uint32_t end = 0;
flag = 1;
if(sscanf(next->value, "bytes=%u-%u", &start, &end) == 2)
{
offset_start = start;
offset_end = end + 1;
}
else if(sscanf(next->value, "bytes=%u-", &start) == 1)
{
offset_start = start;
offset_end = sendlen;
}
else
{
os_printf("invalid range:%s\r\n", next->value);
head = http_create_reply(416, "Range Not Satisfiable");
http_add_header(head, httpIndex.Connection, "close");
snprintf(range_buf, sizeof(range_buf), "bytes */%u", sendlen);
http_add_header(head, "Content-Range", range_buf);
http_header_send(head, httpIndex.Length, 0, fd);
goto reponse_video_end;
}
break;
}
next = next->next;
}
os_printf("offset_start:%u\toffset_end:%u\tsendlen:%u\r\n", offset_start, offset_end, sendlen);
if(offset_start >= sendlen || offset_start >= offset_end)
{
os_printf("offset_start out of range\r\n");
head = http_create_reply(416, "Range Not Satisfiable");
http_add_header(head, httpIndex.Connection, "close");
snprintf(range_buf, sizeof(range_buf), "bytes */%u", sendlen);
http_add_header(head, "Content-Range", range_buf);
http_header_send(head, httpIndex.Length, 0, fd);
goto reponse_video_end;
}
if(offset_end > sendlen)
{
offset_end = sendlen;
}
remain_len = offset_end - offset_start;
if(flag)
{
head = http_create_reply(206, "Partial Content");
}
else
{
head = http_create_reply(200, "OK");
}
http_add_header(head, httpIndex.Connection, "close");
if(file_type == 1)
{
http_add_header(head, httpIndex.Type, "video/mp4");
}
else
{
http_add_header(head, httpIndex.Type, "video/x-msvideo");
}
http_add_header(head, "Accept-Ranges", "bytes");
if(flag)
{
snprintf(range_buf, sizeof(range_buf), "bytes %u-%u/%u", offset_start, offset_end - 1, sendlen);
http_add_header(head, "Content-Range", range_buf);
}
http_header_send(head, httpIndex.Length, remain_len, fd);
osal_fseek(fp, offset_start);
tmp_buf = STREAM_MALLOC(4096);
if(tmp_buf)
{
uint32_t total_len = 0;
while(remain_len > 0)
{
uint32_t sent_len = 0;
uint32_t need_len = (remain_len > 4096) ? 4096 : remain_len;
read_len = osal_fread(tmp_buf, 1, need_len, fp);
if(read_len == 0)
{
break;
}
while(sent_len < read_len)
{
res = send(fd, tmp_buf + sent_len, read_len - sent_len, 0);
if(res <= 0)
{
os_printf("send error, res: %d, total len: %d\r\n", res, total_len);
goto reponse_video_end;
}
sent_len += res;
total_len += res;
}
remain_len -= read_len;
}
os_printf("send over, total len: %d\r\n", total_len);
}
reponse_video_end:
if(fp)
{
osal_fclose(fp);
fp = NULL;
}
if(tmp_buf)
{
STREAM_FREE(tmp_buf);
tmp_buf = NULL;
}
closeRes(httpClient);
}
static void http_reponse_event(struct httpClient *httpClient)
{
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "image/jpeg");
post_content = (char *)jpg_file_read(httpClient->pattern, 0, (int32_t*)&sendlen);
os_printf("normal post_content:%x sendlen:%d\r\n", post_content, sendlen);
http_header_send(head, httpIndex.Length, sendlen, fd);
if (post_content)
{
int send_len = send(fd, post_content, sendlen, 0);
os_printf("send_len: %d\n",send_len);
jpg_file_free(post_content);
}
closeRes(httpClient);
}
static uint8_t file_delete(char *filename)
{
FRESULT res;
char jpg_path[64];
char thumb_path[64];
char *file_name = filename;
uint8_t flag = 0;
gen_photo_video_path(filename, jpg_path, sizeof(jpg_path));
#if APP_LOCK_VIDEO_EN
if(strstr(filename, SOS_PREFIX))
{
file_name = remove_prefix(file_name);
if(file_name == NULL)
{
os_printf("%s remove_prefix err\r\n", __FUNCTION__);
return 1;
}
flag = 1;
}
#endif
file_name = remove_suffix(file_name);
if(file_name == NULL)
{
os_printf("%s remove_suffix err\r\n", __FUNCTION__);
return 1;
}
if(flag)
{
res = osal_fchmod(jpg_path, 0, AM_RDO); // 清除只读属性
if (res != FR_OK) {
_os_printf("Failed to clean file %s AM_RDO attr, error: %d\n", jpg_path, res);
return 1;
}
}
res = osal_unlink(jpg_path);
if (res != FR_OK) {
_os_printf("Failed to delete file: %s, error: %d\n", jpg_path, res);
return 1;
}
_os_printf("File deleted successfully: %s\n", jpg_path);
gen_thumb_path(file_name, thumb_path, sizeof(thumb_path));
res = osal_unlink(thumb_path);
if (res != FR_OK) {
os_printf("Failed to delete thumbnail: %s, error: %d\n", thumb_path, res);
return 1;
}
_os_printf("Thumbnail deleted successfully: %s\n", thumb_path);
return 0; // 成功
}
static void http_reponse_deletefile(struct httpClient *httpClient)
{
uint8_t offset = 0;
if (strncmp(httpClient->pattern, EVENT_PREFIX, strlen(EVENT_PREFIX)) == 0) {
offset = strlen(EVENT_PREFIX) + 1;
}
else if (strncmp(httpClient->pattern, LOOP_PREFIX, strlen(LOOP_PREFIX)) == 0) {
offset = strlen(LOOP_PREFIX) + 1;
}
else if(strncmp(httpClient->pattern, EMR_PREFIX, strlen(EMR_PREFIX)) == 0) {
offset = strlen(EMR_PREFIX) + 1;
}
else if(strncmp(httpClient->pattern, PARK_PREFIX, strlen(PARK_PREFIX)) == 0) {
offset = strlen(PARK_PREFIX) + 1;
}
else {
_os_printf("Unknown parameter: %s\n", httpClient->pattern);
closeRes(httpClient);
return;
}
if(file_delete(httpClient->pattern + offset) == 0)
{
_os_printf("delete file success\r\n");
http_reponse_success(httpClient);
return;
}
_os_printf("delete file failed\r\n");
closeRes(httpClient);
}
typedef void (*takephoto_fn)(uint8_t takephoto_num, uint16_t w, uint16_t h, const char *path);
void takephoto_over_dpi_func(uint8_t takephoto_num, uint16_t w, uint16_t h, const char *path)
{
struct msi *over_dpi_jpg_msi = msi_find(SR_OVER_DPI_JPG, 1);
if(over_dpi_jpg_msi)
{
msi_do_cmd(over_dpi_jpg_msi, MSI_CMD_JPG_THUMB, MSI_JPG_THUMB_TAKEPHOTO_SETPATH, (uint32_t)path);
}
struct msi *over_dpi_recode_msi = msi_find(R_SCALE1_JPG_RECODE, 1);
uint32_t dpi_w_h = w << 16 | h;
if (over_dpi_recode_msi)
{
msi_do_cmd(over_dpi_recode_msi, MSI_CMD_SCALE1, MSI_SCALE1_RESET_DPI, dpi_w_h);
msi_put(over_dpi_recode_msi);
}
struct msi *over_dpi_msi = msi_find(S_SCALE3_OVER_DPI, 1);
if (over_dpi_msi)
{
msi_do_cmd(over_dpi_msi, MSI_CMD_TAKEPHOTO_SCALE3, MSI_TAKEPHOTO_SCALE3_KICK, takephoto_num);
msi_put(over_dpi_msi);
}
}
//这里的w和h是没有用的,一位内是原来分辨率拍照
void takephoto_normal_func(uint8_t takephoto_num, uint16_t w, uint16_t h, const char *path)
{
struct msi *jpg_thumb_msi = msi_find(R_JPG_THUMB, 1); // 需要预先创建,否则不会真正拍照
if (jpg_thumb_msi)
{
msi_do_cmd(jpg_thumb_msi, MSI_CMD_JPG_THUMB, MSI_JPG_THUMB_TAKEPHOTO_SETPATH, (uint32_t)path);
msi_do_cmd(jpg_thumb_msi, MSI_CMD_JPG_THUMB, MSI_JPG_THUMB_TAKEPHOTO, takephoto_num);
msi_put(jpg_thumb_msi);
}
}
void usb_takephoto_normal_func(uint8_t takephoto_num, const char *path)
{
struct msi *usb_jpg_thumb_msi = msi_find(R_JPG_PHOTO_USB, 1);
if (usb_jpg_thumb_msi)
{
msi_do_cmd(usb_jpg_thumb_msi, MSI_CMD_JPG_THUMB, MSI_JPG_THUMB_TAKEPHOTO_SETPATH, (uint32_t)path);
msi_do_cmd(usb_jpg_thumb_msi, MSI_CMD_JPG_THUMB, MSI_JPG_THUMB_TAKEPHOTO, takephoto_num);
msi_put(usb_jpg_thumb_msi);
}
}
static void takephoto_mipi(const char *path)
{
uint8_t dpi_v = items_value_process("image_size", 0, GET_ITEMS_VALUE);
takephoto_fn t_fn;
uint16_t w,h;
switch(dpi_v)
{
case 0:
t_fn = takephoto_normal_func;
w = http_dpi[dpi_v][0];
h = http_dpi[dpi_v][1];
break;
case 1:
t_fn = takephoto_over_dpi_func;
w = http_dpi[dpi_v][0];
h = http_dpi[dpi_v][1];
break;
case 2:
t_fn = takephoto_over_dpi_func;
w = http_dpi[dpi_v][0];
h = http_dpi[dpi_v][1];
break;
case 3:
t_fn = takephoto_over_dpi_func;
w = http_dpi[dpi_v][0];
h = http_dpi[dpi_v][1];
break;
case 4:
t_fn = takephoto_over_dpi_func;
w = http_dpi[dpi_v][0];
h = http_dpi[dpi_v][1];
break;
default:
t_fn = takephoto_normal_func;
w = http_dpi[0][0];
h = http_dpi[0][1];
break;
}
uint8_t take_photo_num = 1;
int continue_shot = items_value_process("continue_shot", 0, GET_ITEMS_VALUE);
switch (continue_shot)
{
case 0:
take_photo_num = 1;
break;
case 1:
take_photo_num = 2;
break;
case 2:
take_photo_num = 10;
break;
}
t_fn(take_photo_num, w, h, path);
}
static void takephoto_usb(const char *path)
{
uint8_t take_photo_num = 1;
int continue_shot = items_value_process("continue_shot", 0, GET_ITEMS_VALUE);
switch (continue_shot)
{
case 0:
take_photo_num = 1;
break;
case 1:
take_photo_num = 2;
break;
case 2:
take_photo_num = 10;
break;
}
usb_takephoto_normal_func(take_photo_num, path);
}
static void http_reponse_snapshot(struct httpClient *httpClient)
{
uint8_t video_num = items_value_process("switchcam", 0, GET_ITEMS_VALUE);
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if((g_cam_configs[i].mask & CAM_MASK_ENABLE) && g_cam_configs[i].enable)
{
if(video_num == 0)
{
if(g_cam_configs[i].src_type == MIPI)
{
takephoto_mipi(g_cam_configs[i].img_path);
}
else if(g_cam_configs[i].src_type == USB)
{
takephoto_usb(g_cam_configs[i].img_path);
}
break;
}
video_num--;
}
}
http_reponse_success(httpClient);
}
static uint32_t json_return_sdmsg(cJSON **root2, char **post_content)
{
int res = 1;
cJSON *root = NULL;
root = cJSON_CreateObject();
*root2 = cJSON_CreateObject();
uint32_t totalsize = 0, freesize = 0;
int sd_status = 0;
#if FS_EN
sd_status = get_fat_isready() ? 0 : 2; // 0: 正常 2: 未插入
#endif
if(sd_status == 0) {
res = osal_fatfsfree("0:", &totalsize, &freesize);
if (res) {
cJSON_AddNumberToObject(root, "status", 1);
cJSON_AddNumberToObject(root, "free", 0);
cJSON_AddNumberToObject(root, "total", 0);
} else {
#if SD_FREE_SIZE_EN
if(freesize < SD_FREE_SIZE_MIN)
cJSON_AddNumberToObject(root, "status", 4);
else
cJSON_AddNumberToObject(root, "status", 0);
#else
cJSON_AddNumberToObject(root, "status", 0);
#endif
_os_printf("sd free size: %d\ttotal size: %d\r\n", freesize, totalsize);
cJSON_AddNumberToObject(root, "free", freesize);
cJSON_AddNumberToObject(root, "total", totalsize);
}
} else {
_os_printf("sd is not inserted\r\n");
cJSON_AddNumberToObject(root, "status", 2); // 0SD 卡正常 1SD 卡未格式化 2SD 卡未插入 4: SD 卡存储已满
cJSON_AddNumberToObject(root, "free", 0);
cJSON_AddNumberToObject(root, "total", 0);
}
cJSON_AddNumberToObject(*root2, "result", 0);
cJSON_AddItemToObject(*root2, "info", root);
*post_content = cJSON_PrintUnformatted(*root2);
_os_printf("postcontent: %s\r\n", *post_content);
_os_printf("postlen: %d\r\n", strlen(*post_content));
return strlen(*post_content);
}
static void http_reponse_getsdinfo(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
sendlen = json_return_sdmsg(&root, &post_content);
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
// 定义一个函数来创建 info 数组中的每个对象
static cJSON *create_info_object(const char *name, const char * const *items, int item_count)
{
cJSON *info_obj = cJSON_CreateObject();
if (info_obj == NULL)
{
return NULL;
}
// 添加 name 字段
cJSON_AddStringToObject(info_obj, "name", name);
// 创建 items 数组
cJSON *items_array = cJSON_CreateArray();
if (items_array == NULL)
{
cJSON_Delete(info_obj);
return NULL;
}
for (int i = 0; i < item_count; i++)
{
cJSON_AddItemToArray(items_array, cJSON_CreateString(items[i]));
}
cJSON_AddItemToObject(info_obj, "items", items_array);
// 创建 index 数组
cJSON *index_array = cJSON_CreateArray();
if (index_array == NULL)
{
cJSON_Delete(info_obj);
return NULL;
}
for (int i = 0; i < item_count; i++)
{
cJSON_AddItemToArray(index_array, cJSON_CreateNumber(i));
}
cJSON_AddItemToObject(info_obj, "index", index_array);
return info_obj;
}
uint32_t json_getparamitem(cJSON **root, char **post_content2)
{
int items_counts = 0;
// 创建根对象
*root = cJSON_CreateObject();
if (*root == NULL)
{
return 0;
}
// 添加 result 字段
cJSON_AddNumberToObject(*root, "result", 0);
// 创建 info 数组
cJSON *info_array = cJSON_CreateArray();
if (info_array == NULL)
{
cJSON_Delete(*root);
return 0;
}
// 为 info 数组添加每个对象
for (int i = 0; i < ITEMS_CONFIG_COUNT; i++)
{
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
{
items_counts = get_items_counts(i);
cJSON *info_obj = create_info_object(items_cfg[i].const_item->name, items_cfg[i].const_item->items_list, items_counts);
if (info_obj == NULL)
{
cJSON_Delete(*root);
return 0;
}
cJSON_AddItemToArray(info_array, info_obj);
}
}
// 将 info 数组添加到根对象中
cJSON_AddItemToObject(*root, "info", info_array);
// 将 JSON 对象转换为字符串
*post_content2 = cJSON_PrintUnformatted(*root);
// 打印 JSON 字符串
_os_printf("postcontent: %s\n", *post_content2);
_os_printf("postlen: %d\r\n", strlen(*post_content2));
return strlen(*post_content2);
}
static void http_reponse_getparamitems_all(struct httpClient *httpClient)
{
cJSON *root = NULL;
char *post_content = NULL;
uint32_t sendlen = 0;
struct httpresp *head;
int fd = httpClient->fdClient;
sendlen = json_getparamitem(&root, &post_content);
if(sendlen == 0)
{
closeRes(httpClient);
return;
}
head = http_create_reply(200, "OK");
http_add_header(head, httpIndex.Connection, "close");
http_add_header(head, httpIndex.Type, "application/json");
http_header_send(head, httpIndex.Length, sendlen, fd);
send(fd, post_content, sendlen, 0);
closeRes(httpClient);
cJSON_free(post_content);
cJSON_Delete(root);
}
void sd_status_push(int fd)
{
static uint8_t sd_status = 0; // 0SD 卡正常 1SD 卡异常或未格式化 2SD 卡未插入 4: SD 卡存储已满
uint8_t sd_status_new = 0;
#if FS_EN
sd_status_new = get_fat_isready() ? 0 : 2;
#endif
char *push_content = NULL;
if(sd_status != sd_status_new)
{
cJSON *root = NULL;
struct timeval ptimeval;
root = cJSON_CreateObject();
if (!root)
goto clean_up;
cJSON_AddStringToObject(root, "msgid", "sd");
cJSON *info = cJSON_CreateObject();
if (!info)
goto clean_up;
cJSON_AddItemToObject(root, "info", info);
if(sd_status_new == 0) {
#if SD_FREE_SIZE_EN
int res = 0;
uint32_t freesize = 0;
res = osal_fatfsfree("0:", NULL, &freesize);
if (res) {
_os_printf("get sd failed\r\n");
cJSON_AddNumberToObject(info, "status", 1);
} else {
if(freesize < SD_FREE_SIZE_MIN)
cJSON_AddNumberToObject(info, "status", 4); // 存储已满
else
cJSON_AddNumberToObject(info, "status", 0);
}
#else
cJSON_AddNumberToObject(info, "status", 0);
#endif
} else {
cJSON_AddNumberToObject(info, "status", 2);
}
sd_status = sd_status_new;
gettimeofday(&ptimeval, NULL);
cJSON_AddNumberToObject(root, "time", ptimeval.tv_sec);
push_content = cJSON_PrintUnformatted(root);
_os_printf("postcontent: %s\r\n", push_content);
_os_printf("postlen: %d\r\n", strlen(push_content));
if (push_content && fd > 0) {
send(fd, push_content, strlen(push_content), 0);
}
clean_up:
if (push_content) cJSON_free(push_content);
if (root) cJSON_Delete(root);
}
}
void lock_status_push(int fd)
{
static uint8_t lock_status = 0; // 0停止加锁 1开始加锁
uint8_t lock_status_new = 0;
char *push_content = NULL;
lock_status_new = items_value_process("lockvideo", 0, GET_ITEMS_VALUE);
if(lock_status != lock_status_new)
{
cJSON *root = NULL;
lock_status = lock_status_new;
root = cJSON_CreateObject();
if (!root)
goto clean_up;
cJSON_AddStringToObject(root, "msgid", "rec_lock");
cJSON *info = cJSON_CreateObject();
if (!info)
goto clean_up;
cJSON_AddItemToObject(root, "info", info);
cJSON_AddNumberToObject(info, "value", lock_status > 0 ? 1 : 0);
push_content = cJSON_PrintUnformatted(root);
os_printf("postcontent: %s\r\n", push_content);
os_printf("postlen: %d\r\n", strlen(push_content));
if (push_content && fd > 0) {
send(fd, push_content, strlen(push_content), 0);
}
clean_up:
if (push_content) cJSON_free(push_content);
if (root) cJSON_Delete(root);
}
}
uint8_t get_mipi_video_status(void)
{
return 1;
}
uint8_t get_mipi2_video_status(void)
{
return 1;
}
uint8_t get_usb_video_status(void)
{
uint8_t camera_num = 0;
struct sysevt_usbh_video_priv_data info;
for(int i = 0; i < CONFIG_SYSEVT_USB_VIDEO_MAX_NUM; i++)
{
system_event_usbh_video_get_info(i, &info);
if(info.status == SYSEVT_USB_STATUS_CONNECT)
{
camera_num++;
}
}
return camera_num;
}
uint8_t get_camera_status(uint8_t *num)
{
uint8_t camera_num = 0;
uint8_t enable = 0;
for(int i = 0; i < CAMERAS_CONFIG_COUNT; i++)
{
if(g_cam_configs[i].mask & CAM_MASK_ENABLE)
{
enable = g_cam_configs[i].get_status();
g_cam_configs[i].enable = enable;
if(enable)
{
camera_num++;
}
}
}
if(camera_num != *num)
{
_os_printf("camera num: %d\r\n", camera_num);
*num = camera_num;
items_value_process("cameranum", camera_num, SET_ITEMS_VALUE);
return 1;
}
return 0;
}
void usb_event_disconnect_hdl(void)
{
os_printf("%s %d\n", __FUNCTION__, __LINE__);
close_rec();
uint8_t num = items_value_process("cameranum", 0, GET_ITEMS_VALUE);
get_camera_status(&num);
/* uvc 镜头拔出后重新录卡 */
// open_rec();
}
void usb_event_connect_hdl(void)
{
os_printf("%s %d\n", __FUNCTION__, __LINE__);
uint8_t num = items_value_process("cameranum", 0, GET_ITEMS_VALUE);
get_camera_status(&num);
/* usb 镜头插入后录卡 */
// open_rec();
}
void camera_status_push(int fd)
{
uint8_t camera_status = 0; // 0拔出 1插入
static uint8_t count = 0;
static uint8_t last_camera_num = 0;
if(!count)
{
last_camera_num = items_value_process("cameranum", 0, GET_ITEMS_VALUE);
count = 1;
}
uint8_t camera_num = last_camera_num;
uint8_t change_flag = 0;
char *push_content = NULL;
change_flag = get_camera_status(&camera_num);
if(change_flag)
{
cJSON *root = NULL;
if(camera_num > last_camera_num) {
camera_status = 1;
} else if(camera_num < last_camera_num) {
camera_status = 0;
} else {
goto clean_up;
}
last_camera_num = camera_num;
root = cJSON_CreateObject();
if (!root)
goto clean_up;
cJSON_AddStringToObject(root, "msgid", "cam_plugin");
cJSON *info = cJSON_CreateObject();
if (!info)
goto clean_up;
cJSON_AddItemToObject(root, "info", info);
cJSON_AddNumberToObject(info, "action", camera_status);
cJSON_AddNumberToObject(info, "curcamid", 0);
cJSON_AddNumberToObject(info, "camnum", camera_num);
push_content = cJSON_PrintUnformatted(root);
os_printf("postcontent: %s\r\n", push_content);
os_printf("postlen: %d\r\n", strlen(push_content));
if (push_content && fd > 0) {
send(fd, push_content, strlen(push_content), 0);
}
clean_up:
if (push_content) cJSON_free(push_content);
if (root) cJSON_Delete(root);
}
}
// 若需要按键或其他APP外的操作更新录卡状态可以启用
void rec_status_push(int fd)
{
static uint8_t rec_status = 1; // 0录制停止 1录制启动
uint8_t rec_status_new = 0;
char *push_content = NULL;
// rec_status_new = get_rec_status(sdh); // rec状态获取函数
if(rec_status != rec_status_new)
{
cJSON *root = NULL;
struct timeval ptimeval;
rec_status = rec_status_new;
root = cJSON_CreateObject();
if (!root)
goto clean_up;
cJSON_AddStringToObject(root, "msgid", "rec");
cJSON *info = cJSON_CreateObject();
if (!info)
goto clean_up;
cJSON_AddItemToObject(root, "info", info);
cJSON_AddNumberToObject(info, "status", rec_status);
gettimeofday(&ptimeval, NULL);
cJSON_AddNumberToObject(root, "time", ptimeval.tv_sec);
push_content = cJSON_PrintUnformatted(root);
os_printf("postcontent: %s\r\n", push_content);
os_printf("postlen: %d\r\n", strlen(push_content));
if (push_content && fd > 0) {
send(fd, push_content, strlen(push_content), 0);
}
clean_up:
if (push_content) cJSON_free(push_content);
if (root) cJSON_Delete(root);
}
}
typedef void (*message_handler_t)(int fd);
message_handler_t handlers[] = {
sd_status_push,
#if APP_LOCK_VIDEO_EN
lock_status_push,
#endif
camera_status_push,
// rec_status_push, // rec消息推送根据需要启用
};
static void detect_loop(void *ei, void *d)
{
int fd = (int)d;
int handles_num = sizeof(handlers) / sizeof(handlers[0]);
int err = 0;
socklen_t len = sizeof(err);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
if (err != 0) {
os_printf("socket error: %d, close socket\n", err);
closesocket(fd);
eloop_remove_event(ei);
}
for(int i = 0; i < handles_num; i++)
{
handlers[i](fd);
}
}
/********************* Initial ********************/
struct item_config {
/******* 参数区头部: 这部分区域不能修改 *****/
uint16 magic_num, crc;
uint16 size, rev1, rev2, rev3;
/*******************************************/
uint32_t front_check;
uint8_t value[ITEMS_CONFIG_COUNT];
uint32_t rear_check;
};
static struct item_config *item_cfg = NULL;
static void itemcfg_getdefault(void)
{
for(int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
item_cfg->value[i] = items_cfg_f[i].const_item->default_value;
}
}
static void itemcfg_getvalue(void)
{
for(int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
item_cfg->value[i] = items_cfg[i].value;
}
}
static void itemcfg_setvalue(void)
{
for(int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
items_cfg[i].value = item_cfg->value[i];
}
}
static void itemcfg_handle(void)
{
for(int i = 0; i < ITEMS_CONFIG_COUNT; i++) {
if(items_cfg[i].const_item->enable == ITEM_ENABLE)
items_cfg[i].const_item->handler(&items_cfg[i], item_cfg->value[i], NULL);
}
}
static int itemcfg_save(uint8_t type)
{
item_cfg->front_check = 0x66666666;
item_cfg->rear_check = 0x88888888;
if(type == 1) {
itemcfg_getvalue();
} else {
itemcfg_getdefault();
}
return syscfg_write("recorder", item_cfg, sizeof(struct item_config));
}
static void item_cfg_load(void)
{
if (syscfg_read("recorder", item_cfg, sizeof(struct item_config)) == RET_OK) {
if(item_cfg->front_check == 0x66666666 && item_cfg->rear_check == 0x88888888) {
itemcfg_handle();
os_printf("item_cfg load ok\r\n");
return;
}
os_printf("item_cfg load fail, front_check: 0x%x\trear_check: 0x%x\r\n", item_cfg->front_check, item_cfg->rear_check);
}
os_printf("recorder use default params.\r\n");
itemcfg_save(0);
itemcfg_handle();
}
static void thread_rec_pool_queue(struct httpserver *httpserver)
{
int32 ret;
struct httpClient *httpClient;
while (1)
{
httpClient = (struct httpClient *)os_msgq_get2(&httpserver->thread_pool_queue,-1,&ret);
if(httpClient && ret == 0)
{
_os_printf("%s %d httpserver->thread_pool_queue:%x\r\n", __FUNCTION__, ret, httpserver->thread_pool_queue);
http_thread_pool(httpClient, (struct url*)getweb, NULL);
STREAM_LIBC_FREE(httpClient);
httpClient = NULL;
}
}
}
// 发送有个队列消息
static uint8_t httpqueue_thread_send_pool(struct httpClient *httpClient)
{
long res;
res = os_msgq_put(&httpClient->httpserver->thread_pool_queue, (uint32_t)httpClient,-1);
_os_printf("QueueSend finish:%d!!!\r\n", res);
if (res != 0)
{
closeRes(httpClient);
STREAM_LIBC_FREE(httpClient);
_os_printf("QueueSend fail!\r\n");
}
return 0;
}
static void do_accept(void *ei, void *d)
{
SOCK_HDL fd;
unsigned int i;
struct sockaddr_in addr;
struct httpClient *httpClient = initHttpClient();
if (!httpClient)
{
return;
}
struct httpserver *httpserver = (struct httpserver *)d;
_os_printf("httpserver fd:%d\r\n", httpserver->fdServer);
i = sizeof(addr);
if ((fd = accept(httpserver->fdServer, (struct sockaddr *)&addr, &i)) < 0)
{
os_printf("accept error\r\n");
STREAM_LIBC_FREE(httpClient);
return;
}
_os_printf("accepted connection from %s: %d\r\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
_os_printf("create new thread fd: %d\r\n", fd);
httpClient->fdClient = fd;
httpClient->httpserver = httpserver;
httpClient->time = os_jiffies();
httpClient->pattern = NULL;
httpClient->http_request = NULL;
#if 1
int recv_timeout = 1000; // 1秒
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&recv_timeout, sizeof(int)) < 0)
{
_os_printf("error setsockopt TCP recv timeout\r\n");
}
int send_timeout = 6000; // 6秒
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&send_timeout, sizeof(int)) < 0)
{
_os_printf("error setsockopt TCP send timeout\r\n");
}
#endif
httpqueue_thread_send_pool(httpClient);
}
static int Viidure_listen(int port)
{
struct sockaddr_in addr;
SOCK_HDL fd;
struct httpserver *httpserver = STREAM_LIBC_ZALLOC(sizeof(struct httpserver));
if(httpserver == NULL)
{
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = 0;
addr.sin_port = htons(port);
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
STREAM_LIBC_FREE(httpserver);
return -1;
}
if (osal_set_reuseaddr(fd, 1) < 0) {}
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
close(fd);
STREAM_LIBC_FREE(httpserver);
return -1;
}
if (listen(fd, 8) < 0)
{
close(fd);
STREAM_LIBC_FREE(httpserver);
return -1;
}
httpserver->fdServer = fd;
os_msgq_init(&httpserver->thread_pool_queue,32);
os_task_create("queue1", (void*)thread_rec_pool_queue, httpserver, OS_TASK_PRIORITY_NORMAL, 0, NULL, 2048);
os_task_create("queue2", (void*)thread_rec_pool_queue, httpserver, OS_TASK_PRIORITY_NORMAL, 0, NULL, 2048);
eloop_add_fd(fd, EVENT_READ, EVENT_F_ENABLED, do_accept, (void *)httpserver);
_os_printf("listening on http port %s:%d\r\n", inet_ntoa(addr.sin_addr), port);
return 0;
}
static void push_do_accept(void *ei, void *d)
{
SOCK_HDL fd;
struct sockaddr_in cliaddr;
socklen_t clienlen = sizeof(cliaddr);
if((fd = accept((int)d, (struct sockaddr *)&cliaddr, &clienlen)) < 0)
{
return;
}
// 设置 TCP keepalive
int keepalive = 1; // 启用 keepalive
int keepidle = 3; // 5 秒无数据后开始探测
int keepintvl = 3; // 每隔 5 秒探测一次
int keepcnt = 3; // 探测 3 次失败后判定连接断开
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) {
os_printf("setsockopt SO_KEEPALIVE failed\n");
close(fd);
return;
}
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle)) < 0) {
os_printf("setsockopt TCP_KEEPIDLE failed\n");
}
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl)) < 0) {
os_printf("setsockopt TCP_KEEPINTVL failed\n");
}
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt)) < 0) {
os_printf("setsockopt TCP_KEEPCNT failed\n");
}
_os_printf("accepted push connection from %s: %d\r\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
_os_printf("create new push fd: %d\r\n", fd);
eloop_add_timer(1500, EVENT_F_ENABLED, detect_loop, (void *)fd);
}
static int push_tcp_server(int port)
{
SOCK_HDL fd;
struct sockaddr_in servaddr;
// 创建socket
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
os_printf("tcp socket create failed\n");
return -1;
}
// 绑定本地地址
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
if (bind(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
os_printf("tcp bind failed\n");
close(fd);
return -1;
}
// 监听端口
if (listen(fd, 5) < 0) {
os_printf("tcp listen failed\n");
close(fd);
return -1;
}
eloop_add_fd(fd, EVENT_READ, EVENT_F_ENABLED, push_do_accept, (void *)fd);
_os_printf("listening on push port %s:%d\r\n", inet_ntoa( servaddr.sin_addr ), port );
return 0;
}
static int32_t recorder_save_loop(struct os_work *work)
{
int saveflag = 0;
saveflag = items_value_process("saveflag", 0, GET_ITEMS_VALUE);
if(saveflag) {
if(itemcfg_save(1) != -1)
{
saveflag = 0;
items_value_process("saveflag", saveflag, SET_ITEMS_VALUE);
}
}
os_run_work_delay(&recorder_wk, 3000);
return 0;
}
/********************* GLOBAL CONFIGURATION DIRECTIVES ********************/
int config_Viidure(int port)
{
if (port <= 0 || port > 65535)
{
_os_printf("invalid listen port %d", port);
return -1;
}
if(!items_cfg)
{
items_cfg = STREAM_LIBC_MALLOC(sizeof(struct items_config) * ITEMS_CONFIG_COUNT);
if(!items_cfg) {
_os_printf("items_cfg malloc failed\r\n");
return -1;
}
os_memcpy(items_cfg, items_cfg_f, sizeof(struct items_config) * ITEMS_CONFIG_COUNT);
}
if(!item_cfg)
{
item_cfg = STREAM_LIBC_ZALLOC(sizeof(struct item_config));
if(!item_cfg)
{
_os_printf("item_cfg malloc failed\r\n");
STREAM_LIBC_FREE(items_cfg);
items_cfg = NULL;
return -1;
}
}
if(!g_cam_configs)
{
g_cam_configs = STREAM_LIBC_ZALLOC(sizeof(struct cam_cfg) * CAMERAS_CONFIG_COUNT);
if(!g_cam_configs)
{
_os_printf("g_cam_configs malloc failed\r\n");
STREAM_LIBC_FREE(item_cfg);
item_cfg = NULL;
STREAM_LIBC_FREE(items_cfg);
items_cfg = NULL;
return -1;
}
os_memcpy(g_cam_configs, g_cam_configs_f, sizeof(struct cam_cfg) * CAMERAS_CONFIG_COUNT);
}
item_cfg_load();
uint8_t camera_num = 0;
get_camera_status(&camera_num);
OS_WORK_INIT(&recorder_wk, recorder_save_loop, 0);
os_run_work_delay(&recorder_wk, 3000);
md_last_cnt = 0;
md_no_motion_ticks = 0;
md_recording = 0;
os_timer_init(&md_timer, md_timer_cb, OS_TIMER_MODE_PERIODIC, NULL);
os_timer_start(&md_timer, 500);
md_enabled = 1;
_os_printf("[MD] Motion detect auto-started\r\n");
if(push_tcp_server(PUSH_MESSAGE_PORT) != 0)
{
_os_printf("push tcp server init failed, port: %d\r\n", PUSH_MESSAGE_PORT);
}
return Viidure_listen(port);
}