/***************************************************************************** * file lib/process/pd_main.c * author YuLiang * version 1.0.0 * date 07-Feb-2023 * brief This file provides all the partial discharge related operation functions. ****************************************************************************** * Attention * *

© COPYRIGHT(c) 2021 LandPower

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of LandPower nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef CFG_DEV_TYPE_LAND_PD /* 标准C库头文件. */ #include #include #include #include #include #include #include #include "main.h" #include "pd_dau.h" #include "pd_csg.h" #include "pd_main.h" #include "pd_dbg.h" #include "pd_net.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define PD_BOARD_PORT 12345 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ pd_data_t pd_data; pd_config_t pd_config; pd_state_t pd_state; cmd_node_t pd_port_node = { PORT_NODE, CONFIG_NODE, 1, NULL, }; /* DAU 端口类型分类. */ static const char *pd_sen_type_str[PD_SEN_TYPE_COUNT] = { "", "sig", "noise", "sig-noise" }; /* DAU 端口降噪类型分类. */ static const char *pd_noise_type_str[PD_DENOISE_TYPE_COUNT] = { "none", "auto", "manual", "variance" }; /* Private function prototypes -----------------------------------------------*/ extern int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port); extern void _pd_port_config_save_port(vty_t *vty, uint8_t unit, uint8_t port); /* Internal functions --------------------------------------------------------*/ /* 进入 DAU 端口模式. */ CMD(pd_port_adj_save, pd_port_adj_save_cmd, "save adj", "Save\n" "Adjusting\n" ) { dau_param_adj_save(); return CMD_SUCCESS; } /* 进入 DAU 端口模式. */ CMD(pd_port_terminal, pd_port_terminal_cmd, "interface port WORD", "Interface\n" "Port\n" "Port id: Ex: 1/1\n") { uint8_t unit = 0; uint8_t port = 0; int32_t vport = 0; /* 取出端口号. */ if (_pd_port_str_to_unit_port(argv[0], &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } /* 计算虚拟端口. */ vport = dau_port_to_vport(unit, port); if (vport <= 0) { return CMD_ERR_NO_MATCH; } pd_port_node.param_num = vport; snprintf(pd_port_node.prompt, PD_PORT_PROMPT_LEN, "%%s(interface port %d/%d)# ", unit + 1, port + 1); vty->node = PORT_NODE; return CMD_SUCCESS; } /* 配置端口类型. */ CMD(pd_sensor_type, pd_sensor_type_cmd, "sensor-type (sig|noise|sig-noise)", "Sensor type\n" "Signal\n" "Noise\n" "Signal associate noise\n") { uint8_t sen_type = 0; uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } for(sen_type = PD_SEN_TYPE_SIG; sen_type < PD_SEN_TYPE_COUNT; sen_type++) { if (strncmp(argv[0], pd_sen_type_str[sen_type], strlen(pd_sen_type_str[sen_type]))) { continue; } pd_config.config_port[unit][port].sensor_type = sen_type; } return CMD_SUCCESS; } /* 配置端口降噪方式 */ CMD(pd_noise_type, pd_noise_type_cmd, "noise-type (none|auto|manual|variance)", "Noise type\n" "None\n" "Auto\n" "Manual\n" "Variance\n") { uint8_t denoise_type = 0; uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } for(denoise_type = PD_DENOISE_TYPE_NONE; denoise_type < PD_DENOISE_TYPE_COUNT; denoise_type++) { if (strncmp(argv[0], pd_noise_type_str[denoise_type], strlen(pd_noise_type_str[denoise_type]))) { continue; } pd_config.config_port[unit][port].denoise_type = denoise_type; pd_config.config_real[unit][port].denoise_type = denoise_type; } return CMD_SUCCESS; } /* 配置端口降噪等级. */ CMD(pd_noise_reduction, pd_noise_reduction_cmd, "noise-reduction <0-4000>", "Noise reduction\n" "Noise reduction unit: 0.1dBm\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].denoise_auto = strtol(argv[0], NULL, 10); return CMD_SUCCESS; } /* 配置端口降噪等级. */ CMD(pd_noise_reduction_auto, pd_noise_reduction_auto_cmd, "noise-reduction-auto (enable|disable)", "Noise reduction auto\n" "Enable\n" "Disable\n") { uint8_t unit = 0; uint8_t port = 0; uint8_t mode = FALSE; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } if (0 == strncmp(argv[0], "en", 2)) { mode = TRUE; } else if (0 == strncmp(argv[0], "di", 2)) { mode = FALSE; } else { mode = FALSE; } pd_config.config_port[unit][port].is_auto_noise = mode; return CMD_SUCCESS; } /* 配置端口降噪等级. */ CMD(pd_noise_reduction_cnt, pd_noise_reduction_cnt_cmd, "noise-reduction-auto cnt <0-6400>", "Noise reduction auto\n" "Count per second. \n" "Count\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].auto_noise_cnt = strtol(argv[0], NULL, 10); return CMD_SUCCESS; } /* 配置端口降噪等级. */ CMD(pd_noise_env, pd_noise_env_cmd, "noise-env <0-4000>", "Noise environment\n" "Noise environment unit: dBm\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].denoise_manual = strtol(argv[0], NULL, 10); pd_config.config_real[unit][port].denoise_manual = pd_config.config_port[unit][port].denoise_manual; return CMD_SUCCESS; } /* 配置端口方差降噪系数 */ CMD(pd_noise_variance, pd_noise_variance_cmd, "noise-variance <1-1000>", "Noise variance coefficient\n" "Noise coefficient unit: 1%\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].denoise_variance = strtol(argv[0], NULL, 10); return CMD_SUCCESS; } /* 事件次数阀值高. */ CMD(pd_evnet_cnt_high, pd_evnet_cnt_high_cmd, "evnet-cnt-high <0-128000> sec <0-12800>", "Event conut threshold high\n" "Conut threshold\n" "Secend\n" "Conut threshold\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].event_counter_h = strtol(argv[0], NULL, 10); pd_config.config_port[unit][port].event_sec_h = strtol(argv[1], NULL, 10); return CMD_SUCCESS; } /* 事件值阀值高 */ CMD(pd_evnet_thr_high, pd_evnet_thr_high_cmd, "evnet-thr-high <0-4000> cnt <0-128000>", "Event conut threshold low\n" "Conut threshold\n" "Secend\n" "Conut threshold\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].event_thr_h = strtol(argv[0], NULL, 10); pd_config.config_port[unit][port].event_counter_thr_h = strtol(argv[1], NULL, 10); return CMD_SUCCESS; } /* 事件次数阀值低 */ CMD(pd_evnet_cnt_low, pd_evnet_cnt_low_cmd, "evnet-cnt-low <0-128000> sec <0-12800>", "Event conut threshold low\n" "Conut threshold\n" "Secend\n" "Conut threshold\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].event_counter_l = strtol(argv[0], NULL, 10); pd_config.config_port[unit][port].event_sec_l = strtol(argv[1], NULL, 10); return CMD_SUCCESS; } /* 事件值阀值低 */ CMD(pd_evnet_thr_low, pd_evnet_thr_low_cmd, "evnet-thr-low <0-4000> cnt <0-128000>", "Event conut threshold low\n" "Conut threshold\n" "Secend\n" "Conut threshold\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].event_thr_l = strtol(argv[0], NULL, 10); pd_config.config_port[unit][port].event_counter_thr_l = strtol(argv[1], NULL, 10); return CMD_SUCCESS; } /* 事件突发时间 */ CMD(pd_evnet_burst, pd_evnet_burst_cmd, "evnet-burst <1-5> thr <0-4000>", "Event burst\n" "Average value time\n" "Threshold\n" "Threshold\n") { uint8_t unit = 0; uint8_t port = 0; /* 取出端口号. */ if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } pd_config.config_port[unit][port].burst_time = strtol(argv[0], NULL, 10); pd_config.config_port[unit][port].burst_thr = strtol(argv[1], NULL, 10); return CMD_SUCCESS; } /* 趋势数据上传间隔. */ CMD(pd_trend_interval, pd_trend_interval_cmd, "trend-interval <1-60>", "Trend data interval\n" "Interval time: min\n") { pd_config.config.trend_period = strtol(argv[0], NULL, 10) * 60; if (is_system_init) { dau_trend_inv_set(); } return CMD_SUCCESS; } /* 心跳上传间隔. */ CMD(pd_heartbeat_interval, pd_heartbeat_interval_cmd, "heartbeat-interval <1-60>", "heartbeat interval\n" "Interval time: min\n") { pd_config.config.heartbeat_period = strtol(argv[0], NULL, 10); return CMD_SUCCESS; } /* 趋势数据文件数量. */ CMD(pd_trend_amount, pd_trend_amount_cmd, "trend-amount <1-5000>", "Trend file amount\n" "Trend file amount\n") { pd_config.config.trend_storage = strtol(argv[0], NULL, 10); csg.trend_file.files_max = pd_config.config.trend_storage; return CMD_SUCCESS; } /* 事件数据文件数量. */ CMD(pd_evnet_amount, pd_evnet_amount_cmd, "evnet-amount <500-5000>", "Evnet file amount\n" "Evnet file amount\n") { pd_config.config.event_storage = strtol(argv[0], NULL, 10); csg.event_file.files_max = pd_config.config.event_storage; return CMD_SUCCESS; } /* 同步模式. */ CMD(pd_sync_mode, pd_sync_mode_cmd, "sync-mode (pt|inside|outside)", "Synchronize mode\n" "PT\n" "Power\n" "Outside\n") { uint8_t mode = 0; if (0 == strncmp(argv[0], "pt", 2)) { mode = PD_SYNC_PT; } else if (0 == strncmp(argv[0], "inside", 5)) { mode = PD_SYNC_INSIDE; } else if (0 == strncmp(argv[0], "outside", 5)) { mode = PD_SYNC_OUTSIDE; } else { mode = 0; } pd_config.config.sync_mode = mode; if (is_system_init) { dau_sync_mode_set(); } return CMD_SUCCESS; } /* 同步模式. */ CMD(pd_sync_fre, pd_sync_fre_cmd, "sync-inside <400-3000>", "Synchronize outside mode\n" "Outside frequency\n") { pd_config.config.power_frequency = strtol(argv[0], NULL, 10); if (is_system_init) { dau_sync_fre_set(); } return CMD_SUCCESS; } /* 同步模式. */ CMD(pd_pps_mode, pd_pps_mode_cmd, "pps-mode (auto|master|slave)", "PPS mode\n" "Master\n" "Slave\n") { uint8_t mode = 0; if (0 == strncmp(argv[0], "a", 1)) { mode = PD_PPS_AUTO; } else if (0 == strncmp(argv[0], "m", 1)) { mode = PD_PPS_MASTER; } else { mode = PD_PPS_SLAVE; } pd_config.config.pps_mode = mode; if (is_system_init) { dau_pps_mode_set(); } return CMD_SUCCESS; } /* 4G 模块是否使能. */ CMD(pd_4G_enable, pd_4G_enable_cmd, "wireless (enable|disable)", "Wireless\n" "Enable\n" "Disable\n") { uint8_t enable = FALSE; if (0 == strncmp(argv[0], "e", 1)) { enable = TRUE; } else { enable = FALSE; } pd_config.config.is_4G_enable = enable; return CMD_SUCCESS; } /* 4G 模块 APN. */ CMD(pd_4G_APN, pd_4G_APN_cmd, "wireless apn WORD", "Wireless\n" "APN\n" "Enable\n" "Disable\n") { snprintf(pd_config.config.APN, PD_4G_APN_LEN, "%s", argv[0]); return CMD_SUCCESS; } /* 通信协议选择. */ CMD(pd_protocol_type, pd_protocol_type_cmd, "protocol-type (land|csg)", "Protocol type\n" "Land\n" "Csg\n") { uint8_t type = 0; if (0 == strncmp(argv[0], "land", 4)) { type = PD_PROTOCOL_LAND; } else if (0 == strncmp(argv[0], "csg", 3)) { type = PD_PROTOCOL_CSG; } else { type = PD_PROTOCOL_LAND; } pd_config.config.protocol_type = type; return CMD_SUCCESS; } /* 显示 DAU 状态. */ CMD(show_prps, show_prps_cmd, "show prps", "Show\n" "PRPS\n") { pd_prps_show(); return CMD_SUCCESS; } /* 显示 DAU 状态. */ CMD(show_pd, show_pd_cmd, "show pd", "Show\n" "Partial discharge\n") { pd_show(); return CMD_SUCCESS; } /* 在终端上显示当前配置信息. */ CMD(show_running_port, show_running_port_cmd, "show running-config interface port WORD", SHOW_STR "Running configuration\n" "Interface\n" "Port\n" "Port id: Ex: 1/1\n") { uint8_t unit = 0; uint8_t port = 0; int32_t vport = 0; /* 取出端口号. */ if (_pd_port_str_to_unit_port(argv[0], &unit, &port) != E_NONE) { return CMD_ERR_NO_MATCH; } /* 计算虚拟端口. */ vport = dau_port_to_vport(unit, port); if (vport <= 0) { return CMD_ERR_NO_MATCH; } vty_out(vty, "Current configuration:%s", VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); _pd_port_config_save_port(vty, unit, port); vty_out(vty, "end%s", VTY_NEWLINE); return CMD_SUCCESS; } /* 在终端上显示当前配置信息. */ CMD(show_running_current, show_running_current_cmd, "show running-config current", SHOW_STR "Running configuration\n" "Current\n") { uint8_t unit = 0; uint8_t port = 0; vty_out(vty, "Current configuration:%s", VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); if (PORT_NODE == vty->node) { dau_vport_to_port(pd_port_node.param_num, &unit, &port); _pd_port_config_save_port(vty, unit, port); } else if(CONFIG_NODE == vty->node) { config_write_host(vty); } vty_out(vty, "end%s", VTY_NEWLINE); return CMD_SUCCESS; } /* 配置保存函数. */ int _pd_config_save(vty_t* vty) { int16_t i = 0; switch (pd_config.config.protocol_type) { case PD_PROTOCOL_LAND: vty_out(vty, "protocol-type land%s", VTY_NEWLINE); i++; break; case PD_PROTOCOL_CSG: vty_out(vty, "protocol-type csg%s", VTY_NEWLINE); i++; break; default: break; } vty_out(vty, "evnet-amount %d%s", pd_config.config.event_storage, VTY_NEWLINE); i++; vty_out(vty, "trend-interval %d%s", pd_config.config.trend_period / 60, VTY_NEWLINE); i++; vty_out(vty, "trend-amount %d%s", pd_config.config.trend_storage, VTY_NEWLINE); i++; vty_out(vty, "heartbeat-interval %d%s", pd_config.config.heartbeat_period, VTY_NEWLINE); i++; switch(pd_config.config.sync_mode) { case PD_SYNC_PT: vty_out(vty, "sync-mode pt%s", VTY_NEWLINE); i++; break; case PD_SYNC_INSIDE: vty_out(vty, "sync-mode inside%s", VTY_NEWLINE); i++; break; case PD_SYNC_OUTSIDE: vty_out(vty, "sync-mode outside%s", VTY_NEWLINE); i++; break; default: break; } vty_out(vty, "sync-inside %d%s", pd_config.config.power_frequency, VTY_NEWLINE); i++; switch(pd_config.config.pps_mode) { case PD_PPS_AUTO: vty_out(vty, "pps-mode auto%s", VTY_NEWLINE); i++; break; case PD_PPS_MASTER: vty_out(vty, "pps-mode master%s", VTY_NEWLINE); i++; break; case PD_PPS_SLAVE: vty_out(vty, "pps-mode slave%s", VTY_NEWLINE); i++; break; default: break; } vty_out(vty, "wireless %s%s", pd_config.config.is_4G_enable ? "enable" : "disable", VTY_NEWLINE); i++; vty_out(vty, "wireless apn %s%s", pd_config.config.APN, VTY_NEWLINE); i++; return i; } /* config模式配置保存函数: vty -- 相应的终端 */ void _pd_port_config_save_port(vty_t *vty, uint8_t unit, uint8_t port) { array_t *configs = pd_port_node.configs; pd_port_cmd_save_config_f *func = NULL; uint8_t i = 0; uint16_t field = 0; vty_out(vty, "interface port %d/%d%s", unit + 1, port + 1, VTY_NEWLINE); for(i = 0; i < array_active(configs); i++) { func = array_lookup(configs, i); if (!func) { continue; } func(vty, unit, port); } field = pd_config.config_port[unit][port].sensor_type; vty_out(vty, " sensor-type %s%s", pd_sen_type_str[field], VTY_NEWLINE); field = pd_config.config_port[unit][port].denoise_type; vty_out(vty, " noise-type %s%s", pd_noise_type_str[field], VTY_NEWLINE); vty_out(vty, " noise-reduction %d%s", pd_config.config_port[unit][port].denoise_auto, VTY_NEWLINE); vty_out(vty, " noise-env %d%s", pd_config.config_port[unit][port].denoise_manual, VTY_NEWLINE); vty_out(vty, " noise-variance %d%s", pd_config.config_port[unit][port].denoise_variance, VTY_NEWLINE); vty_out(vty, " noise-reduction-auto %s%s", pd_config.config_port[unit][port].is_auto_noise ? "enable" : "disable", VTY_NEWLINE); vty_out(vty, " noise-reduction-auto cnt %d%s", pd_config.config_port[unit][port].auto_noise_cnt, VTY_NEWLINE); vty_out(vty, " evnet-cnt-high %d sec %d%s", pd_config.config_port[unit][port].event_counter_h, pd_config.config_port[unit][port].event_sec_h, VTY_NEWLINE); vty_out(vty, " evnet-thr-high %d cnt %d%s", pd_config.config_port[unit][port].event_thr_h, pd_config.config_port[unit][port].event_counter_thr_h, VTY_NEWLINE); vty_out(vty, " evnet-cnt-low %d sec %d%s", pd_config.config_port[unit][port].event_counter_l, pd_config.config_port[unit][port].event_sec_l, VTY_NEWLINE); vty_out(vty, " evnet-thr-low %d cnt %d%s", pd_config.config_port[unit][port].event_thr_l, pd_config.config_port[unit][port].event_counter_thr_l, VTY_NEWLINE); vty_out(vty, " evnet-burst %d thr %d%s", pd_config.config_port[unit][port].burst_time, pd_config.config_port[unit][port].burst_thr, VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); } /* config模式配置保存函数: vty -- 相应的终端 */ int32_t _pd_port_config_save(vty_t *vty) { uint8_t unit = 0; uint8_t port = 0; /* 其他配置保存 */ for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau_is_valid(dau[unit])) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { _pd_port_config_save_port(vty, unit, port); } } return E_NONE; } /* 将端口字符串, 转换成 unit port 格式. */ int32_t _pd_port_str_to_unit_port(const char *port_str, uint8_t *unit, uint8_t *port) { char *str = NULL; char *p = NULL; char temp[8]; uint8_t len = 0; uint8_t i = 0; snprintf(temp, 8, "%s", port_str); str = strtok_r(temp, "/", &p); while(str != NULL) { /* 检查长度. */ if (len >= 2) { return E_BAD_PARAM; } /* 检查字符串 */ for(i = 0; str[i] && str[i] != '\0'; i++) { if (!(str[i] >= '0' && str[i] <= '9')) { return E_BAD_PARAM; } } /* 检查数据长度 */ if (i != 1) { return E_BAD_PARAM; } /* 读取板卡和端口号. */ if (0 == len) { *unit = strtol(str, NULL, 10) - 1; } else { *port = strtol(str, NULL, 10) - 1; } len++; /* 获取下个数据 */ str = strtok_r(NULL, "/", &p); } return E_NONE; } /* 广播接收程序 */ void *_pd_broadcast_handle(void *arg) { struct sockaddr_in broad_addr; struct sockaddr_in peer_addr; socklen_t addr_len = 0; char packet[1024]; int fd = 0; int len = 0; int rv = -1; /* 创建报文套接字 */ fd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == fd) { log_err(LOG_PD, "Fail to open broadcast socket."); return NULL; } bzero(&broad_addr, sizeof(broad_addr)); broad_addr.sin_family = AF_INET; broad_addr.sin_port = htons(PD_BOARD_PORT); broad_addr.sin_addr.s_addr = INADDR_ANY; rv = bind(fd, (struct sockaddr *)&broad_addr, sizeof(broad_addr)); if (-1 == rv) { log_err(LOG_PD, "Fail to bind broad socket."); return NULL; } while (1) { /* 接收广播 */ len = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addr_len); if (-1 == len) { continue; } packet[len] = '\0'; if (strncmp(packet, "hello", 5) == 0) { len = snprintf(packet, 1024, "world,GIS7.0_V%s,", softversion_get()); snprintf(packet + len, 1024 - len, "%s", device_info.hostname); sendto(fd, packet, strlen(packet) + 1, 0, (struct sockaddr *)&peer_addr, sizeof(peer_addr)); } } /* 关闭套接字 */ close(fd); return NULL; } int32_t _pd_broadcast_init(void) { struct sched_param param; pthread_attr_t attr; pthread_t pid; int32_t rv = E_NONE; /* 初始化广播报文处理线程. */ /* 配置线程RR调度, 优先级25 */ pthread_attr_init(&attr); param.sched_priority = 25; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); rv = pthread_create(&pid, &attr, _pd_broadcast_handle, NULL); if (rv != 0) { log_err(LOG_PD, "PD can't create broadcast pthread %d!", rv); return E_SYS_CALL; } else { thread_m_add("PD_BROADCAST", pid); } pthread_attr_destroy(&attr); return E_NONE; } /* 4G 模块服务程序 */ void *_pd_4G_handle(void *arg) { struct ifaddrs *ifa = NULL, *ifList = NULL; int8_t err_cnt = 0; bool is_found = FALSE; char cmd[256]; while(!dau[0]->reg) { sleep(1); } /* 4G 模块上电 */ dau[0]->reg->reg_port[0].AFR[1] = 1; /* 上电拨号 */ sleep(30); snprintf(cmd, 256, "/etc/ppp/peers/quectel-pppd.sh /dev/ttyUSB3 %s", pd_config.config.APN); system(cmd); while(1) { sleep(40); /* 查询 4G 是否连接 */ is_found = FALSE; if (getifaddrs(&ifList) < 0) { //err_cnt++; continue; } for(ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) { continue; } if (ifa->ifa_addr->sa_family != AF_INET) { continue; } if (strncmp(ifa->ifa_name, "ppp0", 4)) { continue; } is_found = TRUE; break; } freeifaddrs(ifList); /* 没有连接, 重新拨号 */ if (is_found) { pd_state.is_4G_connect = TRUE; err_cnt = 0; continue; } else { pd_state.is_4G_connect = FALSE; DBG(DBG_M_PD, "4G connect start...\r\n"); err_cnt++; if(err_cnt > 64) { /* 每 64 分钟没有拨号成功则重启 */ reboot_system(LOG_PD, REBOOT_4G_ERROR); continue; } /* 每 8 分钟拨号一次 */ if (0 == (err_cnt & 0x7)) { /* 重新拨号 */ log_warn(LOG_PD, "Wireless dialing restart!"); system("/etc/ppp/peers/quectel-ppp-kill"); sleep(20); snprintf(cmd, 256, "/etc/ppp/peers/quectel-pppd.sh /dev/ttyUSB3 %s", pd_config.config.APN); system(cmd); } } } return NULL; } void _pd_config_init_uhf(void) { uint8_t i = 0; uint8_t j = 0; /* 初始化基本参数. */ for(i = 0; i < PD_DAU_SUM; i++) { for(j = 0; j < PD_DAU_PORT_SUM; j++) { pd_config.config_port[i][j].port_type = PD_PORT_TYPE_UHF; pd_config.config_port[i][j].sensor_type = PD_SEN_TYPE_SIG; pd_config.config_port[i][j].is_auto_noise = TRUE; pd_config.config_port[i][j].filter = CSG_FILTER_TYPE_FR; pd_config.config_real[i][j].filter_cfg = CSG_FILTER_TYPE_FR; pd_config.config_real[i][j].denoise_type = PD_DENOISE_TYPE_AOTU; pd_config.config_real[i][j].denoise_manual = 100; pd_config.config_port[i][j].denoise_type = PD_DENOISE_TYPE_AOTU; pd_config.config_port[i][j].denoise_variance = 100; pd_config.config_port[i][j].burst_time = 5; pd_config.config_port[i][j].burst_thr = 200; pd_config.config_port[i][j].event_counter_h = 8000; pd_config.config_port[i][j].event_sec_h = 800; pd_config.config_port[i][j].event_counter_thr_h = 8000; pd_config.config_port[i][j].event_thr_h = 200; pd_config.config_port[i][j].event_counter_l = 8000; pd_config.config_port[i][j].event_sec_l = 800; pd_config.config_port[i][j].event_counter_thr_l = 8000; pd_config.config_port[i][j].event_thr_l = 200; pd_config.config_port[i][j].denoise_manual = 100; pd_config.config_port[i][j].denoise_auto = 40; pd_config.config_port[i][j].auto_noise_cnt = 1600; } } } int32_t _pd_main_init(void) { int32_t rv = 0; _pd_config_init_uhf(); pd_config.config.protocol_type = PD_PROTOCOL_LAND; pd_config.config.power_frequency = 500; pd_config.config.sync_mode = PD_SYNC_PT; pd_config.config.is_4G_enable = FALSE; snprintf(pd_config.config.APN, PD_4G_APN_LEN, "3gnet"); pd_config.config.trend_period = 900; pd_config.config.trend_storage = 10; pd_config.config.event_storage = 500; pd_config.config.heartbeat_period = 5; /* 注册配置保存函数 */ rv = cmd_config_node_config_register(CONFIG_PRI_PD, _pd_config_save); if (rv != E_NONE) { log_err(LOG_PD, "Command save register ERROR %d!", rv); return rv; } /* 注册端口节点. */ cmd_install_node(&pd_port_node, _pd_port_config_save); pd_port_node.prompt = XMALLOC(MTYPE_DAU, PD_PORT_PROMPT_LEN); pd_port_node.configs = array_init(PD_PORT_CMD_PRI_COUNT, MTYPE_DAU); cmd_install_element(ENABLE_NODE, &pd_port_adj_save_cmd); cmd_install_element(CONFIG_NODE, &pd_evnet_amount_cmd); cmd_install_element(CONFIG_NODE, &pd_trend_interval_cmd); cmd_install_element(CONFIG_NODE, &pd_trend_amount_cmd); cmd_install_element(CONFIG_NODE, &pd_heartbeat_interval_cmd); cmd_install_element(CONFIG_NODE, &pd_sync_mode_cmd); cmd_install_element(CONFIG_NODE, &pd_sync_fre_cmd); cmd_install_element(CONFIG_NODE, &pd_pps_mode_cmd); cmd_install_element(CONFIG_NODE, &pd_4G_enable_cmd); cmd_install_element(CONFIG_NODE, &pd_4G_APN_cmd); cmd_install_element(CONFIG_NODE, &pd_protocol_type_cmd); cmd_install_element(CONFIG_NODE, &pd_port_terminal_cmd); cmd_install_element(PORT_NODE, &pd_port_terminal_cmd); cmd_install_element(PORT_NODE, &pd_sensor_type_cmd); cmd_install_element(PORT_NODE, &pd_noise_type_cmd); cmd_install_element(PORT_NODE, &pd_noise_reduction_cmd); cmd_install_element(PORT_NODE, &pd_noise_reduction_auto_cmd); cmd_install_element(PORT_NODE, &pd_noise_reduction_cnt_cmd); cmd_install_element(PORT_NODE, &pd_noise_env_cmd); cmd_install_element(PORT_NODE, &pd_noise_variance_cmd); cmd_install_element(PORT_NODE, &pd_evnet_cnt_high_cmd); cmd_install_element(PORT_NODE, &pd_evnet_thr_high_cmd); cmd_install_element(PORT_NODE, &pd_evnet_cnt_low_cmd); cmd_install_element(PORT_NODE, &pd_evnet_thr_low_cmd); cmd_install_element(PORT_NODE, &pd_evnet_burst_cmd); cmd_install_element(COMMON_NODE, &show_prps_cmd); cmd_install_element(COMMON_NODE, &show_pd_cmd); cmd_install_element(COMMON_NODE, &show_running_port_cmd); cmd_install_element(COMMON_NODE, &show_running_current_cmd); return E_NONE; } int32_t _pd_main_init_after(void) { struct sockaddr_in addr; thread_param_t param = {0}; uint8_t i = 0; uint8_t j = 0; char cmd[256]; /* 初始化基本参数 */ for(i = 0; i < PD_DAU_SUM; i++) { for(j = 0; j < PD_DAU_PORT_SUM; j++) { pd_config.config_port[i][j].vport = dau_port_to_vport(i, j); } } if (pd_config.config.is_4G_enable) { param.arg = NULL; param.priority = 20; param.thread_name = "4G"; param.log_module = LOG_PD; create_thread(_pd_4G_handle, ¶m); } else { addr.sin_addr.s_addr = device_info.gw; snprintf(cmd, 256, "route add default gw %s", inet_ntoa(addr.sin_addr)); system(cmd); } return E_NONE; } /* Interface functions -------------------------------------------------------*/ /* description: 局放程序入口函数. param: return: */ int32_t pd_main(void) { int32_t rv = 0; rv |= _pd_main_init(); rv |= dau_handle_init(); rv |= csg_handle_init(); //rv |= net_handle_init(); //rv |= debug_handle_init(); return E_NONE; } int32_t pd_main_after(void) { int32_t rv = E_NONE; rv |= _pd_main_init_after(); rv |= dau_handle_init_after(); rv |= csg_handle_init_after(); //rv |= net_handle_init_after(); //rv |= debug_handle_init_after(); rv |= _pd_broadcast_init(); return rv; } int32_t pd_port_cmd_config_register(int32_t pri, pd_port_cmd_save_config_f *func) { cmd_node_t *node = &pd_port_node; /* 参数检查 */ if (pri >= PD_PORT_CMD_PRI_COUNT || !func) { return E_BAD_PARAM; } /* 加入列表 */ array_set(node->configs, pri, func, MTYPE_DAU); return 0; } /* config模式配置保存函数: vty -- 相应的终端 */ void pd_port_config_save_port(vty_t *vty, uint8_t unit, uint8_t port) { array_t *configs = pd_port_node.configs; pd_port_cmd_save_config_f *func = NULL; uint8_t i = 0; uint16_t field = 0; vty_out(vty, "interface port %d/%d%s", unit + 1, port + 1, VTY_NEWLINE); for(i = 0; i < array_active(configs); i++) { func = array_lookup(configs, i); if (!func) { continue; } func(vty, unit, port); } field = pd_config.config_port[unit][port].sensor_type; vty_out(vty, " sensor-type %s%s", pd_sen_type_str[field], VTY_NEWLINE); field = pd_config.config_port[unit][port].denoise_type; vty_out(vty, " noise-type %s%s", pd_noise_type_str[field], VTY_NEWLINE); vty_out(vty, " noise-reduction %d%s", pd_config.config_port[unit][port].denoise_auto, VTY_NEWLINE); vty_out(vty, " noise-env %d%s", pd_config.config_port[unit][port].denoise_manual, VTY_NEWLINE); vty_out(vty, " noise-variance %d%s", pd_config.config_port[unit][port].denoise_variance, VTY_NEWLINE); vty_out(vty, " noise-reduction-auto %s%s", pd_config.config_port[unit][port].is_auto_noise ? "enable" : "disable", VTY_NEWLINE); vty_out(vty, " noise-reduction-auto cnt %d%s", pd_config.config_port[unit][port].auto_noise_cnt, VTY_NEWLINE); vty_out(vty, " evnet-cnt-high %d sec %d%s", pd_config.config_port[unit][port].event_counter_h, pd_config.config_port[unit][port].event_sec_h, VTY_NEWLINE); vty_out(vty, " evnet-thr-high %d cnt %d%s", pd_config.config_port[unit][port].event_thr_h, pd_config.config_port[unit][port].event_counter_thr_h, VTY_NEWLINE); vty_out(vty, " evnet-cnt-low %d sec %d%s", pd_config.config_port[unit][port].event_counter_l, pd_config.config_port[unit][port].event_sec_l, VTY_NEWLINE); vty_out(vty, " evnet-thr-low %d cnt %d%s", pd_config.config_port[unit][port].event_thr_l, pd_config.config_port[unit][port].event_counter_thr_l, VTY_NEWLINE); vty_out(vty, " evnet-burst %d thr %d%s", pd_config.config_port[unit][port].burst_time, pd_config.config_port[unit][port].burst_thr, VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); } void pd_prps_show(void) { uint8_t unit = 0; uint8_t port = 0; pd_config_port_t *config = NULL; pd_config_real_t *real = NULL; printh("Concern:\r\n"); printh("UN PO CO RN NT MN FC AU NL NV\r\n"); for(unit = 0; unit < PD_DAU_SUM; unit++) { if (!dau[unit]) { continue; } for(port = 0; port < dau[unit]->port_num; port++) { config = &pd_config.config_port[unit][port]; real = &pd_config.config_real[unit][port]; printh("%-02d %-02d %-02d %-02d %-02d %-03d %-02d %-02d %-04d %-04d\r\n", unit, port, real->is_concern, real->denoise_correlation, real->denoise_type, real->denoise_manual, real->filter_cfg, config->is_auto_noise, dau[unit]->port_state[port].denoise_auto, dau[unit]->port_state[port].denoise_variance); } } } void pd_show(void) { printh("Connect: %s\r\n", csg.is_connect ? "yes" : "no"); printh("Synchronization: %s\r\n", pd_state.sync ? "valid" : "invalid"); printh("PT: %s\r\n", (pd_state.state & 0x2) ? "valid" : "invalid"); printh("PPS: %s\r\n", (pd_state.state & 0x4) ? "valid" : "invalid"); printh("PPS mode: %s\r\n", (pd_state.state & 0x8) ? "slave" : "master"); } #else int32_t PD_main(void) { return 0; } #endif /************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/