diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c index 08452c8ee..b018be453 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c @@ -38,7 +38,7 @@ char tcp_socket_ip[] = {192, 168, 250, 252}; -#define TCP_BUF_SIZE 1024 +#define TCP_DEMO_BUF_SIZE 65535 /******************************************************************************* * Code @@ -46,17 +46,15 @@ char tcp_socket_ip[] = {192, 168, 250, 252}; static void tcp_recv_demo(void *arg) { - lw_print("tcp_recv_demo start.\n"); - - int fd = -1; - char *recv_buf; - struct sockaddr_in tcp_addr, server_addr; + int fd = -1, clientfd; int recv_len; + char *recv_buf; + struct sockaddr_in tcp_addr; socklen_t addr_len; while(1) { - recv_buf = (char *)malloc(TCP_BUF_SIZE); + recv_buf = (char *)malloc(TCP_DEMO_BUF_SIZE); if (recv_buf == NULL) { lw_print("No memory\n"); @@ -72,7 +70,7 @@ static void tcp_recv_demo(void *arg) tcp_addr.sin_family = AF_INET; tcp_addr.sin_addr.s_addr = INADDR_ANY; - tcp_addr.sin_port = htons(LOCAL_PORT_SERVER); + tcp_addr.sin_port = htons(LWIP_LOCAL_PORT); memset(&(tcp_addr.sin_zero), 0, sizeof(tcp_addr.sin_zero)); if (bind(fd, (struct sockaddr *)&tcp_addr, sizeof(struct sockaddr)) == -1) @@ -81,16 +79,30 @@ static void tcp_recv_demo(void *arg) goto __exit; } - lw_print("tcp bind sucess, start to receive.\n"); - lw_print("\n\nLocal Port:%d\n\n", LOCAL_PORT_SERVER); + lw_print("tcp bind success, start to receive.\n"); + lw_print("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT); + + // setup socket fd as listening mode + if (listen(fd, 5) != 0 ) + { + lw_print("Unable to listen\n"); + goto __exit; + } + + // accept client connection + clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len); + lw_print("client %s connected\n", inet_ntoa(tcp_addr.sin_addr)); while(1) { - memset(recv_buf, 0, TCP_BUF_SIZE); - recv_len = recvfrom(fd, recv_buf, TCP_BUF_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len); - lw_pr_info("Receive from : %s\n", inet_ntoa(server_addr.sin_addr)); - lw_pr_info("Receive data : %s\n\n", recv_buf); - sendto(fd, recv_buf, recv_len, 0, (struct sockaddr*)&server_addr, addr_len); + memset(recv_buf, 0, TCP_DEMO_BUF_SIZE); + recv_len = recvfrom(clientfd, recv_buf, TCP_DEMO_BUF_SIZE, 0, (struct sockaddr *)&tcp_addr, &addr_len); + if(recv_len > 0) + { + lw_pr_info("Receive from : %s\n", inet_ntoa(tcp_addr.sin_addr)); + lw_pr_info("Receive data : %d - %s\n\n", recv_len, recv_buf); + } + sendto(clientfd, recv_buf, recv_len, 0, (struct sockaddr*)&tcp_addr, addr_len); } __exit: @@ -116,7 +128,7 @@ void tcp_socket_recv_run(int argc, char *argv[]) ETH_BSP_Config(); lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr); - sys_thread_new("tcp_recv_demo", tcp_recv_demo, NULL, 4096, 15); + sys_thread_new("tcp_recv_demo", tcp_recv_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), @@ -124,11 +136,12 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | static void tcp_send_demo(void *arg) { - int cnt = TEST_LWIP_TIMES; - lw_print("tcp_send_demo start.\n"); + int cnt = LWIP_DEMO_TIMES; int fd = -1; char send_msg[128]; + lw_print("%s start\n", __func__); + memset(send_msg, 0, sizeof(send_msg)); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) @@ -139,8 +152,8 @@ static void tcp_send_demo(void *arg) struct sockaddr_in tcp_sock; tcp_sock.sin_family = AF_INET; - tcp_sock.sin_port = htons(TARGET_PORT_CLIENT); - tcp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(tcp_socket_ip[0],tcp_socket_ip[1],tcp_socket_ip[2],tcp_socket_ip[3])); + tcp_sock.sin_port = htons(LWIP_TARGET_PORT); + tcp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(tcp_socket_ip[0], tcp_socket_ip[1], tcp_socket_ip[2], tcp_socket_ip[3])); memset(&(tcp_sock.sin_zero), 0, sizeof(tcp_sock.sin_zero)); if (connect(fd, (struct sockaddr *)&tcp_sock, sizeof(struct sockaddr))) @@ -150,14 +163,14 @@ static void tcp_send_demo(void *arg) } lw_print("tcp connect success, start to send.\n"); - lw_print("\n\nTarget Port:%d\n\n", tcp_sock.sin_port); + lw_pr_info("\n\nTarget Port:%d\n\n", tcp_sock.sin_port); while (cnt --) { lw_print("Lwip client is running.\n"); snprintf(send_msg, sizeof(send_msg), "TCP test package times %d\r\n", cnt); sendto(fd, send_msg, strlen(send_msg), 0, (struct sockaddr*)&tcp_sock, sizeof(struct sockaddr)); - lw_print("Send tcp msg: %s ", send_msg); + lw_pr_info("Send tcp msg: %s ", send_msg); MdelayKTask(1000); } @@ -178,8 +191,8 @@ void tcp_socket_send_run(int argc, char *argv[]) } ETH_BSP_Config(); - lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr); - sys_thread_new("tcp socket", tcp_send_demo, NULL, 4096, 25); + lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip); + sys_thread_new("tcp socket", tcp_send_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c index 3f71783a3..b04311f5f 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c @@ -78,7 +78,7 @@ static void udp_recv_demo(void *arg) udp_addr.sin_family = AF_INET; udp_addr.sin_addr.s_addr = INADDR_ANY; - udp_addr.sin_port = htons(LOCAL_PORT_SERVER); + udp_addr.sin_port = htons(LWIP_LOCAL_PORT); memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero)); if (bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) @@ -88,7 +88,7 @@ static void udp_recv_demo(void *arg) } lw_print("UDP bind sucess, start to receive.\n"); - lw_print("\n\nLocal Port:%d\n\n", LOCAL_PORT_SERVER); + lw_print("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT); while(1) { @@ -135,7 +135,7 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | static void udp_send_demo(void *arg) { - int cnt = TEST_LWIP_TIMES; + int cnt = LWIP_DEMO_TIMES; char send_str[128]; lw_print("udp_send_demo start.\n"); @@ -152,7 +152,7 @@ static void udp_send_demo(void *arg) struct sockaddr_in udp_sock; udp_sock.sin_family = AF_INET; - udp_sock.sin_port = htons(TARGET_PORT_CLIENT); + udp_sock.sin_port = htons(LWIP_TARGET_PORT); udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0],udp_target[1],udp_target[2],udp_target[3])); memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero)); diff --git a/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c b/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c index 76634b9d4..9e948c81f 100755 --- a/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c +++ b/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c @@ -28,10 +28,9 @@ /******************************************************************************* * Definitions ******************************************************************************/ -//#define ua_print KPrintf -#define ua_trace() KPrintf("ua: [%s] %d pass!\n", __func__, __LINE__) #define TCP_LOCAL_PORT 4840 +#define UA_URL_SIZE 100 /******************************************************************************* * Prototypes @@ -41,24 +40,19 @@ * Variables ******************************************************************************/ -const char *test_uri = "opc.tcp://192.168.250.5:4840"; -const char *test_cb_str = "tcp client connected\r\n"; - -char test_ua_gw[] = {192, 168, 250, 5}; - -static pthread_t eth_input_id = 0; -static pthread_t ua_demo_id; +char test_ua_ip[] = {192, 168, 250, 5}; /******************************************************************************* * Code ******************************************************************************/ -void *test_ua_get_server_info(void *param); - static void test_ua_connect(void *arg) { struct netif net; UA_StatusCode retval; + char ua_uri[UA_URL_SIZE]; + + memset(ua_uri, 0, sizeof(ua_uri)); UA_Client *client = UA_Client_new(); @@ -71,7 +65,10 @@ static void test_ua_connect(void *arg) UA_ClientConfig *config = UA_Client_getConfig(client); UA_ClientConfig_setDefault(config); - retval = UA_Client_connect(client, test_uri); + snprintf(ua_uri, UA_URL_SIZE, "opc.tcp://%d.%d.%d.%d:4840", + test_ua_ip[0], test_ua_ip[1], test_ua_ip[2], test_ua_ip[3]); + + retval = UA_Client_connect(client, ua_uri); if (retval != UA_STATUSCODE_GOOD) { ua_print("ua: [%s] ret %x\n", __func__, retval); @@ -85,7 +82,7 @@ static void test_ua_connect(void *arg) void test_ua_connect_thr(void *arg) { ETH_BSP_Config(); - lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_gw); + lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip); test_ua_connect(NULL); } @@ -100,16 +97,16 @@ void test_sh_ua_connect(void) SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), UaConnect, test_sh_ua_connect, Test Opc UA connection); -void *test_ua_get_server_info(void *param) +void test_ua_browser_objects(void *param) { UA_Client *client = UA_Client_new(); - ua_print("ua: [%s] start ...\n", __func__); + ua_pr_info("ua: [%s] start ...\n", __func__); if (client == NULL) { ua_print("ua: [%s] tcp client null\n", __func__); - return NULL; + return; } UA_ClientConfig *config = UA_Client_getConfig(client); @@ -119,12 +116,69 @@ void *test_ua_get_server_info(void *param) if(retval != UA_STATUSCODE_GOOD) { ua_print("ua: [%s] connect failed %#x\n", __func__, retval); UA_Client_delete(client); - return NULL; + return; } ua_print("ua: [%s] connect ok!\n", __func__); + ua_pr_info("--- start read time ---\n", __func__); ua_read_time(client); + + ua_pr_info("--- get server info ---\n", __func__); + ua_browser_objects(client); + + /* Clean up */ + UA_Client_disconnect(client); + UA_Client_delete(client); /* Disconnects the client internally */ +} + +void *test_sh_ua_brower_objects(int argc, char *argv[]) +{ + if(argc == 2) + { + if(isdigit(argv[1][0])) + { + if(sscanf(argv[1], "%d.%d.%d.%d", &test_ua_ip[0], &test_ua_ip[1], &test_ua_ip[2], &test_ua_ip[3]) == EOF) + { + lw_pr_info("input wrong ip\n"); + return NULL; + } + } + } + + ETH_BSP_Config(); + lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip); + sys_thread_new("ua object", test_ua_browser_objects, NULL, 4096, 15); + return NULL; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), + UaObj, test_sh_ua_brower_objects, UaObj [IP]); + +void test_ua_get_info(void *param) +{ + UA_Client *client = UA_Client_new(); + + ua_pr_info("ua: [%s] start ...\n", __func__); + + if (client == NULL) + { + ua_print("ua: [%s] tcp client null\n", __func__); + return; + } + + UA_ClientConfig *config = UA_Client_getConfig(client); + UA_ClientConfig_setDefault(config); + + UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER); + if(retval != UA_STATUSCODE_GOOD) { + ua_print("ua: [%s] connect failed %#x\n", __func__, retval); + UA_Client_delete(client); + return; + } + + ua_print("ua: [%s] connect ok!\n", __func__); + ua_pr_info("--- get server info ---\n", __func__); ua_get_server_info(client); /* Clean up */ @@ -132,29 +186,26 @@ void *test_ua_get_server_info(void *param) UA_Client_delete(client); /* Disconnects the client internally */ } -void *test_ua_get_server_info_thr(void *arg) +void *test_sh_ua_get_info(int argc, char *argv[]) { - ETH_BSP_Config(); - lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_gw); - test_ua_get_server_info(NULL); -} - -void *test_sh_ua_get_server_info(void *param) -{ - int result = 0; - pthread_attr_t attr; - - attr.schedparam.sched_priority = 15; - attr.stacksize = 4096; - - result = pthread_create(&ua_demo_id, &attr, test_ua_get_server_info_thr, NULL); - if (0 == result) { - lw_print("test_ua_get_server_info %d successfully!\n", __func__, ua_demo_id); - } else { - lw_print("test_ua_get_server_info failed! error code is %d\n", __func__, result); + if(argc == 2) + { + if(isdigit(argv[1][0])) + { + if(sscanf(argv[1], "%d.%d.%d.%d", &test_ua_ip[0], &test_ua_ip[1], &test_ua_ip[2], &test_ua_ip[3]) == EOF) + { + lw_pr_info("input wrong ip\n"); + return NULL; + } + } } + + ETH_BSP_Config(); + lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip); + sys_thread_new("ua object", test_ua_browser_objects, NULL, 4096, 15); + return NULL; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), - UaGetInfo, test_sh_ua_get_server_info, Get information from OpcUA server); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), + UaInfo, test_sh_ua_get_info, UaInfo [IP]); diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c b/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c index 961f243a1..d94e28a6b 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c @@ -46,9 +46,7 @@ #endif #include "open62541.h" - -#define ua_print KPrintf -#define ua_trace() KPrintf("ua: [%s] line %d checked!\n", __func__, __LINE__) +#include "ua_api.h" #if LWIP_DNS @@ -7147,6 +7145,8 @@ encodeWithExchangeBuffer(const void *ptr, const UA_DataType *type, Ctx *ctx) { ctx->pos = oldpos; /* Set to the last known good position and exchange */ ret = exchangeBuffer(ctx); UA_CHECK_STATUS(ret, return ret); + + ua_print("ua: [%s] exchange kind %d ret %d\n", __func__, type->typeKind, ret); ret = encodeBinaryJumpTable[type->typeKind](ptr, type, ctx); } return ret; @@ -7493,6 +7493,11 @@ Array_encodeBinary(const void *src, size_t length, const UA_DataType *type, Ctx ret = Array_encodeBinaryComplex((uintptr_t)src, length, type, ctx); } UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); + + //tst by wly + ua_debug("ua: [%s] src %p len %d %d type %p <%d> <%d> %p ret %d\n", __func__, + src, length, signed_length, *type, type->typeKind, type->overlayable, ctx, ret); + return ret; } @@ -8335,6 +8340,26 @@ encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) { const UA_DataType *mt = m->memberType; ptr += m->padding; + if(mt->typeKind > UA_DATATYPEKINDS) + { + ua_debug("ua: [%s] %d type %d %p ptr %p failed\n", __func__, i, mt->typeKind, m->memberType, ptr); + return ret; + } + + ua_debug("ua: [%s] > %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, + i, + type->membersSize, + mt, + mt->typeKind, + mt->memSize, + ctx->depth, + ptr, + src, + ((UA_TcpMessageHeader *)src)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)src)->messageSize, + m->isArray, + ret); + /* Array. Buffer-exchange is done inside Array_encodeBinary if required. */ if(m->isArray) { const size_t length = *((const size_t*)ptr); @@ -8348,6 +8373,21 @@ encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) { /* Scalar */ ret = encodeWithExchangeBuffer((const void*)ptr, mt, ctx); UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); + + ua_debug("ua: [%s] >> %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, + i, + type->membersSize, + mt, + mt->typeKind, + mt->memSize, + ctx->depth, + ptr, + src, + ((UA_TcpMessageHeader *)src)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)src)->messageSize, + m->isArray, + ret); + ptr += mt->memSize; } @@ -8584,20 +8624,70 @@ decodeBinaryStructure(void *dst, const UA_DataType *type, Ctx *ctx) { const UA_DataType *mt = m->memberType; ptr += m->padding; + if(mt->typeKind >= UA_DATATYPEKINDS) + { + ua_debug("ua: [%s] fail %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d>\n", __func__, + i, + membersSize, + mt, + mt->typeKind, + mt->memSize, + ctx->depth, + ptr, + dst, + ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize); + + return ret; + } + + ua_debug("ua: [%s] > %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, + i, + membersSize, + mt, + mt->typeKind, + mt->memSize, + ctx->depth, + ptr, + dst, + ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize, + m->isArray, + ret); + /* Array */ if(m->isArray) { size_t *length = (size_t*)ptr; ptr += sizeof(size_t); ret = Array_decodeBinary((void *UA_RESTRICT *UA_RESTRICT)ptr, length, mt , ctx); ptr += sizeof(void*); + ua_debug("ua: [%s] %d ret %d ptr %p len %d\n", __func__, i, ret, ptr, length); continue; } /* Scalar */ ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx); ptr += mt->memSize; + + ua_debug("ua: [%s] >> %d < %d dep %d msg %p %p:<%x> <%d> ret %d\n", __func__, + i, + membersSize, + ctx->depth, + ptr, + dst, + ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize, + ret); } + ua_debug("ua: [%s] >>> dep %d msg %p %p:<%x> <%d> ret %d\n", __func__, + ctx->depth, + ptr, + dst, + ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize, + ret); + ctx->depth--; return ret; } @@ -8739,8 +8829,18 @@ UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset, /* Decode */ memset(dst, 0, type->memSize); /* Initialize the value */ + + ua_debug("ua: [%s] t %d mem %d len %d off %d pos %d end %d dst %p type %x size %x\n", __func__, + type->typeKind, type->memSize, src->length, *offset, *ctx.pos, *ctx.end, + dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize); + status ret = decodeBinaryJumpTable[type->typeKind](dst, type, &ctx); + ua_debug("ua: [%s] -> t %d dst %p type %x size %x ret %d\n", __func__, + type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize, ret); + if(UA_LIKELY(ret == UA_STATUSCODE_GOOD)) { /* Set the new offset */ *offset = (size_t)(ctx.pos - src->data) / sizeof(u8); @@ -8748,7 +8848,16 @@ UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset, /* Clean up */ UA_clear(dst, type); memset(dst, 0, type->memSize); + + ua_debug("ua: [%s] => t %d dst %p type %x size %x\n", __func__, + type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize); } + + ua_debug("ua: [%s] #> off %d %p %p t %d dst %p type %x size %x\n", __func__, *offset, + ctx.pos, src->data, + type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, + ((UA_TcpMessageHeader *)dst)->messageSize); return ret; } @@ -18516,6 +18625,12 @@ processChunks(UA_SecureChannel *channel, void *application, channel->decryptedChunksCount > channel->config.localMaxChunkCount) || (channel->config.localMaxMessageSize != 0 && channel->decryptedChunksLength > channel->config.localMaxMessageSize)) { + ua_print("ua: [%s] count %d max %d len %d mess %d\n", + channel->decryptedChunksCount, + channel->config.localMaxChunkCount, + channel->decryptedChunksLength, + channel->config.localMaxMessageSize + ); return UA_STATUSCODE_BADTCPMESSAGETOOLARGE; } @@ -18552,6 +18667,10 @@ extractCompleteChunk(UA_SecureChannel *channel, const UA_ByteString *buffer, UA_StatusCode res = UA_decodeBinaryInternal(buffer, &initial_offset, &hdr, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], NULL); + + ua_debug("ua: [%s] res %d buf %p offset %d hdr %d size %d\n", __func__, res, buffer, *offset, + hdr.messageTypeAndChunkType, hdr.messageSize); + UA_assert(res == UA_STATUSCODE_GOOD); (void)res; /* pacify compilers if assert is ignored */ UA_MessageType msgType = (UA_MessageType) @@ -18563,7 +18682,10 @@ extractCompleteChunk(UA_SecureChannel *channel, const UA_ByteString *buffer, if(hdr.messageSize < UA_SECURECHANNEL_MESSAGE_MIN_LENGTH) return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; if(hdr.messageSize > channel->config.recvBufferSize) + { + ua_debug("lw: [%s] msg size %d rec %d\n", __func__, hdr.messageSize, channel->config.recvBufferSize); return UA_STATUSCODE_BADTCPMESSAGETOOLARGE; + } /* Incomplete chunk */ if(hdr.messageSize > remaining) { @@ -44134,6 +44256,8 @@ UA_Client_run_iterate(UA_Client *client, UA_UInt32 timeout) { client->sessionState < UA_SESSIONSTATE_ACTIVATED) { retval = connectIterate(client, timeout); notifyClientState(client); + lw_print("lw: [%s] ret %d timeout %d state %d ch %d\n", __func__, retval, timeout, + client->sessionState, client->channel.state); return retval; } @@ -45075,21 +45199,21 @@ connectIterate(UA_Client *client, UA_UInt32 timeout) { return UA_STATUSCODE_BADCONNECTIONCLOSED; } + ua_debug("ua: [%s] conn %d state %d handle %p\n", __func__, client->connectStatus, + client->connection.state, client->connection.handle); + /* The connection is closed. Reset the SecureChannel and open a new TCP * connection */ if(client->connection.state == UA_CONNECTIONSTATE_CLOSED) return initConnect(client); - ua_print("ua: [%s] state %d %d handle %p\n", __func__, client->connectStatus, - client->connection.state, client->connection.handle); - /* Poll the connection status */ if(client->connection.state == UA_CONNECTIONSTATE_OPENING) { client->connectStatus = client->config.pollConnectionFunc(&client->connection, timeout, &client->config.logger); - ua_print("ua: [%s] exit conn %x %d time %d handle %p\n", __func__, + ua_debug("ua: [%s] exit conn %x %d time %d handle %p\n", __func__, client->connectStatus, client->connection.state, timeout, client->connection.handle); @@ -45175,6 +45299,7 @@ connectIterate(UA_Client *client, UA_UInt32 timeout) { break; } + lw_print("lw: [%s] sess %d conn %d\n", __func__, client->sessionState, client->connectStatus); return client->connectStatus; } @@ -45286,6 +45411,8 @@ connectSync(UA_Client *client) { UA_DateTime now = UA_DateTime_nowMonotonic(); UA_DateTime maxDate = now + ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC); + ua_print("ua; [%s] time %d\n", __func__, (UA_DateTime)client->config.timeout); + UA_StatusCode retval = initConnect(client); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -68096,6 +68223,9 @@ void UA_Log_Stdout_log(void *context, UA_LogLevel level, UA_LogCategory category, const char *msg, va_list args) { + char str[120]; + memset(str, 0, sizeof(str)); + /* Assume that context is casted to UA_LogLevel */ /* TODO we may later change this to a struct with bitfields to filter on category */ if ( context != NULL && (UA_LogLevel)(uintptr_t)context > level ) @@ -68115,8 +68245,8 @@ UA_Log_Stdout_log(void *context, UA_LogLevel level, UA_LogCategory category, KPrintf("%s/%s" ANSI_COLOR_RESET "\t", logLevelNames[level], logCategoryNames[category]); - - KPrintf(msg, args); + vsnprintf(str, sizeof(str) - 1, msg, args); + KPrintf(msg, str); KPrintf("\n"); // printf("\n"); @@ -70191,7 +70321,7 @@ UA_Client * UA_Client_new() { UA_StatusCode UA_ClientConfig_setDefault(UA_ClientConfig *config) { - config->timeout = 5000; + config->timeout = 20000; config->secureChannelLifeTime = 10 * 60 * 1000; /* 10 minutes */ if(!config->logger.log) { @@ -70656,13 +70786,15 @@ UA_Log_Syslog_withLevel(UA_LogLevel minlevel) { #define configTICK_RATE_HZ TICK_PER_SECOND #define xTaskGetTickCount CurrentTicksGain -#define EHOSTUNREACH 113 /* No route to host */ -#define EINPROGRESS 115 /* Operation now in progress */ #define EADDRINUSE 98 /* Address already in use */ -#define EALREADY 114 /* Operation already in progress */ +#define ECONNABORTED 103 /* Software caused connection abort */ + #define EISCONN 106 /* Transport endpoint is already connected */ #define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ECONNABORTED 103 /* Software caused connection abort */ + +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ #ifdef UA_ARCHITECTURE_FREERTOSLWIP_POSIX_CLOCK diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h index 19790b2a6..30345d4c5 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h @@ -15,10 +15,16 @@ #include "open62541.h" #define OPC_SERVER "opc.tcp://192.168.250.5:4840" -#define ua_print printf + +#define ua_print //printf +#define ua_trace() //printf("ua: [%s] line %d checked!\n", __func__, __LINE__) +#define ua_pr_info KPrintf +#define ua_debug int ua_server_connect(void); int ua_get_server_info(UA_Client *client); +void ua_browser_objects(UA_Client *client); +void ua_browser_nodes(UA_Client *client); void ua_read_time(UA_Client *client); int16 ua_test(void); diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c index a6795b618..eb8e439ea 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c @@ -12,9 +12,7 @@ #include "open62541.h" #include - -#define OPC_SERVER "opc.tcp://192.168.250.5:4840" -#define ua_print printf +#include "ua_api.h" #ifdef UA_ENABLE_SUBSCRIPTIONS static void handler_TheAnswerChanged(UA_Client *client, UA_UInt32 subId, void *subContext, @@ -32,7 +30,7 @@ static UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId } UA_NodeId *parent = (UA_NodeId *)handle; - ua_print("%d, %d --- %d ---> NodeId %d, %d\n", + ua_pr_info("%d, %d --- %d ---> NodeId %d, %d\n", parent->namespaceIndex, parent->identifier.numeric, referenceTypeId.identifier.numeric, childId.namespaceIndex, childId.identifier.numeric); @@ -61,32 +59,42 @@ int ua_get_points(UA_Client *client) endpointArray[i].endpointUrl.data); } UA_Array_delete(endpointArray,endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } void ua_browser_objects(UA_Client *client) { /* Browse some objects */ - ua_print("Browsing nodes in objects folder:\n"); + ua_pr_info("Browsing nodes in objects folder:\n"); + UA_BrowseRequest bReq; UA_BrowseRequest_init(&bReq); + bReq.requestedMaxReferencesPerNode = 0; bReq.nodesToBrowse = UA_BrowseDescription_new(); bReq.nodesToBrowseSize = 1; bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); /* browse objects folder */ bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */ + UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq); - ua_print("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME"); - for(size_t i = 0; i < bResp.resultsSize; ++i) { - for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) { + + ua_pr_info("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME"); + + for(size_t i = 0; i < bResp.resultsSize; ++i) + { + for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) + { UA_ReferenceDescription *ref = &(bResp.results[i].references[j]); - if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) { - ua_print("%-9d %-16d %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex, + if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) + { + ua_pr_info("%-9d %-16d %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex, ref->nodeId.nodeId.identifier.numeric, (int)ref->browseName.name.length, ref->browseName.name.data, (int)ref->displayName.text.length, ref->displayName.text.data); - } else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) { - ua_print("%-9d %-16.*s %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex, + } + else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) + { + ua_pr_info("%-9d %-16.*s %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex, (int)ref->nodeId.nodeId.identifier.string.length, ref->nodeId.nodeId.identifier.string.data, (int)ref->browseName.name.length, ref->browseName.name.data, @@ -95,6 +103,7 @@ void ua_browser_objects(UA_Client *client) /* TODO: distinguish further types */ } } + ua_pr_info("\n"); UA_BrowseRequest_clear(&bReq); UA_BrowseResponse_clear(&bResp); } @@ -133,7 +142,7 @@ UA_UInt32 ua_start_sub(UA_Client *client) /* The first publish request should return the initial value of the variable */ UA_Client_run_iterate(client, 1000); - return subId; + return subId; } void ua_read_attr(UA_Client *client) @@ -165,7 +174,8 @@ void ua_read_attr(UA_Client *client) wReq.nodesToWrite[0].value.value.data = &value; UA_WriteResponse wResp = UA_Client_Service_write(client, wReq); if(wResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD) - ua_print("the new value is: %i\n", value); + ua_print("the new value is: %i\n", value); + UA_WriteRequest_clear(&wReq); UA_WriteResponse_clear(&wResp); @@ -189,11 +199,14 @@ void ua_call_remote(UA_Client *client) UA_Variant *output; UA_StatusCode retval = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(1, 62541), 1, &input, &outputSize, &output); - if(retval == UA_STATUSCODE_GOOD) { + if(retval == UA_STATUSCODE_GOOD) + { ua_print("Method call was successful, and %lu returned values available.\n", (unsigned long)outputSize); UA_Array_delete(output, outputSize, &UA_TYPES[UA_TYPES_VARIANT]); - } else { + } + else + { ua_print("Method call was unsuccessful, and %x returned values available.\n", retval); } UA_Variant_clear(&input); @@ -271,33 +284,16 @@ void ua_add_nodes(UA_Client *client) int ua_get_server_info(UA_Client *client) { - UA_StatusCode retval; - - /* Listing endpoints */ - retval = ua_get_points(client); - if(retval != UA_STATUSCODE_GOOD) { - UA_Client_delete(client); - return EXIT_FAILURE; - } - - /* Connect to a server */ - /* anonymous connect would be: retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); */ - retval = UA_Client_connect(client, OPC_SERVER); - if(retval != UA_STATUSCODE_GOOD) { - UA_Client_delete(client); - return EXIT_FAILURE; - } - - ua_browser_objects(client); + ua_browser_objects(client); /* Same thing, this time using the node iterator... */ - ua_browser_nodes(client); + ua_browser_nodes(client); #ifdef UA_ENABLE_SUBSCRIPTIONS - UA_Int32 subId = ua_start_sub(client); + UA_Int32 subId = ua_start_sub(client); #endif - ua_read_attr(client); + ua_read_attr(client); #ifdef UA_ENABLE_SUBSCRIPTIONS /* Take another look at the.answer */ @@ -308,11 +304,11 @@ int ua_get_server_info(UA_Client *client) #endif #ifdef UA_ENABLE_METHODCALLS - ua_call_remote(client); + ua_call_remote(client); #endif #ifdef UA_ENABLE_NODEMANAGEMENT - ua_add_nodes(client); + ua_add_nodes(client); #endif return EXIT_SUCCESS; diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c index 39d9f45be..40a9e3251 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c @@ -216,7 +216,7 @@ void ethernetif_input(struct netif *netif) /* pass all packets to ethernet_input, which decides what packets it supports */ if ((ret = netif->input(p, netif)) != ERR_OK) { -// LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); lw_print("lw: [%s] ret %d p %p\n", __func__, ret, p); pbuf_free(p); p = NULL; diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_kinetis.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_kinetis.c index 68c63777c..dd91ce952 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_kinetis.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_kinetis.c @@ -1,735 +1,686 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * 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 - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* - * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Copyright (c) 2021 AIIT XUOS Lab - * XiUOS is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -/** - * @file enet_ethernetif_kinetis.c - * @brief ethernet drivers - * @version 1.0 - * @author AIIT XUOS Lab - * @date 2021.11.11 - */ - -#include "lwip/opt.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/ethip6.h" -#include "netif/etharp.h" -#include "netif/ppp/pppoe.h" -#include "lwip/igmp.h" -#include "lwip/mld6.h" - -//#define USE_RTOS 1 -//#define FSL_RTOS_FREE_RTOS -//#define FSL_RTOS_XIUOS - -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) - -#ifdef FSL_RTOS_XIUOS -#include "xs_sem.h" - -#else -#include "FreeRTOS.h" -#include "event_groups.h" -#include "list.h" -#endif - -typedef uint32_t TickType_t; -#define portMAX_DELAY ( TickType_t ) 0xffffffffUL - -typedef TickType_t EventBits_t; - -typedef long BaseType_t; -typedef unsigned long UBaseType_t; - -#define portBASE_TYPE long - -#define pdFALSE ( ( BaseType_t ) 0 ) -#define pdTRUE ( ( BaseType_t ) 1 ) - -#define pdPASS ( pdTRUE ) -#define pdFAIL ( pdFALSE ) - -#ifndef FSL_RTOS_XIUOS -typedef struct EventGroupDef_t -{ - EventBits_t uxEventBits; - List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ - - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxEventGroupNumber; - #endif - - #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ - #endif -} EventGroup_t; - -struct EventGroupDef_t; -typedef struct EventGroupDef_t * EventGroupHandle_t; -#endif - -#endif - -#include "enet_ethernetif.h" -#include "enet_ethernetif_priv.h" - -#include "fsl_enet.h" -#include "fsl_phy.h" - -#include "sys_arch.h" - - - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/** - * Helper struct to hold private data used to operate your ethernet interface. - */ -struct ethernetif -{ - ENET_Type *base; -#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \ - (USE_RTOS && defined(FSL_RTOS_FREE_RTOS)) - enet_handle_t handle; -#endif -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) - -#ifdef FSL_RTOS_XIUOS - int enetSemaphore; -#else - EventGroupHandle_t enetTransmitAccessEvent; -#endif - EventBits_t txFlag; -#endif - enet_rx_bd_struct_t *RxBuffDescrip; - enet_tx_bd_struct_t *TxBuffDescrip; - rx_buffer_t *RxDataBuff; - tx_buffer_t *TxDataBuff; -}; - - -/******************************************************************************* - * Code - ******************************************************************************/ -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) -#if FSL_FEATURE_ENET_QUEUE > 1 -static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, uint32_t ringId, enet_event_t event, void *param) -#else -static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param) -#endif /* FSL_FEATURE_ENET_QUEUE */ -{ - struct netif *netif = (struct netif *)param; - struct ethernetif *ethernetif = netif->state; - BaseType_t xResult; - - - lw_print("lw: [%s] input event %#x \n", __func__, event); - - switch (event) - { - case kENET_RxEvent: - ethernetif_input(netif); - break; - case kENET_TxEvent: - { - portBASE_TYPE taskToWake = pdFALSE; - -#ifdef FSL_RTOS_XIUOS - -#else -#ifdef __CA7_REV - if (SystemGetIRQNestingLevel()) -#else - if (__get_IPSR()) -#endif - { - xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake); - if ((pdPASS == xResult) && (pdTRUE == taskToWake)) - { - portYIELD_FROM_ISR(taskToWake); - } - } - else - { - xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag); - } -#endif - } - break; - default: - break; - } - - KSemaphoreAbandon(ethernetif->enetSemaphore); -} -#endif - -#if LWIP_IPV4 && LWIP_IGMP -err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, - enum netif_mac_filter_action action) -{ - struct ethernetif *ethernetif = netif->state; - uint8_t multicastMacAddr[6]; - err_t result; - - multicastMacAddr[0] = 0x01U; - multicastMacAddr[1] = 0x00U; - multicastMacAddr[2] = 0x5EU; - multicastMacAddr[3] = (group->addr >> 8) & 0x7FU; - multicastMacAddr[4] = (group->addr >> 16) & 0xFFU; - multicastMacAddr[5] = (group->addr >> 24) & 0xFFU; - - switch (action) - { - case IGMP_ADD_MAC_FILTER: - /* Adds the ENET device to a multicast group.*/ - ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); - result = ERR_OK; - break; - case IGMP_DEL_MAC_FILTER: - /* - * Moves the ENET device from a multicast group. - * Since the ENET_LeaveMulticastGroup() could filter out also other - * group addresses having the same hash, the call is commented out. - */ - /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ - result = ERR_OK; - break; - default: - result = ERR_IF; - break; - } - - return result; -} -#endif - -#if LWIP_IPV6 && LWIP_IPV6_MLD -err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group, - enum netif_mac_filter_action action) -{ - struct ethernetif *ethernetif = netif->state; - uint8_t multicastMacAddr[6]; - err_t result; - - multicastMacAddr[0] = 0x33U; - multicastMacAddr[1] = 0x33U; - multicastMacAddr[2] = (group->addr[3]) & 0xFFU; - multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU; - multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU; - multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU; - - switch (action) - { - case NETIF_ADD_MAC_FILTER: - /* Adds the ENET device to a multicast group.*/ - ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); - result = ERR_OK; - break; - case NETIF_DEL_MAC_FILTER: - /* - * Moves the ENET device from a multicast group. - * Since the ENET_LeaveMulticastGroup() could filter out also other - * group addresses having the same hash, the call is commented out. - */ - /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ - result = ERR_OK; - break; - default: - result = ERR_IF; - break; - } - - return result; -} -#endif - -#define netifINTERFACE_TASK_STACK_SIZE ( 4096 ) - -/** - * This function is the ethernetif_input task, it is processed when a packet - * is ready to be read from the interface. It uses the function low_level_input() - * that should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -//void eth_input( void * pvParameters ) -//{ -// struct pbuf *p; -// -// for( ;; ) -// { -// if (KSemaphoreObtain( s_xSemaphore, WAITING_FOREVER)==EOK) -// { -// p = low_level_input( s_pxNetIf ); -// -// if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) -// { -// KPrintf("netif input return not OK ! \n"); -// pbuf_free(p); -// p=NULL; -// } -// } -// } -//} -// -//void low_level_init() -//{ -// /* create the task that handles the ETH_MAC */ -// uint32 thr_id = KTaskCreate((signed char*) "eth_input", -// eth_input, -// NULL, -// netifINTERFACE_TASK_STACK_SIZE, -// 15); -// if (thr_id >= 0) -// { -// StartupKTask(thr_id); -// } -// else -// { -// KPrintf("Eth create failed !"); -// } -//} - - -/** - * Initializes ENET driver. - */ -void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif, - const ethernetif_config_t *ethernetifConfig) -{ - enet_config_t config; - uint32_t sysClock; - enet_buffer_config_t buffCfg[ENET_RING_NUM]; - - /* prepare the buffer configuration. */ - buffCfg[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */ - buffCfg[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */ - buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */ - buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */ - buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */ - buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */ - buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */ - buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */ - - sysClock = CLOCK_GetFreq(ethernetifConfig->clockName); - - ENET_GetDefaultConfig(&config); - config.ringNum = ENET_RING_NUM; - - ethernetif_phy_init(ethernetif, ethernetifConfig, &config); - -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) - uint32_t instance; - static ENET_Type *const enetBases[] = ENET_BASE_PTRS; - static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS; - /*! @brief Pointers to enet receive IRQ number for each instance. */ - static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS; -#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /*! @brief Pointers to enet timestamp IRQ number for each instance. */ - static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS; -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Create the Event for transmit busy release trigger. */ -#ifdef FSL_RTOS_XIUOS - if(ethernetif->enetSemaphore < 0) - { - ethernetif->enetSemaphore = KSemaphoreCreate(0); - } -#else - ethernetif->enetTransmitAccessEvent = xEventGroupCreate(); -#endif - ethernetif->txFlag = 0x1; - - config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt; - - for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++) - { - if (enetBases[instance] == ethernetif->base) - { -#ifdef __CA7_REV - GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); - GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); -#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ -#else - NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); - NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); -#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ -#endif /* __CA7_REV */ - break; - } - } - - LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases))); -#endif /* USE_RTOS */ - - /* Initialize the ENET module.*/ - ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock); - -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) - ENET_SetCallback(ðernetif->handle, ethernet_callback, netif); -#endif - - ENET_ActiveRead(ethernetif->base); -// low_level_init(); -} - -ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif) -{ - return &(ethernetif->base); -} - -/** - * Returns next buffer for TX. - * Can wait if no buffer available. - */ -static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif) -{ - static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN]; - return ucBuffer; -} - -/** - * Sends frame via ENET. - */ -static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length) -{ -#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) - { - status_t result; - - lw_print("lw: [%s] len %d\n", __func__, length); - - do - { - result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length); - - if (result == kStatus_ENET_TxFrameBusy) - { -#ifdef FSL_RTOS_XIUOS -// KSemaphoreObtain(ethernetif->enetSemaphore, portMAX_DELAY); -#else - xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false, - portMAX_DELAY); -#endif - } - - } while (result == kStatus_ENET_TxFrameBusy); - - return ERR_OK; - } -#else - { - uint32_t counter; - - for (counter = ENET_TIMEOUT; counter != 0U; counter--) - { - if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length) != kStatus_ENET_TxFrameBusy) - { - return ERR_OK; - } - } - - return ERR_TIMEOUT; - } -#endif -} - -struct pbuf *ethernetif_linkinput(struct netif *netif) -{ - struct ethernetif *ethernetif = netif->state; - struct pbuf *p = NULL; - struct pbuf *q; - uint32_t len; - status_t status; - - /* Obtain the size of the packet and put it into the "len" - variable. */ - status = ENET_GetRxFrameSize(ðernetif->handle, &len); - - if (kStatus_ENET_RxFrameEmpty != status) - { - /* Call ENET_ReadFrame when there is a received frame. */ - if (len != 0) - { -#if ETH_PAD_SIZE - len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ -#endif - - /* We allocate a pbuf chain of pbufs from the pool. */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - - if (p != NULL) - { -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - if (p->next == 0) /* One-chain buffer.*/ - { - ENET_ReadFrame(ethernetif->base, ðernetif->handle, p->payload, p->len); - } - else /* Multi-chain buffer.*/ - { - uint8_t data_tmp[ENET_FRAME_MAX_FRAMELEN]; - uint32_t data_tmp_len = 0; - - ENET_ReadFrame(ethernetif->base, ðernetif->handle, data_tmp, p->tot_len); - - /* We iterate over the pbuf chain until we have read the entire - * packet into the pbuf. */ - for (q = p; (q != NULL) && ((data_tmp_len + q->len) <= sizeof(data_tmp)); q = q->next) - { - /* Read enough bytes to fill this pbuf in the chain. The - * available data in the pbuf is given by the q->len - * variable. */ - memcpy(q->payload, &data_tmp[data_tmp_len], q->len); - data_tmp_len += q->len; - } - } - - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - if (((u8_t *)p->payload)[0] & 1) - { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); - } - else - { - /* unicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - } -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.recv); - } - else - { - /* drop packet*/ - ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U); - - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: Fail to allocate new memory space\n")); - - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifindiscards); - } - } - else - { - /* Update the received buffer when error happened. */ - if (status == kStatus_ENET_RxFrameError) - { -#if 0 && defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) /* Error statisctics */ - enet_data_error_stats_t eErrStatic; - /* Get the error information of the received g_frame. */ - ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic); -#endif - - /* Update the receive buffer. */ - ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U); - - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n")); - - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifindiscards); - } - } - } - - return p; -} - -err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) -{ - err_t result; - struct ethernetif *ethernetif = netif->state; - struct pbuf *q; - unsigned char *pucBuffer; - unsigned char *pucChar; - - LWIP_ASSERT("Output packet buffer empty", p); - - pucBuffer = enet_get_tx_buffer(ethernetif); - if (pucBuffer == NULL) - { - return ERR_BUF; - } - -/* Initiate transfer. */ - -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - - if (p->len == p->tot_len) - { - /* No pbuf chain, don't have to copy -> faster. */ - pucBuffer = (unsigned char *)p->payload; - } - else - { - /* pbuf chain, copy into contiguous ucBuffer. */ - if (p->tot_len > ENET_FRAME_MAX_FRAMELEN) - { - return ERR_BUF; - } - else - { - pucChar = pucBuffer; - - for (q = p; q != NULL; q = q->next) - { - /* Send the data from the pbuf to the interface, one pbuf at a - time. The size of the data in each pbuf is kept in the ->len - variable. */ - /* send data from(q->payload, q->len); */ - memcpy(pucChar, q->payload, q->len); - pucChar += q->len; - } - } - } - - /* Send frame. */ - result = enet_send_frame(ethernetif, pucBuffer, p->tot_len); - - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - if (((u8_t *)p->payload)[0] & 1) - { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - } - else - { - /* unicast packet */ - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } -/* increase ifoutdiscards or ifouterrors on error */ - -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.xmit); - - return result; -} - -/** - * Should be called at the beginning of the program to set up the - * first network interface. It calls the function ethernetif_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t ethernetif0_init(struct netif *netif) -{ - static struct ethernetif ethernetif_0; - AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - - ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]); - ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]); - ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]); - ethernetif_0.TxDataBuff = &(txDataBuff_0[0]); - - return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state); -} - -#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1) -/** - * Should be called at the beginning of the program to set up the - * second network interface. It calls the function ethernetif_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t ethernetif1_init(struct netif *netif) -{ - static struct ethernetif ethernetif_1; - AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); - - ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]); - ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]); - ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]); - ethernetif_1.TxDataBuff = &(txDataBuff_1[0]); - - return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state); -} -#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * 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 + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Copyright (c) 2021 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file enet_ethernetif_kinetis.c + * @brief ethernet drivers + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2021.11.11 + */ + +#include "sys_arch.h" +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ethip6.h" +#include "netif/etharp.h" +#include "netif/ppp/pppoe.h" +#include "lwip/igmp.h" +#include "lwip/mld6.h" + +#ifdef FSL_RTOS_XIUOS +#define USE_RTOS 1 +#define FSL_RTOS_FREE_RTOS +#endif + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + +#ifdef FSL_RTOS_XIUOS +#include "xs_sem.h" + +#else +#include "FreeRTOS.h" +#include "event_groups.h" +#include "list.h" +#endif + +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +typedef TickType_t EventBits_t; + +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#define portBASE_TYPE long + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) + +#ifndef FSL_RTOS_XIUOS +typedef struct EventGroupDef_t +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; +#endif + +#endif + +#include "enet_ethernetif.h" +#include "enet_ethernetif_priv.h" + +#include "fsl_enet.h" +#include "fsl_phy.h" + +#include "sys_arch.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/** + * Helper struct to hold private data used to operate your ethernet interface. + */ +struct ethernetif +{ + ENET_Type *base; +#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \ + (USE_RTOS && defined(FSL_RTOS_FREE_RTOS)) + enet_handle_t handle; +#endif +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + +#ifdef FSL_RTOS_XIUOS + int enetSemaphore; +#else + EventGroupHandle_t enetTransmitAccessEvent; +#endif + EventBits_t txFlag; +#endif + enet_rx_bd_struct_t *RxBuffDescrip; + enet_tx_bd_struct_t *TxBuffDescrip; + rx_buffer_t *RxDataBuff; + tx_buffer_t *TxDataBuff; +}; + + +/******************************************************************************* + * Code + ******************************************************************************/ +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + +int32 lwip_obtain_semaphore(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + return (KSemaphoreObtain(ethernetif->enetSemaphore, WAITING_FOREVER) == EOK); +} + +#if FSL_FEATURE_ENET_QUEUE > 1 +static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, uint32_t ringId, enet_event_t event, void *param) +#else +static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param) +#endif /* FSL_FEATURE_ENET_QUEUE */ +{ + struct netif *netif = (struct netif *)param; + struct ethernetif *ethernetif = netif->state; + BaseType_t xResult; + + switch (event) + { + case kENET_RxEvent: + ethernetif_input(netif); + break; + case kENET_TxEvent: +#ifndef FSL_RTOS_XIUOS + { + portBASE_TYPE taskToWake = pdFALSE; + +#ifdef __CA7_REV + if (SystemGetIRQNestingLevel()) +#else + if (__get_IPSR()) +#endif + { + xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake); + if ((pdPASS == xResult) && (pdTRUE == taskToWake)) + { + portYIELD_FROM_ISR(taskToWake); + } + } + else + { + xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag); + } + } +#endif + break; + default: + break; + } + + KSemaphoreAbandon(ethernetif->enetSemaphore); +} +#endif + +#if LWIP_IPV4 && LWIP_IGMP +err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, + enum netif_mac_filter_action action) +{ + struct ethernetif *ethernetif = netif->state; + uint8_t multicastMacAddr[6]; + err_t result; + + multicastMacAddr[0] = 0x01U; + multicastMacAddr[1] = 0x00U; + multicastMacAddr[2] = 0x5EU; + multicastMacAddr[3] = (group->addr >> 8) & 0x7FU; + multicastMacAddr[4] = (group->addr >> 16) & 0xFFU; + multicastMacAddr[5] = (group->addr >> 24) & 0xFFU; + + switch (action) + { + case IGMP_ADD_MAC_FILTER: + /* Adds the ENET device to a multicast group.*/ + ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); + result = ERR_OK; + break; + case IGMP_DEL_MAC_FILTER: + /* + * Moves the ENET device from a multicast group. + * Since the ENET_LeaveMulticastGroup() could filter out also other + * group addresses having the same hash, the call is commented out. + */ + /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ + result = ERR_OK; + break; + default: + result = ERR_IF; + break; + } + + return result; +} +#endif + +#if LWIP_IPV6 && LWIP_IPV6_MLD +err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group, + enum netif_mac_filter_action action) +{ + struct ethernetif *ethernetif = netif->state; + uint8_t multicastMacAddr[6]; + err_t result; + + multicastMacAddr[0] = 0x33U; + multicastMacAddr[1] = 0x33U; + multicastMacAddr[2] = (group->addr[3]) & 0xFFU; + multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU; + multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU; + multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU; + + switch (action) + { + case NETIF_ADD_MAC_FILTER: + /* Adds the ENET device to a multicast group.*/ + ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); + result = ERR_OK; + break; + case NETIF_DEL_MAC_FILTER: + /* + * Moves the ENET device from a multicast group. + * Since the ENET_LeaveMulticastGroup() could filter out also other + * group addresses having the same hash, the call is commented out. + */ + /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ + result = ERR_OK; + break; + default: + result = ERR_IF; + break; + } + + return result; +} +#endif + +/** + * Initializes ENET driver. + */ +void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif, + const ethernetif_config_t *ethernetifConfig) +{ + enet_config_t config; + uint32_t sysClock; + enet_buffer_config_t buffCfg[ENET_RING_NUM]; + + /* prepare the buffer configuration. */ + buffCfg[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */ + buffCfg[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */ + buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */ + buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */ + buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */ + buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */ + buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */ + buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */ + + sysClock = CLOCK_GetFreq(ethernetifConfig->clockName); + + ENET_GetDefaultConfig(&config); + config.ringNum = ENET_RING_NUM; + + ethernetif_phy_init(ethernetif, ethernetifConfig, &config); + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + uint32_t instance; + static ENET_Type *const enetBases[] = ENET_BASE_PTRS; + static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS; + /*! @brief Pointers to enet receive IRQ number for each instance. */ + static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS; +#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + /*! @brief Pointers to enet timestamp IRQ number for each instance. */ + static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS; +#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ + + /* Create the Event for transmit busy release trigger. */ +#ifdef FSL_RTOS_XIUOS + if(ethernetif->enetSemaphore < 0) + { + ethernetif->enetSemaphore = KSemaphoreCreate(0); + } +#else + ethernetif->enetTransmitAccessEvent = xEventGroupCreate(); +#endif + ethernetif->txFlag = 0x1; + + config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt; + + for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++) + { + if (enetBases[instance] == ethernetif->base) + { +#ifdef __CA7_REV + GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); + GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); +#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); +#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ +#else + NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); + NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); +#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); +#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ +#endif /* __CA7_REV */ + break; + } + } + + LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases))); +#endif /* USE_RTOS */ + + /* Initialize the ENET module.*/ + ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock); + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + ENET_SetCallback(ðernetif->handle, ethernet_callback, netif); +#endif + + ENET_ActiveRead(ethernetif->base); +// low_level_init(); +} + +ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif) +{ + return &(ethernetif->base); +} + +/** + * Returns next buffer for TX. + * Can wait if no buffer available. + */ +static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif) +{ + static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN]; + return ucBuffer; +} + +/** + * Sends frame via ENET. + */ +static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length) +{ +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + { + status_t result; + + lw_print("lw: [%s] len %d\n", __func__, length); + + do + { + result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length); + + if (result == kStatus_ENET_TxFrameBusy) + { +#ifdef FSL_RTOS_XIUOS + KSemaphoreObtain(ethernetif->enetSemaphore, portMAX_DELAY); +#else + xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false, + portMAX_DELAY); +#endif + } + + } while (result == kStatus_ENET_TxFrameBusy); + + return ERR_OK; + } +#else + { + uint32_t counter; + + for (counter = ENET_TIMEOUT; counter != 0U; counter--) + { + if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length) != kStatus_ENET_TxFrameBusy) + { + return ERR_OK; + } + } + + return ERR_TIMEOUT; + } +#endif +} + +struct pbuf *ethernetif_linkinput(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *p = NULL; + struct pbuf *q; + uint32_t len; + status_t status; + + /* Obtain the size of the packet and put it into the "len" + variable. */ + status = ENET_GetRxFrameSize(ðernetif->handle, &len); + + if (kStatus_ENET_RxFrameEmpty != status) + { + /* Call ENET_ReadFrame when there is a received frame. */ + if (len != 0) + { +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) + { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + if (p->next == 0) /* One-chain buffer.*/ + { + ENET_ReadFrame(ethernetif->base, ðernetif->handle, p->payload, p->len); + } + else /* Multi-chain buffer.*/ + { + uint8_t data_tmp[ENET_FRAME_MAX_FRAMELEN]; + uint32_t data_tmp_len = 0; + + ENET_ReadFrame(ethernetif->base, ðernetif->handle, data_tmp, p->tot_len); + + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for (q = p; (q != NULL) && ((data_tmp_len + q->len) <= sizeof(data_tmp)); q = q->next) + { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. */ + memcpy(q->payload, &data_tmp[data_tmp_len], q->len); + data_tmp_len += q->len; + } + } + + MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); + } + else + { + /* unicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinucastpkts); + } +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } + else + { + /* drop packet*/ + ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U); + + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: Fail to allocate new memory space\n")); + + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + } + else + { + /* Update the received buffer when error happened. */ + if (status == kStatus_ENET_RxFrameError) + { +#if 0 && defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) /* Error statisctics */ + enet_data_error_stats_t eErrStatic; + /* Get the error information of the received g_frame. */ + ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic); +#endif + /* Update the receive buffer. */ + ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U); + + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n")); + + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + } + } + + return p; +} + +err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) +{ + err_t result; + struct ethernetif *ethernetif = netif->state; + struct pbuf *q; + unsigned char *pucBuffer; + unsigned char *pucChar; + + LWIP_ASSERT("Output packet buffer empty", p); + + pucBuffer = enet_get_tx_buffer(ethernetif); + if (pucBuffer == NULL) + { + return ERR_BUF; + } + +/* Initiate transfer. */ + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + if (p->len == p->tot_len) + { + /* No pbuf chain, don't have to copy -> faster. */ + pucBuffer = (unsigned char *)p->payload; + } + else + { + /* pbuf chain, copy into contiguous ucBuffer. */ + if (p->tot_len > ENET_FRAME_MAX_FRAMELEN) + { + return ERR_BUF; + } + else + { + pucChar = pucBuffer; + + for (q = p; q != NULL; q = q->next) + { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + /* send data from(q->payload, q->len); */ + memcpy(pucChar, q->payload, q->len); + pucChar += q->len; + } + } + } + + /* Send frame. */ + result = enet_send_frame(ethernetif, pucBuffer, p->tot_len); + + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); + } + else + { + /* unicast packet */ + MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); + } +/* increase ifoutdiscards or ifouterrors on error */ + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return result; +} + +/** + * Should be called at the beginning of the program to set up the + * first network interface. It calls the function ethernetif_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif0_init(struct netif *netif) +{ + static struct ethernetif ethernetif_0; + AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + + ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]); + ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]); + ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]); + ethernetif_0.TxDataBuff = &(txDataBuff_0[0]); + + return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state); +} + +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1) +/** + * Should be called at the beginning of the program to set up the + * second network interface. It calls the function ethernetif_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif1_init(struct netif *netif) +{ + static struct ethernetif ethernetif_1; + AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); + + ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]); + ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]); + ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]); + ethernetif_1.TxDataBuff = &(txDataBuff_1[0]); + + return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state); +} +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_lpc.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_lpc.c index 3afc0da46..d851dc709 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_lpc.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif_lpc.c @@ -801,30 +801,30 @@ err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) } } - if (copy) + if (copy) { /* Pbuf needs to be copied. */ p_copy = pbuf_alloc(PBUF_RAW, (uint16_t) p->tot_len, PBUF_POOL); - if (p_copy == NULL) + if (p_copy == NULL) { - return ERR_MEM; - } + return ERR_MEM; + } - dst = (uint8_t *) p_copy->payload; - for (q = p; q != NULL; q = q->next) + dst = (uint8_t *) p_copy->payload; + for (q = p; q != NULL; q = q->next) { LWIP_ASSERT("Copied bytes would exceed p->tot_len", (q->len + dst - (uint8_t *) p_copy->payload) <= p->tot_len); memcpy(dst, (uint8_t *)q->payload, q->len); - dst += q->len; - } + dst += q->len; + } LWIP_ASSERT("Copied bytes != p->tot_len", (dst - (uint8_t *) p_copy->payload) == p->tot_len); - p_copy->len = p_copy->tot_len = p->tot_len; + p_copy->len = p_copy->tot_len = p->tot_len; - p = p_copy; - } + p = p_copy; + } else { /* diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/fsl_enet.c b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/fsl_enet.c index 4da401faf..a5f14720d 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/fsl_enet.c +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/ethernet/fsl_enet.c @@ -1490,6 +1490,9 @@ static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint3 assert(handle); assert(ringId < FSL_FEATURE_ENET_QUEUE); + +// lw_print("lw: [%s] base %p handle %p ring %d\n", __func__, base, handle, ringId); + /* Clears status. */ handle->rxBdCurrent[ringId]->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; /* Sets the receive buffer descriptor with the empty flag. */ diff --git a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/include/enet_ethernetif.h b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/include/enet_ethernetif.h index b7009bc3d..cc7016b3b 100755 --- a/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/include/enet_ethernetif.h +++ b/Ubiquitous/XiUOS/board/ok1052-c/third_party_driver/include/enet_ethernetif.h @@ -195,6 +195,8 @@ void ethernetif_input( struct netif *netif); void ETH_BSP_Config(void); +int32 lwip_obtain_semaphore(struct netif *netif); + #if defined(__cplusplus) } #endif /* __cplusplus */ diff --git a/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.c index 99845580f..388263fcb 100644 --- a/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.c @@ -81,20 +81,13 @@ #include "enet_ethernetif.h" #include -/* MAC address configuration. */ -#define configMAC_ADDR { 0x02, 0x12, 0x13, 0x10, 0x15, 0x11} - char lwip_ipaddr[] = {192, 168, 250, 253}; char lwip_netmask[] = {255, 255, 255, 0}; char lwip_gwaddr[] = {192, 168, 250, 252}; - -int errno; -int is_lwip_test = 0; //for lwip input thread +char lwip_flag = 0; x_ticks_t lwip_sys_now; -static int lwip_init_flag = 0; - struct sys_timeouts { struct sys_timeo *next; }; @@ -389,7 +382,7 @@ ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gw; -void TcpIpInit(void) +void lwip_tcp_init(void) { tcpip_init(NULL, NULL); @@ -400,14 +393,9 @@ void TcpIpInit(void) ip_addr_set_zero_ip4(&netmask); ip_addr_set_zero_ip4(&gw); #else - #ifdef SET_AS_SERVER - IP4_ADDR(&ipaddr,IP_ADDR0_SERVER,IP_ADDR1_SERVER,IP_ADDR2_SERVER,IP_ADDR3_SERVER); - #else - IP4_ADDR(&ipaddr,IP_ADDR0_ClIENT,IP_ADDR1_ClIENT,IP_ADDR2_ClIENT,IP_ADDR3_ClIENT); - #endif - - IP4_ADDR(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3); - IP4_ADDR(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3); + IP4_ADDR(&ipaddr, lwip_ipaddr[0], lwip_ipaddr[1], lwip_ipaddr[2], lwip_ipaddr[3]); + IP4_ADDR(&netmask, lwip_netmask[0], lwip_netmask[1], lwip_netmask[2], lwip_netmask[3]); + IP4_ADDR(&gw, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]); #endif /* USE_DHCP */ /* USER CODE END 0 */ /* Initilialize the LwIP stack without RTOS */ @@ -420,13 +408,13 @@ void TcpIpInit(void) if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ - KPrintf("TcpIpInit : netif_set_up\n"); + KPrintf("%s : netif_set_up\n", __func__); netif_set_up(&gnetif); } else { /* When the netif link is down this function must be called */ - KPrintf("TcpIpInit : netif_set_down\n"); + KPrintf("%s : netif_set_down\n", __func__); netif_set_down(&gnetif); } @@ -462,10 +450,14 @@ void lwip_input_thread(void *param) while (1) { - /* Poll the driver, get any outstanding frames */ - ethernetif_input(net); - sys_check_timeouts(); /* Handle all system timeouts for all core protocols */ -// DelayKTask(1); +#ifdef FSL_RTOS_XIUOS + if (lwip_obtain_semaphore(net) == EOK) +#endif + { + /* Poll the driver, get any outstanding frames */ + ethernetif_input(net); + sys_check_timeouts(); /* Handle all system timeouts for all core protocols */ + } } } @@ -497,7 +489,7 @@ void lwip_config_net(char *ip, char *mask, char *gw) #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ }; - if(lwip_init_flag) + if(chk_lwip_bit(LWIP_INIT_FLAG)) { lw_print("lw: [%s] already ...\n", __func__); @@ -505,6 +497,7 @@ void lwip_config_net(char *ip, char *mask, char *gw) IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); + // update ip addr netif_set_down(&gnetif); netif_set_gw(&gnetif, &net_gw); netif_set_netmask(&gnetif, &net_netmask); @@ -512,7 +505,7 @@ void lwip_config_net(char *ip, char *mask, char *gw) netif_set_up(&gnetif); return; } - lwip_init_flag = 1; + set_lwip_bit(LWIP_INIT_FLAG); lw_print("lw: [%s] start ...\n", __func__); @@ -527,7 +520,7 @@ void lwip_config_net(char *ip, char *mask, char *gw) netif_set_default(&gnetif); netif_set_up(&gnetif); - if(is_lwip_test) + if(chk_lwip_bit(LWIP_PRINT_FLAG)) { lw_pr_info("\r\n************************************************\r\n"); lw_pr_info(" Network Configuration\r\n"); @@ -558,12 +551,13 @@ void lwip_config_tcp(char *ip, char *mask, char *gw) #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ }; - if(lwip_init_flag) + if(chk_lwip_bit(LWIP_INIT_FLAG)) { lw_print("lw: [%s] already ...\n", __func__); return; } - lwip_init_flag = 1; + + set_lwip_bit(LWIP_INIT_FLAG); tcpip_init(NULL, NULL); diff --git a/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.h b/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.h index dab1c5445..ab5a66b2a 100644 --- a/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.h +++ b/Ubiquitous/XiUOS/resources/ethernet/LwIP/arch/sys_arch.h @@ -60,38 +60,18 @@ #include -/* USER CODE BEGIN 0 */ -// #define SET_AS_SERVER 1 /* define this terminal is udp server or not*/ +/* LWIP task parameter */ +#define LWIP_LOCAL_PORT 4840 +#define LWIP_TARGET_PORT LWIP_LOCAL_PORT -#define LOCAL_PORT_SERVER 4840 -#define TARGET_PORT_CLIENT LOCAL_PORT_SERVER +#define LWIP_DEMO_TIMES 3 +#define LWIP_TASK_STACK_SIZE 4096 +#define LWIP_DEMO_TASK_PRIO 20 -#define TEST_LWIP_TIMES 3 +/* MAC address configuration. */ +#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} -/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */ -#define IP_ADDR0_SERVER 192 -#define IP_ADDR1_SERVER 168 -#define IP_ADDR2_SERVER 250 -#define IP_ADDR3_SERVER 252 - -#define IP_ADDR0_ClIENT 192 -#define IP_ADDR1_ClIENT 168 -#define IP_ADDR2_ClIENT 250 -#define IP_ADDR3_ClIENT 253 - -/*NETMASK*/ -#define NETMASK_ADDR0 255 -#define NETMASK_ADDR1 255 -#define NETMASK_ADDR2 255 -#define NETMASK_ADDR3 0 - -/*Gateway Address*/ -#define GW_ADDR0 192 -#define GW_ADDR1 168 -#define GW_ADDR2 250 -#define GW_ADDR3 5 /* USER CODE END 0 */ - #define SYS_MBOX_NULL -1 #define SYS_SEM_NULL 0 #define SYS_MRTEX_NULL SYS_SEM_NULL @@ -100,18 +80,28 @@ typedef int32 sys_sem_t; typedef int32 sys_mutex_t; typedef int32 sys_mbox_t; typedef int32 sys_thread_t; - typedef x_base sys_prot_t; -#define MS_PER_SYSTICK_F407 1000/TICK_PER_SECOND +#define MS_PER_SYSTICK_F407 (1000 / TICK_PER_SECOND) + +//debug rtos with IRQ +//#define FSL_RTOS_XIUOS + +extern char lwip_flag; + +#define LWIP_INIT_FLAG (1 << 0) +#define LWIP_PRINT_FLAG (1 << 1) + +#define set_lwip_bit(__bit) lwip_flag |= (__bit) +#define clr_lwip_bit(__bit) lwip_flag &= ~(__bit) +#define chk_lwip_bit(__bit) ((lwip_flag & (__bit)) == (__bit)) extern char lwip_ipaddr[]; extern char lwip_netmask[]; extern char lwip_gwaddr[]; -extern int is_lwip_test; extern struct netif gnetif; -void TcpIpInit(void); +void lwip_tcp_init(void); void lwip_config_net(char *ip, char *mask, char *gw); void lwip_config_tcp(char *ip, char *mask, char *gw); diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_config_demo.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_config_demo.c index 4268d2306..8a5c13be9 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_config_demo.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_config_demo.c @@ -107,8 +107,10 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | setip, lwip_setip_thread, SetIp [IP] [Netmask] [Gateway]); -void lwip_getip_thread(int argc, char *argv[]) +void lwip_showip_thread(int argc, char *argv[]) { + char mac_addr[] = configMAC_ADDR; + lw_pr_info("\r\n************************************************\r\n"); lw_pr_info(" Network Configuration\r\n"); lw_pr_info("************************************************\r\n"); @@ -118,10 +120,12 @@ void lwip_getip_thread(int argc, char *argv[]) ((u8_t *)&lwip_netmask)[2], ((u8_t *)&lwip_netmask)[3]); lw_pr_info(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_gwaddr)[1], ((u8_t *)&lwip_gwaddr)[2], ((u8_t *)&lwip_gwaddr)[3]); + lw_pr_info(" MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); lw_pr_info("************************************************\r\n"); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), - showip, lwip_getip_thread, GetIp [IP] [Netmask] [Gateway]); + showip, lwip_showip_thread, GetIp [IP] [Netmask] [Gateway]); #endif diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_demo.h b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_demo.h index c2cf2ebbb..99e273aa1 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_demo.h +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_demo.h @@ -1,6 +1,7 @@ #ifndef __LWIP_DEMO_H__ #define __LWIP_DEMO_H__ -void *eth_input_thread(void *param); +#define LWIP_TEST_STACK_SIZE 4096 +#define LWIP_TEST_TASK_PRIO 20 #endif /* __LWIP_DEMO_H__ */ diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_dhcp_demo.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_dhcp_demo.c index b4e47d00e..6cf60699e 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_dhcp_demo.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_dhcp_demo.c @@ -133,7 +133,7 @@ void lwip_dhcp_test(void) ETH_BSP_Config(); lwip_config_net(ip_addr, ip_addr, ip_addr); - is_lwip_test = 1; + set_lwip_bit(LWIP_PRINT_FLAG); dhcp_start(&gnetif); @@ -167,7 +167,7 @@ void lwip_dhcp_test(void) } } - is_lwip_test = 0; + clr_lwip_bit(LWIP_PRINT_FLAG); } diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_ping_demo.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_ping_demo.c index 65a159cdb..a0c6807bb 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_ping_demo.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_ping_demo.c @@ -101,11 +101,13 @@ void lwip_ping_thread(int argc, char *argv[]) return; } } +#if (LWIP_DHCP) && (PING_USE_SOCKETS) else { get_url_ip(argv[1]); return; } +#endif } lw_print("lw: [%s] argc %d\n", __func__, argc); diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_tcp_demo.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_tcp_demo.c index 647199d97..baebfbbcb 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_tcp_demo.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_tcp_demo.c @@ -29,6 +29,8 @@ * Definitions ******************************************************************************/ +#define MSG_SIZE 128 + /******************************************************************************* * Prototypes ******************************************************************************/ @@ -37,10 +39,9 @@ * Variables ******************************************************************************/ -char tcp_target[] = {192, 168, 250, 252}; -#define MSG_SIZE 128 // this is for test in shell, in fact, shell restrict the length of input string, which is less then 128 char tcp_send_msg[MSG_SIZE] = {0}; +char tcp_target[] = {192, 168, 250, 252}; /******************************************************************************* * Code @@ -60,7 +61,7 @@ static void lwip_tcp_send_thread(void *arg) struct sockaddr_in tcp_sock; tcp_sock.sin_family = AF_INET; - tcp_sock.sin_port = htons(TARGET_PORT_CLIENT); + tcp_sock.sin_port = htons(LWIP_TARGET_PORT); tcp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(tcp_target[0], tcp_target[1], tcp_target[2], tcp_target[3])); memset(&(tcp_sock.sin_zero), 0, sizeof(tcp_sock.sin_zero)); @@ -104,7 +105,7 @@ void lwip_tcp_send_run(int argc, char *argv[]) ETH_BSP_Config(); lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr); - sys_thread_new("tcp send", lwip_tcp_send_thread, NULL, 4096, 25); + sys_thread_new("tcp send", lwip_tcp_send_thread, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_udp_demo.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_udp_demo.c index 37c16b0e2..5dd19c5c3 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_udp_demo.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/lwip_udp_demo.c @@ -53,7 +53,7 @@ char udp_send_msg[] = "\n\nThis one is UDP pkg. Congratulations on you.\n\n"; static void lwip_udp_send(void *arg) { - int cnt = TEST_LWIP_TIMES; + int cnt = LWIP_DEMO_TIMES; lw_print("udp_send_demo start.\n"); @@ -67,7 +67,7 @@ static void lwip_udp_send(void *arg) struct sockaddr_in udp_sock; udp_sock.sin_family = AF_INET; - udp_sock.sin_port = htons(TARGET_PORT_CLIENT); + udp_sock.sin_port = htons(LWIP_TARGET_PORT); udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0],udp_target[1],udp_target[2],udp_target[3])); memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero)); @@ -170,7 +170,7 @@ void udpecho_raw_init(void) return; } - err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, LOCAL_PORT_SERVER); + err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, LWIP_LOCAL_PORT); if (err == ERR_OK) { udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL); diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/ping.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/ping.c index 925f174ba..1a66bd272 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/ping.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/ping.c @@ -105,10 +105,6 @@ static u32_t ping_time; static struct raw_pcb *ping_pcb; #endif /* PING_USE_SOCKETS */ -#define PING_THREAD_STACKSIZE 4096 -#define PING_THREAD_PRIO 15 - - /** Prepare a echo ICMP request */ static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) @@ -248,7 +244,7 @@ ping_thread(void *arg) { int s; int ret; - int cnt = TEST_LWIP_TIMES; + int cnt = LWIP_DEMO_TIMES; #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD int timeout = PING_RCV_TIMEO; @@ -268,7 +264,7 @@ ping_thread(void *arg) s = lwip_socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6); } #else - s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP); + s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP); #endif if (s < 0) { lw_print("lw: [%s] ping failed %d!\n", __func__, s); @@ -367,7 +363,7 @@ ping_send(struct raw_pcb *raw, const ip_addr_t *addr) static void ping_timeout(void *arg) { - static int cnt = TEST_LWIP_TIMES; + static int cnt = LWIP_DEMO_TIMES; struct raw_pcb *pcb = (struct raw_pcb*)arg; LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); @@ -380,7 +376,7 @@ ping_timeout(void *arg) } else { - cnt = TEST_LWIP_TIMES; + cnt = LWIP_DEMO_TIMES; } } @@ -412,7 +408,7 @@ ping_init(const ip_addr_t* ping_addr) ping_target = ping_addr; #if PING_USE_SOCKETS - th = sys_thread_new("ping_thread", ping_thread, NULL, PING_THREAD_STACKSIZE, PING_THREAD_PRIO); + th = sys_thread_new("ping_thread", ping_thread, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); lw_print("lw: [%s] new thread %d addr %#x\n", __func__, th, (*ping_addr).addr); #else /* PING_USE_SOCKETS */ ping_raw_init(); @@ -476,6 +472,7 @@ int lwip_ping_recv(int s, int *ttl) return len; } +#if (LWIP_DHCP) && (PING_USE_SOCKETS) int get_url_ip(char* url) { #if LWIP_VERSION_MAJOR >= 2U @@ -483,7 +480,7 @@ int get_url_ip(char* url) #else int timeout = PING_RCV_TIMEO * 1000UL / TICK_PER_SECOND; #endif - int cnt = TEST_LWIP_TIMES; + int cnt = LWIP_DEMO_TIMES; int s, ttl, recv_len; ip_addr_t target_addr; @@ -539,6 +536,6 @@ int get_url_ip(char* url) lwip_close(s); return 0; } - +#endif #endif /* LWIP_RAW */ diff --git a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/tcpecho_raw.c b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/tcpecho_raw.c index 887e8bcd8..026207891 100755 --- a/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/tcpecho_raw.c +++ b/Ubiquitous/XiUOS/resources/ethernet/cmd_lwip/tcpecho_raw.c @@ -49,7 +49,10 @@ #if LWIP_TCP && LWIP_CALLBACK_API -#define MAX_TESTED_TCP_SEND_SIZE (56000) +#define MAX_TCP_RECV_SIZE (56000) +#define MAX_TCP_SHOW_SIZE 80 +#define TCP_ACK_MSG_SIZE 20 +#define TCP_EOF_CH '\n' static struct tcp_pcb *tcpecho_raw_pcb; @@ -109,70 +112,73 @@ tcpecho_raw_error(void *arg, err_t err) tcpecho_raw_free(es); } -#define SHELL_TCP_LENGTH 80 -char* recved_msg; -int recved_msg_length; +static void +tcpecho_raw_ack_size(struct tcp_pcb *tpcb, int ack_len) +{ + struct pbuf *ack_buf = NULL; + + // ack message + ack_buf = pbuf_alloc(PBUF_TRANSPORT, TCP_ACK_MSG_SIZE, PBUF_RAM); + snprintf(ack_buf->payload, TCP_ACK_MSG_SIZE, "%d\n\0", ack_len); + ack_buf->len = strlen(ack_buf->payload); + ack_buf->tot_len = strlen(ack_buf->payload); + ack_buf->next = NULL; + + tcp_write(tpcb, ack_buf->payload, ack_buf->len, 1); + pbuf_free(ack_buf); +} + // compute received message length until '\n' -static void record_msg(struct tcp_pcb *tpcb, struct tcpecho_raw_state* es){ - struct pbuf* ptr = es->p; - int plen = ptr->len; - if(es==NULL||ptr==NULL||plen==0){ - if(recved_msg){ - free(recved_msg); - recved_msg = NULL; - } - recved_msg_length = 0; +static void +tcpecho_raw_ack(struct tcp_pcb *tpcb, struct tcpecho_raw_state* es){ + struct pbuf *ptr = es->p; + char *recv_buf = ptr->payload; + int recv_len = ptr->len; + static char *g_buf = NULL; //global received buffer + static int g_buf_size = 0; + + lw_print("lw: [%s] recv %d tot %d next %p ref %d tye %d id %d %s\n", __func__, ptr->len, ptr->tot_len, + ptr->next, ptr->ref, ptr->type_internal, + ptr->if_idx, ptr->payload); + + if(g_buf == NULL) + { + g_buf = (char *)malloc(MAX_TCP_RECV_SIZE); + memset(g_buf, 0, MAX_TCP_RECV_SIZE); + memcpy(g_buf, recv_buf, recv_len); } - int new_size = plen+1; - char* temp = recved_msg; - if(temp!=NULL){ - new_size += strlen(temp); - } - recved_msg = malloc(new_size); - memset(recved_msg, 0, new_size); - if(temp!=NULL){ - memcpy(recved_msg,temp,strlen(temp)); - } - memcpy(recved_msg+new_size-plen-1, ptr->payload, plen); - free(temp); - recved_msg_length += plen; - if(recved_msg_length>=SHELL_TCP_LENGTH){ - if(recved_msg){ - free(recved_msg); - recved_msg = NULL; + else + { + if(g_buf_size + recv_len <= MAX_TCP_RECV_SIZE) + { + memcpy(g_buf + g_buf_size, recv_buf, recv_len); } } - if(((char*)ptr->payload)[plen-1]=='\n'){ - if(recved_msg_length>MAX_TESTED_TCP_SEND_SIZE){ - KPrintf("Recved_msg_length is larger than %d, which may lead to unexpected exceptions.\n",MAX_TESTED_TCP_SEND_SIZE); - } - if(recved_msg_lengthpayload,"%d\n\0",recved_msg_length); - reply_pbuf->len = strlen(reply_pbuf->payload); - reply_pbuf->tot_len = strlen(reply_pbuf->payload); - reply_pbuf->next = NULL; - - tcp_write(tpcb, reply_pbuf->payload, reply_pbuf->len, 1); - - pbuf_free(reply_pbuf); - free(recved_msg); - recved_msg = NULL; - recved_msg_length = 0; + + tcpecho_raw_ack_size(tpcb, g_buf_size); + + free(g_buf); + g_buf = NULL; + g_buf_size = 0; } + es->p = ptr->next; if(es->p != NULL) { /* new reference! */ pbuf_ref(es->p); } pbuf_free(ptr); - tcp_recved(tpcb, plen); -} + tcp_recved(tpcb, recv_len); +} static err_t tcpecho_raw_poll(void *arg, struct tcp_pcb *tpcb) @@ -184,7 +190,7 @@ tcpecho_raw_poll(void *arg, struct tcp_pcb *tpcb) if (es != NULL) { if (es->p != NULL) { /* there is a remaining pbuf (chain) */ - record_msg(tpcb, es); + tcpecho_raw_ack(tpcb, es); } else { /* no remaining pbuf (chain) */ if(es->state == ES_CLOSING) { @@ -233,7 +239,7 @@ tcpecho_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) tcpecho_raw_close(tpcb, es); } else { /* we're not done yet */ - record_msg(tpcb, es); + tcpecho_raw_ack(tpcb, es); } ret_err = ERR_OK; } else if(err != ERR_OK) { @@ -248,13 +254,13 @@ tcpecho_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) es->state = ES_RECEIVED; /* store reference to incoming pbuf (chain) */ es->p = p; - record_msg(tpcb, es); + tcpecho_raw_ack(tpcb, es); ret_err = ERR_OK; } else if (es->state == ES_RECEIVED) { /* read some more data */ if(es->p == NULL) { es->p = p; - record_msg(tpcb, es); + tcpecho_raw_ack(tpcb, es); } else { struct pbuf *ptr; @@ -277,8 +283,6 @@ tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; struct tcpecho_raw_state *es; - recved_msg = NULL; - recved_msg_length = 0; LWIP_UNUSED_ARG(arg); if ((err != ERR_OK) || (newpcb == NULL)) {