1. fixed IRQ interrupt

2. changed lwip test command
3. merge dns and ping command
4. change test to cmd_lwip
This commit is contained in:
wlyu 2022-01-07 13:56:54 +08:00
parent ddb889623d
commit 877ef9e221
19 changed files with 556 additions and 546 deletions

View File

@ -121,7 +121,7 @@ static void UdpSocketThreadServer(void *arg)
lw_print("Receive from : %s\n",inet_ntoa(seraddr.sin_addr)); lw_print("Receive from : %s\n",inet_ntoa(seraddr.sin_addr));
lw_print("Recevce data : %s\n\n",recv_data); lw_print("Receive data : %s\n\n",recv_data);
sendto(sock,recv_data, sendto(sock,recv_data,
recv_data_len,0, recv_data_len,0,

View File

@ -71,14 +71,15 @@ static void test_ua_connect(void *arg)
UA_ClientConfig *config = UA_Client_getConfig(client); UA_ClientConfig *config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config); UA_ClientConfig_setDefault(config);
retval = UA_Client_connect(client, test_uri); retval = UA_Client_connect(client, test_uri);
if (retval != UA_STATUSCODE_GOOD) if (retval != UA_STATUSCODE_GOOD)
{ {
ua_print("ua: [%s] connect failed\n", __func__); ua_print("ua: [%s] ret %x\n", __func__, retval);
} }
return; ua_print("ua: [%s] start Ua Test!\n", __func__);
UA_Client_disconnect(client);
UA_Client_delete(client);
} }
void test_ua_connect_thr(void *arg) void test_ua_connect_thr(void *arg)
@ -93,7 +94,6 @@ void test_sh_ua_connect(void)
int result = 0; int result = 0;
pthread_t th_id; pthread_t th_id;
pthread_attr_t attr; pthread_attr_t attr;
sys_thread_new("ua test", test_ua_connect_thr, NULL, 4096, 15); sys_thread_new("ua test", test_ua_connect_thr, NULL, 4096, 15);
} }
@ -117,21 +117,19 @@ void *test_ua_get_server_info(void *param)
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER); UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
if(retval != UA_STATUSCODE_GOOD) { if(retval != UA_STATUSCODE_GOOD) {
ua_print("ua: [%s] connect failed %d\n", __func__, retval); ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
UA_Client_delete(client); UA_Client_delete(client);
return NULL; return NULL;
} }
ua_print("ua: [%s] connect ok!\n", __func__); ua_print("ua: [%s] connect ok!\n", __func__);
while(1) ua_read_time(client);
{ ua_get_server_info(client);
ua_read_time(client);
ua_get_server_info(client);
}
/* Clean up */ /* Clean up */
// UA_Client_disconnect(client); UA_Client_disconnect(client);
// UA_Client_delete(client); /* Disconnects the client internally */ UA_Client_delete(client); /* Disconnects the client internally */
} }
void *test_ua_get_server_info_thr(void *arg) void *test_ua_get_server_info_thr(void *arg)

View File

@ -17,11 +17,17 @@
#define ARCH_MAX_IRQ_NUM (256) #define ARCH_MAX_IRQ_NUM (256)
#define ARCH_IRQ_NUM_OFFSET 0 //#define ARCH_IRQ_NUM_OFFSET 0
#define SYSTICK_IRQN 15 //#define SYSTICK_IRQN 15
#define UART1_IRQn 36 //#define UART1_IRQn 36
#define UART2_IRQn 37 //#define UART2_IRQn 37
#define ARCH_IRQ_NUM_OFFSET 16
#define SYSTICK_IRQN -1
#define UART1_IRQn 20
#define UART2_IRQn 21
int32 ArchEnableHwIrq(uint32 irq_num); int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num); int32 ArchDisableHwIrq(uint32 irq_num);

View File

@ -70,7 +70,6 @@
#include "lwip/igmp.h" #include "lwip/igmp.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
//
//#define USE_RTOS 1 //#define USE_RTOS 1
//#define FSL_RTOS_FREE_RTOS //#define FSL_RTOS_FREE_RTOS
//#define FSL_RTOS_XIUOS //#define FSL_RTOS_XIUOS

View File

@ -32,6 +32,7 @@
#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
#include "lwipopts.h" #include "lwipopts.h"
#include <xs_isr.h>
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
@ -3384,7 +3385,8 @@ void ENET_1588_Timer_IRQHandler(void)
#endif #endif
} }
void ENET_DriverIRQHandler(void) //void ENET_DriverIRQHandler(void)
void ENET_DriverIRQHandler(int vector, void *param)
{ {
ENET_CommonFrame0IRQHandler(ENET); ENET_CommonFrame0IRQHandler(ENET);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
@ -3399,6 +3401,8 @@ void ENET_DriverIRQHandler(void)
#endif #endif
} }
DECLARE_HW_IRQ(ENET_IRQn, ENET_DriverIRQHandler, NONE);
#endif #endif
#if defined(ENET1) #if defined(ENET1)

View File

@ -1,3 +1,3 @@
SRC_DIR += LwIP test SRC_DIR += LwIP cmd_lwip
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,172 +1,177 @@
/* /*
* Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP * Copyright 2016-2019 NXP
* All rights reserved. * All rights reserved.
* *
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
/******************************************************************************* /*******************************************************************************
* Includes * Includes
******************************************************************************/ ******************************************************************************/
#include "lwip/opt.h" #include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_DHCP #if LWIP_IPV4 && LWIP_DHCP
#include "lwip/timeouts.h" #include "lwip/timeouts.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/init.h" #include "lwip/init.h"
#include "lwip/dhcp.h" #include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h" #include "lwip/prot/dhcp.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"
#include "enet_ethernetif.h" #include "enet_ethernetif.h"
#include "board.h" #include "board.h"
#include "pin_mux.h" #include "pin_mux.h"
#include "clock_config.h" #include "clock_config.h"
#include "fsl_gpio.h" #include "fsl_gpio.h"
#include "fsl_iomuxc.h" #include "fsl_iomuxc.h"
#include "sys_arch.h" #include "sys_arch.h"
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
/******************************************************************************* #define LWIP_DHCP_TIME 10000 // 10s
* Prototypes
******************************************************************************/ /*******************************************************************************
* Prototypes
/******************************************************************************* ******************************************************************************/
* Variables
******************************************************************************/ /*******************************************************************************
* Variables
/******************************************************************************* ******************************************************************************/
* Code
******************************************************************************/ /*******************************************************************************
* Code
/*! ******************************************************************************/
* @brief Prints DHCP status of the interface when it has changed from last status.
* /*!
* @param netif network interface structure * @brief Prints DHCP status of the interface when it has changed from last status.
*/ *
int print_dhcp_state(struct netif *netif) * @param netif network interface structure
{ */
static u8_t dhcp_last_state = DHCP_STATE_OFF; int print_dhcp_state(struct netif *netif)
struct dhcp *dhcp = netif_dhcp_data(netif); {
static u8_t dhcp_last_state = DHCP_STATE_OFF;
if (dhcp == NULL) struct dhcp *dhcp = netif_dhcp_data(netif);
{
dhcp_last_state = DHCP_STATE_OFF; if (dhcp == NULL)
} {
else if (dhcp_last_state != dhcp->state) dhcp_last_state = DHCP_STATE_OFF;
{ }
dhcp_last_state = dhcp->state; else if (dhcp_last_state != dhcp->state)
{
lw_pr_info(" DHCP state : "); dhcp_last_state = dhcp->state;
switch (dhcp_last_state)
{ lw_pr_info(" DHCP state : ");
case DHCP_STATE_OFF: switch (dhcp_last_state)
lw_pr_info("OFF"); {
break; case DHCP_STATE_OFF:
case DHCP_STATE_REQUESTING: lw_pr_info("OFF");
lw_pr_info("REQUESTING"); break;
break; case DHCP_STATE_REQUESTING:
case DHCP_STATE_INIT: lw_pr_info("REQUESTING");
lw_pr_info("INIT"); break;
break; case DHCP_STATE_INIT:
case DHCP_STATE_REBOOTING: lw_pr_info("INIT");
lw_pr_info("REBOOTING"); break;
break; case DHCP_STATE_REBOOTING:
case DHCP_STATE_REBINDING: lw_pr_info("REBOOTING");
lw_pr_info("REBINDING"); break;
break; case DHCP_STATE_REBINDING:
case DHCP_STATE_RENEWING: lw_pr_info("REBINDING");
lw_pr_info("RENEWING"); break;
break; case DHCP_STATE_RENEWING:
case DHCP_STATE_SELECTING: lw_pr_info("RENEWING");
lw_pr_info("SELECTING"); break;
break; case DHCP_STATE_SELECTING:
case DHCP_STATE_INFORMING: lw_pr_info("SELECTING");
lw_pr_info("INFORMING"); break;
break; case DHCP_STATE_INFORMING:
case DHCP_STATE_CHECKING: lw_pr_info("INFORMING");
lw_pr_info("CHECKING"); break;
break; case DHCP_STATE_CHECKING:
case DHCP_STATE_BOUND: lw_pr_info("CHECKING");
lw_pr_info("BOUND"); break;
break; case DHCP_STATE_BOUND:
case DHCP_STATE_BACKING_OFF: lw_pr_info("BOUND");
lw_pr_info("BACKING_OFF"); break;
break; case DHCP_STATE_BACKING_OFF:
default: lw_pr_info("BACKING_OFF");
lw_pr_info("%u", dhcp_last_state); break;
assert(0); default:
break; lw_pr_info("%u", dhcp_last_state);
} assert(0);
lw_pr_info("\r\n"); break;
}
if (dhcp_last_state == DHCP_STATE_BOUND) lw_pr_info("\r\n");
{
lw_pr_info("\r\n IPv4 Address : %s\r\n", ipaddr_ntoa(&netif->ip_addr)); if (dhcp_last_state == DHCP_STATE_BOUND)
lw_pr_info(" IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask)); {
lw_pr_info(" IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw)); lw_pr_info("\r\n IPv4 Address : %s\r\n", ipaddr_ntoa(&netif->ip_addr));
return 1; lw_pr_info(" IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask));
} lw_pr_info(" IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw));
} return 1;
return 0; }
} }
return 0;
/*! }
* @brief Main function.
*/ /*!
void lwip_dhcp_test(void) * @brief Main function.
{ */
static int flag = 0; void lwip_dhcp_test(void)
char ip_addr[4] = {0, 0, 0, 0}; {
u32_t dhcp_time;
ETH_BSP_Config(); static int flag = 0;
char ip_addr[4] = {0, 0, 0, 0};
lwip_config_net(ip_addr, ip_addr, ip_addr);
is_lwip_test = 1; ETH_BSP_Config();
dhcp_start(&gnetif); lwip_config_net(ip_addr, ip_addr, ip_addr);
is_lwip_test = 1;
lw_pr_info("\r\n************************************************\r\n");
lw_pr_info(" DHCP example\r\n"); dhcp_start(&gnetif);
lw_pr_info("************************************************\r\n");
lw_print("\r\n************************************************\r\n");
while (1) lw_print(" DHCP example\r\n");
{ lw_print("************************************************\r\n");
/* Poll the driver, get any outstanding frames */
ethernetif_input(&gnetif); dhcp_time = sys_now();
/* Handle all system timeouts for all core protocols */ while ((sys_now() - dhcp_time) < LWIP_DHCP_TIME)
sys_check_timeouts(); {
/* Poll the driver, get any outstanding frames */
/* Print DHCP progress */ ethernetif_input(&gnetif);
if(print_dhcp_state(&gnetif))
{ /* Handle all system timeouts for all core protocols */
sscanf(ipaddr_ntoa(&gnetif.ip_addr), "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], sys_check_timeouts();
&lwip_ipaddr[2], &lwip_ipaddr[3]);
/* Print DHCP progress */
sscanf(ipaddr_ntoa(&gnetif.netmask), "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], if(print_dhcp_state(&gnetif))
&lwip_netmask[2], &lwip_netmask[3]); {
sscanf(ipaddr_ntoa(&gnetif.ip_addr), "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1],
sscanf(ipaddr_ntoa(&gnetif.gw), "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
&lwip_gwaddr[2], &lwip_gwaddr[3]);
sscanf(ipaddr_ntoa(&gnetif.netmask), "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1],
break; &lwip_netmask[2], &lwip_netmask[3]);
}
} sscanf(ipaddr_ntoa(&gnetif.gw), "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1],
&lwip_gwaddr[2], &lwip_gwaddr[3]);
is_lwip_test = 0;
} break;
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
getip, lwip_dhcp_test, DHCP_Test); is_lwip_test = 0;
}
#endif
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
getdynip, lwip_dhcp_test, DHCP_Test);
#endif

View File

@ -93,7 +93,19 @@ void lwip_ping_thread(int argc, char *argv[])
else if(argc == 2) else if(argc == 2)
{ {
lw_print("lw: [%s] gw %s\n", __func__, argv[1]); lw_print("lw: [%s] gw %s\n", __func__, argv[1]);
sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); if(isdigit(argv[1][0]))
{
if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF)
{
lw_pr_info("input wrong ip\n");
return;
}
}
else
{
get_url_ip(argv[1]);
return;
}
} }
lw_print("lw: [%s] argc %d\n", __func__, argc); lw_print("lw: [%s] argc %d\n", __func__, argc);
@ -107,18 +119,4 @@ void lwip_ping_thread(int argc, char *argv[])
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
ping, lwip_ping_thread, ping [IP] 3 times); ping, lwip_ping_thread, ping [IP] 3 times);
int lwip_dns_test(int argc, char **argv)
{
if (argc <= 1)
{
lw_pr_info("Please input: ping <host address>\n");
return 0;
}
get_url_ip(argv[1]);
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(2),
dns, lwip_dns_test, dns [url]);
#endif #endif

View File

@ -1,302 +1,302 @@
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of and a contribution to the lwIP TCP/IP stack. * This file is part of and a contribution to the lwIP TCP/IP stack.
* *
* Credits go to Adam Dunkels (and the current maintainers) of this software. * Credits go to Adam Dunkels (and the current maintainers) of this software.
* *
* Christiaan Simons rewrote this file to get a more stable echo example. * Christiaan Simons rewrote this file to get a more stable echo example.
*/ */
/** /**
* @file * @file
* TCP echo server example using raw API. * TCP echo server example using raw API.
* *
* Echos all bytes sent by connecting client, * Echos all bytes sent by connecting client,
* and passively closes when client is done. * and passively closes when client is done.
* *
*/ */
#include "lwip/opt.h" #include "lwip/opt.h"
#include "lwip/debug.h" #include "lwip/debug.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/tcp.h" #include "lwip/tcp.h"
#include "tcpecho_raw.h" #include "tcpecho_raw.h"
#if LWIP_TCP && LWIP_CALLBACK_API #if LWIP_TCP && LWIP_CALLBACK_API
static struct tcp_pcb *tcpecho_raw_pcb; static struct tcp_pcb *tcpecho_raw_pcb;
enum tcpecho_raw_states enum tcpecho_raw_states
{ {
ES_NONE = 0, ES_NONE = 0,
ES_ACCEPTED, ES_ACCEPTED,
ES_RECEIVED, ES_RECEIVED,
ES_CLOSING ES_CLOSING
}; };
struct tcpecho_raw_state struct tcpecho_raw_state
{ {
u8_t state; u8_t state;
u8_t retries; u8_t retries;
struct tcp_pcb *pcb; struct tcp_pcb *pcb;
/* pbuf (chain) to recycle */ /* pbuf (chain) to recycle */
struct pbuf *p; struct pbuf *p;
}; };
static void static void
tcpecho_raw_free(struct tcpecho_raw_state *es) tcpecho_raw_free(struct tcpecho_raw_state *es)
{ {
if (es != NULL) { if (es != NULL) {
if (es->p) { if (es->p) {
/* free the buffer chain if present */ /* free the buffer chain if present */
pbuf_free(es->p); pbuf_free(es->p);
} }
mem_free(es); mem_free(es);
} }
} }
static void static void
tcpecho_raw_close(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es) tcpecho_raw_close(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es)
{ {
tcp_arg(tpcb, NULL); tcp_arg(tpcb, NULL);
tcp_sent(tpcb, NULL); tcp_sent(tpcb, NULL);
tcp_recv(tpcb, NULL); tcp_recv(tpcb, NULL);
tcp_err(tpcb, NULL); tcp_err(tpcb, NULL);
tcp_poll(tpcb, NULL, 0); tcp_poll(tpcb, NULL, 0);
tcpecho_raw_free(es); tcpecho_raw_free(es);
tcp_close(tpcb); tcp_close(tpcb);
} }
static void static void
tcpecho_raw_send(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es) tcpecho_raw_send(struct tcp_pcb *tpcb, struct tcpecho_raw_state *es)
{ {
struct pbuf *ptr; struct pbuf *ptr;
err_t wr_err = ERR_OK; err_t wr_err = ERR_OK;
while ((wr_err == ERR_OK) && while ((wr_err == ERR_OK) &&
(es->p != NULL) && (es->p != NULL) &&
(es->p->len <= tcp_sndbuf(tpcb))) { (es->p->len <= tcp_sndbuf(tpcb))) {
ptr = es->p; ptr = es->p;
/* enqueue data for transmission */ /* enqueue data for transmission */
wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1); wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);
if (wr_err == ERR_OK) { if (wr_err == ERR_OK) {
u16_t plen; u16_t plen;
plen = ptr->len; plen = ptr->len;
/* continue with next pbuf in chain (if any) */ /* continue with next pbuf in chain (if any) */
es->p = ptr->next; es->p = ptr->next;
if(es->p != NULL) { if(es->p != NULL) {
/* new reference! */ /* new reference! */
pbuf_ref(es->p); pbuf_ref(es->p);
} }
/* chop first pbuf from chain */ /* chop first pbuf from chain */
pbuf_free(ptr); pbuf_free(ptr);
/* we can read more data now */ /* we can read more data now */
tcp_recved(tpcb, plen); tcp_recved(tpcb, plen);
} else if(wr_err == ERR_MEM) { } else if(wr_err == ERR_MEM) {
/* we are low on memory, try later / harder, defer to poll */ /* we are low on memory, try later / harder, defer to poll */
es->p = ptr; es->p = ptr;
} else { } else {
/* other problem ?? */ /* other problem ?? */
} }
} }
} }
static void static void
tcpecho_raw_error(void *arg, err_t err) tcpecho_raw_error(void *arg, err_t err)
{ {
struct tcpecho_raw_state *es; struct tcpecho_raw_state *es;
LWIP_UNUSED_ARG(err); LWIP_UNUSED_ARG(err);
es = (struct tcpecho_raw_state *)arg; es = (struct tcpecho_raw_state *)arg;
tcpecho_raw_free(es); tcpecho_raw_free(es);
} }
static err_t static err_t
tcpecho_raw_poll(void *arg, struct tcp_pcb *tpcb) tcpecho_raw_poll(void *arg, struct tcp_pcb *tpcb)
{ {
err_t ret_err; err_t ret_err;
struct tcpecho_raw_state *es; struct tcpecho_raw_state *es;
es = (struct tcpecho_raw_state *)arg; es = (struct tcpecho_raw_state *)arg;
if (es != NULL) { if (es != NULL) {
if (es->p != NULL) { if (es->p != NULL) {
/* there is a remaining pbuf (chain) */ /* there is a remaining pbuf (chain) */
tcpecho_raw_send(tpcb, es); tcpecho_raw_send(tpcb, es);
} else { } else {
/* no remaining pbuf (chain) */ /* no remaining pbuf (chain) */
if(es->state == ES_CLOSING) { if(es->state == ES_CLOSING) {
tcpecho_raw_close(tpcb, es); tcpecho_raw_close(tpcb, es);
} }
} }
ret_err = ERR_OK; ret_err = ERR_OK;
} else { } else {
/* nothing to be done */ /* nothing to be done */
tcp_abort(tpcb); tcp_abort(tpcb);
ret_err = ERR_ABRT; ret_err = ERR_ABRT;
} }
return ret_err; return ret_err;
} }
static err_t static err_t
tcpecho_raw_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) tcpecho_raw_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{ {
struct tcpecho_raw_state *es; struct tcpecho_raw_state *es;
LWIP_UNUSED_ARG(len); LWIP_UNUSED_ARG(len);
es = (struct tcpecho_raw_state *)arg; es = (struct tcpecho_raw_state *)arg;
es->retries = 0; es->retries = 0;
if(es->p != NULL) { if(es->p != NULL) {
/* still got pbufs to send */ /* still got pbufs to send */
tcp_sent(tpcb, tcpecho_raw_sent); tcp_sent(tpcb, tcpecho_raw_sent);
tcpecho_raw_send(tpcb, es); tcpecho_raw_send(tpcb, es);
} else { } else {
/* no more pbufs to send */ /* no more pbufs to send */
if(es->state == ES_CLOSING) { if(es->state == ES_CLOSING) {
tcpecho_raw_close(tpcb, es); tcpecho_raw_close(tpcb, es);
} }
} }
return ERR_OK; return ERR_OK;
} }
static err_t static err_t
tcpecho_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) tcpecho_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{ {
struct tcpecho_raw_state *es; struct tcpecho_raw_state *es;
err_t ret_err; err_t ret_err;
LWIP_ASSERT("arg != NULL",arg != NULL); LWIP_ASSERT("arg != NULL",arg != NULL);
es = (struct tcpecho_raw_state *)arg; es = (struct tcpecho_raw_state *)arg;
if (p == NULL) { if (p == NULL) {
/* remote host closed connection */ /* remote host closed connection */
es->state = ES_CLOSING; es->state = ES_CLOSING;
if(es->p == NULL) { if(es->p == NULL) {
/* we're done sending, close it */ /* we're done sending, close it */
tcpecho_raw_close(tpcb, es); tcpecho_raw_close(tpcb, es);
} else { } else {
/* we're not done yet */ /* we're not done yet */
tcpecho_raw_send(tpcb, es); tcpecho_raw_send(tpcb, es);
} }
ret_err = ERR_OK; ret_err = ERR_OK;
} else if(err != ERR_OK) { } else if(err != ERR_OK) {
/* cleanup, for unknown reason */ /* cleanup, for unknown reason */
if (p != NULL) { if (p != NULL) {
pbuf_free(p); pbuf_free(p);
} }
ret_err = err; ret_err = err;
} }
else if(es->state == ES_ACCEPTED) { else if(es->state == ES_ACCEPTED) {
/* first data chunk in p->payload */ /* first data chunk in p->payload */
es->state = ES_RECEIVED; es->state = ES_RECEIVED;
/* store reference to incoming pbuf (chain) */ /* store reference to incoming pbuf (chain) */
es->p = p; es->p = p;
tcpecho_raw_send(tpcb, es); tcpecho_raw_send(tpcb, es);
ret_err = ERR_OK; ret_err = ERR_OK;
} else if (es->state == ES_RECEIVED) { } else if (es->state == ES_RECEIVED) {
/* read some more data */ /* read some more data */
if(es->p == NULL) { if(es->p == NULL) {
es->p = p; es->p = p;
tcpecho_raw_send(tpcb, es); tcpecho_raw_send(tpcb, es);
} else { } else {
struct pbuf *ptr; struct pbuf *ptr;
/* chain pbufs to the end of what we recv'ed previously */ /* chain pbufs to the end of what we recv'ed previously */
ptr = es->p; ptr = es->p;
pbuf_cat(ptr,p); pbuf_cat(ptr,p);
} }
ret_err = ERR_OK; ret_err = ERR_OK;
} else { } else {
/* unkown es->state, trash data */ /* unkown es->state, trash data */
tcp_recved(tpcb, p->tot_len); tcp_recved(tpcb, p->tot_len);
pbuf_free(p); pbuf_free(p);
ret_err = ERR_OK; ret_err = ERR_OK;
} }
return ret_err; return ret_err;
} }
static err_t static err_t
tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err) tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{ {
err_t ret_err; err_t ret_err;
struct tcpecho_raw_state *es; struct tcpecho_raw_state *es;
LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(arg);
if ((err != ERR_OK) || (newpcb == NULL)) { if ((err != ERR_OK) || (newpcb == NULL)) {
return ERR_VAL; return ERR_VAL;
} }
/* Unless this pcb should have NORMAL priority, set its priority now. /* Unless this pcb should have NORMAL priority, set its priority now.
When running out of pcbs, low priority pcbs can be aborted to create When running out of pcbs, low priority pcbs can be aborted to create
new pcbs of higher priority. */ new pcbs of higher priority. */
tcp_setprio(newpcb, TCP_PRIO_MIN); tcp_setprio(newpcb, TCP_PRIO_MIN);
es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state)); es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state));
if (es != NULL) { if (es != NULL) {
es->state = ES_ACCEPTED; es->state = ES_ACCEPTED;
es->pcb = newpcb; es->pcb = newpcb;
es->retries = 0; es->retries = 0;
es->p = NULL; es->p = NULL;
/* pass newly allocated es to our callbacks */ /* pass newly allocated es to our callbacks */
tcp_arg(newpcb, es); tcp_arg(newpcb, es);
tcp_recv(newpcb, tcpecho_raw_recv); tcp_recv(newpcb, tcpecho_raw_recv);
tcp_err(newpcb, tcpecho_raw_error); tcp_err(newpcb, tcpecho_raw_error);
tcp_poll(newpcb, tcpecho_raw_poll, 0); tcp_poll(newpcb, tcpecho_raw_poll, 0);
tcp_sent(newpcb, tcpecho_raw_sent); tcp_sent(newpcb, tcpecho_raw_sent);
ret_err = ERR_OK; ret_err = ERR_OK;
} else { } else {
ret_err = ERR_MEM; ret_err = ERR_MEM;
} }
return ret_err; return ret_err;
} }
void void
tcpecho_raw_init(void) tcpecho_raw_init(void)
{ {
tcpecho_raw_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); tcpecho_raw_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (tcpecho_raw_pcb != NULL) { if (tcpecho_raw_pcb != NULL) {
err_t err; err_t err;
err = tcp_bind(tcpecho_raw_pcb, IP_ANY_TYPE, LWIP_TEST_TCP_PORT); err = tcp_bind(tcpecho_raw_pcb, IP_ANY_TYPE, LWIP_TEST_TCP_PORT);
if (err == ERR_OK) { if (err == ERR_OK) {
tcpecho_raw_pcb = tcp_listen(tcpecho_raw_pcb); tcpecho_raw_pcb = tcp_listen(tcpecho_raw_pcb);
tcp_accept(tcpecho_raw_pcb, tcpecho_raw_accept); tcp_accept(tcpecho_raw_pcb, tcpecho_raw_accept);
} else { } else {
/* abort? output diagnostic? */ /* abort? output diagnostic? */
} }
} else { } else {
/* abort? output diagnostic? */ /* abort? output diagnostic? */
} }
} }
#endif /* LWIP_TCP && LWIP_CALLBACK_API */ #endif /* LWIP_TCP && LWIP_CALLBACK_API */

View File

@ -1,37 +1,37 @@
/* /*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * 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 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. * OF SUCH DAMAGE.
* *
* This file is part of the lwIP TCP/IP stack. * This file is part of the lwIP TCP/IP stack.
* *
*/ */
#ifndef LWIP_TCPECHO_RAW_H #ifndef LWIP_TCPECHO_RAW_H
#define LWIP_TCPECHO_RAW_H #define LWIP_TCPECHO_RAW_H
#define LWIP_TEST_TCP_PORT 4840 #define LWIP_TEST_TCP_PORT 4840
void tcpecho_raw_init(void); void tcpecho_raw_init(void);
#endif /* LWIP_TCPECHO_RAW_H */ #endif /* LWIP_TCPECHO_RAW_H */