Я использую LWIP (2.1.3) на LPC546xx со связью по 2 портам. После инициализации TCPIP вызывается port_init (), port2_init () для портов binf 23,24. Когда я получаю данные, я передаю их функциям task_port1 и task_port2. Когда у меня есть данные, я вызываю функцию send_response_port, send_response_port2. Это работает, но моя проблема в том, что он иногда теряет ответный пакет, а иногда застревает, поэтому его необходимо сбросить.
Правильно ли я использую ссылку на pcbAcceptedport, которую я сохраняю в переменной в функции port_accept?
Спасибо.
static struct tcp_pcb *pcbAcceptedport = NULL;
static struct tcp_pcb *pcbAcceptedport2 = NULL;
void
port1_init(void)
{
pcbAcceptedport = tcp_new();
if (pcbAcceptedport != NULL)
{
err_t err;
err = tcp_bind(pcbAcceptedport, IP_ADDR_ANY, 23);
if (err == ERR_OK)
{
pcbAcceptedport = tcp_listen(pcbAcceptedport);
tcp_accept(pcbAcceptedport, port_accept);
}
else
{
/* abort? output diagnostic? */
}
}
else
{
/* abort? output diagnostic? */
}
}
static void port_close_conn(struct tcp_pcb *pcb){
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_close(pcb);
}
static err_t port_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){
int i;
int len;
char *pc;
if (err == ERR_OK && p != NULL) {
/* Inform TCP that we have taken the data. */
u32_rec_port = p->tot_len;
tcp_recved(pcbAcceptedport, u32_rec_port);
task_port1(p);
//Free the packet buffer
pbuf_free(p);
} else {
pbuf_free(p);
}
if (err == ERR_OK && p == NULL) {
port_close_conn(pcb);
}
return ERR_OK;
}
void port_error(void *arg, err_t err)
{
LWIP_UNUSED_ARG(err);
}
static err_t port_accept(void *arg, struct tcp_pcb *pcb, err_t err){
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
tcp_setprio(pcb, TCP_PRIO_NORMAL);
tcp_recv(pcb, port_recv);
tcp_err(pcb, port_error); //Don't care about error here
tcp_poll(pcb, NULL, 4); //No polling here
pcbAcceptedport = pcb;
return ERR_OK;
}
err_t port_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
LWIP_UNUSED_ARG(len);
return ERR_OK;
}
err_t send_response_port(uint8_t *data, uint32_t len){
err_t e = 0xFF;
//check output buffer capacity
if (len < tcp_sndbuf(pcbAcceptedPort)){
e = tcp_write(pcbAcceptedport, data, len, 0);
if(e == ERR_OK){
tcp_sent(pcbAcceptedport, port_sent); /* No need to call back */
if(e == ERR_OK){
tcp_recved(pcbAcceptedport, u32_rec_port);
e = tcp_output(pcbAcceptedport);
}
}
}
return e;
}
/************************************************************/
void
port2_init(void)
{
pcbAcceptedPort2 = tcp_new();
if (pcbAcceptedPort2 != NULL)
{
err_t err;
err = tcp_bind(pcbAcceptedPort2, IP_ADDR_ANY, 24);
if (err == ERR_OK)
{
pcbAcceptedPort2 = tcp_listen(pcbAcceptedPort2);
tcp_accept(pcbAcceptedPort2, port2_accept);
}
else
{
/* abort? output diagnostic? */
}
}
else
{
/* abort? output diagnostic? */
}
}
static void port2_close_conn(struct tcp_pcb *pcb){
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
tcp_close(pcb);
}
static err_t port2_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){
if (err == ERR_OK && p != NULL) {
/* Inform TCP that we have taken the data. */
u32_rec_Port2 = p->tot_len;
tcp_recved(pcbAcceptedPort2, u32_rec_Port2);
task_port2(p);
//Free the packet buffer
pbuf_free(p);
} else {
pbuf_free(p);
}
if (err == ERR_OK && p == NULL) {
port2_close_conn(pcb);
}
return ERR_OK;
}
void port2_error(void *arg, err_t err)
{
LWIP_UNUSED_ARG(err);
}
static err_t port2_accept(void *arg, struct tcp_pcb *pcb, err_t err){
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
tcp_setprio(pcb, TCP_PRIO_NORMAL);
tcp_recv(pcb, port2_recv);
tcp_err(pcb, port2_error); //Don't care about error here
tcp_poll(pcb, NULL, 4); //No polling here
pcbAcceptedPort2 = pcb;
return ERR_OK;
}
err_t Port2_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
LWIP_UNUSED_ARG(len);
return ERR_OK;
}
err_t send_response_Port2(uint8_t *data, uint32_t len){
err_t e = 0xFF;
if (len <= tcp_sndbuf(pcbAcceptedPort2)){
e = tcp_write(pcbAcceptedPort2, data, len, 0);
if(e == ERR_OK){
tcp_sent(pcbAcceptedPort2, Port2_sent); /* No need to call back */
if(e == ERR_OK){
e = tcp_output(pcbAcceptedPort2);
}
}
}
return e;
}