/******************************************************************************
 * file    include/pd_csg.h 
 * author  YuLiang
 * version 1.0.0
 * date    21-Feb-2023
 * brief   This file provides all the headers of the csg server 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.
 *
 ******************************************************************************/

#ifndef _PD_CSG_H_
#define _PD_CSG_H_

#ifdef CFG_DEV_TYPE_LAND_PD
/* Includes ------------------------------------------------------------------*/
#include "pd_main.h"
#include <semaphore.h>

/* Define --------------------------------------------------------------------*/
#define CSG_TYPE_NANRUI   0 // 南瑞设备类型
#define CSG_TYPE_SELF     1 // 自定义设备类型
#define CSG_MAX_POINTS    (700)       // 最大单帧点数.

#define CSG_FIFO_ORI      "CSG_FIFO_ORI"
#define ORI_FIFO_NUM      (4)
#define CSG_TREND_FIFO_NUM  (8)
#define CSG_HEAD_LEN      (32)
#define CSG_TOTLE_LEN     (26)
#define CSG_PKT_LEN       (1400)
#define CSG_ADBUF_MAX_LEN (65000)

#define CSG_SEND_SELF_WAVE_NUM (6)   //2ms send 4 pulse self
#define CSG_SEND_NR_WAVE_NUM   (2)   //2ms send 4 pulse nanrui

#define CSG_SHIQUCHA        (28800)     // 8 * 3600.

#define CSG_ORIG_ID     "original"
#define CSG_FIFO_TREND  "CSG_FIFO_TREND"
#define CSG_MAX_SOCKET      (PD_DAU_PORT_SUM  + 1)

/* 命令类型. */
enum CSG_CMD_TYPE
{
    CSG_REQUEST = 1,   /* 请求 */
    CSG_REPLY = 2,     /* 应答 */
    CSG_PRV_REQUEST = 121,  /* 私有请求 */
    CSG_PRV_REPLY = 122     /* 私有应答 */
};

/* 共有命令字. */
enum CSG_CMD
{
    CSG_C_CONTACT = 1,       /* 设备连接 */
    CSG_C_RESET = 3,         /* 设备复位 */
    CSG_C_UPDATE = 5,        /* 设备升级 */
    CSG_C_DEV_INFO_SET = 6,  /* 设备基本信息设置 */
    CSG_C_DEV_INFO_GET = 7,  /* 设备基本信息获取 */
    CSG_C_UPDATE_RESULT = 9, /* 升级结果上报 */
    CSG_C_HEARTBEAT = 10     /* 心跳包 */
};

/* 私有命令字. */
enum DEBUG_CM_CMD
{
    CSG_PRV_CONFIG_GLOBAL_SET = 1,    /* 设备全局参数设置 */
    CSG_PRV_CONFIG_GLOBAL_GET = 2,    /* 设备全局参数获取 */
    CSG_PRV_CONFIG_PORT_SET = 3,      /* 设备端口参数设置 */
    CSG_PRV_CONFIG_PORT_GET = 4,      /* 设备端口参数获取 */
    CSG_PRV_CONFIG_EIGEN_SET = 5,     /* 特征量参数设置 */
    CSG_PRV_CONFIG_EIGEN_GET = 6,     /* 特征量参数获取 */
    CSG_PRV_CONFIG_NANRUI_SET = 20,   /* 南瑞设备参数设置 */
    CSG_PRV_CONFIG_NANRUI_GET = 21,   /* 南瑞设备参数获取 */
    CSG_PRV_REAL_WAVE = 50,           /* 实时触发波形上传 50-self 52nanrui*/       
    CSG_PRV_REAL_EIGEN = 51,           /* 特征量数据上传 */
    CSG_PRV_TREND = 52,
};

typedef struct{
    uint8_t port;
    uint8_t reserved1[3];
    uint32_t century_second;
    uint32_t pulse_num;
    int16_t pulse_max;
    int16_t pulse_avg;
    int16_t noise;
    uint16_t phase;
    uint8_t reserved2[32];
} csg_trend_t;

typedef struct {
    uint32_t port;              /* 端口号 0 ~ 7 */
    uint32_t length;            /* 端口数据长度 */
}port_info_t;

#pragma pack(push, 1)
typedef struct 
{
    int16_t amplitude;  // 幅值
    uint16_t phase;      // 相位
    uint16_t period;     // 周期
} prps_t;
#pragma pack(pop)

/* 特征量报文头 32Byte. */
typedef struct
{
    uint8_t vport;                  // 通道编号 1 ~ 8
    uint8_t pkt_sum;                // 总包
    uint8_t pkt_index;              // 当前包
    uint8_t reserved1;              // 保留
    uint8_t channel_type;           // 通道类型 (1: UHF)
    uint8_t unit;                   // 单位 (1: dBm; 2: mV)
    int16_t noise;                  // 噪声
    int16_t pulse_peak;             // 脉冲峰值
    uint16_t power_frequency;       // 工频周期
    uint8_t reserved2[8];           // 保留 
    uint16_t discharge_nums;        // 放电次数
    uint16_t frame_num;             // 特征量数量
    uint32_t first_sec;             // 第一次放电的世纪秒
    uint32_t first_ns;              // 第一次放电的纳秒
    uint32_t last_sec;              // 最后一次放电的世纪秒
    uint32_t last_ns;               // 最后一次放电的纳秒
} csg_eigen_value_t;

typedef struct {
    uint8_t vport;                              // 通道编号 1 ~ 8
    uint8_t is_concern;                         // 关注 1: 关注 0: 取消关注
    uint8_t reserve[30];
} csg_config_real_wave_t;

typedef struct
{
    uint8_t port;
    int skfd;
    csg_eigen_value_t eigen;
    prps_t wave[10000];   // 20*500 2ms最大有20个，统计1s
    char *pbuf;
    uint32_t times;
    uint32_t inums;
    uint32_t noise_sum;
    uint32_t cycle;
} channel_t;

/* . */
typedef struct
{
    int skfd;                                           // 后台通讯使用的 socket.
    int sockfds[CSG_MAX_SOCKET];
    int num_sockets;
    uint32_t pkt_index;                                 // 报文索引.
    uint32_t fifo_real_image_id[PD_DAU_PORT_SUM];       // adc原始数据fifo
    uint32_t fifo_trend_id;
    char buf_send[1500];                                // 发送缓冲区.
    char buf_recv[1500];                                // 接收缓冲区.
    struct sockaddr_in server;                          // 服务器地址.
    struct sockaddr_in wave_svr;
    int32_t server_ip;                                  // server ip.
    uint16_t server_port;                               // server port.
    uint8_t is_connect;                                 // 是否连接上服务器.
    uint8_t heartbeat;                                  // 心跳发送后没有收到回复的次数.
    int32_t communication_time;                         // 最后通讯时间.
    pthread_mutex_t mutex;                              // 互斥锁.
    pthread_mutex_t lock;                               // 离线监控锁.
    uint8_t dest_mac[6];                                // 目标MAC地址.
    uint8_t is_send;                                    // 是否发送波形和特征数据数据
    volatile uint8_t new_data_flag[8];                  // 新数据更新标志位
    csg_config_real_wave_t real_cfg[8];
    
} csg_t;

/* 报文头结构. */
typedef struct{
    uint16_t len;              // 报文长度.
    uint8_t dev_type_m;        // 设备类型高字节.
    uint8_t dev_type_s;        // 设备类型低字节.
    uint32_t dev_id;           // 设备ID.
    uint8_t cmd_type;          // 命令类型. 1:请求 2:应答 121:私有请求 122:私有应答
    uint8_t cmd;               // 命令字. 1:设备连接 3:设备复位 5:设备升级 6:设备基本信息设置 7:设备基本信息获取 9:升级结果上报 10:心跳包
    uint16_t pkt_id;           // 报文ID, 用于区分不同的报文.
    uint8_t version;           // 版本号, 用于兼容不同版本的报文.
    uint8_t reserve[19];       // 保留字段, 用于将来扩展.
} csg_pkt_head_t;

/* 报文头结构. */
typedef struct{
    uint8_t dest_mac[6];       // 目标MAC地址.
    uint8_t src_mac[6];        // 源MAC地址.
    uint8_t cmd_type[2];       // 命令类型. 0xf0:特征量 0x11:波形
    uint8_t reserve;           // 保留字段, 用于将来扩展.
    uint8_t port_nums;         // 端口数量, 用于标识有多少个端口的数据.
} csg_pkt_nanrui_head_t;

typedef struct {
    uint8_t result;             // 应答结果. 0:成功 1:失败
    uint8_t reserved[3];        // 保留 
}csg_ack_t;

typedef struct {
    uint8_t vport;                              // 通道编号 1 ~ 8
    uint8_t result;             // 应答结果. 0:成功 1:失败
    uint8_t reserved[2];        // 保留 
} csg_channel_ack_t;

/* 升级文件包结构体 */
typedef struct
{
    uint8_t type;               // 升级类型
    uint8_t resverd[3];
    uint16_t index;             // 报文索引
    uint16_t sum;               // 总包数.
    uint32_t len;               // 数据包长度.
} csg_upgrade_data_t;

/* 应答升级结构体 */
typedef struct
{
    uint16_t index;             // 应答包序号.
    uint8_t result;             // 应答结果. 0:失败 1:成功
    uint8_t reserve;            // 保留
} csg_upgrade_ack_t;

/* 升级结果通知 */
typedef struct 
{
    uint8_t result;         // 升级结果
    uint8_t reserved[3];
    char context[128];
} csg_upgrade_res_t;

/* 心跳报文. */
typedef struct
{
    uint32_t power_freq;                       // 电网频率, 单位Hz.
    uint8_t dau_state[PD_DAU_PORT_SUM];        // 采集模块的状态.
    uint8_t pt_sync_mode;                      // PT同步模式, 0:外同步, 1:内同步.
    uint8_t dau_port_nums;                     // 采集模块端口数量, 1 ~ 8.
    uint8_t reserve[6];                        // 保留字段, 用于将来扩展.
} csg_heartbeat_t;


/* 设备信息 */
typedef struct
{
    uint8_t type_m;                 // 主设备号
    uint8_t type_s;                 // 次设备号
    uint8_t reserved1[2];           // 保留
    uint32_t dev_id;                // 设备ID
    char hostname[FILE_NAME_LEN];   // 设备名 128byte
    uint32_t factory_date;          // 出厂日期.
    uint32_t deployment_date;       // 部署日期.
    uint8_t app_version[32];        // 软件版本
    uint8_t app_compile_time[32];   // 软件编译时间
    uint8_t hardware_version[32];   // 硬件版本
    uint8_t FPGA_version[32];       // fpga版本
    uint32_t ip;                    // 本机 IP.
    uint32_t mask;                  // 本机 MASK.
    uint32_t gw;                    // 本机网关
    uint8_t mac[6];                 // MAC地址.
    uint16_t server_port;           // 服务器端口号.
    uint32_t server_ipv4;           // 服务器 IP.
} csg_dev_info_t;

typedef struct 
{
    uint8_t type_m;                 // 主设备号
    uint8_t type_s;                 // 次设备号
    uint8_t reserved1[2];           // 保留
    uint32_t dev_id;                // 设备ID
    char hostname[FILE_NAME_LEN];   // 设备名 128byte
    uint32_t factory_date;          // 出厂日期.
    uint32_t deployment_date;       // 部署日期.
    uint8_t app_version[32];        // 软件版本
    uint8_t app_compile_time[32];   // 软件编译时间
    uint8_t hardware_version[32];   // 硬件版本
    uint8_t FPGA_version[32];       // fpga版本
    uint32_t ip;                    // 本机 IP.
    uint32_t mask;                  // 本机 MASK.
    uint32_t gw;                    // 本机网关
    uint8_t mac[6];                 // MAC地址.
    uint16_t server_port;           // 服务器端口号.
    uint32_t server_ipv4;           // 服务器 IP.                 
    uint8_t port[PD_DAU_PORT_SUM];  // 端口号, 1 ~ 8.
    uint8_t port_type[PD_DAU_PORT_SUM]; // 端口类型
} csg_contact_t;

/* 实时图谱报文头 16Byte. */
typedef struct
{
    uint8_t channel_id;           // 通道编号
    uint8_t reserved1;            // 保留
    uint8_t channel_type;         // 通道类型 (1: UHF)
    uint8_t unit;                 // 单位 (1: dBm; 2: mV)
    uint16_t sample_rate;         // 采样率 (Msps)
    uint16_t record_points;       // 录波点数 N
    uint16_t phase;               // 脉冲所在相位
    int16_t pulse_peak;           // 脉冲峰值
    uint16_t pre_trigger;         // 预触发
    uint16_t trigger_level;        // 触发电平 (mv)
    uint32_t filter_frequency;    // 过滤频率
    uint16_t rise_time;           // 上升时间 (ns)
    uint16_t peak_time;           // 峰值时间
    uint16_t fall_time;           // 下降时间
    uint16_t pulse_width;         // 脉冲宽度
    uint16_t peak_count;          // 波峰数量
    uint8_t reserved2[2];         // 保留 (2字节)
    int32_t signal_envelope_area; // 信号包络面积
    float signal_mean;            // 信号均值
    float signal_variance;        // 信号方差值
    int32_t first_main_freq;      // 第一主频
    int16_t first_main_freq_peak; // 第一主频峰值
    uint16_t spectral_peak_count; // 谱峰个数
    float spectral_mean;          // 频谱均值
    float spectral_variance;      // 频谱方差值
    uint32_t century_second;      // 采样时间世纪秒
    uint32_t nanosecond;          // 纳秒
    int16_t cycle_count;          // 周期数 - 脉冲所在的周期
    int16_t frequency;            // 频率
    int16_t noise;                // 噪声
    int16_t sampling_time;        // 采集时长 - 采样时长
    uint8_t reserved3[20];        // 预留 (20字节)
} csg_real_image_t;

typedef struct{
    uint32_t sample_frequency;                      //采样频率  MHz
    uint32_t trigger_sample_numbers;                //触发采样长度  us
    uint32_t pre_trigger_percent;                   //预触发百分比 0-100%
    uint32_t trigLevel;                             //触发电平  mv
    uint32_t trend_up_period;                       //趋势上升周期
    uint16_t heartbeat_period;                      //心跳包周期 s
    uint8_t ch_en_mask;                             //通道使能  bit0-7对应ch1-ch8
    uint8_t sync_mode;                              //同步模式  0-外同步 1-内同步
    uint32_t pt_internal_period;                    //内同步频率 40~300
    uint8_t reserved[8];                            //预留
} csg_global_config_t;

typedef struct{
    uint32_t trigLevel;                             //触发电平  mv
    uint8_t ch_en_mask;                             //通道使能  bit0-7对应ch1-ch8
    uint8_t send_port_num[PD_DAU_PORT_SUM];         //南瑞传输编号
    uint8_t reserve[3];                             //保留
} csg_nr_config_t;

// 通道类型枚举定义
typedef enum {
    SIGNAL_CHANNEL_WITH_NOISE = 0,  // 信号通道关联噪声
    SIGNAL_CHANNEL = 1,             // 信号通道
    NOISE_CHANNEL = 2               // 噪声通道
} ChannelType;

//#pragma pack(push, 1)
typedef struct{
    uint8_t vport;                  // 通道编号.
    uint8_t channel_type;           // 通道类型.
    uint8_t reserved1[2];
    uint32_t filter_frequency;      // 过滤频率(32位按位设置)
    int16_t rise_time;              // 上升时间(10%到90%峰值)
    int16_t peak_time;              // 峰值时间
    int16_t fall_time;              // 下降时间(90%到10%峰值)
    int16_t pulse_width;            // 脉冲宽度
    int16_t peak_count;             // 波峰数量
    int16_t reserved2;              // 保留字段(2字节)
    int32_t signal_envelope;        // 信号包络面
    float signal_mean;              // 信号平均值
    float signal_variance;          // 信号方差值
    int32_t primary_frequency;      // 第一主频
    int16_t primary_freq_peak;      // 第一主频峰值
    int16_t spectral_peak_count;    // 谱峰个数
    float spectrum_mean;            // 频谱均值
    float spectrum_variance;        // 频谱方差值
    uint8_t reserved3[32];          // 预留字段(32字节)
} csg_config_port_t;
//#pragma pack(pop)

typedef struct {
    uint8_t vport;              // 通道编号.
    uint8_t result;             // 应答结果. 0:成功 1:失败
    uint8_t reserved[2];        // 保留 
}csg_config_port_ack_t;

/* Exported macro ------------------------------------------------------------*/

/* Extern global variables ---------------------------------------------------*/
extern csg_t csg;

/* Extern functions ----------------------------------------------------------*/
extern int32_t csg_handle_init(void);
extern int32_t csg_handle_init_after(void);
extern void csg_upgrade_result_send(int32_t rv, char *buf);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
