You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1874 lines
61 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/******************************************************************************
* 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>&copy; 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]; // 最大长度为 1712 位十六进制 + 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, &param);
#if CSG_TYPE_SELF
param.priority = 80;
param.thread_name = "CSG_HEARTBEAT";
create_thread(_csg_heartbeat_handle, &param);
#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, &param);
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, &param);
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