|
|
@ -27,16 +27,58 @@
|
|
|
|
#include "pd_csg.h"
|
|
|
|
#include "pd_csg.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* Define --------------------------------------------------------------------*/
|
|
|
|
/* Define --------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#define DUA_UDP_PORT 23760
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* 上传平台回调函数类型 */
|
|
|
|
|
|
|
|
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 ---------------------------------------------------------*/
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
//dau_t dau;
|
|
|
|
|
|
|
|
pthread_mutex_t board_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
pthread_mutex_t board_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
int udp_socket;
|
|
|
|
int udp_socket;
|
|
|
|
dau_t daus[PD_SLOTS_MAX];
|
|
|
|
dau_t daus[PD_SLOTS_MAX];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 上传平台回调函数类型
|
|
|
|
|
|
|
|
typedef void (*UploadCallback)(int slot, const void *data, size_t len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
int _dau_insert(int slot, DauType type);
|
|
|
|
int _dau_insert(int slot, DauType type);
|
|
|
@ -287,7 +329,7 @@ static int32_t _dau_find_proper_function(char *pkt)
|
|
|
|
if (daus[i].slot != head->slot)
|
|
|
|
if (daus[i].slot != head->slot)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (daus[i].state == DAU_STATE_REGISTERED)
|
|
|
|
if (daus[i].stat == DAU_STATE_REGISTERED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
flag = 1;
|
|
|
|
flag = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -507,7 +549,7 @@ int _dau_insert(int slot, DauType type)
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&board_mutex);
|
|
|
|
pthread_mutex_lock(&board_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
if (daus[slot].state != DAU_STATE_DISCONNECTED)
|
|
|
|
if (daus[slot].stat != DAU_STATE_DISCONNECTED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
|
return E_ERROR;
|
|
|
|
return E_ERROR;
|
|
|
@ -523,7 +565,7 @@ int _dau_insert(int slot, DauType type)
|
|
|
|
|
|
|
|
|
|
|
|
// 更新板卡信息
|
|
|
|
// 更新板卡信息
|
|
|
|
daus[slot].type = type;
|
|
|
|
daus[slot].type = type;
|
|
|
|
daus[slot].state = DAU_STATE_CONNECTED;
|
|
|
|
daus[slot].stat = DAU_STATE_CONNECTED;
|
|
|
|
daus[slot].private_data = priv_data;
|
|
|
|
daus[slot].private_data = priv_data;
|
|
|
|
daus[slot].slot = slot;
|
|
|
|
daus[slot].slot = slot;
|
|
|
|
|
|
|
|
|
|
|
@ -538,7 +580,7 @@ void _dau_remove(int slot)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&board_mutex);
|
|
|
|
pthread_mutex_lock(&board_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
if (daus[slot].state == DAU_STATE_DISCONNECTED)
|
|
|
|
if (daus[slot].stat == DAU_STATE_DISCONNECTED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -549,7 +591,7 @@ void _dau_remove(int slot)
|
|
|
|
|
|
|
|
|
|
|
|
// 重置板卡信息
|
|
|
|
// 重置板卡信息
|
|
|
|
daus[slot].type = DAU_TYPE_NONE;
|
|
|
|
daus[slot].type = DAU_TYPE_NONE;
|
|
|
|
daus[slot].state = DAU_STATE_DISCONNECTED;
|
|
|
|
daus[slot].stat = DAU_STATE_DISCONNECTED;
|
|
|
|
daus[slot].private_data = NULL;
|
|
|
|
daus[slot].private_data = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
|
pthread_mutex_unlock(&board_mutex);
|
|
|
@ -612,45 +654,10 @@ int main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化UDP服务器
|
|
|
|
|
|
|
|
int _dau_init_udp_server()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
|
|
|
if (sock < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
perror("UDP socket creation failed");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct sockaddr_in server_addr =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
.sin_family = AF_INET,
|
|
|
|
|
|
|
|
.sin_port = htons(UDP_PORT),
|
|
|
|
|
|
|
|
.sin_addr.s_addr = INADDR_ANY
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
perror("UDP bind failed");
|
|
|
|
|
|
|
|
close(sock);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return sock;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void *_dau_manager_handle(void *arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
prctl(PR_SET_NAME, "CSG_RCVE", 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void *_dau_udp_receive_handle(void *arg)
|
|
|
|
void *_dau_udp_receive_handle(void *arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -674,7 +681,7 @@ void *_dau_udp_receive_handle(void *arg)
|
|
|
|
for (int i = 0; i < DAU_ETH_SLOTS_SUM; i++)
|
|
|
|
for (int i = 0; i < DAU_ETH_SLOTS_SUM; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//printf("state=%d\n", daus[i].state);
|
|
|
|
//printf("state=%d\n", daus[i].state);
|
|
|
|
if (daus[i].state == DAU_STATE_DISCONNECTED)
|
|
|
|
if (daus[i].stat == DAU_STATE_DISCONNECTED)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
udp_client_data *client = (udp_client_data *)daus[i].private_data;
|
|
|
|
udp_client_data *client = (udp_client_data *)daus[i].private_data;
|
|
|
@ -684,11 +691,11 @@ void *_dau_udp_receive_handle(void *arg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是新连接
|
|
|
|
// 如果是新连接
|
|
|
|
if (daus[i].state == DAU_STATE_CONNECTED &&
|
|
|
|
if (daus[i].stat == DAU_STATE_CONNECTED &&
|
|
|
|
client->addr.sin_port == 0)
|
|
|
|
client->addr.sin_port == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
memcpy(&client->addr, &client_addr, sizeof(client_addr));
|
|
|
|
memcpy(&client->addr, &client_addr, sizeof(client_addr));
|
|
|
|
daus[i].state = DAU_STATE_REGISTERED;
|
|
|
|
daus[i].stat = DAU_STATE_REGISTERED;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -705,11 +712,117 @@ void *_dau_udp_receive_handle(void *arg)
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 初始化UDP服务器 */
|
|
|
|
|
|
|
|
int32_t _dau_udp_server_init(dau_t *dau)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct sockaddr_in server = {0};
|
|
|
|
|
|
|
|
int fd = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_err(LOG_DAU, "ERROR at socket creating 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(DUA_UDP_PORT);
|
|
|
|
|
|
|
|
if (bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_err(LOG_DAU, "ERROR at socket bind return %s!", safe_strerror(errno));
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dau->fd = fd;
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 校验收到包的包头, 长度, 校验码. */
|
|
|
|
|
|
|
|
int32_t _dau_pkt_check(char *pkt)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* dau 数据包处理函数 */
|
|
|
|
|
|
|
|
void _dau_recv_data_process(dau_t *dau, uint16_t recv_len)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* dau 开机联络处理函数 */
|
|
|
|
|
|
|
|
void _dau_recv_connect_process(dau_t *dau, uint16_t recv_len)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* dau 收包线程 */
|
|
|
|
|
|
|
|
void *_dau_recv_handle(void *arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dau_t *dau = (dau_t*)arg;
|
|
|
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
|
|
|
socklen_t server_len;
|
|
|
|
|
|
|
|
uint16_t data_len = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 初始化 socket */
|
|
|
|
|
|
|
|
if (_dau_udp_server_init(dau) != E_NONE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* 读取数据. */
|
|
|
|
|
|
|
|
data_len = recvfrom(dau->fd, dau->buf_recv, DAU_BUF_SIZE, 0, (struct sockaddr*)&server, &server_len);
|
|
|
|
|
|
|
|
if (data_len <= 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
DBG(DBG_M_PD_DAU_ERR, "Recvfrom return ERROR %s!\r\n", safe_strerror(errno));
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (dau->state.is_connect)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_dau_recv_data_process(dau, data_len);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_dau_recv_connect_process(dau, data_len);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* dau 预初始化 */
|
|
|
|
/* dau 预初始化 */
|
|
|
|
int32_t dau_handle_init(void)
|
|
|
|
int32_t dau_handle_init(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
memset(&daus, 0, sizeof(dau_t) * PD_SLOTS_MAX);
|
|
|
|
memset(&daus, 0, sizeof(dau_t) * PD_SLOTS_MAX);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < PD_SLOTS_MAX; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
daus[i].slot = i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cmd_install_element(COMMON_NODE, &dau_add_cmd);
|
|
|
|
cmd_install_element(COMMON_NODE, &dau_add_cmd);
|
|
|
|
cmd_install_element(COMMON_NODE, &no_dau_add_cmd);
|
|
|
|
cmd_install_element(COMMON_NODE, &no_dau_add_cmd);
|
|
|
@ -723,19 +836,14 @@ int32_t dau_handle_init_after(void)
|
|
|
|
thread_param_t param = {0};
|
|
|
|
thread_param_t param = {0};
|
|
|
|
uint8_t i = 0;
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (0 == udp_socket)
|
|
|
|
/* 初始收包线程 */
|
|
|
|
{
|
|
|
|
|
|
|
|
udp_socket = _dau_init_udp_server();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("udp_socket=%d\n", udp_socket);
|
|
|
|
|
|
|
|
/* 初始化模块. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < DAU_ETH_SLOTS_SUM; i++)
|
|
|
|
for (i = 0; i < DAU_ETH_SLOTS_SUM; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
param.arg = (void*)(&daus[i]);
|
|
|
|
param.priority = 80;
|
|
|
|
param.priority = 80;
|
|
|
|
|
|
|
|
param.log_module = LOG_DAU;
|
|
|
|
snprintf(param.thread_name, THREAD_NAME_LEN, "DAU_RECV_%d", i);
|
|
|
|
snprintf(param.thread_name, THREAD_NAME_LEN, "DAU_RECV_%d", i);
|
|
|
|
create_thread(_dau_manager_handle, ¶m);
|
|
|
|
create_thread(_dau_recv_handle, ¶m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
return E_NONE;
|
|
|
|