260 lines
7.3 KiB
C
260 lines
7.3 KiB
C
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "lwip/err.h"
|
|
#include "lwip/tcp.h"
|
|
#include "ql_log.h"
|
|
|
|
extern struct netif *t2n_if;
|
|
#define LOGD(msg, ...) QL_LOG(QL_LOG_LEVEL_DEBUG, "modbus_tcp", msg, ##__VA_ARGS__)
|
|
#define LOGI(msg, ...) QL_LOG(QL_LOG_LEVEL_INFO, "modbus_tcp", msg, ##__VA_ARGS__)
|
|
#define LOGW(msg, ...) QL_LOG(QL_LOG_LEVEL_WARN, "modbus_tcp", msg, ##__VA_ARGS__)
|
|
#define LOGE(msg, ...) QL_LOG(QL_LOG_LEVEL_ERROR, "modbus_tcp", msg, ##__VA_ARGS__)
|
|
struct tcp_pcb *gps1_acce_newpacb[1]; // 只能容纳1个客户端
|
|
struct tcp_pcb *gps2_acce_newpacb[1]; // 只能容纳1个客户端
|
|
#define NMEA_TCP_SEND_BUF_LEN 512
|
|
// static char nmea1_tcp_sendBuf[NMEA_TCP_SEND_BUF_LEN] = {0}; // 发送缓冲区 // gga+rmc[512]
|
|
// static char nmea2_tcp_sendBuf[NMEA_TCP_SEND_BUF_LEN] = {0}; // 发送缓冲区 // gga+rmc[512]
|
|
// int nmea1_idx = 0;
|
|
// int nmea2_idx = 0;
|
|
typedef struct
|
|
{
|
|
int index;
|
|
char data[NMEA_TCP_SEND_BUF_LEN];
|
|
} tcp_send_buf_t;
|
|
|
|
tcp_send_buf_t nmea_tcp_send_buf[2];
|
|
/**
|
|
* @brief Gps Tcp数据发送处理
|
|
*
|
|
* @param newpcb
|
|
* @param input_line
|
|
* @return int
|
|
*/
|
|
int NmeaTcp_send(uint8_t gps_id, char *input_line)
|
|
{
|
|
struct tcp_pcb *newpcb = NULL;
|
|
tcp_send_buf_t *tcp_send_buf = NULL;
|
|
if (gps_id == 0)
|
|
{
|
|
newpcb = gps1_acce_newpacb[0];
|
|
tcp_send_buf = &nmea_tcp_send_buf[0];
|
|
}
|
|
else if (gps_id == 1)
|
|
{
|
|
newpcb = gps2_acce_newpacb[0];
|
|
tcp_send_buf = &nmea_tcp_send_buf[1];
|
|
}
|
|
else
|
|
{
|
|
return ERR_ARG;
|
|
}
|
|
if (newpcb == NULL || input_line == NULL || tcp_send_buf == NULL)
|
|
{
|
|
return ERR_ARG;
|
|
}
|
|
int input_len = strlen(input_line);
|
|
if (tcp_send_buf->index == 0)
|
|
{
|
|
strncpy(tcp_send_buf->data, input_line, NMEA_TCP_SEND_BUF_LEN - 2); // 入参已经确保为字符串
|
|
tcp_send_buf->index = input_len;
|
|
tcp_send_buf->data[tcp_send_buf->index++] = '\r';
|
|
tcp_send_buf->data[tcp_send_buf->index++] = '\n';
|
|
}
|
|
else
|
|
{
|
|
strncpy(&tcp_send_buf->data[tcp_send_buf->index], input_line, NMEA_TCP_SEND_BUF_LEN - tcp_send_buf->index - 2); // 入参已经确保为字符串
|
|
tcp_send_buf->index += input_len;
|
|
tcp_send_buf->data[tcp_send_buf->index++] = '\r';
|
|
tcp_send_buf->data[tcp_send_buf->index++] = '\n';
|
|
tcp_write(newpcb, tcp_send_buf->data, tcp_send_buf->index, 1);
|
|
tcp_send_buf->index = 0;
|
|
tcp_output(newpcb);
|
|
}
|
|
|
|
// if (*nmea_idx == 0)
|
|
// { // 当前只判断第一字节是否为0和长度是否为0
|
|
// // memset(nmea_tcp_sendBuf, 0x00, NMEA_TCP_SEND_BUF_LEN);
|
|
// strncpy(nmea_tcp_sendBuf, input_line, input_len); // 入参已经确保为字符串
|
|
// nmea_tcp_sendBuf[input_len] = '\r';
|
|
// nmea_tcp_sendBuf[input_len + 1] = '\n';
|
|
// *nmea_idx += input_len + 2;
|
|
// }
|
|
// else
|
|
// {
|
|
// int buf_len = strlen(nmea_tcp_sendBuf);
|
|
// if (input_len > (NMEA_TCP_SEND_BUF_LEN - buf_len))
|
|
// { // 查询剩余空间是否充足
|
|
// nmea_tcp_sendBuf[buf_len] = '\r';
|
|
// nmea_tcp_sendBuf[buf_len + 1] = '\n';
|
|
// buf_len = buf_len + 2;
|
|
// log_printf(LDEBUG, LOG_TAG "A:NmeaTcp_send buf:%s,len:%d\n", nmea_tcp_sendBuf, buf_len);
|
|
// tcp_write(newpcb, nmea_tcp_sendBuf, buf_len, 1);
|
|
// tcp_output(newpcb);
|
|
// }
|
|
// else
|
|
// {
|
|
// strcpy(nmea_tcp_sendBuf + buf_len, input_line);
|
|
// buf_len = strlen(nmea_tcp_sendBuf);
|
|
// nmea_tcp_sendBuf[buf_len] = '\r';
|
|
// nmea_tcp_sendBuf[buf_len + 1] = '\n';
|
|
// buf_len = buf_len + 2;
|
|
// log_printf(LDEBUG, LOG_TAG "B:NmeaTcp_send buf:%s,len:%d\n", nmea_tcp_sendBuf, buf_len);
|
|
// tcp_write(newpcb, nmea_tcp_sendBuf, buf_len, 1);
|
|
// tcp_output(newpcb);
|
|
// }
|
|
// memset(nmea_tcp_sendBuf, 0x00, NMEA_TCP_SEND_BUF_LEN);
|
|
// }
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Gps Tcp数据接收处理
|
|
*
|
|
* @param arg
|
|
* @param newpcb
|
|
* @param p
|
|
* @param err
|
|
* @return err_t
|
|
*/
|
|
static err_t Gps1NmeaTcp_recv(void *arg, struct tcp_pcb *newpcb, struct pbuf *p, err_t err)
|
|
{
|
|
if (p != NULL)
|
|
{
|
|
uint8_t *rxbuf;
|
|
int rxlen;
|
|
tcp_recved(newpcb, p->tot_len);
|
|
rxbuf = (uint8_t *)p->payload;
|
|
rxlen = p->len;
|
|
LOGI("rxlen = %d,rxbuf = %d",rxlen,rxbuf);
|
|
pbuf_free(p);
|
|
}
|
|
else if (err == ERR_OK)
|
|
{
|
|
LOGW("gps1 remote end is closing the connection\n");
|
|
for (uint8_t i = 0; i < 1; i++)
|
|
{ // 清空所有客户端
|
|
gps1_acce_newpacb[i] = 0;
|
|
}
|
|
tcp_err(newpcb, NULL);
|
|
tcp_recv(newpcb, NULL);
|
|
tcp_poll(newpcb, NULL, 120);
|
|
err_t err_p = tcp_close(newpcb);
|
|
if (ERR_OK != err_p)
|
|
{
|
|
LOGE("gps1 close error. err:%d\n", err_p);
|
|
}
|
|
return err_p;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
static err_t Gps2NmeaTcp_recv(void *arg, struct tcp_pcb *newpcb, struct pbuf *p, err_t err)
|
|
{
|
|
if (p != NULL)
|
|
{
|
|
uint8_t *rxbuf;
|
|
int rxlen;
|
|
tcp_recved(newpcb, p->tot_len);
|
|
rxbuf = (uint8_t *)p->payload;
|
|
rxlen = p->len;
|
|
pbuf_free(p);
|
|
LOGI("rxlen = %d,rxbuf = %d",rxlen,rxbuf);
|
|
}
|
|
else if (err == ERR_OK)
|
|
{
|
|
LOGW("gps2 remote end is closing the connection\n");
|
|
for (uint8_t i = 0; i < 1; i++)
|
|
{ // 清空所有客户端
|
|
gps2_acce_newpacb[i] = 0;
|
|
}
|
|
tcp_err(newpcb, NULL);
|
|
tcp_recv(newpcb, NULL);
|
|
tcp_poll(newpcb, NULL, 120);
|
|
err_t err_p = tcp_close(newpcb);
|
|
if (ERR_OK != err_p)
|
|
{
|
|
LOGE("gps2 close error. err:%d\n", err_p);
|
|
}
|
|
return err_p;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
/**
|
|
* @brief Gps Tcp client连接错误处理
|
|
*
|
|
* @param arg
|
|
* @param err
|
|
*/
|
|
static void NmeaTcp_conn_err(void *arg, err_t err)
|
|
{
|
|
LOGE("connection error, err:%d\n", err);
|
|
}
|
|
|
|
static err_t NmeaTcp_poll(void *arg, struct tcp_pcb *newpcb)
|
|
{
|
|
if (newpcb)
|
|
{
|
|
LOGI("close pcb\n");
|
|
tcp_close(newpcb);
|
|
newpcb = NULL;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Gps1 Tcp client连接处理
|
|
*
|
|
* @param arg
|
|
* @param newpcb
|
|
* @param err
|
|
* @return err_t
|
|
*/
|
|
static err_t Gps1NmeaTcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|
{
|
|
tcp_err(newpcb, NmeaTcp_conn_err);
|
|
tcp_recv(newpcb, Gps1NmeaTcp_recv);
|
|
tcp_poll(newpcb, NmeaTcp_poll, 120);
|
|
gps1_acce_newpacb[0] = newpcb;
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Gps2 Tcp client连接处理
|
|
*
|
|
* @param arg
|
|
* @param newpcb
|
|
* @param err
|
|
* @return err_t
|
|
*/
|
|
static err_t Gps2NmeaTcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|
{
|
|
tcp_err(newpcb, NmeaTcp_conn_err);
|
|
tcp_recv(newpcb, Gps2NmeaTcp_recv);
|
|
tcp_poll(newpcb, NmeaTcp_poll, 120);
|
|
gps2_acce_newpacb[0] = newpcb;
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Gps2 Tcp server初始化处理
|
|
*
|
|
*/
|
|
void NmeaTcp_init(void)
|
|
{
|
|
struct tcp_pcb *pcb_gps1;
|
|
pcb_gps1 = tcp_new();
|
|
tcp_bind(pcb_gps1, NULL, 6061);
|
|
tcp_bind_netif(pcb_gps1, t2n_if);
|
|
pcb_gps1 = tcp_listen(pcb_gps1);
|
|
tcp_accept(pcb_gps1, Gps1NmeaTcp_accept);
|
|
LOGD("Gps1 Nmea Tcp server listen port:%d\n", 6061);
|
|
|
|
struct tcp_pcb *pcb_gps2;
|
|
pcb_gps2 = tcp_new();
|
|
tcp_bind(pcb_gps2, NULL, 6062);
|
|
tcp_bind_netif(pcb_gps2, t2n_if);
|
|
pcb_gps2 = tcp_listen(pcb_gps2);
|
|
tcp_accept(pcb_gps2, Gps2NmeaTcp_accept);
|
|
LOGD("Gps2 Nmea Tcp server listen port:%d\n", 6062);
|
|
}
|