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

5403 lines
168 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}