FIX | 修改DAU代码.

main
yuliang 2 weeks ago
parent d894b24395
commit 26077c703d

@ -120,6 +120,15 @@ typedef struct
} \
} while(0)
#define LD_E_RETURN_N(_f_) \
do { \
int _rv_ = E_ERROR; \
if ((_rv_ = _f_) != E_NONE) \
{ \
return _rv_; \
} \
} while(0)
#define LD_NULL_RETURN(_module_, _f_) \
do { \
if (NULL == (_f_)) \
@ -129,6 +138,34 @@ typedef struct
} \
} while(0)
#define LD_NULL_RETURN_N(_f_) \
do { \
if (NULL == (_f_)) \
{ \
return E_NULL; \
} \
} while(0)
#define LD_N_RETURN(_module_, _f_) \
do { \
int _rv_ = E_ERROR; \
if ((_rv_ = _f_) != E_NONE) \
{ \
DBG(_module_, "ERROR return %d!\r\n", _rv_); \
return; \
} \
} while(0)
#define LD_N_RETURN_N(_f_) \
do { \
int _rv_ = E_ERROR; \
if ((_rv_ = _f_) != E_NONE) \
{ \
return; \
} \
} while(0)
/* Extern global variables ---------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
@ -136,7 +173,7 @@ extern char *str_to_lower(char *str);
extern char *str_omit_space(char *str, bool omit_end);
extern size_t time_string(int32_t timestamp_precision, char *buf, size_t buflen);
extern const char *safe_strerror(int errnum);
extern void buf_print(char *buf, int32_t len);
extern void buf_print(char *buf, uint32_t len);
extern void buf_print_16(uint16_t *buf, int32_t len);
extern int32_t mac_generate_from_ip(uint32_t ip, uint8_t *mac);
extern uint16_t crc16(uint8_t *data, uint16_t size);

@ -66,7 +66,8 @@ typedef enum
DBG_M_STORAGE_ERR,
DBG_M_DEBUG,
DBG_M_PD_UPGRADE,
DBG_M_PD_DATA,
DBG_M_PD_HF,
DBG_M_PD_HF_ERR,
DBG_M_COUNT
} DBG_MODULE_E;

@ -61,6 +61,45 @@
/* Exported types ------------------------------------------------------------*/
typedef int32_t (*dau_recv_cb)(uint8_t, char*, uint16_t);
typedef void (*dau_recv_fun_cb)(uint8_t, char*, uint16_t);
/* 命令类型. */
enum DAU_CMD_TYPE
{
DAU_REQUEST = 1,
DAU_REPLY = 2,
DAU_PRV_REQUEST = 121,
DAU_PRV_REPLY = 122
};
/* 共有命令字. */
enum DAU_CMD
{
DAU_C_CONTACT = 1,
DAU_C_ADD_DAU = 2,
DAU_C_RESET = 3,
DAU_C_UPDATE = 5,
DAU_C_DEV_INFO_SET = 6,
DAU_C_DEV_INFO_GET = 7,
DAU_C_UPDATE_RESULT = 9,
DAU_C_HEARTBEAT = 10,
DAU_C_MAX
};
/* 私有命令字. */
enum DAU_P_CMD
{
DAU_P_CONFIG_SET = 1, // 设备全局参数设置
DAU_P_CONFIG_GET = 2, // 设备全局参数获取
DAU_P_CONFIG_PORT_SET = 3, // 设备端口参数设置
DAU_P_CONFIG_PORT_GET = 4, // 设备端口参数获取
DAU_P_CONFIG_REAL_WAVE = 5, // 实时波形配置
DAU_P_TREND = 10,
DAU_P_REAL_PRPS = 11,
DAU_P_EVENT = 12,
DAU_P_MAX
};
// 板卡类型枚举
typedef enum {
@ -129,7 +168,41 @@ typedef struct {
uint8_t address; // 从机地址
} rs485_device_data;
/* 报文头初始化结构体 */
typedef struct
{
uint8_t cmd_type;
uint8_t cmd;
uint16_t pkt_id;
char *pkt;
uint32_t len;
} dau_head_init_t;
/* 应答报文 */
typedef struct
{
uint8_t result; // 应答结果. 0:成功 1:失败
uint8_t reserved[3]; // 保留
} dau_ack_t;
/* 报文头 */
typedef struct
{
uint16_t len;
uint8_t dev_type_m;
uint8_t dev_type_s;
uint32_t dev_id;
uint8_t cmd_type;
uint8_t cmd;
uint16_t pkt_id;
uint8_t version;
uint8_t reserve1[2];
uint8_t slot;
uint32_t sdev_id;
uint8_t reserve2[12];
} dau_pkt_head_t;
/* 开机联络 */
typedef struct
{
uint8_t type_m; // 主设备号
@ -139,19 +212,52 @@ typedef struct
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版本
uint8_t app_version[DEV_VERSION_STR_LEN]; // 软件版本
uint8_t app_compile_time[DEV_VERSION_STR_LEN]; // 软件编译时间
uint8_t hardware_version[DEV_VERSION_STR_LEN]; // 硬件版本
uint8_t FPGA_version[DEV_VERSION_STR_LEN]; // fpga版本
uint32_t ip; // 本机 IP.
uint32_t mask; // 本机 MASK.
uint32_t gw; // 本机网关
uint8_t mac[6]; // MAC地址.
uint8_t mac[MAC_ADDR_LEN]; // MAC地址.
uint16_t server_port; // 服务器端口号.
uint32_t server_ipv4; // 服务器 IP.
uint8_t port[8];
uint8_t port_type[8];
} dau_info_t;
uint8_t port[PD_PORT_SUM];
uint8_t port_type[PD_PORT_SUM];
} dau_contact_t;
/* 心跳报文. */
typedef struct
{
float freq; // 实测同步源工频频率.
uint8_t dau_state[4]; // 采集模块的状态.
uint8_t out_sync; // 外接调频同步 1: 有效 0: 无效.
uint8_t pt_sync; // PT同步 1: 有效 0: 无效.
uint8_t in_sync; // 内同步 1: 有效 0: 无效.
uint8_t reserved1; // 预留 字节对齐.
uint8_t port_link_alarm[PD_PORT_SUM]; // 通道传感器连接状态 断线告警.
uint8_t dau_port_num[4]; // 采集板端口数量.
} dau_heartbeat_t;
/* 时间头 */
typedef struct
{
uint16_t index; // 包索引
uint16_t sum; // 总包数
uint8_t vport; // 通道号
uint8_t boosterpack; // 是否补包 0否 1
int16_t max; // 通道的最大值.
uint32_t power_fre; // 工频周期.
uint8_t type; // 事件类型.
uint8_t reserved[3]; // 保留
uint32_t identifier; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint32_t cnt; // 通道每秒脉冲计数值.
uint16_t avg_o; // 通道原始信号 (降噪前) 的平均值.
uint16_t avg; // 脉冲平均值.
uint32_t point_cnt; // 数据累计点数
uint32_t len; // 当前包长度
} dau_event_head_t;
// 板卡管理器结构
typedef struct
@ -177,8 +283,6 @@ typedef struct
pthread_t thread_id;
int slot;
bool occupied; // 槽位占用标志
dau_info_t info;
} dau_manager_t;
/* DAU 状态结构体 */
@ -191,14 +295,17 @@ typedef struct
/* DAU 全局结构体 */
typedef struct
{
uint8_t slot;
uint8_t slot; // dau slot
DauType type;
int fd;
char buf_recv[DAU_BUF_SIZE];
int fd; // dau socket fd
struct sockaddr_in server; // dau client ip
char buf_recv[DAU_BUF_SIZE]; // dau 收包 buf
DauState stat;
void *private_data;
dau_info_t info;
dau_state_t state;
dau_contact_t info; // dau 信息
dau_heartbeat_t run_status; // dau 运行状态
dau_state_t state; // dau 状态
dau_recv_cb recv_cb; // dau 收包处理函数
} dau_t;
/* Exported macro ------------------------------------------------------------*/
@ -216,7 +323,7 @@ extern dau_t daus[PD_SLOTS_MAX];
/* Extern functions ----------------------------------------------------------*/
extern int32_t dau_handle_init(void);
extern int32_t dau_handle_init_after(void);
extern void _dau_response(int slot, char *buf, int len);
extern void dau_send_data(dau_t *dau, dau_head_init_t *head_data);
#endif
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/

@ -28,9 +28,7 @@ typedef struct
uint8_t port_type[8];
} hf_dev_info_t;
extern int32_t _hf_recv_process(int slot, char *pkt);
extern int32_t hf_recv_process(uint8_t slot, char *pkt, uint16_t len);
#endif
#endif

@ -308,7 +308,7 @@ void _csg_connect_recv(void)
void _csg_add_dau_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
int slot = head->slot;
//int slot = head->slot;
printf("_csg_add_dau_recv slot = %d\n", head->slot);
head->dev_id = head->sdev_id;
@ -320,7 +320,7 @@ void _csg_add_dau_recv(char *pkt)
*timestamp = time(NULL);
//_dau_response(slot, pkt, head->len);
_dau_response(slot, pkt, head->len);
//_dau_response(slot, pkt, head->len);
}
/* 解析心跳报文. */
@ -653,13 +653,13 @@ int32_t _csg_upgrade_recv(char *pkt)
int32_t _csg_event_recv(char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
int slot = head->slot;
//int slot = head->slot;
printf("_csg_event_recv slot = %d\n", head->slot);
head->dev_id = head->sdev_id;
head->cmd = CSG_PRV_EVENT;
_dau_response(slot, pkt, head->len);
//_dau_response(slot, pkt, head->len);
return E_NONE;
}

@ -33,570 +33,29 @@
/* 上传平台回调函数类型 */
typedef void (*UploadCallback)(int slot, const void *data, size_t len);
/* 报文头 */
typedef struct
{
uint16_t len;
uint8_t dev_type_m;
uint8_t dev_type_s;
uint32_t dev_id;
uint8_t cmd_type;
uint8_t cmd;
uint16_t pkt_id;
uint8_t version;
uint8_t reserve[19];
} dau_pkt_head_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[8];
uint8_t port_type[8];
} dau_contact_t;
/* Private variables ---------------------------------------------------------*/
pthread_mutex_t board_mutex = PTHREAD_MUTEX_INITIALIZER;
int udp_socket;
dau_t daus[PD_SLOTS_MAX];
/* Private function prototypes -----------------------------------------------*/
int _dau_insert(int slot, DauType type);
void _dau_remove(int slot);
extern void _print_sockaddr_in(const struct sockaddr_in *addr);
/* Internal functions --------------------------------------------------------*/
CMD(dau_add,
dau_add_cmd,
"dau <1-6>",
"DAU\n"
"Dau number\n")
{
uint8_t unit = 0;
unit = strtol(argv[0], NULL, 10) - 1;
_dau_insert(unit, DAU_TYPE_UDP);
return CMD_SUCCESS;
}
CMD(no_dau_add,
no_dau_add_cmd,
"no dau <1-6>",
"DAU\n"
"Dau number\n")
{
uint8_t unit = 0;
unit = strtol(argv[0], NULL, 10) - 1;
_dau_remove(unit);
return CMD_SUCCESS;
}
#if 0
// ================== UDP 操作函数 ==================
static int _dau_udp_init(dau_private_data_t *data, const char *config)
{
// 解析配置: "ip:port:board_id"
char ip[32], board_id[32];
int port;
struct sockaddr_in server_addr;
int sockfd;
if (sscanf(config, "%[^:]:%d:%s", ip, &port, board_id) != 3)
{
return -1;
}
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
log_err(LOG_DAU, "ERROR at socket create return %s!", safe_strerror(errno));
return E_SYS_CALL;
}
// 设置地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//inet_pton(AF_INET, ip, &server_addr.sin_addr);
// 绑定套接字
if (bind(sockfd, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
log_err(LOG_DAU, "ERROR at socket create return %s!", safe_strerror(errno));
close(sockfd);
return E_SYS_CALL;
}
strncpy(data->board_id, board_id, sizeof(data->board_id));
// 配置缓冲区 (示例)
data->buffer_size = 4096;
data->rx_buffer = malloc(data->buffer_size);
if (!data->rx_buffer)
{
close(sockfd);
return E_SYS_CALL;;
}
//data->comm.udp.addr = server_addr;
data->comm.udp.sockfd = sockfd;
printf("UDP board %s initialized at %s:%d\n",
board_id, ip, port);
return 0;
}
static int _dau_udp_receive(dau_private_data_t *data, void *buf, size_t len)
{
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int data_len = 0;
do
{
data_len = recvfrom(data->comm.udp.sockfd, buf, len, 0,
(struct sockaddr*)&client_addr, &addr_len);
if (data_len <= 0)
{
DBG(DBG_M_PD_DAU_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
continue;
}
// 获取客户端IP和端口
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
int client_port = ntohs(client_addr.sin_port);
//memcpy(&data->comm.add, &client_addr, sizeof(client_addr));
data->comm.udp.addr = client_addr;
printf("Received from %s:%d:\n", client_ip, client_port);
} while(0);
return data_len;
}
static int _dau_udp_transmit(dau_private_data_t *data, const void *buf, size_t len)
{
printf("sockfd=%d\n", data->comm.udp.sockfd);
_print_sockaddr_in(&data->comm.udp.addr);
return sendto(data->comm.udp.sockfd, buf, len, 0,
(struct sockaddr*)&data->comm.udp.addr,
sizeof(data->comm.udp.addr));
}
static void _dau_udp_cleanup(dau_private_data_t *data)
{
if (data->comm.udp.sockfd >= 0)
{
close(data->comm.udp.sockfd);
data->comm.udp.sockfd = -1;
}
if (data->rx_buffer)
{
free(data->rx_buffer);
data->rx_buffer = NULL;
}
printf("UDP board %s cleaned up\n", data->board_id);
}
#endif
#if 0
// ================== RS485 操作函数 ==================
static int _dau_rs485_init(dau_private_data_t *data, const char *config)
{
// 解析配置: "port:baudrate:board_id"
char port[32], board_id[32];
int baudrate;
if (sscanf(config, "%[^:]:%d:%s", port, &baudrate, board_id) != 3) {
return -1;
}
// 打开串口
data->comm.rs485.fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (data->comm.rs485.fd < 0)
{
perror("RS485 open failed");
return -1;
}
// 获取当前串口设置
tcgetattr(data->comm.rs485.fd, &data->comm.rs485.options);
// 设置波特率
cfsetispeed(&data->comm.rs485.options, baudrate);
cfsetospeed(&data->comm.rs485.options, baudrate);
// 设置8N1
data->comm.rs485.options.c_cflag &= ~PARENB;
data->comm.rs485.options.c_cflag &= ~CSTOPB;
data->comm.rs485.options.c_cflag &= ~CSIZE;
data->comm.rs485.options.c_cflag |= CS8;
// 应用设置
tcsetattr(data->comm.rs485.fd, TCSANOW, &data->comm.rs485.options);
strncpy(data->board_id, board_id, sizeof(data->board_id));
strncpy(data->comm.rs485.port, port, sizeof(data->comm.rs485.port));
// 配置缓冲区
data->buffer_size = 1024;
data->rx_buffer = malloc(data->buffer_size);
if (!data->rx_buffer) {
close(data->comm.rs485.fd);
return -1;
}
printf("RS485 board %s initialized on %s@%d\n",
board_id, port, baudrate);
return 0;
}
static int _dau_rs485_receive(dau_private_data_t *data, void *buf, size_t len)
{
return read(data->comm.rs485.fd, buf, len);
}
static int _dau_rs485_transmit(dau_private_data_t *data, const void *buf, size_t len)
{
return write(data->comm.rs485.fd, buf, len);
}
static void _dau_rs485_cleanup(dau_private_data_t *data)
{
if (data->comm.rs485.fd >= 0)
{
close(data->comm.rs485.fd);
data->comm.rs485.fd = -1;
}
if (data->rx_buffer)
{
free(data->rx_buffer);
data->rx_buffer = NULL;
}
printf("RS485 board %s cleaned up\n", data->board_id);
}
// ================== 板卡管理函数 ==================
static void _dau_seek_proper_function(int slot, dau_private_data_t *data)
{
if (strncmp(data->board_id, UHF, strlen(UHF)) == 0)
{
}
else if (strncmp(data->board_id, HF, strlen(HF)) == 0)
{
_hf_recv_process(slot, data->rx_buffer);
}
else if (strncmp(data->board_id, ULTRASONIC, strlen(ULTRASONIC)) == 0)
{
}
else if (strncmp(data->board_id, IRONCORE, strlen(IRONCORE)) == 0)
{
}
}
#endif
static int32_t _dau_find_proper_function(char *pkt)
{
int flag = 0;
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
for (int i = 0; i < PD_SLOTS_MAX; i++)
{
if (daus[i].slot != head->slot)
continue;
if (daus[i].stat == DAU_STATE_REGISTERED)
{
flag = 1;
}
}
if (!flag)
return E_NONE;
if (head->dev_type_m == 0x03)
{
if (head->dev_type_s == 0x01)
{
_hf_recv_process(head->slot, pkt);
}
else if (head->dev_type_s == 0x02)
{}
else if (head->dev_type_s == 0x03)
{}
}
return E_NONE;
}
// 申请板卡私有数据
void* _dau_alloc_private_data(DauType type, int slot)
{
if (type == DAU_TYPE_UDP)
{
udp_client_data *data = malloc(sizeof(udp_client_data));
memset(data, 0, sizeof(udp_client_data));
return data;
}
else if (type == DAU_TYPE_RS485)
{
rs485_device_data *data = malloc(sizeof(rs485_device_data));
memset(data, 0, sizeof(rs485_device_data));
// 根据槽位分配串口设备
//const char *device = (slot == 4) ? "/dev/ttyS0" : "/dev/ttyS1";
//data->fd = init_rs485(device);
data->address = (slot == 4) ? 0x01 : 0x02;
if (data->fd < 0)
{
free(data);
return NULL;
}
return data;
}
return NULL;
}
// 释放板卡私有数据
void _dau_free_private_data(DauType type, void *data)
{
if (!data)
{
return;
}
if (type == DAU_TYPE_UDP)
{
free(data);
}
else if (type == DAU_TYPE_RS485)
{
rs485_device_data *dev = (rs485_device_data*)data;
if (dev->fd >= 0)
{
close(dev->fd);
}
free(data);
}
}
// ================== 板卡管理函数 ==================
#if 0
static void *_dau_thread_func(void *arg)
{
dau_manager_t *manager = (dau_manager_t *)arg;
dau_private_data_t *data = manager->private_data;
prctl(PR_SET_NAME, (unsigned long)data->board_id, 0, 0, 0);
printf("Board thread started for slot %d (%s)\n",
manager->slot, data->board_id);
while (manager->occupied)
{
// 接收数据
ssize_t bytes = manager->ops.receive(data, data->rx_buffer, data->buffer_size);
if (bytes > 0)
{
// 处理数据
printf("Slot %d received %zd bytes\n", manager->slot, bytes);
_dau_seek_proper_function(manager->slot, data);
}
else if (bytes < 0)
{
perror("Receive error");
usleep(100000); // 100ms 延迟后重试
}
}
printf("Board thread exiting for slot %d\n", manager->slot);
return NULL;
}
int _dau_insert(int slot, DauType type, const char *config)
/* 包头填充 */
void _dau_head_init(dau_t *dau, dau_head_init_t *head_data)
{
if (slot < 0 || slot >= MAX_SLOTS) return -1;
pthread_mutex_lock(&dau.mutex);
if (dau.mgr[slot].occupied)
{
pthread_mutex_unlock(&dau.mutex);
return -2; // 槽位已被占用
}
// 创建私有数据
dau_private_data_t *data = malloc(sizeof(dau_private_data_t));
if (!data)
{
pthread_mutex_unlock(&dau.mutex);
return -3;
}
memset(data, 0, sizeof(dau_private_data_t));
data->type = type;
// 设置操作函数
dau_operations_t ops;
switch (type)
{
case DAU_UDP:
ops.init = _dau_udp_init;
ops.receive = _dau_udp_receive;
ops.transmit = _dau_udp_transmit;
ops.cleanup = _dau_udp_cleanup;
break;
case DAU_RS485:
ops.init = _dau_rs485_init;
ops.receive = _dau_rs485_receive;
ops.transmit = _dau_rs485_transmit;
ops.cleanup = _dau_rs485_cleanup;
break;
default:
free(data);
pthread_mutex_unlock(&dau.mutex);
return -4;
}
// 初始化板卡
if (ops.init(data, config) != 0)
{
free(data);
pthread_mutex_unlock(&dau.mutex);
return -5;
}
// 配置管理器
dau.mgr[slot].private_data = data;
dau.mgr[slot].ops = ops;
dau.mgr[slot].slot = slot + 1;
dau.mgr[slot].occupied = TRUE;
// 创建线程
if (pthread_create(&dau.mgr[slot].thread_id, NULL,
_dau_thread_func, &dau.mgr[slot]) != 0)
{
ops.cleanup(data);
free(data);
memset(&dau.mgr[slot], 0, sizeof(dau_manager_t));
pthread_mutex_unlock(&dau.mutex);
return -6;
}
pthread_mutex_unlock(&dau.mutex);
return 0;
}
int _dau_remove(int slot)
{
if (slot < 0 || slot >= MAX_SLOTS) return -1;
pthread_mutex_lock(&dau.mutex);
if (!dau.mgr[slot].occupied)
{
pthread_mutex_unlock(&dau.mutex);
return -2; // 槽位空闲
}
// 设置停止标志
dau.mgr[slot].occupied = FALSE;
// 等待线程结束
pthread_join(dau.mgr[slot].thread_id, NULL);
// 清理资源
dau.mgr[slot].ops.cleanup(dau.mgr[slot].private_data);
free(dau.mgr[slot].private_data);
memset(&dau.mgr[slot], 0, sizeof(dau_manager_t));
pthread_mutex_unlock(&dau.mutex);
return 0;
}
#endif
int _dau_insert(int slot, DauType type)
{
if (slot < 0 || slot >= PD_SLOTS_MAX)
{
return E_BAD_PARAM;
}
pthread_mutex_lock(&board_mutex);
if (daus[slot].stat != DAU_STATE_DISCONNECTED)
{
pthread_mutex_unlock(&board_mutex);
return E_ERROR;
}
// 分配私有数据
void *priv_data = _dau_alloc_private_data(type, slot);
if (!priv_data)
{
pthread_mutex_unlock(&board_mutex);
return E_ERROR;
}
// 更新板卡信息
daus[slot].type = type;
daus[slot].stat = DAU_STATE_CONNECTED;
daus[slot].private_data = priv_data;
daus[slot].slot = slot;
pthread_mutex_unlock(&board_mutex);
printf("Board inserted in slot %d (Type: %s)\n",
slot, (type == DAU_TYPE_UDP) ? "UDP" : "RS485");
return E_NONE;
}
void _dau_remove(int slot)
{
pthread_mutex_lock(&board_mutex);
if (daus[slot].stat == DAU_STATE_DISCONNECTED)
{
pthread_mutex_unlock(&board_mutex);
return;
}
// 释放资源
_dau_free_private_data(daus[slot].type, daus[slot].private_data);
// 重置板卡信息
daus[slot].type = DAU_TYPE_NONE;
daus[slot].stat = DAU_STATE_DISCONNECTED;
daus[slot].private_data = NULL;
pthread_mutex_unlock(&board_mutex);
printf("Board removed from slot %d\n", slot);
dau_pkt_head_t *head = (dau_pkt_head_t*)head_data->pkt;
/* 封装报文头. */
head->len = head_data->len;
head->dev_type_m = dau->info.type_m;
head->dev_type_s= dau->info.type_s;
head->dev_id = dau->info.dev_id;
head->cmd_type = head_data->cmd_type;
head->cmd = head_data->cmd;
head->version = 1;
head->pkt_id = head_data->pkt_id;
}
void _dau_response(int slot, char *buf, int len)
@ -620,97 +79,21 @@ void _dau_response(int slot, char *buf, int len)
}
}
#if 0
int main() {
_board_init_system();
register_upload_callback(example_upload_callback);
// 插入UDP板卡
_board_insert(0, BOARD_UDP, "192.168.1.100:5000:UDP_CARD_1");
_board_insert(1, BOARD_UDP, "192.168.1.101:5000:UDP_CARD_2");
_board_insert(2, BOARD_UDP, "192.168.1.102:5000:UDP_CARD_3");
_board_insert(3, BOARD_UDP, "192.168.1.103:5000:UDP_CARD_4");
// 插入RS485板卡
_board_insert(4, BOARD_RS485, "/dev/ttyS0:115200:RS485_CARD_1");
_board_insert(5, BOARD_RS485, "/dev/ttyS1:115200:RS485_CARD_2");
// 模拟运行
sleep(5);
// 拔出板卡示例
_board_remove(2);
sleep(2);
// 重新插入板卡
_board_insert(2, BOARD_UDP, "192.168.1.104:5000:UDP_CARD_NEW");
sleep(5);
_board_shutdown_system();
return 0;
}
#endif
void *_dau_udp_receive_handle(void *arg)
/* dau 插入处理 */
int _dau_insert(dau_t *dau)
{
prctl(PR_SET_NAME, "DAU_RCVE", 0, 0, 0);
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[2048];
while(1)
if (3 == dau->info.type_m && 1 == dau->info.type_s)
{
ssize_t len = recvfrom(udp_socket, buffer, sizeof(buffer), 0,
(struct sockaddr*)&client_addr, &addr_len);
if (len <= 0) continue;
buffer[len] = '\0';
_print_sockaddr_in(&client_addr);
// 查找匹配的UDP板卡
pthread_mutex_lock(&board_mutex);
for (int i = 0; i < DAU_ETH_SLOTS_SUM; i++)
{
//printf("state=%d\n", daus[i].state);
if (daus[i].stat == DAU_STATE_DISCONNECTED)
continue;
udp_client_data *client = (udp_client_data *)daus[i].private_data;
if (memcmp(&client->addr, &client_addr, sizeof(client_addr)) == 0)
{
break;
dau->recv_cb = hf_recv_process;
}
// 如果是新连接
if (daus[i].stat == DAU_STATE_CONNECTED &&
client->addr.sin_port == 0)
else
{
memcpy(&client->addr, &client_addr, sizeof(client_addr));
daus[i].stat = DAU_STATE_REGISTERED;
break;
return E_NOT_FOUND;
}
}
pthread_mutex_unlock(&board_mutex);
// 处理数据
if (!csg.is_connect)
continue;
_dau_find_proper_function(buffer);
usleep(1000);
}
dau->state.is_connect = TRUE;
return NULL;
return E_NONE;
}
/* 初始化UDP服务器 */
@ -730,7 +113,7 @@ int32_t _dau_udp_server_init(dau_t *dau)
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(DUA_UDP_PORT);
server.sin_port = htons(DUA_UDP_PORT + dau->slot);
if (bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
{
log_err(LOG_DAU, "ERROR at socket bind return %s!", safe_strerror(errno));
@ -742,37 +125,59 @@ int32_t _dau_udp_server_init(dau_t *dau)
return E_NONE;
}
/* 校验收到包的包头, 长度, 校验码. */
int32_t _dau_pkt_check(char *pkt)
/* dau 开机联络处理函数 */
void _dau_recv_connect(dau_t *dau, uint16_t recv_len)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
/* 对主次设备号进行识别, 次设备号可以是广播. */
if (head->dev_type_m != device_info.type_m)
{
DBG(DBG_M_PD_CSG_ERR, "@1 type_m=%d %d\r\n", head->dev_type_m, device_info.type_m);
return E_ERROR;
}
dau_head_init_t head_data;
dau_pkt_head_t *head = (dau_pkt_head_t*)dau->buf_recv;
dau_contact_t *pnet = (dau_contact_t*)(dau->buf_recv + sizeof(dau_pkt_head_t));
dau_ack_t *ack = (dau_ack_t*)(dau->buf_recv + sizeof(dau_pkt_head_t));
/* 复制设备信息 */
memcpy(&dau->info, pnet, sizeof(dau_contact_t));
/* 添加 dau */
LD_N_RETURN_N(_dau_insert(dau));
/* 回复报文 */
ack->result = 0;
head_data.cmd_type = DAU_REQUEST;
head_data.cmd = DAU_C_CONTACT;
head_data.pkt_id = head->pkt_id;
head_data.pkt = dau->buf_recv;
head_data.len = sizeof(dau_pkt_head_t) + sizeof(dau_ack_t);
dau_send_data(dau, &head_data);
if (head->len > DAU_BUF_SIZE)
{
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;
return;
}
/* dau 数据包处理函数 */
void _dau_recv_data_process(dau_t *dau, uint16_t recv_len)
void _dau_recv_data_process(dau_t *dau, uint16_t recv_len, struct sockaddr_in *server)
{
dau_pkt_head_t *head = (dau_pkt_head_t*)dau->buf_recv;
}
if (DAU_REPLY == head->cmd_type && DAU_C_CONTACT == head->cmd)
{
/* 响应连接报文 */
if (head->len > DAU_BUF_SIZE)
{
DBG(DBG_M_PD_DAU_ERR, "Recvfrom len %d ERROR!\r\n", head->len);
return;
}
/* dau 开机联络处理函数 */
void _dau_recv_connect_process(dau_t *dau, uint16_t recv_len)
{
memcpy(&dau->server, server, sizeof(struct sockaddr_in));
_dau_recv_connect(dau, recv_len);
}
else
{
/* 响应其他报文 */
if (dau->recv_cb)
{
dau->recv_cb(dau->slot, dau->buf_recv, recv_len);
}
}
return;
}
/* dau 收包线程 */
@ -780,7 +185,7 @@ void *_dau_recv_handle(void *arg)
{
dau_t *dau = (dau_t*)arg;
struct sockaddr_in server;
socklen_t server_len;
socklen_t server_len = sizeof(struct sockaddr_in);
uint16_t data_len = 0;
/* 初始化 socket */
@ -799,14 +204,7 @@ void *_dau_recv_handle(void *arg)
continue;
}
if (dau->state.is_connect)
{
_dau_recv_data_process(dau, data_len);
}
else
{
_dau_recv_connect_process(dau, data_len);
}
_dau_recv_data_process(dau, data_len, &server);
}
return NULL;
@ -824,9 +222,6 @@ int32_t dau_handle_init(void)
daus[i].slot = i;
}
cmd_install_element(COMMON_NODE, &dau_add_cmd);
cmd_install_element(COMMON_NODE, &no_dau_add_cmd);
return E_NONE;
}
@ -849,4 +244,19 @@ int32_t dau_handle_init_after(void)
return E_NONE;
}
/* 数据发送 */
void dau_send_data(dau_t *dau, dau_head_init_t *head_data)
{
int32_t rv = 0;
/* 封装报文头. */
_dau_head_init(dau, head_data);
rv = sendto(dau->fd, head_data->pkt, head_data->len, 0, (struct sockaddr*)&dau->server, sizeof(dau->server));
if (rv < 0)
{
DBG(DBG_M_PD_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
}
}
#endif

@ -58,84 +58,47 @@
/* Private function prototypes -----------------------------------------------*/
void _hf_contact_recv(int slot, char *pkt);
void _hf_heartbeat_recv(int slot, char *pkt);
void _hf_real_image_recv(int slot, char *pkt);
void _hf_trend_recv(int slot, char *pkt);
void _hf_event_recv(int slot, char *pkt);
extern void _hf_contact_recv(int slot, char *pkt);
extern void _hf_heartbeat_recv(uint8_t slot, char *pkt, uint16_t len);
extern void _hf_real_image_recv(int slot, char *pkt);
extern void _hf_trend_recv(int slot, char *pkt);
extern void _hf_event_recv(uint8_t slot, char *pkt, uint16_t len);
// 命令映射表
static command_entry hf_request_command_table[] =
static dau_recv_fun_cb _hf_command[] =
{
{CSG_C_CONTACT, _hf_contact_recv},
{CSG_C_HEARTBEAT, _hf_heartbeat_recv},
{CMD_INVALID, NULL}
NULL, // 0
NULL, // DAU_C_CONTACT 1
NULL, // DAU_C_ADD_DAU 2
NULL, // DAU_C_RESET 3
NULL, // 4
NULL, // DAU_C_UPDATE 5
NULL, // DAU_C_DEV_INFO_SET 6
NULL, // DAU_C_DEV_INFO_GET 7
NULL, // 8
NULL, // DAU_C_UPDATE_RESULT 9
_hf_heartbeat_recv, // DAU_C_HEARTBEAT 10
};
// 命令映射表
static command_entry hf_prv_request_command_table[] =
static dau_recv_fun_cb _hf_prv_command[] =
{
{CSG_PRV_TREND, _hf_event_recv},
{CSG_PRV_REAL_PRPS, _hf_event_recv},
{CSG_PRV_EVENT, _hf_event_recv},
{CMD_INVALID, NULL}
NULL, // 0
NULL, // DAU_P_CONFIG_SET 1
NULL, // DAU_P_CONFIG_GET 2
NULL, // DAU_P_CONFIG_PORT_SET 3
NULL, // DAU_P_CONFIG_PORT_GET 4
NULL, // DAU_P_CONFIG_REAL_WAVE 5
NULL, // 6
NULL, // 7
NULL, // 8
NULL, // 9
NULL, // DAU_P_TREND 10
NULL, // DAU_P_REAL_PRPS 11
NULL, // DAU_P_EVENT 12
};
/* Interface functions -------------------------------------------------------*/
void _hf_contact_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
csg_contact_t *pnet = (csg_contact_t *)(pkt + sizeof(csg_pkt_head_t));
csg_add_dau_t snd = {0} ;
dau_info_t *pinfo = &daus[slot].info;
memset(pinfo, 0, sizeof(dau_info_t));
pinfo->type_m = pnet->type_m;
pinfo->type_s = pnet->type_s;
pinfo->dev_id = pnet->dev_id;
strncpy(pinfo->hostname, pnet->hostname, sizeof(pinfo->hostname) - 1);
pinfo->factory_date = pnet->factory_date;
pinfo->deployment_date = pnet->deployment_date;
strncpy((char *)pinfo->app_version, (char *)pnet->app_version, sizeof(pinfo->app_version) -1);
strncpy((char *)pinfo->app_compile_time, (char *)pnet->app_compile_time, sizeof(pinfo->app_compile_time) -1);
strncpy((char *)pinfo->hardware_version, (char *)pnet->hardware_version, sizeof(pinfo->hardware_version) -1);
strncpy((char *)pinfo->FPGA_version, (char *)pnet->FPGA_version, sizeof(pinfo->FPGA_version) -1);
pinfo->ip = pnet->ip;
pinfo->mask = pnet->mask;
pinfo->gw = pnet->gw;
memcpy(pinfo->mac, pnet->mac, sizeof(pinfo->mac));
pinfo->server_port = pnet->server_port;
pinfo->server_ipv4 = pnet->server_ipv4;
memcpy(pinfo->port, pnet->port, sizeof(pinfo->port));
memcpy(pinfo->port_type, pnet->port_type, sizeof(pinfo->port_type));
snd.dev_id = pnet->dev_id;
snd.slot = slot;
snd.status = 1;
memcpy(snd.port, pnet->port, sizeof(pnet->port));
memcpy(snd.port_type, pnet->port_type, sizeof(pnet->port_type));
memcpy(pkt + sizeof(csg_pkt_head_t), (char *)&snd, sizeof(csg_add_dau_t));
head->slot = slot;
head->sdev_id = head->dev_id;
printf("recv contact dev_id = 0x%x slot = %d\n", snd.dev_id, snd.slot);
_csg_send_data(CSG_REPLY, CSG_C_ADD_DAU, pkt, sizeof(csg_add_dau_t));
}
void _hf_heartbeat_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
printf("_hf_heartbeat_recv slot = %d\n", slot);
head->cmd_type = CSG_REQUEST;
head->cmd = CSG_C_HEARTBEAT;
head->len = CSG_HEAD_LEN + 4;
uint32_t *timestamp = (uint32_t *)(pkt + CSG_HEAD_LEN);
*timestamp = time(NULL);
_dau_response(slot, pkt, head->len);
}
void _hf_real_image_recv(int slot, char *pkt)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
@ -152,41 +115,106 @@ void _hf_trend_recv(int slot, char *pkt)
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_TREND, pkt, head->len - sizeof(csg_pkt_head_t));
}
void _hf_event_recv(int slot, char *pkt)
/* 心跳报文接收 */
void _hf_heartbeat_recv(uint8_t slot, char *pkt, uint16_t len)
{
csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
head->slot = slot;
head->sdev_id = head->dev_id;
_csg_send_data(CSG_PRV_REPLY, CSG_PRV_EVENT, pkt, head->len - sizeof(csg_pkt_head_t));
dau_head_init_t head_data;
dau_t *dau = &daus[slot];
dau_pkt_head_t *head = (dau_pkt_head_t*)pkt;
dau_heartbeat_t *data = (dau_heartbeat_t*)(pkt + sizeof(dau_pkt_head_t));
uint32_t *timestamp = (uint32_t*)(pkt + sizeof(dau_pkt_head_t));
memcpy(&dau->run_status, data, sizeof(dau_heartbeat_t));
/* 回复报文 */
head_data.cmd_type = DAU_REQUEST;
head_data.cmd = DAU_C_HEARTBEAT;
head_data.pkt_id = head->pkt_id;
head_data.pkt = pkt;
head_data.len = sizeof(dau_pkt_head_t) + 4;
*timestamp = time(NULL);
dau_send_data(dau, &head_data);
return;
}
/* 事件报文接收 */
void _hf_event_recv(uint8_t slot, char *pkt, uint16_t len)
{
//dau_head_init_t head_data;
//dau_t *dau = &daus[slot];
//dau_pkt_head_t *head = (dau_pkt_head_t*)pkt;
//dau_event_head_t *head_event = (dau_event_head_t*)(pkt + sizeof(dau_pkt_head_t));
/* 第一个报文 */
//if (0 == head_event->index)
//{
//}
return;
}
/* 校验收到包的包头, 长度, 校验码. */
int32_t _hf_pkt_check(uint8_t slot, char *pkt)
{
dau_t *dau = &daus[slot];
dau_pkt_head_t *head = (dau_pkt_head_t*)pkt;
/* 对主次设备号进行识别, 次设备号可以是广播. */
if (head->dev_type_m != dau->info.type_m || head->dev_type_s != dau->info.type_s)
{
DBG(DBG_M_PD_HF_ERR, "Device type %d:%d ERROR\r\n", head->dev_type_m, head->dev_type_s);
return E_ERROR;
}
if (head->dev_id != dau->info.dev_id)
{
DBG(DBG_M_PD_HF_ERR, "Device id %08x ERROR\r\n", head->dev_id);
return E_ERROR;
}
if (head->len > DAU_BUF_SIZE)
{
DBG(DBG_M_PD_HF_ERR, "Packet len %d ERROR\r\n", head->len);
return E_ERROR;
}
if ((DAU_REPLY == head->cmd_type && head->cmd >= DAU_C_MAX)
|| (DAU_PRV_REPLY == head->cmd_type && head->cmd >= DAU_P_MAX))
{
DBG(DBG_M_PD_HF_ERR, "Cmd %d:%d ERROR\r\n", head->cmd_type, head->cmd);
return E_ERROR;
}
return E_NONE;
}
int32_t _hf_recv_process(int slot, char *pkt)
/* 高频收包处理函数 */
int32_t hf_recv_process(uint8_t slot, char *pkt, uint16_t len)
{
csg_pkt_head_t *head = (csg_pkt_head_t *)pkt;
command_handler handle = NULL;
dau_pkt_head_t *head = (dau_pkt_head_t*)pkt;
/* 报文头和 CRC 校验. */
LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_pkt_check(pkt));
LD_E_RETURN_N(_hf_pkt_check(slot, pkt));
if (CSG_REPLY == head->cmd_type)
if (DAU_REPLY == head->cmd_type)
{
handle = _csg_get_table_handle(hf_request_command_table, head->cmd);
if (handle)
if (_hf_command[head->cmd])
{
handle(slot, pkt);
_hf_command[head->cmd](slot, pkt, len);
}
}
else if (CSG_PRV_REPLY == head->cmd_type)
{
handle = _csg_get_table_handle(hf_prv_request_command_table, head->cmd);
if (handle)
if (_hf_prv_command[head->cmd])
{
handle(slot, pkt);
_hf_command[head->cmd](slot, pkt, len);
}
}
return E_NONE;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/

@ -265,7 +265,7 @@ const char *safe_strerror(int errnum)
param: buf --
len --
return: */
void buf_print(char *buf, int32_t len)
void buf_print(char *buf, uint32_t len)
{
int32_t i = 0;

@ -63,14 +63,15 @@ dbg_module_t _dbg_module[DBG_M_COUNT] =
{DBG_M_PD_DAU_RECV, FALSE, "pd_dau_recv"},
{DBG_M_PD_DAU_ERR, TRUE, "pd_dau_err"},
{DBG_M_FIFO, FALSE, "fifo"},
{DBG_M_FIFO_ERR, FALSE, "fifo_err"},
{DBG_M_FIFO_ERR, TRUE, "fifo_err"},
{DBG_M_PD_CSG, FALSE, "csg"},
{DBG_M_PD_CSG_ERR, FALSE, "csg_err"},
{DBG_M_PD_NET_ERR, TRUE, "net_err"},
{DBG_M_PD_CSG_ERR, TRUE, "csg_err"},
{DBG_M_PD_NET_ERR, FALSE, "net_err"},
{DBG_M_STORAGE_ERR, FALSE, "stroage"},
{DBG_M_DEBUG, FALSE, "debug"},
{DBG_M_PD_UPGRADE, FALSE, "upgrade"},
{DBG_M_PD_DATA, FALSE, "pd_data"},
{DBG_M_PD_HF, FALSE, "pd_hf"},
{DBG_M_PD_HF_ERR, TRUE, "pd_hf_err"},
};
/* Private function prototypes -----------------------------------------------*/

@ -56,8 +56,6 @@ else ifeq ($(DEFARCH), MYiR)
LDLIB := -L./libother -lreadline -lncurses -pthread -lrt -lsqlite3 -lm -lssh -lssl -lcrypto -lz
endif
# 这里如果是‘@’则隐藏具体的编译命令
QUIET := @
ENULL := > /dev/null

Loading…
Cancel
Save