|
|
|
|
/******************************************************************************
|
|
|
|
|
* file lib/process/pd_csg.c
|
|
|
|
|
* author YuLiang
|
|
|
|
|
* version 1.0.0
|
|
|
|
|
* date 09-Jun-2025
|
|
|
|
|
* brief This file provides all the csg server operation functions.
|
|
|
|
|
*
|
|
|
|
|
******************************************************************************
|
|
|
|
|
* Attention
|
|
|
|
|
*
|
|
|
|
|
* <h2><center>© COPYRIGHT(c) 2021 LandPower</center></h2>
|
|
|
|
|
*
|
|
|
|
|
* 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 <sys/types.h>
|
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
|
#include <sys/msg.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <netpacket/packet.h>
|
|
|
|
|
#include <net/ethernet.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
#include <net/if.h>
|
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
|
#include <netinet/if_ether.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <sys/prctl.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <sys/statvfs.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
/* 用户代码头文件. */
|
|
|
|
|
#include "main.h"
|
|
|
|
|
#include "cmd.h"
|
|
|
|
|
#include "fifo.h"
|
|
|
|
|
#include "pd_main.h"
|
|
|
|
|
#include "pd_dau.h"
|
|
|
|
|
#include "pd_csg.h"
|
|
|
|
|
#include "pd_upgrade.h"
|
|
|
|
|
|
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
|
#define CSG_LOCK pthread_mutex_lock(&csg.mutex)
|
|
|
|
|
#define CSG_UNLOCK pthread_mutex_unlock(&csg.mutex)
|
|
|
|
|
#define MKDIR(dir) mkdir(dir, 0755)
|
|
|
|
|
|
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
|
csg_t csg;
|
|
|
|
|
extern int upg_state;
|
|
|
|
|
channel_t channel[8];
|
|
|
|
|
|
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
|
extern void _csg_server_set(int32_t ip, uint16_t port);
|
|
|
|
|
extern void _csg_show();
|
|
|
|
|
extern int _csg_server_mac_set(char* input);
|
|
|
|
|
extern void doy_to_date(struct tm *tmpr, uint16_t btime[]);
|
|
|
|
|
|
|
|
|
|
/* Internal functions --------------------------------------------------------*/
|
|
|
|
|
CMD(csg_server_set,
|
|
|
|
|
csg_server_set_cmd,
|
|
|
|
|
"csg server A.B.C.D <1-65535>",
|
|
|
|
|
"Csg\n"
|
|
|
|
|
"Server\n"
|
|
|
|
|
"IPv4 address\n"
|
|
|
|
|
"UDP port\n")
|
|
|
|
|
{
|
|
|
|
|
_csg_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10));
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 显示模块状态 */
|
|
|
|
|
CMD(csg_show,
|
|
|
|
|
csg_show_cmd,
|
|
|
|
|
"show csg",
|
|
|
|
|
"Show\n"
|
|
|
|
|
"CSG\n")
|
|
|
|
|
{
|
|
|
|
|
_csg_show();
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
CMD(csg_server_mac_set,
|
|
|
|
|
csg_server_mac_set_cmd,
|
|
|
|
|
"csg serverMac A-B-C-D-E-F",
|
|
|
|
|
"Csg\n"
|
|
|
|
|
"Server mac\n"
|
|
|
|
|
"mac address\n")
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
ret = _csg_server_mac_set((char*)argv[0]);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int _csg_get_connection_status()
|
|
|
|
|
{
|
|
|
|
|
int status;
|
|
|
|
|
pthread_mutex_lock(&csg.lock);
|
|
|
|
|
status = csg.is_connect;
|
|
|
|
|
pthread_mutex_unlock(&csg.lock);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _csg_show()
|
|
|
|
|
{
|
|
|
|
|
printh("CSG connect: %s \n", (csg.is_connect == 1)? "OK" : "FAIL");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 设置服务器地址. */
|
|
|
|
|
void _csg_server_set(int32_t ip, uint16_t port)
|
|
|
|
|
{
|
|
|
|
|
/* 比较配置 */
|
|
|
|
|
if (csg.server_ip != ip
|
|
|
|
|
|| csg.server_port != port)
|
|
|
|
|
{
|
|
|
|
|
csg.server_ip = ip;
|
|
|
|
|
csg.server_port = port;
|
|
|
|
|
|
|
|
|
|
/* 发送数据. */
|
|
|
|
|
bzero(&csg.server, sizeof(csg.server));
|
|
|
|
|
csg.server.sin_family = AF_INET;
|
|
|
|
|
csg.server.sin_addr.s_addr = csg.server_ip;
|
|
|
|
|
csg.server.sin_port = htons(csg.server_port);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 设置服务器的 MAC 地址. */
|
|
|
|
|
int _csg_server_mac_set(char* input)
|
|
|
|
|
{
|
|
|
|
|
uint8_t mac_dest[6];
|
|
|
|
|
char *endptr;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
// 检查参数是否有效
|
|
|
|
|
if (!input) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: No MAC address provided");
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制输入字符串以便安全操作
|
|
|
|
|
char mac_str[18]; // 最大长度为 17(12 位十六进制 + 5 个连字符)+ 1(终止符)
|
|
|
|
|
if (strlen(input) >= sizeof(mac_str)) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: MAC address string too long");
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
strncpy(mac_str, input, sizeof(mac_str) - 1);
|
|
|
|
|
mac_str[sizeof(mac_str) - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
// 分割并解析 MAC 地址
|
|
|
|
|
char *token = strtok(mac_str, "-");
|
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
|
if (!token) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: Invalid MAC address format, missing segment %d", i + 1);
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重置 errno
|
|
|
|
|
errno = 0;
|
|
|
|
|
// 解析十六进制数
|
|
|
|
|
long value = strtol(token, &endptr, 16);
|
|
|
|
|
|
|
|
|
|
// 检查是否解析成功
|
|
|
|
|
if (endptr == token || *endptr != '\0') {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: Invalid hex value in segment %d: %s", i + 1, token);
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否在 uint8_t 范围内
|
|
|
|
|
if (value < 0 || value > 0xFF || errno == ERANGE) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: Value out of range in segment %d: %ld", i + 1, value);
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 存储到 mac_dest
|
|
|
|
|
mac_dest[i] = (uint8_t)value;
|
|
|
|
|
|
|
|
|
|
// 获取下一个 token
|
|
|
|
|
token = strtok(NULL, "-");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否有额外的 token
|
|
|
|
|
if (strtok(NULL, "-") != NULL) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR: Too many segments in MAC address");
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打印结果(用于调试)
|
|
|
|
|
printf("server mac address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
|
|
|
|
mac_dest[0], mac_dest[1], mac_dest[2],
|
|
|
|
|
mac_dest[3], mac_dest[4], mac_dest[5]);
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 配置保存函数. */
|
|
|
|
|
int _csg_config_save(vty_t* vty)
|
|
|
|
|
{
|
|
|
|
|
int16_t i = 0;
|
|
|
|
|
struct in_addr addr;
|
|
|
|
|
|
|
|
|
|
addr.s_addr = csg.server_ip;
|
|
|
|
|
vty_out(vty, "csg server %s %d%s", inet_ntoa(addr), csg.server_port, VTY_NEWLINE);
|
|
|
|
|
i++;
|
|
|
|
|
vty_out(vty, "csg serverMac %02x-%02x-%02x-%02x-%02x-%02x%s", csg.dest_mac[0], csg.dest_mac[1], csg.dest_mac[2], csg.dest_mac[3], csg.dest_mac[4], csg.dest_mac[5], VTY_NEWLINE);
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 校验收到包的包头, 长度, 校验码. */
|
|
|
|
|
int32_t _csg_pkt_check(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
//unsigned int crc = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
|
|
|
|
|
/* 对主次设备号进行识别, 次设备号可以是广播. */
|
|
|
|
|
if (head->dev_id != device_info.dev_id
|
|
|
|
|
|| head->dev_type_m != device_info.type_m
|
|
|
|
|
|| head->dev_type_s != device_info.type_s)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Device type not match:0x%x(0x%x) %d-%d(%d-%d)\r\n", device_info.dev_id, head->dev_id,
|
|
|
|
|
device_info.type_m, device_info.type_s, head->dev_type_m, head->dev_type_s);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (head->len > 2048)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "@2 receive packet len(%d) is out of range\r\n", head->len);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 包头填充. */
|
|
|
|
|
void _csg_head_init(char *buf, uint16_t len, uint8_t cmdType, uint8_t cmd)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)buf;
|
|
|
|
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
|
|
head->len = len;
|
|
|
|
|
head->dev_type_m = device_info.type_m;
|
|
|
|
|
head->dev_type_s= device_info.type_s;
|
|
|
|
|
head->dev_id = device_info.dev_id;
|
|
|
|
|
head->cmd_type = cmdType;
|
|
|
|
|
head->cmd = cmd;
|
|
|
|
|
head->version = 1;
|
|
|
|
|
head->pkt_id = csg.pkt_index++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 数据发送 */
|
|
|
|
|
void _csg_send_data(uint8_t cmd_type, uint8_t cmd, char *pkt, int32_t len)
|
|
|
|
|
{
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
|
|
_csg_head_init(pkt, sizeof(csg_pkt_head_t) + len, cmd_type, cmd);
|
|
|
|
|
|
|
|
|
|
rv = sendto(csg.skfd, pkt, head->len, 0, (struct sockaddr*)&csg.server, sizeof(csg.server));
|
|
|
|
|
if (rv < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 与后台连接断开 */
|
|
|
|
|
void _csg_disconnect_set(const char *message)
|
|
|
|
|
{
|
|
|
|
|
if (csg.is_connect)
|
|
|
|
|
{
|
|
|
|
|
csg.is_connect = FALSE;
|
|
|
|
|
log_warn(LOG_CSG, "[%s]CSG Connection lost!!!\r\n", message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 主动连接请求. */
|
|
|
|
|
int32_t _csg_connect_send(void)
|
|
|
|
|
{
|
|
|
|
|
char *pkt = csg.buf_send;
|
|
|
|
|
csg_contact_t *pinfo = (csg_contact_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
|
|
|
|
|
pinfo->type_m = device_info.type_m;
|
|
|
|
|
pinfo->type_s = device_info.type_s;
|
|
|
|
|
pinfo->dev_id = device_info.dev_id;
|
|
|
|
|
strncpy(pinfo->hostname, host.name, sizeof(pinfo->hostname)-1);
|
|
|
|
|
pinfo->factory_date = device_info.factory_date;
|
|
|
|
|
pinfo->deployment_date = device_info.deployment_date;
|
|
|
|
|
strncpy((char *)pinfo->app_version, host.version, sizeof(pinfo->app_version)-1);
|
|
|
|
|
strncpy((char *)pinfo->app_compile_time, host.compile, sizeof(pinfo->app_compile_time)-1);
|
|
|
|
|
//strncpy((char *)pinfo->hardware_version, host.hardversion, 31);
|
|
|
|
|
//strncpy((char *)pinfo->FPGA_version, host.FPGAversion, 31);
|
|
|
|
|
strncpy((char *)pinfo->hardware_version, "RFSOC_V1.0", 31);
|
|
|
|
|
strncpy((char *)pinfo->FPGA_version, "20250730", 31);
|
|
|
|
|
pinfo->ip = device_info.ip;
|
|
|
|
|
pinfo->mask = device_info.mask;
|
|
|
|
|
pinfo->gw = device_info.gw;
|
|
|
|
|
memcpy(pinfo->mac, device_info.mac, sizeof(pinfo->mac));
|
|
|
|
|
pinfo->server_port = csg.server_port;
|
|
|
|
|
pinfo->server_ipv4 = csg.server_ip;
|
|
|
|
|
|
|
|
|
|
memset(pinfo->port, 0, sizeof(pinfo->port));
|
|
|
|
|
memset(pinfo->port, 0, sizeof(pinfo->port_type));
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
pinfo->port[i] = i + 1;
|
|
|
|
|
pinfo->port_type[i] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_REPLY, CSG_C_CONTACT, pkt, sizeof(csg_contact_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 心跳包. */
|
|
|
|
|
int32_t _csg_heartbeat_send(void)
|
|
|
|
|
{
|
|
|
|
|
char *pkt = csg.buf_send;
|
|
|
|
|
csg_heartbeat_t *pinfo = (csg_heartbeat_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
uint16_t i = 0;
|
|
|
|
|
|
|
|
|
|
pinfo->power_freq = 50; //电网频率默认为50Hz,后续获取实际值
|
|
|
|
|
pinfo->pt_sync_mode = 0;
|
|
|
|
|
for(i = 0; i < PD_DAU_PORT_SUM; i++)
|
|
|
|
|
{
|
|
|
|
|
pinfo->dau_state[i] = pd_config.config_port[0][i].is_enbale;
|
|
|
|
|
}
|
|
|
|
|
pinfo->dau_port_nums = PD_DAU_PORT_SUM;
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_REPLY, CSG_C_HEARTBEAT, pkt, sizeof(csg_heartbeat_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t _csg_trend_send(pd_trend_port_t *ptrend)
|
|
|
|
|
{
|
|
|
|
|
char *pkt = csg.buf_send;
|
|
|
|
|
csg_trend_t *pinfo = (csg_trend_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
|
|
|
|
|
pinfo->port = ptrend->port + 1;
|
|
|
|
|
pinfo->century_second = ptrend->century_second;
|
|
|
|
|
pinfo->pulse_num = ptrend->pulse_num;
|
|
|
|
|
pinfo->pulse_max = ptrend->pulse_max;
|
|
|
|
|
pinfo->pulse_avg = ptrend->pulse_avg;
|
|
|
|
|
pinfo->noise = ptrend->noise;
|
|
|
|
|
pinfo->phase = ptrend->phase;
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_TREND, pkt, sizeof(csg_trend_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if CSG_TYPE_SELF
|
|
|
|
|
/* 主动提交特征量数据 */
|
|
|
|
|
int32_t _csg_real_eigen_send(channel_t * ch, pd_original_port_t *real)
|
|
|
|
|
{
|
|
|
|
|
char *pkt = NULL;
|
|
|
|
|
uint8_t port_idx;
|
|
|
|
|
uint32_t nums;
|
|
|
|
|
uint32_t len;
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
char *data_point = NULL;
|
|
|
|
|
int fd;
|
|
|
|
|
if (!ch)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
port_idx = ch->port;
|
|
|
|
|
pkt = ch->pbuf;
|
|
|
|
|
fd = ch->skfd;
|
|
|
|
|
|
|
|
|
|
csg_pkt_head_t *pkt_head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
pd_original_port_t *data = real;
|
|
|
|
|
int sum = 0;
|
|
|
|
|
|
|
|
|
|
if (!csg.real_cfg[port_idx].is_concern)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(data->data_vaild == FALSE)
|
|
|
|
|
{
|
|
|
|
|
nums = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nums = data->frame_numbers;
|
|
|
|
|
}
|
|
|
|
|
if(nums > CSG_SEND_SELF_WAVE_NUM)
|
|
|
|
|
{
|
|
|
|
|
nums = CSG_SEND_SELF_WAVE_NUM;
|
|
|
|
|
}
|
|
|
|
|
ch->times++;
|
|
|
|
|
|
|
|
|
|
ch->eigen.vport = pd_config.config_port[0][port_idx].vport;;
|
|
|
|
|
ch->eigen.channel_type = pd_config.config_port[0][port_idx].type;
|
|
|
|
|
ch->eigen.unit = 2;
|
|
|
|
|
|
|
|
|
|
ch->eigen.power_frequency = _pd_get_frequency();
|
|
|
|
|
ch->eigen.discharge_nums += data->total_pulse_nums;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < nums; i++)
|
|
|
|
|
{
|
|
|
|
|
data_point = (char*)(data->original_pointer) + (i * data->single_frame_length * sizeof(int16_t));
|
|
|
|
|
if (data_point == NULL)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Original pointer is NULL for port %d!\r\n", port_idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wave_additional_data_t *header = _dau_get_wave_addtion_data(data_point, data->single_frame_length);
|
|
|
|
|
if (!header)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "addion data is NULL\r\n");
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ch->noise_sum += abs(header->noise);
|
|
|
|
|
if (header->max > ch->eigen.pulse_peak)
|
|
|
|
|
{
|
|
|
|
|
ch->eigen.pulse_peak = header->max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ch->times == 1)
|
|
|
|
|
{
|
|
|
|
|
ch->eigen.first_sec = header->epoch_sec;
|
|
|
|
|
ch->eigen.first_ns = header->nano_sec;
|
|
|
|
|
}
|
|
|
|
|
else if (ch->times == 500)
|
|
|
|
|
{
|
|
|
|
|
ch->eigen.last_sec = header->epoch_sec;
|
|
|
|
|
ch->eigen.last_ns = header->nano_sec;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ch->wave[ch->inums+i].amplitude = header->max;
|
|
|
|
|
ch->wave[ch->inums+i].period = ch->cycle++;
|
|
|
|
|
if (ch->cycle > 50)
|
|
|
|
|
ch->cycle = 1;
|
|
|
|
|
ch->wave[ch->inums+i].phase = header->phase;
|
|
|
|
|
}
|
|
|
|
|
ch->inums += nums;
|
|
|
|
|
|
|
|
|
|
if (ch->times < 500)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ch->eigen.frame_num = ch->inums;
|
|
|
|
|
ch->eigen.noise = ch->noise_sum / ch->inums;
|
|
|
|
|
|
|
|
|
|
int total_len = sizeof(csg_pkt_head_t) + sizeof(csg_eigen_value_t) +
|
|
|
|
|
sizeof(prps_t) * ch->inums;
|
|
|
|
|
|
|
|
|
|
sum = total_len / CSG_ADBUF_MAX_LEN;
|
|
|
|
|
if (total_len % CSG_ADBUF_MAX_LEN)
|
|
|
|
|
{
|
|
|
|
|
sum += 1;
|
|
|
|
|
}
|
|
|
|
|
ch->eigen.pkt_sum = sum;
|
|
|
|
|
DBG(DBG_M_PD_CSG_EIGEN,"vport=%d pkt_sum=%d noise_sum=%d noise=%d pulse_peak=%d frame_num=%d\r\n",
|
|
|
|
|
ch->eigen.vport, ch->eigen.pkt_sum, ch->noise_sum, ch->eigen.noise, ch->eigen.pulse_peak, ch->eigen.frame_num);
|
|
|
|
|
ch->times = 0;
|
|
|
|
|
ch->inums = 0;
|
|
|
|
|
ch->noise_sum = 0;
|
|
|
|
|
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ch->eigen, sizeof(csg_eigen_value_t));
|
|
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
|
while (index < sum)
|
|
|
|
|
{
|
|
|
|
|
ch->eigen.pkt_index = index;
|
|
|
|
|
len = total_len > CSG_ADBUF_MAX_LEN ? CSG_ADBUF_MAX_LEN : total_len;
|
|
|
|
|
_csg_head_init(pkt, sizeof(csg_pkt_head_t) + sizeof(csg_eigen_value_t) + len, CSG_PRV_REPLY, CSG_PRV_REAL_EIGEN);
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t) + sizeof(csg_eigen_value_t), (char *)ch->wave, len);
|
|
|
|
|
|
|
|
|
|
total_len -= len;
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rv = sendto(fd, pkt, pkt_head->len, 0, (struct sockaddr*)&csg.server, sizeof(csg.server));
|
|
|
|
|
if (rv < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
usleep(100);
|
|
|
|
|
}
|
|
|
|
|
memset(&ch->eigen, 0, sizeof(csg_eigen_value_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 主动提交实时波形 */
|
|
|
|
|
int32_t _csg_real_image_send(channel_t * ch, pd_original_port_t *real)
|
|
|
|
|
{
|
|
|
|
|
char *data_point = NULL;
|
|
|
|
|
char *pkt = NULL;
|
|
|
|
|
char *pdata = NULL;
|
|
|
|
|
uint8_t port_idx;
|
|
|
|
|
uint32_t nums;
|
|
|
|
|
uint32_t len;
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
int i;
|
|
|
|
|
int fd;
|
|
|
|
|
if (!ch)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
port_idx = ch->port;
|
|
|
|
|
pkt = ch->pbuf;
|
|
|
|
|
fd = ch->skfd;
|
|
|
|
|
|
|
|
|
|
csg_pkt_head_t *pkt_head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_real_image_t *image_head = NULL;
|
|
|
|
|
pd_original_port_t *data = real;
|
|
|
|
|
|
|
|
|
|
if(data->data_vaild == FALSE)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 封装帧报文头 */
|
|
|
|
|
len = DEFAULT_SEND_WAVE_POINTS * sizeof(int16_t);
|
|
|
|
|
_csg_head_init(pkt, sizeof(csg_pkt_head_t) + sizeof(csg_real_image_t) + len, CSG_PRV_REPLY, CSG_PRV_REAL_WAVE);
|
|
|
|
|
|
|
|
|
|
/* 波形数据报文头 */
|
|
|
|
|
pdata = pkt + sizeof(csg_pkt_head_t);
|
|
|
|
|
image_head = (csg_real_image_t*)pdata;
|
|
|
|
|
image_head->channel_id = pd_config.config_port[0][port_idx].vport;
|
|
|
|
|
image_head->channel_type = pd_config.config_port[0][port_idx].type;
|
|
|
|
|
image_head->unit = 2;
|
|
|
|
|
image_head->sample_rate = DEFAULT_SAMPLE_FREQ_MHZ;
|
|
|
|
|
image_head->record_points = pd_config.config.trigger_sample_nums; //发送10000个点
|
|
|
|
|
image_head->pre_trigger = (pd_config.config.trig_location * 100)>>4;
|
|
|
|
|
image_head->trigger_level = pd_config.config.trig_threshold;
|
|
|
|
|
|
|
|
|
|
image_head->century_second = 0;
|
|
|
|
|
image_head->nanosecond = 0;
|
|
|
|
|
image_head->frequency = _pd_get_frequency();
|
|
|
|
|
image_head->sampling_time = 2;
|
|
|
|
|
|
|
|
|
|
nums = data->frame_numbers;
|
|
|
|
|
if(nums > CSG_SEND_SELF_WAVE_NUM)
|
|
|
|
|
{
|
|
|
|
|
nums = CSG_SEND_SELF_WAVE_NUM;
|
|
|
|
|
}
|
|
|
|
|
for(i = 0; i < nums; i++)
|
|
|
|
|
{
|
|
|
|
|
if(csg.new_data_flag[port_idx] == FALSE)
|
|
|
|
|
{
|
|
|
|
|
// 发送波形数据
|
|
|
|
|
data_point = (char*)(data->original_pointer) + (i * data->single_frame_length * sizeof(int16_t));
|
|
|
|
|
if (data_point == NULL)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Original pointer is NULL for port %d!\r\n", port_idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wave_additional_data_t *header = _dau_get_wave_addtion_data(data_point, data->single_frame_length);
|
|
|
|
|
if (!header)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "addion data is NULL\r\n");
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
image_head->phase = header->phase;
|
|
|
|
|
image_head->pulse_peak = header->max;
|
|
|
|
|
image_head->cycle_count = (header->pt_frame_num % 50) + 1;
|
|
|
|
|
image_head->noise = header->noise;
|
|
|
|
|
image_head->century_second = header->epoch_sec;
|
|
|
|
|
image_head->nanosecond = header->nano_sec;
|
|
|
|
|
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t) + sizeof(csg_real_image_t), data_point, image_head->record_points*sizeof(int16_t));
|
|
|
|
|
rv = sendto(fd, pkt, pkt_head->len, 0, (struct sockaddr*)&csg.server, sizeof(csg.server));
|
|
|
|
|
if (rv < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
usleep(50);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(csg.new_data_flag[port_idx] == TRUE)
|
|
|
|
|
{
|
|
|
|
|
csg.new_data_flag[port_idx] = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
#elif CSG_TYPE_NANRUI
|
|
|
|
|
/* 主动提交特征量数据 */
|
|
|
|
|
int32_t _csg_real_eigen_send(int fd, char buf[], uint8_t port, pd_original_port_t *real, struct sockaddr_ll *sa, uint8_t *dest_mac)
|
|
|
|
|
{
|
|
|
|
|
static uint8_t pkt_id[PD_DAU_PORT_SUM] = {0,0,0,0,0,0,0,0}; // 包ID
|
|
|
|
|
char *pkg_point = NULL;
|
|
|
|
|
char *pkt = buf;
|
|
|
|
|
char *pdata = NULL;
|
|
|
|
|
wave_additional_data_t* wave_additional_data = NULL;
|
|
|
|
|
uint8_t port_idx = port;
|
|
|
|
|
uint32_t nums;
|
|
|
|
|
uint32_t len;
|
|
|
|
|
uint32_t send_frame_len = 0; //单帧传输长度
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
int16_t temp_max_buf[1] = {1000};
|
|
|
|
|
uint16_t temp_phase_buf[1] = {100};
|
|
|
|
|
uint16_t time_buf[5];
|
|
|
|
|
struct tm tptr = {0};
|
|
|
|
|
time_t timestamp;
|
|
|
|
|
|
|
|
|
|
csg_pkt_nanrui_head_t *pkt_head = (csg_pkt_nanrui_head_t *)pkt;
|
|
|
|
|
pd_original_port_t *data = real;
|
|
|
|
|
csg_eigen_value_t *eigen_head = NULL;
|
|
|
|
|
|
|
|
|
|
if(data->data_vaild == FALSE)
|
|
|
|
|
{
|
|
|
|
|
nums = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nums = data->frame_numbers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
len = nums * 4;
|
|
|
|
|
/* 封装帧报文头 */
|
|
|
|
|
memcpy(pkt_head->src_mac, device_info.mac, 6);
|
|
|
|
|
memcpy(pkt_head->dest_mac, dest_mac, 6);
|
|
|
|
|
pkt_head->reserve = 0;
|
|
|
|
|
pkt_head->port_nums = 1; // 发送数据端口数量
|
|
|
|
|
pkt_head->cmd_type[0] = 0xf0;
|
|
|
|
|
pkt_head->cmd_type[1] = 0x10;
|
|
|
|
|
|
|
|
|
|
pkt_id[port_idx]++;
|
|
|
|
|
if(pkt_id[port_idx] > 127)
|
|
|
|
|
{
|
|
|
|
|
pkt_id[port_idx] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 特征量数据报文头 */
|
|
|
|
|
pdata = pkt + sizeof(csg_pkt_nanrui_head_t);
|
|
|
|
|
eigen_head = (csg_eigen_value_t*)pdata;
|
|
|
|
|
eigen_head->vport = pd_config.config_port[0][port_idx].send_port_num;
|
|
|
|
|
eigen_head->count = pkt_id[port_idx];
|
|
|
|
|
eigen_head->port_type = pd_config.config_port[0][port_idx].type;
|
|
|
|
|
eigen_head->unit = 2;
|
|
|
|
|
eigen_head->discharge_nums = nums;
|
|
|
|
|
eigen_head->ground_noise = 0;
|
|
|
|
|
eigen_head->century_second = 0;
|
|
|
|
|
eigen_head->nano_second = 0;
|
|
|
|
|
|
|
|
|
|
//数据
|
|
|
|
|
pkg_point = pkt + sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_eigen_value_t);
|
|
|
|
|
for(i=0; i<nums; i++)
|
|
|
|
|
{
|
|
|
|
|
wave_additional_data = (wave_additional_data_t*)(data->original_pointer + ((i+1)*data->single_frame_length - ALL_ADDITIONAL_LEN)* sizeof(int16_t));
|
|
|
|
|
temp_max_buf[0] = wave_additional_data->max;
|
|
|
|
|
temp_phase_buf[0] = wave_additional_data->phase * 100;
|
|
|
|
|
if(i==0)
|
|
|
|
|
{
|
|
|
|
|
time_buf[0] = wave_additional_data->year;
|
|
|
|
|
time_buf[1] = wave_additional_data->day;
|
|
|
|
|
time_buf[2] = wave_additional_data->hour;
|
|
|
|
|
time_buf[3] = wave_additional_data->minute;
|
|
|
|
|
time_buf[4] = wave_additional_data->sec;
|
|
|
|
|
doy_to_date(&tptr, time_buf);
|
|
|
|
|
// 转换为 time_t
|
|
|
|
|
timestamp = mktime(&tptr);
|
|
|
|
|
eigen_head->ground_noise = wave_additional_data->noise * 10;
|
|
|
|
|
eigen_head->century_second = timestamp;
|
|
|
|
|
eigen_head->nano_second = wave_additional_data->nano_sec;
|
|
|
|
|
// printf("noise:%d\n",eigen_head->ground_noise);
|
|
|
|
|
}
|
|
|
|
|
// printf("phase:%d\n",temp_buf[1]);
|
|
|
|
|
memcpy(pkg_point, (char *)temp_max_buf, 2);
|
|
|
|
|
memcpy(pkg_point+2, (char *)temp_phase_buf, 2);
|
|
|
|
|
if(i < nums-1)
|
|
|
|
|
pkg_point = pkg_point + 4;
|
|
|
|
|
}
|
|
|
|
|
send_frame_len = sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_eigen_value_t) + len;
|
|
|
|
|
rv = sendto(fd, pkt, send_frame_len, 0, (const struct sockaddr *)sa, sizeof(struct sockaddr_ll));
|
|
|
|
|
if (rv < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
usleep(100);
|
|
|
|
|
rv = sendto(fd, pkt, send_frame_len, 0, (const struct sockaddr *)sa, sizeof(struct sockaddr_ll));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 单帧波形数据发送.
|
|
|
|
|
int _csg_wave_signel_frame_send(int fd, char buf[], char* data_addr, pd_original_port_t *real, uint8_t port, struct sockaddr_ll *sa_temp)
|
|
|
|
|
{
|
|
|
|
|
static uint8_t pkt_id[PD_DAU_PORT_SUM] = {0,0,0,0,0,0,0,0}; // 包ID
|
|
|
|
|
csg_real_image_t *image_head = NULL;
|
|
|
|
|
pd_original_port_t *data = real;
|
|
|
|
|
char *pdata = NULL;
|
|
|
|
|
wave_additional_data_t* wave_additional_data = NULL;
|
|
|
|
|
char *pkt = buf;
|
|
|
|
|
uint32_t send_frame_len = 0; //单帧传输长度
|
|
|
|
|
uint32_t len = 0; //临时变量
|
|
|
|
|
uint16_t i = 0;
|
|
|
|
|
uint16_t send_nums = 0; //波形分帧传输次数
|
|
|
|
|
uint16_t send_remainder = 0; //波形分帧传输剩余点数
|
|
|
|
|
int ret = E_NONE;
|
|
|
|
|
char *data_addr_point = NULL;
|
|
|
|
|
uint16_t time_buf[5];
|
|
|
|
|
struct tm tptr = {0};
|
|
|
|
|
time_t timestamp;
|
|
|
|
|
|
|
|
|
|
/* 波形数据报文头 */
|
|
|
|
|
pdata = (char *)(pkt + sizeof(csg_pkt_nanrui_head_t));
|
|
|
|
|
image_head = (csg_real_image_t*)pdata;
|
|
|
|
|
image_head->vport = pd_config.config_port[0][port].send_port_num;
|
|
|
|
|
image_head->port_type = pd_config.config_port[0][port].type;
|
|
|
|
|
image_head->unit = 2;
|
|
|
|
|
image_head->sample_freq_val = DEFAULT_SAMPLE_FREQ_MHZ;
|
|
|
|
|
|
|
|
|
|
wave_additional_data = (wave_additional_data_t*)(data_addr + (data->single_frame_length - ALL_ADDITIONAL_LEN)* sizeof(int16_t));
|
|
|
|
|
time_buf[0] = wave_additional_data->year;
|
|
|
|
|
time_buf[1] = wave_additional_data->day;
|
|
|
|
|
time_buf[2] = wave_additional_data->hour;
|
|
|
|
|
time_buf[3] = wave_additional_data->minute;
|
|
|
|
|
time_buf[4] = wave_additional_data->sec;
|
|
|
|
|
doy_to_date(&tptr, time_buf);
|
|
|
|
|
// 转换为 time_t
|
|
|
|
|
timestamp = mktime(&tptr);
|
|
|
|
|
image_head->century_second = timestamp;
|
|
|
|
|
image_head->nano_second = wave_additional_data->nano_sec;
|
|
|
|
|
|
|
|
|
|
/* 计算波形传输次数 */
|
|
|
|
|
send_nums = DEFAULT_SEND_WAVE_POINTS / CSG_MAX_POINTS;
|
|
|
|
|
send_remainder = DEFAULT_SEND_WAVE_POINTS % CSG_MAX_POINTS;
|
|
|
|
|
|
|
|
|
|
if(send_nums >= 1)
|
|
|
|
|
{
|
|
|
|
|
image_head->sample_nums = CSG_MAX_POINTS;
|
|
|
|
|
len = CSG_MAX_POINTS * sizeof(int16_t);
|
|
|
|
|
send_frame_len = sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_real_image_t) + len;
|
|
|
|
|
for(i=0; i<send_nums; i++)
|
|
|
|
|
{
|
|
|
|
|
pkt_id[port]++;
|
|
|
|
|
if(pkt_id[port] > 127)
|
|
|
|
|
{
|
|
|
|
|
pkt_id[port] = 0;
|
|
|
|
|
}
|
|
|
|
|
image_head->count = pkt_id[port] + 0x80;
|
|
|
|
|
data_addr_point = data_addr + i*CSG_MAX_POINTS*sizeof(int16_t);
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_real_image_t), (char *)data_addr_point, len);
|
|
|
|
|
if (sendto(fd, pkt, send_frame_len, 0, (const struct sockaddr *)sa_temp, sizeof(struct sockaddr_ll)) < 0)
|
|
|
|
|
{
|
|
|
|
|
ret = E_ERROR;
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(send_remainder != 0)
|
|
|
|
|
{
|
|
|
|
|
data_addr_point = data_addr + i*CSG_MAX_POINTS*sizeof(int16_t);
|
|
|
|
|
image_head->sample_nums = send_remainder;
|
|
|
|
|
len = send_remainder * sizeof(int16_t);
|
|
|
|
|
send_frame_len = sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_real_image_t) + len;
|
|
|
|
|
pkt_id[port]++;
|
|
|
|
|
if(pkt_id[port] > 127)
|
|
|
|
|
{
|
|
|
|
|
pkt_id[port] = 0;
|
|
|
|
|
}
|
|
|
|
|
image_head->count = pkt_id[port];
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_nanrui_head_t) + sizeof(csg_real_image_t), (char *)data_addr_point, len);
|
|
|
|
|
if (sendto(fd, pkt, send_frame_len, 0, (const struct sockaddr *)sa_temp, sizeof(struct sockaddr_ll)) < 0)
|
|
|
|
|
{
|
|
|
|
|
ret = E_ERROR;
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 主动提交实时波形*/
|
|
|
|
|
int32_t _csg_real_image_send(int fd, char buf[], uint8_t port, pd_original_port_t *real, struct sockaddr_ll *sa, uint8_t *dest_mac)
|
|
|
|
|
{
|
|
|
|
|
char *pkt = buf;
|
|
|
|
|
char *data_point = NULL;
|
|
|
|
|
uint8_t port_idx = port;
|
|
|
|
|
uint32_t nums;
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
|
|
|
|
csg_pkt_nanrui_head_t *pkt_head = (csg_pkt_nanrui_head_t *)pkt;
|
|
|
|
|
pd_original_port_t *data = real;
|
|
|
|
|
|
|
|
|
|
if(data->data_vaild == FALSE)
|
|
|
|
|
{
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 封装帧报文头 */
|
|
|
|
|
memcpy(pkt_head->src_mac, device_info.mac, 6);
|
|
|
|
|
memcpy(pkt_head->dest_mac, dest_mac, 6);
|
|
|
|
|
pkt_head->reserve = 0;
|
|
|
|
|
pkt_head->port_nums = 1; // 发送数据端口数量
|
|
|
|
|
pkt_head->cmd_type[0] = 0xf0;
|
|
|
|
|
pkt_head->cmd_type[1] = 0x11;
|
|
|
|
|
|
|
|
|
|
nums = data->frame_numbers;
|
|
|
|
|
if(nums > CSG_SEND_NR_WAVE_NUM)
|
|
|
|
|
{
|
|
|
|
|
nums = CSG_SEND_NR_WAVE_NUM;
|
|
|
|
|
}
|
|
|
|
|
for(i = 0; i < nums; i++)
|
|
|
|
|
{
|
|
|
|
|
if(csg.new_data_flag[port_idx] == FALSE)
|
|
|
|
|
{
|
|
|
|
|
// 发送波形数据
|
|
|
|
|
data_point = (char*)(data->original_pointer) + (i * data->single_frame_length * sizeof(int16_t));
|
|
|
|
|
if (data_point == NULL)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Original pointer is NULL for port %d!\r\n", port_idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
rv = _csg_wave_signel_frame_send(fd, pkt, data_point, data, port_idx, sa);
|
|
|
|
|
if (rv < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Send wave failed\r\n");
|
|
|
|
|
usleep(50);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(csg.new_data_flag[port_idx] == TRUE)
|
|
|
|
|
{
|
|
|
|
|
csg.new_data_flag[port_idx] = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void _csg_connect_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
uint32_t server_time = *(uint32_t*)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
|
|
|
|
|
csg.is_connect = TRUE;
|
|
|
|
|
csg.heartbeat = 0;
|
|
|
|
|
|
|
|
|
|
// printf("server_time:%d now:%ld\n", server_time, time(NULL));
|
|
|
|
|
if (abs(server_time - time(NULL)) > 3)
|
|
|
|
|
{
|
|
|
|
|
//server_time += 8*3600;
|
|
|
|
|
time_set(server_time); //北京时间
|
|
|
|
|
_dau_set_time(server_time);
|
|
|
|
|
}
|
|
|
|
|
log_warn(LOG_CSG, "CSG connection OK!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 解析心跳报文. */
|
|
|
|
|
void _csg_heartbeat_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg.heartbeat = 0;
|
|
|
|
|
uint32_t server_time = *(uint32_t*)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
|
|
|
|
|
// printf("server_time:%d now:%ld\n", server_time, time(NULL));
|
|
|
|
|
if (abs(server_time - time(NULL)) > 3)
|
|
|
|
|
{
|
|
|
|
|
//server_time += 8*3600;
|
|
|
|
|
time_set(server_time); //北京时间
|
|
|
|
|
_dau_set_time(server_time);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 设备重启报文. */
|
|
|
|
|
void _csg_reboot_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
sleep(3);
|
|
|
|
|
reboot_system(LOG_CSG, REBOOT_REMOTE_RESET);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 厂家参数设置报文处理.
|
|
|
|
|
说明: 调用本接口会导致设备重启 */
|
|
|
|
|
int32_t _csg_dev_info_set_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_dev_info_t *pinfo = (csg_dev_info_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
bool change_ip = FALSE;
|
|
|
|
|
uint8_t mac[MAC_ADDR_LEN] = {0};
|
|
|
|
|
|
|
|
|
|
device_info.dev_id = pinfo->dev_id;
|
|
|
|
|
device_info.mask = pinfo->mask;
|
|
|
|
|
device_info.gw = pinfo->gw;
|
|
|
|
|
snprintf((char*)device_info.hostname, FILE_NAME_LEN, "%s", pinfo->hostname);
|
|
|
|
|
if (device_info.ip != pinfo->ip)
|
|
|
|
|
{
|
|
|
|
|
device_info.ip = pinfo->ip;
|
|
|
|
|
change_ip = TRUE;
|
|
|
|
|
}
|
|
|
|
|
memcpy(device_info.mac, pinfo->mac, MAC_ADDR_LEN);
|
|
|
|
|
csg.server_ip = pinfo->server_ipv4;
|
|
|
|
|
csg.server_port = pinfo->server_port;
|
|
|
|
|
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
|
|
|
|
|
vtysh_config_save();
|
|
|
|
|
if (change_ip)
|
|
|
|
|
{
|
|
|
|
|
mac_generate_from_ip(device_info.ip, mac);
|
|
|
|
|
memcpy(device_info.mac, mac, MAC_ADDR_LEN);
|
|
|
|
|
vtysh_eth0_save();
|
|
|
|
|
}
|
|
|
|
|
vtysh_device_save();
|
|
|
|
|
reboot_system(LOG_CSG, REBOOT_REMOTE_DEVINFO_CHANGE);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 厂家参数查询报文处理. */
|
|
|
|
|
int32_t _csg_dev_info_get_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
printf("%s\n", __FUNCTION__);
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_dev_info_t *pinfo = (csg_dev_info_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
|
|
|
|
|
pinfo->type_m = device_info.type_m;
|
|
|
|
|
pinfo->type_s = device_info.type_s;
|
|
|
|
|
pinfo->dev_id = device_info.dev_id;
|
|
|
|
|
strcpy(pinfo->hostname, device_info.hostname);
|
|
|
|
|
pinfo->factory_date = device_info.factory_date;
|
|
|
|
|
pinfo->deployment_date = device_info.deployment_date;
|
|
|
|
|
strncpy((char *)pinfo->app_compile_time, host.compile, 31);
|
|
|
|
|
strncpy((char *)pinfo->app_version, host.version, 31);
|
|
|
|
|
//strncpy((char *)pinfo->hardware_version, host.hardversion, 31);
|
|
|
|
|
//strncpy((char *)pinfo->FPGA_version, host.FPGAversion, 31);
|
|
|
|
|
strncpy((char *)pinfo->hardware_version, "RFSOC_V1.0", 31);
|
|
|
|
|
strncpy((char *)pinfo->FPGA_version, "20250730", 31);
|
|
|
|
|
pinfo->ip = device_info.ip;
|
|
|
|
|
pinfo->mask = device_info.mask;
|
|
|
|
|
pinfo->gw = device_info.gw;
|
|
|
|
|
memcpy(pinfo->mac, device_info.mac, sizeof(pinfo->mac));
|
|
|
|
|
pinfo->server_port = csg.server_port;
|
|
|
|
|
pinfo->server_ipv4 = csg.server_ip;
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_dev_info_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 配置用户参数报文报文处理. */
|
|
|
|
|
int32_t _csg_config_set_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_global_config_t *config = (csg_global_config_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
pd_config.config.sample_frequency = config->sample_frequency;
|
|
|
|
|
pd_config.config.trigger_sample_nums = config->trigger_sample_numbers;
|
|
|
|
|
pd_config.config.trig_location = (config->pre_trigger_percent << 4) / 100.00;
|
|
|
|
|
pd_config.config.trig_threshold = config->trigLevel;
|
|
|
|
|
pd_config.config.trend_up_period = config->trend_up_period;
|
|
|
|
|
pd_config.config.heartbeat_period = config->heartbeat_period;
|
|
|
|
|
pd_config.config.ch_en_mask = config->ch_en_mask;
|
|
|
|
|
if (config->sync_mode == 0)
|
|
|
|
|
{
|
|
|
|
|
BITMAP_RESET(pd_config.config.pt_B_sync_mode, PD_BIT_PT);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_PT);
|
|
|
|
|
}
|
|
|
|
|
pd_config.config.pt_internal_period = 1000000000UL / config->pt_internal_period;
|
|
|
|
|
vtysh_config_save();
|
|
|
|
|
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 查询用户参数查询报文处理. */
|
|
|
|
|
int32_t _csg_config_get_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
printf("%s\n", __FUNCTION__);
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_global_config_t *config = (csg_global_config_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
config->sample_frequency = pd_config.config.sample_frequency;
|
|
|
|
|
config->trigger_sample_numbers = pd_config.config.trigger_sample_nums;
|
|
|
|
|
config->pre_trigger_percent = (uint32_t)(pd_config.config.trig_location * 100 / 16.00 + 0.5);
|
|
|
|
|
config->trigLevel = pd_config.config.trig_threshold;
|
|
|
|
|
config->trend_up_period = pd_config.config.trend_up_period;
|
|
|
|
|
config->heartbeat_period = pd_config.config.heartbeat_period;
|
|
|
|
|
config->ch_en_mask = pd_config.config.ch_en_mask;
|
|
|
|
|
if (IS_BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_PT))
|
|
|
|
|
{
|
|
|
|
|
config->sync_mode = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
config->sync_mode = 0;
|
|
|
|
|
}
|
|
|
|
|
config->pt_internal_period = 1000000000UL / pd_config.config.pt_internal_period;
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_global_config_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 配置南瑞参数设置报文处理. */
|
|
|
|
|
int32_t _csg_nr_config_set_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
int need_save = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_nr_config_t *pnet = (csg_nr_config_t *)(pkt + CSG_HEAD_LEN);
|
|
|
|
|
|
|
|
|
|
if ((pd_config.config.ch_en_mask != pnet->ch_en_mask)
|
|
|
|
|
|| (pd_config.config.trig_threshold != pnet->trigLevel))
|
|
|
|
|
{
|
|
|
|
|
need_save++;
|
|
|
|
|
if(pnet->ch_en_mask <= 0xFF)
|
|
|
|
|
{
|
|
|
|
|
pd_config.config.ch_en_mask = pnet->ch_en_mask;
|
|
|
|
|
for(i=0; i<PD_DAU_PORT_SUM; i++)
|
|
|
|
|
{
|
|
|
|
|
if(READ_BIT(pnet->ch_en_mask, 0x1<<i))
|
|
|
|
|
pd_config.config_port[0][i].is_enbale = TRUE;
|
|
|
|
|
else
|
|
|
|
|
pd_config.config_port[0][i].is_enbale = FALSE;
|
|
|
|
|
}
|
|
|
|
|
dau[0]->reg->reg_global.port_enable = pd_config.config.ch_en_mask;
|
|
|
|
|
}
|
|
|
|
|
if(pnet->trigLevel <= 32767)
|
|
|
|
|
{
|
|
|
|
|
pd_config.config.trig_threshold = pnet->trigLevel;
|
|
|
|
|
dau[0]->reg->reg_global.trig_threshold = pd_config.config.trig_threshold;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for(i=0; i<PD_DAU_PORT_SUM; i++)
|
|
|
|
|
{
|
|
|
|
|
if (pd_config.config_port[0][i].send_port_num != pnet->send_port_num[i])
|
|
|
|
|
{
|
|
|
|
|
pd_config.config_port[0][i].send_port_num = pnet->send_port_num[i];
|
|
|
|
|
dau[0]->reg->reg_port[i].ch_send_num = pd_config.config_port[0][i].send_port_num;
|
|
|
|
|
need_save++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (need_save)
|
|
|
|
|
{
|
|
|
|
|
vtysh_config_save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 查询南瑞参数查询报文处理. */
|
|
|
|
|
int32_t _csg_nr_config_get_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_nr_config_t *config = (csg_nr_config_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
config->ch_en_mask = pd_config.config.ch_en_mask;
|
|
|
|
|
config->trigLevel = pd_config.config.trig_threshold;
|
|
|
|
|
for(int i = 0; i < PD_DAU_PORT_SUM; i++)
|
|
|
|
|
{
|
|
|
|
|
config->send_port_num[i] = pd_config.config_port[0][i].send_port_num;
|
|
|
|
|
}
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_nr_config_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 通道提交端口参数设置. */
|
|
|
|
|
int32_t _csg_port_config_set_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
uint8_t unit = 0;
|
|
|
|
|
uint8_t port = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_config_port_t *pnet = (csg_config_port_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
csg_config_port_ack_t ack = {0};
|
|
|
|
|
|
|
|
|
|
if (dau_vport_to_port(pnet->vport, &unit, &port) != E_NONE)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", pnet->vport);
|
|
|
|
|
ack.vport = pnet->vport;
|
|
|
|
|
ack.result = FALSE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_config_port_ack_t));
|
|
|
|
|
_csg_send_data(CSG_REPLY, head->cmd, pkt, sizeof(csg_config_port_ack_t));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pd_config.config_port[unit][port].vport = pnet->vport;
|
|
|
|
|
pd_config.config_port[unit][port].type = pnet->channel_type;
|
|
|
|
|
|
|
|
|
|
vtysh_config_save();
|
|
|
|
|
|
|
|
|
|
ack.vport = pnet->vport;
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_config_port_ack_t));
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_config_port_ack_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 按通道提交端口参数查询结果. */
|
|
|
|
|
int32_t _csg_port_config_get_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_config_port_t *pnet = (csg_config_port_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
uint8_t unit = 0;
|
|
|
|
|
uint8_t port = 0;
|
|
|
|
|
|
|
|
|
|
if (dau_vport_to_port(pnet->vport, &unit, &port) != E_NONE)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", pnet->vport);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pnet->vport = pd_config.config_port[unit][port].vport;
|
|
|
|
|
pnet->channel_type = pd_config.config_port[unit][port].type;
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_config_port_t));
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t _csg_config_eigen_set_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
uint8_t vport;
|
|
|
|
|
uint8_t unit = 0;
|
|
|
|
|
uint8_t port = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_config_real_wave_t *config = (csg_config_real_wave_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
vport = config->vport;
|
|
|
|
|
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "vport:%d is_concern=%d\r\n", config->vport, config->is_concern);
|
|
|
|
|
|
|
|
|
|
if (dau_vport_to_port(vport, &unit, &port) != E_NONE)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", vport);
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
ack.result = FALSE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_PRV_REPLY, head->cmd);
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "vport(%d)-->port(%d)\r\n", vport, port);
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "is_concern=%d\r\n", config->is_concern);
|
|
|
|
|
//csg.channel[port].real_cfg.vport = vport;
|
|
|
|
|
//csg.channel[port].real_cfg.is_concern = config->is_concern;
|
|
|
|
|
csg.real_cfg[port].vport = vport;
|
|
|
|
|
csg.real_cfg[port].is_concern = config->is_concern;
|
|
|
|
|
|
|
|
|
|
csg_channel_ack_t ack = {0};
|
|
|
|
|
ack.vport = vport;
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_channel_ack_t), CSG_PRV_REPLY, head->cmd);
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t _csg_config_eigen_get_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
uint8_t vport;
|
|
|
|
|
uint8_t unit = 0;
|
|
|
|
|
uint8_t port = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_config_real_wave_t *pinfo = (csg_config_real_wave_t *)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
vport = *(uint8_t*)(pkt + CSG_HEAD_LEN);
|
|
|
|
|
|
|
|
|
|
if (dau_vport_to_port(vport, &unit, &port) != E_NONE)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Pkt port %d error!\r\n", vport);
|
|
|
|
|
csg_ack_t ack = {0};
|
|
|
|
|
ack.result = FALSE;
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_PRV_REPLY, head->cmd);
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//_csg_send_data(pkt, (char *)&csg.channel[port].real_cfg, sizeof(csg_config_real_wave_t), CSG_PRV_REPLY, head->cmd);
|
|
|
|
|
memcpy(pinfo, &csg.real_cfg[port], sizeof(csg_config_real_wave_t));
|
|
|
|
|
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_config_real_wave_t));
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 升级文件接收 */
|
|
|
|
|
int32_t _csg_upgrade_recv(char *pkt)
|
|
|
|
|
{
|
|
|
|
|
static int fd = -1;
|
|
|
|
|
static uint32_t fix_len = 0;
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
|
|
|
|
|
csg_upgrade_data_t *head_msg = (csg_upgrade_data_t*)(pkt + sizeof(csg_pkt_head_t));
|
|
|
|
|
char *pdata = pkt + sizeof(csg_pkt_head_t) + sizeof(csg_upgrade_data_t);
|
|
|
|
|
csg_upgrade_ack_t ack = {0};
|
|
|
|
|
int32_t size = 0;
|
|
|
|
|
int32_t len_wr = 0;
|
|
|
|
|
uint32_t offset = 0;
|
|
|
|
|
|
|
|
|
|
csg.is_connect = FALSE; //关闭主动上传
|
|
|
|
|
/* 首保处理, 打开文件描述符, 初始化变量 */
|
|
|
|
|
if (head_msg->index == 0)
|
|
|
|
|
{
|
|
|
|
|
if (fd > 0)
|
|
|
|
|
{
|
|
|
|
|
close(fd);
|
|
|
|
|
fd = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fd = open(PD_UPG_SOFTWARE, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Open file " PD_UPG_SOFTWARE " error!\r\n");
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
fix_len = head_msg->len;
|
|
|
|
|
|
|
|
|
|
DBG(DBG_M_PD_CSG, "Receive upgrade file start.\r\n");
|
|
|
|
|
}
|
|
|
|
|
// DBG(DBG_M_PD_CSG,"type=%d,sum=%d,index=%d,len=%d,fix_len=%d\r\n", head_msg->type, head_msg->sum, head_msg->index, head_msg->len, fix_len);
|
|
|
|
|
|
|
|
|
|
/* 收包流程 */
|
|
|
|
|
size = head_msg->len;
|
|
|
|
|
offset = head_msg->index * fix_len;
|
|
|
|
|
if (lseek(fd, offset, SEEK_SET) < 0)
|
|
|
|
|
{
|
|
|
|
|
int error = errno;
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "lseek file " PD_UPG_SOFTWARE " error: %s, fd=%d, offset=%ld\r\n",
|
|
|
|
|
strerror(error), fd, offset);
|
|
|
|
|
|
|
|
|
|
// 检查具体错误类型
|
|
|
|
|
switch(error) {
|
|
|
|
|
case EBADF: // 无效文件描述符
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Invalid file descriptor\r\n");
|
|
|
|
|
break;
|
|
|
|
|
case EINVAL: // 无效的 whence 或 offset
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Invalid offset or whence\r\n");
|
|
|
|
|
break;
|
|
|
|
|
case EOVERFLOW: // offset 过大
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Offset overflow\r\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ack.index = head_msg->index;
|
|
|
|
|
ack.result = FALSE;
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_REPLY, head->cmd);
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
// if (lseek(fd, offset, SEEK_SET) < 0)
|
|
|
|
|
// {
|
|
|
|
|
// DBG(DBG_M_PD_CSG_ERR, "lseek file " PD_UPG_SOFTWARE " error!\r\n");
|
|
|
|
|
// ack.index = head_msg->index;
|
|
|
|
|
// ack.result = FALSE;
|
|
|
|
|
// /* 发送应答 */
|
|
|
|
|
// _csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_REPLY, head->cmd);
|
|
|
|
|
// return E_SYS_CALL;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
len_wr = write(fd, pdata, size);
|
|
|
|
|
if (len_wr != size)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Write file " PD_UPG_SOFTWARE " error!\r\n");
|
|
|
|
|
ack.index = head_msg->index;
|
|
|
|
|
ack.result = FALSE;
|
|
|
|
|
/* 发送应答 */
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_REPLY, head->cmd);
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 最后一个报文处理 */
|
|
|
|
|
if (head_msg->sum - 1 == head_msg->index)
|
|
|
|
|
{
|
|
|
|
|
close(fd);
|
|
|
|
|
fd = -1;
|
|
|
|
|
DBG(DBG_M_PD_CSG, "Receive upgrade file end.\r\n");
|
|
|
|
|
pd_upg_start(PD_UPG_FROM_CSG, head_msg->type);
|
|
|
|
|
}
|
|
|
|
|
ack.index = head_msg->index;
|
|
|
|
|
ack.result = TRUE;
|
|
|
|
|
|
|
|
|
|
/* 发送应答 */
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_ack_t));
|
|
|
|
|
_csg_send_data(CSG_PRV_REPLY, head->cmd, pkt, sizeof(csg_ack_t));
|
|
|
|
|
//_csg_send_data(pkt, (char *)&ack, sizeof(csg_ack_t), CSG_REPLY, head->cmd);
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t _csg_recv_process(char *pkt, uint32_t len)
|
|
|
|
|
{
|
|
|
|
|
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
|
|
|
|
|
|
|
|
|
|
/* 报文头和 CRC 校验. */
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_pkt_check(pkt));
|
|
|
|
|
|
|
|
|
|
if (CSG_REQUEST == head->cmd_type)
|
|
|
|
|
{
|
|
|
|
|
switch (head->cmd)
|
|
|
|
|
{
|
|
|
|
|
#if CSG_TYPE_SELF
|
|
|
|
|
case CSG_C_CONTACT:
|
|
|
|
|
_csg_connect_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_C_HEARTBEAT:
|
|
|
|
|
_csg_heartbeat_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case CSG_C_RESET:
|
|
|
|
|
_csg_reboot_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_C_UPDATE:
|
|
|
|
|
_csg_upgrade_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_C_DEV_INFO_SET:
|
|
|
|
|
_csg_dev_info_set_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_C_DEV_INFO_GET:
|
|
|
|
|
_csg_dev_info_get_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (CSG_PRV_REQUEST == head->cmd_type)
|
|
|
|
|
{
|
|
|
|
|
switch (head->cmd)
|
|
|
|
|
{
|
|
|
|
|
case CSG_PRV_CONFIG_GLOBAL_SET:
|
|
|
|
|
_csg_config_set_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_GLOBAL_GET:
|
|
|
|
|
_csg_config_get_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_PORT_SET:
|
|
|
|
|
_csg_port_config_set_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_PORT_GET:
|
|
|
|
|
_csg_port_config_get_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_EIGEN_SET:
|
|
|
|
|
_csg_config_eigen_set_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_EIGEN_GET:
|
|
|
|
|
_csg_config_eigen_get_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_NANRUI_SET:
|
|
|
|
|
_csg_nr_config_set_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
case CSG_PRV_CONFIG_NANRUI_GET:
|
|
|
|
|
_csg_nr_config_get_recv(pkt);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 心跳和连接处理函数. */
|
|
|
|
|
void *_csg_recv_handle(void *arg)
|
|
|
|
|
{
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
int32_t addr = 0;
|
|
|
|
|
socklen_t addr_len = sizeof(server);
|
|
|
|
|
fd_set readfds;
|
|
|
|
|
|
|
|
|
|
/* 等待初始化完成 */
|
|
|
|
|
while(!is_system_init)
|
|
|
|
|
{
|
|
|
|
|
usleep(100000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prctl(PR_SET_NAME, "CSG_RCVE", 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
// 初始化 fd_set
|
|
|
|
|
FD_ZERO(&readfds);
|
|
|
|
|
int max_fd = -1;
|
|
|
|
|
|
|
|
|
|
// 将需要监听的 socket 描述符加入集合,并找出最大的描述符
|
|
|
|
|
for (int i = 0; i < csg.num_sockets; i++)
|
|
|
|
|
{
|
|
|
|
|
FD_SET(csg.sockfds[i], &readfds);
|
|
|
|
|
if (csg.sockfds[i] > max_fd)
|
|
|
|
|
{
|
|
|
|
|
max_fd = csg.sockfds[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用 select 等待任何一个 socket 变得可读
|
|
|
|
|
// 参数:最大fd+1, 读集合, 写集合, 异常集合, 超时时间(NULL为无限等待)
|
|
|
|
|
int activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if ((activity < 0) && (errno != EINTR))
|
|
|
|
|
{
|
|
|
|
|
perror("select error");
|
|
|
|
|
}
|
|
|
|
|
else if (activity > 0)
|
|
|
|
|
{
|
|
|
|
|
// 遍历所有 socket,检查哪个有数据到达
|
|
|
|
|
for (int i = 0; i < csg.num_sockets; i++)
|
|
|
|
|
{
|
|
|
|
|
if (FD_ISSET(csg.sockfds[i], &readfds))
|
|
|
|
|
{
|
|
|
|
|
// 接收数据
|
|
|
|
|
memset(csg.buf_recv, 0, sizeof(csg.buf_recv));
|
|
|
|
|
memset(&server, 0, sizeof(server));
|
|
|
|
|
ssize_t recv_len = recvfrom(csg.sockfds[i], csg.buf_recv, CSG_PKT_LEN, 0,
|
|
|
|
|
(struct sockaddr*)&server, &addr_len);
|
|
|
|
|
|
|
|
|
|
if (recv_len < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addr = server.sin_addr.s_addr;
|
|
|
|
|
if (addr != csg.server_ip)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_csg_recv_process(csg.buf_recv, recv_len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 心跳和连接处理函数. */
|
|
|
|
|
void *_csg_heartbeat_handle(void *arg)
|
|
|
|
|
{
|
|
|
|
|
time_t now = 0;
|
|
|
|
|
time_t t_connect = 0;
|
|
|
|
|
time_t t_heartbeat = 0;
|
|
|
|
|
|
|
|
|
|
prctl(PR_SET_NAME, "CSG_HEARTBEAT", 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
/* 等待初始化完成 */
|
|
|
|
|
while(!is_system_init)
|
|
|
|
|
{
|
|
|
|
|
usleep(100000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
usleep(100000);
|
|
|
|
|
now = time(NULL);
|
|
|
|
|
|
|
|
|
|
/* 发送连接报文. */
|
|
|
|
|
if (!csg.is_connect)
|
|
|
|
|
{
|
|
|
|
|
if (now - t_connect >= 10)
|
|
|
|
|
{
|
|
|
|
|
_csg_connect_send();
|
|
|
|
|
t_connect = now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 发送心跳包. */
|
|
|
|
|
if (abs(now - t_heartbeat) / pd_config.config.heartbeat_period >= 1/*pd_config.config.heartbeat_period*/)
|
|
|
|
|
{
|
|
|
|
|
_csg_heartbeat_send();
|
|
|
|
|
t_heartbeat = now;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//自有传输协议------------------------------------------------------------------------------------------------------自有传输协议
|
|
|
|
|
#if CSG_TYPE_SELF
|
|
|
|
|
/* 主动提交ad原始波形. */
|
|
|
|
|
void *_csg_real_image_handle(void *arg)
|
|
|
|
|
{
|
|
|
|
|
channel_t *pch = (channel_t *)arg;
|
|
|
|
|
pd_csg_msg_t *recv_msg = NULL;
|
|
|
|
|
socklen_t optlen;
|
|
|
|
|
int send_size = 16 * 1024 * 1024;
|
|
|
|
|
int recv_size = 16 * 1024 * 1024;
|
|
|
|
|
optlen = sizeof(send_size);
|
|
|
|
|
printf("port = %d skfd = %d \n", pch->port, pch->skfd);
|
|
|
|
|
if (pch->port >= 8 || pch->skfd < 0)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setsockopt(pch->skfd, SOL_SOCKET, SO_SNDBUF, &send_size, optlen);
|
|
|
|
|
setsockopt(pch->skfd, SOL_SOCKET, SO_RCVBUF, &recv_size, optlen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pch->pbuf = XMALLOC_Q(MTYPE_CSG, sizeof(CSG_ADBUF_MAX_LEN));
|
|
|
|
|
if (!pch->pbuf)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "csg %dport send data malloc failed!\r\n",pch->port);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
pch->cycle = 1;
|
|
|
|
|
|
|
|
|
|
/* 等待初始化完成 */
|
|
|
|
|
while(!is_system_init)
|
|
|
|
|
{
|
|
|
|
|
usleep(100000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (fifo_read(csg.fifo_real_image_id[pch->port], (void**)&recv_msg) != 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "ERROR at fifo %d read!\r\n", csg.fifo_real_image_id[pch->port]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
csg.new_data_flag[pch->port] = FALSE;
|
|
|
|
|
|
|
|
|
|
if (csg.is_connect)
|
|
|
|
|
{
|
|
|
|
|
_csg_real_image_send(pch, (pd_original_port_t *)recv_msg->data); //波形数据上传
|
|
|
|
|
_csg_real_eigen_send(pch, (pd_original_port_t *)recv_msg->data); //特征数据上传
|
|
|
|
|
}
|
|
|
|
|
XFREE(MTYPE_CSG, recv_msg->data);
|
|
|
|
|
fifo_push(csg.fifo_real_image_id[pch->port]);
|
|
|
|
|
}
|
|
|
|
|
close(pch->skfd);
|
|
|
|
|
XFREE(MTYPE_CSG, pch->pbuf);
|
|
|
|
|
pch->pbuf = NULL;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
//南瑞传输协议---------------------------------------------------------------------------------------------------南瑞传输协议
|
|
|
|
|
#elif CSG_TYPE_NANRUI
|
|
|
|
|
/* 主动提交ad原始波形. */
|
|
|
|
|
void *_csg_real_image_handle(void *arg)
|
|
|
|
|
{
|
|
|
|
|
unsigned char dest_mac[6] = {0x01, 0x0C, 0xCD, 0x01, 0x00, 0x01}; // 南瑞MAC地址固定
|
|
|
|
|
char buf_send[ETH_FRAME_LEN];
|
|
|
|
|
uint8_t port = *(uint8_t *)arg;
|
|
|
|
|
pd_csg_msg_t *recv_msg = NULL;
|
|
|
|
|
int fd = 0;
|
|
|
|
|
socklen_t optlen;
|
|
|
|
|
int send_size = 16 * 1024 * 1024;
|
|
|
|
|
int recv_size = 16 * 1024 * 1024;
|
|
|
|
|
optlen = sizeof(send_size);
|
|
|
|
|
|
|
|
|
|
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket create return %s!", safe_strerror(errno));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &send_size, optlen);
|
|
|
|
|
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recv_size, optlen);
|
|
|
|
|
|
|
|
|
|
// 获取网络接口索引
|
|
|
|
|
struct ifreq ifr;
|
|
|
|
|
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
|
|
|
|
|
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket create return %s!", safe_strerror(errno));
|
|
|
|
|
close(fd);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
// 设置发送地址
|
|
|
|
|
struct sockaddr_ll sa;
|
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
|
|
|
sa.sll_family = AF_PACKET;
|
|
|
|
|
sa.sll_ifindex = ifr.ifr_ifindex;
|
|
|
|
|
sa.sll_halen = ETH_ALEN;
|
|
|
|
|
memcpy(sa.sll_addr, dest_mac, 6);
|
|
|
|
|
|
|
|
|
|
/* 等待初始化完成 */
|
|
|
|
|
while(!is_system_init)
|
|
|
|
|
{
|
|
|
|
|
usleep(100000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dest_mac, csg.dest_mac, 6);
|
|
|
|
|
memcpy(sa.sll_addr, dest_mac, 6);
|
|
|
|
|
if (fifo_read(csg.fifo_real_image_id[port], (void**)&recv_msg) != 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "ERROR at fifo %d read!\r\n", csg.fifo_real_image_id[port]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
csg.new_data_flag[port] = FALSE;
|
|
|
|
|
|
|
|
|
|
//_csg_real_image_send(fd, buf_send, port, (pd_original_port_t *)recv_msg->data, &sa, dest_mac);
|
|
|
|
|
//_csg_real_eigen_send(fd, buf_send, port, (pd_original_port_t *)recv_msg->data, &sa, dest_mac);
|
|
|
|
|
|
|
|
|
|
XFREE(MTYPE_CSG, recv_msg->data);
|
|
|
|
|
fifo_push(csg.fifo_real_image_id[port]);
|
|
|
|
|
}
|
|
|
|
|
close(fd);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void *_csg_trend_handle(void *arg)
|
|
|
|
|
{
|
|
|
|
|
pd_csg_msg_t *recv_msg = NULL;
|
|
|
|
|
|
|
|
|
|
/* 等待初始化完成 */
|
|
|
|
|
while(!is_system_init)
|
|
|
|
|
{
|
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (fifo_read(csg.fifo_trend_id, (void**)&recv_msg) != 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "ERROR at fifo %d read!\r\n", csg.fifo_trend_id);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (csg.is_connect)
|
|
|
|
|
{
|
|
|
|
|
_csg_trend_send((pd_trend_port_t *)recv_msg->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
|
|
|
|
|
XFREE(MTYPE_CSG, recv_msg->data);
|
|
|
|
|
fifo_push(csg.fifo_trend_id);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t _csg_udp_create(int port)
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
/* 创建socket */
|
|
|
|
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket create return %s!", safe_strerror(errno));
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 绑定端口 */
|
|
|
|
|
bzero(&server, sizeof(server));
|
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
|
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
server.sin_port = htons(9000 + port);
|
|
|
|
|
if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket bind return %s!", safe_strerror(errno));
|
|
|
|
|
close(fd);
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
return fd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 后台通讯公共部分初始化. */
|
|
|
|
|
int32_t _csg_handle_init_common(void)
|
|
|
|
|
{
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
int fd = 0;
|
|
|
|
|
thread_param_t param = {0};
|
|
|
|
|
uint8_t idx = 0;
|
|
|
|
|
char str[20];
|
|
|
|
|
|
|
|
|
|
/* 创建协议 socket. */
|
|
|
|
|
if (0 == csg.skfd)
|
|
|
|
|
{
|
|
|
|
|
/* 创建socket */
|
|
|
|
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket create return %s!", safe_strerror(errno));
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 绑定端口 */
|
|
|
|
|
bzero(&server, sizeof(server));
|
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
|
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
server.sin_port = htons(7777);
|
|
|
|
|
if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "ERROR at socket bind return %s!", safe_strerror(errno));
|
|
|
|
|
close(fd);
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 保存数据. */
|
|
|
|
|
csg.skfd = fd;
|
|
|
|
|
csg.sockfds[csg.num_sockets] = fd;
|
|
|
|
|
csg.num_sockets++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&csg.mutex, NULL);
|
|
|
|
|
|
|
|
|
|
param.arg = NULL;
|
|
|
|
|
|
|
|
|
|
param.priority = 80;
|
|
|
|
|
param.thread_name = "CSG_RCVE";
|
|
|
|
|
create_thread(_csg_recv_handle, ¶m);
|
|
|
|
|
|
|
|
|
|
#if CSG_TYPE_SELF
|
|
|
|
|
param.priority = 80;
|
|
|
|
|
param.thread_name = "CSG_HEARTBEAT";
|
|
|
|
|
create_thread(_csg_heartbeat_handle, ¶m);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < PD_DAU_PORT_SUM; idx++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
csg.fifo_real_image_id[idx] = fifo_create(CSG_ORIG_ID, ORI_FIFO_NUM);
|
|
|
|
|
param.log_module = LOG_CSG;
|
|
|
|
|
|
|
|
|
|
channel_t *pchannel = XMALLOC_Q(MTYPE_CSG, sizeof(channel_t));
|
|
|
|
|
if (!pchannel)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "csg port%d malloc channel_t data failed!\r\n", idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
memset(pchannel, 0, sizeof(channel_t));
|
|
|
|
|
pchannel->port = idx;
|
|
|
|
|
fd = _csg_udp_create(idx);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
{
|
|
|
|
|
XFREE(MTYPE_CSG, pchannel);
|
|
|
|
|
DBG(DBG_M_PD_CSG_ERR, "csg port%d create udp failed!\r\n", idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
pchannel->skfd = fd;
|
|
|
|
|
csg.sockfds[csg.num_sockets] = fd;
|
|
|
|
|
csg.num_sockets++;
|
|
|
|
|
|
|
|
|
|
param.arg = (void *)pchannel;
|
|
|
|
|
param.priority = 90;
|
|
|
|
|
sprintf(str,"CSG_RT_REAL_IMAGE%d", idx);
|
|
|
|
|
param.thread_name = str;
|
|
|
|
|
create_thread(_csg_real_image_handle, ¶m);
|
|
|
|
|
if (csg.fifo_real_image_id[idx] < 0)
|
|
|
|
|
{
|
|
|
|
|
XFREE(MTYPE_CSG, pchannel);
|
|
|
|
|
log_err(LOG_CSG, "Open fifo " CSG_ORIG_ID "%d error!",idx);
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
csg.fifo_trend_id = fifo_create(CSG_FIFO_TREND, CSG_TREND_FIFO_NUM);
|
|
|
|
|
if (csg.fifo_trend_id < 0)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "Open fifo " CSG_FIFO_TREND " error!");
|
|
|
|
|
return E_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
param.priority = 60;
|
|
|
|
|
param.thread_name = "CSG_TREND";
|
|
|
|
|
create_thread(_csg_trend_handle, ¶m);
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Interface functions -------------------------------------------------------*/
|
|
|
|
|
/* 后台通讯模块预初始化. */
|
|
|
|
|
int32_t csg_handle_init(void)
|
|
|
|
|
{
|
|
|
|
|
int32_t rv = 0;
|
|
|
|
|
unsigned char dest_mac[6] = {0x01, 0x0C, 0xCD, 0x01, 0x00, 0x01}; // 南瑞MAC地址固定
|
|
|
|
|
memset(&csg, 0, sizeof(csg_t));
|
|
|
|
|
|
|
|
|
|
/* 发送数据. */
|
|
|
|
|
csg.server_ip = inet_addr("192.168.0.1");
|
|
|
|
|
csg.server_port = 1885;
|
|
|
|
|
bzero(&csg.server, sizeof(csg.server));
|
|
|
|
|
csg.server.sin_family = AF_INET;
|
|
|
|
|
csg.server.sin_addr.s_addr = csg.server_ip;
|
|
|
|
|
csg.server.sin_port = htons(csg.server_port);
|
|
|
|
|
memcpy(csg.dest_mac, dest_mac, 6);
|
|
|
|
|
|
|
|
|
|
cmd_install_element(CONFIG_NODE, &csg_server_set_cmd);
|
|
|
|
|
cmd_install_element(CONFIG_NODE, &csg_server_mac_set_cmd);
|
|
|
|
|
cmd_install_element(COMMON_NODE, &csg_show_cmd);
|
|
|
|
|
|
|
|
|
|
/* 注册配置保存函数 */
|
|
|
|
|
rv = cmd_config_node_config_register(CONFIG_PRI_CSG, _csg_config_save);
|
|
|
|
|
if (rv != E_NONE)
|
|
|
|
|
{
|
|
|
|
|
log_err(LOG_CSG, "Command save register ERROR %d!", rv);
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* description: 远程升级结果返回回调函数
|
|
|
|
|
param: rv -- 返回结果
|
|
|
|
|
buf -- 描述字符串
|
|
|
|
|
return: */
|
|
|
|
|
void csg_upgrade_result_send(int32_t rv, char *buf)
|
|
|
|
|
{
|
|
|
|
|
csg_upgrade_res_t ack = {0};
|
|
|
|
|
char *pkt = csg.buf_send;
|
|
|
|
|
|
|
|
|
|
ack.result = rv;
|
|
|
|
|
strcpy(ack.context, buf);
|
|
|
|
|
|
|
|
|
|
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&ack, sizeof(csg_upgrade_res_t));
|
|
|
|
|
_csg_send_data(CSG_REPLY, CSG_C_UPDATE_RESULT, pkt, sizeof(csg_upgrade_res_t));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 后台通讯模块初始化. */
|
|
|
|
|
int32_t csg_handle_init_after(void)
|
|
|
|
|
{
|
|
|
|
|
/* 初始化模块. */
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_handle_init_common());
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|