summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorYuxin Zhou <[email protected]>2021-07-28 07:24:24 +0000
committerYuxin Zhou <[email protected]>2021-07-28 07:24:24 +0000
commitcb2245c8d1041d8250df797dd145091d08cd194c (patch)
tree939ad587587d3169c5b3360610a95798e979fbf8 /common
parentc187d60014b149ee7c5e79b4d84c416caddbdef7 (diff)
Release 6.1.8v6.1.8_rel
Diffstat (limited to 'common')
-rw-r--r--common/CMakeLists.txt4
-rw-r--r--common/inc/nx_api.h81
-rw-r--r--common/inc/nx_ipv4.h8
-rw-r--r--common/inc/nx_tcp.h13
-rw-r--r--common/inc/nx_udp.h10
-rw-r--r--common/inc/nx_user_sample.h11
-rw-r--r--common/src/nx_ip_address_set.c72
-rw-r--r--common/src/nx_ip_header_add.c10
-rw-r--r--common/src/nx_ip_interface_attach.c18
-rw-r--r--common/src/nx_ip_packet_receive.c19
-rw-r--r--common/src/nx_ip_packet_send.c41
-rw-r--r--common/src/nx_ip_thread_entry.c14
-rw-r--r--common/src/nx_ipv6_header_add.c21
-rw-r--r--common/src/nx_ipv6_packet_send.c53
-rw-r--r--common/src/nx_tcp_server_socket_driver_listen.c119
-rw-r--r--common/src/nx_tcp_server_socket_listen.c21
-rw-r--r--common/src/nx_tcp_server_socket_relisten.c18
-rw-r--r--common/src/nx_tcp_server_socket_unlisten.c93
-rw-r--r--common/src/nx_tcp_socket_disconnect.c27
-rw-r--r--common/src/nx_tcp_socket_driver_establish.c243
-rw-r--r--common/src/nx_tcp_socket_driver_packet_receive.c181
-rw-r--r--common/src/nx_tcp_socket_packet_process.c33
-rw-r--r--common/src/nx_tcp_socket_send_internal.c199
-rw-r--r--common/src/nx_tcp_socket_state_data_check.c55
-rw-r--r--common/src/nx_udp_socket_bind.c130
-rw-r--r--common/src/nx_udp_socket_driver_packet_receive.c158
-rw-r--r--common/src/nx_udp_socket_unbind.c95
-rw-r--r--common/src/nx_utility.c112
-rw-r--r--common/src/nxd_tcp_client_socket_connect.c173
-rw-r--r--common/src/nxd_udp_socket_send.c209
30 files changed, 2092 insertions, 149 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 8351a24f..6c27f223 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -226,6 +226,7 @@ target_sources(${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_receive_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_accept.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_listen.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_driver_listen.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_relisten.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_unaccept.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_server_socket_unlisten.c
@@ -236,6 +237,8 @@ target_sources(${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_disconnect.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_disconnect_complete_notify.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_driver_establish.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_driver_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_establish_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_tcp_socket_mss_get.c
@@ -287,6 +290,7 @@ target_sources(${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_checksum_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_create.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_delete.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_driver_packet_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_port_get.c
${CMAKE_CURRENT_LIST_DIR}/src/nx_udp_socket_receive.c
diff --git a/common/inc/nx_api.h b/common/inc/nx_api.h
index 824d9655..4412ef12 100644
--- a/common/inc/nx_api.h
+++ b/common/inc/nx_api.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* nx_api.h PORTABLE C */
-/* 6.1.7 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -70,6 +70,12 @@
/* 06-02-2021 Yuxin Zhou Modified comment(s), and */
/* updated product constants, */
/* resulting in version 6.1.7 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* added new ip filter, */
+/* added function to convert */
+/* unsigned integer to string, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
@@ -115,6 +121,12 @@ extern "C" {
#include "tx_trace.h"
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+#ifndef NX_ENABLE_INTERFACE_CAPABILITY
+#error "NX_ENABLE_INTERFACE_CAPABILITY must be defined to enable TCP/IP offload"
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Define symbols for compatibility before and after ThreadX 5.8. */
#if (((THREADX_MAJOR_VERSION << 8) | THREADX_MINOR_VERSION) >= 0x0508)
#define NX_CLEANUP_PARAMETER , ULONG suspension_sequence
@@ -477,7 +489,7 @@ VOID _nx_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, ULONG
#define AZURE_RTOS_NETXDUO
#define NETXDUO_MAJOR_VERSION 6
#define NETXDUO_MINOR_VERSION 1
-#define NETXDUO_PATCH_VERSION 7
+#define NETXDUO_PATCH_VERSION 8
/* Define the following symbols for backward compatibility */
#define EL_PRODUCT_NETXDUO
@@ -1271,6 +1283,7 @@ typedef struct NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT
#define NX_PACKET_OFFSET_ERROR 0x53
#define NX_OPTION_HEADER_ERROR 0x54
#define NX_CONTINUE 0x55
+#define NX_TCPIP_OFFLOAD_ERROR 0x56
/* Define Link Driver constants. */
@@ -1305,6 +1318,19 @@ typedef struct NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT
#define NX_LINK_USER_COMMAND 50 /* Values after this value are reserved for application. */
+
+/* Define operations for TCP/IP offload callback functions. */
+#define NX_TCPIP_OFFLOAD_TCP_CLIENT_SOCKET_CONNECT 0
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_LISTEN 1
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_ACCEPT 2
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_UNLISTEN 3
+#define NX_TCPIP_OFFLOAD_TCP_SOCKET_DISCONNECT 4
+#define NX_TCPIP_OFFLOAD_TCP_SOCKET_SEND 5
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_BIND 6
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_UNBIND 7
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_SEND 8
+
+
/* Define Link Driver Capability Flags. */
#ifdef NX_ENABLE_INTERFACE_CAPABILITY
#define NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM 0x00000001
@@ -1320,6 +1346,19 @@ typedef struct NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT
#define NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM 0x00000400
#define NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM 0x00000800
#define NX_INTERFACE_CAPABILITY_PTP_TIMESTAMP 0x00001000
+#define NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD 0x00002000
+#define NX_INTERFACE_CAPABILITY_CHECKSUM_ALL (NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM | \
+ NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM)
#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
#define NX_IP_VERSION_V4 0x4
@@ -1764,7 +1803,12 @@ typedef struct NX_UDP_SOCKET_STRUCT
/* This pointer is reserved for application specific use. */
/*lint -esym(768,NX_UDP_SOCKET_STRUCT::nx_udp_socket_reserved_ptr) suppress member not referenced. It is reserved for future use. */
void *nx_udp_socket_reserved_ptr;
-
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ /* Store a pointer to TCP/IP offload context. */
+ VOID *nx_udp_socket_tcpip_offload_context;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Define the port extension in the UDP socket control block. This
is typically defined to whitespace in nx_port.h. */
NX_UDP_SOCKET_MODULE_EXTENSION
@@ -2040,6 +2084,11 @@ typedef struct NX_TCP_SOCKET_STRUCT
#endif /* NX_IPSEC_ENABLE */
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ /* Store a pointer to TCP/IP offload context. */
+ VOID *nx_tcp_socket_tcpip_offload_context;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Define the port extension in the TCP socket control block. This
is typically defined to whitespace in nx_port.h. */
NX_TCP_SOCKET_MODULE_EXTENSION
@@ -2244,6 +2293,15 @@ typedef struct NX_INTERFACE_STRUCT
ARP packet that matches that of nx_interface_ip_probe_address. */
VOID (*nx_interface_ip_conflict_notify_handler)(struct NX_IP_STRUCT *, UINT, ULONG, ULONG, ULONG);
#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ /* Define the TCP/IP offload handler. */
+ UINT (*nx_interface_tcpip_offload_handler)(struct NX_IP_STRUCT *ip_ptr,
+ struct NX_INTERFACE_STRUCT *interface_ptr,
+ VOID *socket_ptr, UINT operation, NX_PACKET *packet_ptr,
+ NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip,
+ UINT local_port, UINT *remote_port, UINT wait_option);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
} NX_INTERFACE;
/* Define the static IPv4 routing table entry structure. */
@@ -2913,6 +2971,10 @@ typedef struct NX_IP_STRUCT
#ifdef NX_ENABLE_IP_PACKET_FILTER
/* Define the IP packet filter routine. */
UINT (*nx_ip_packet_filter)(VOID *, UINT);
+
+ /* Define the IP packet filter extended routine. */
+ /* Note: Developers are encouraged to use nx_ip_packet_filter_extended since nx_ip_packet_filter will be deprecated.*/
+ UINT (*nx_ip_packet_filter_extended)(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction);
#endif /* NX_ENABLE_IP_PACKET_FILTER */
/* Define the port extension in the IP control block. This
@@ -3746,6 +3808,18 @@ VOID _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
processing in the driver's receive ISR. */
VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/* Define the direct TCP packet receive processing. This is used with TCP/IP offload feature. */
+VOID _nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr);
+
+/* Define the direct TCP established processing. This is used with TCP/IP offload feature. */
+UINT _nx_tcp_socket_driver_establish(NX_TCP_SOCKET *socket_ptr, NX_INTERFACE *interface_ptr, UINT remote_port);
+
+/* Define the direct UDP packet receive processing. This is used with TCP/IP offload feature. */
+VOID _nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+ NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip, UINT remote_port);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
#endif
#ifdef FEATURE_NX_IPV6
@@ -3823,6 +3897,7 @@ VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index);
/* Utility functions. */
UINT _nx_utility_string_length_check(CHAR *input_string, UINT *string_length, UINT max_string_length);
UINT _nx_utility_string_to_uint(CHAR *input_string, UINT string_length, UINT *number);
+UINT _nx_utility_uint_to_string(UINT number, UINT base, CHAR *string_buffer, UINT string_buffer_size);
UINT _nx_utility_base64_encode(UCHAR *name, UINT name_size, UCHAR *base64name, UINT base64name_size, UINT *bytes_copied);
UINT _nx_utility_base64_decode(UCHAR *base64name, UINT base64name_size, UCHAR *name, UINT name_size, UINT *bytes_copied);
diff --git a/common/inc/nx_ipv4.h b/common/inc/nx_ipv4.h
index 7f19e18a..2a929d9e 100644
--- a/common/inc/nx_ipv4.h
+++ b/common/inc/nx_ipv4.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_ipv4.h PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
@@ -151,7 +154,8 @@ typedef struct NX_IPV4_HEADER_STRUCT
VOID _nx_ip_forward_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
VOID _nx_ip_fragment_forward_packet(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG fragment, ULONG next_hop_address);
void _nx_ip_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment, ULONG next_hop_address);
-UINT _nx_ip_header_add(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment);
+UINT _nx_ip_header_add(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG source_ip, ULONG destination_ip,
+ ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment);
VOID _nx_ip_driver_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG fragment, ULONG next_hop_address);
ULONG _nx_ip_route_find(NX_IP *ip_ptr, ULONG destination_address, NX_INTERFACE **nx_ip_interface, ULONG *next_hop_address);
VOID _nx_ipv4_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
diff --git a/common/inc/nx_tcp.h b/common/inc/nx_tcp.h
index ad83972f..3834d7d7 100644
--- a/common/inc/nx_tcp.h
+++ b/common/inc/nx_tcp.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_tcp.h PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
@@ -278,6 +281,14 @@ UINT _nx_tcp_socket_establish_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_estab
UINT _nx_tcp_socket_disconnect_complete_notify(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_disconnect_complete_notify)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_timed_wait_callback(NX_TCP_SOCKET *socket_ptr, VOID (*tcp_timed_wait_callback)(NX_TCP_SOCKET *socket_ptr));
UINT _nx_tcp_socket_receive_queue_max_set(NX_TCP_SOCKET *socket_ptr, UINT receive_queue_maximum);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/* Define the direct TCP packet receive processing. This is used with TCP/IP offload feature. */
+VOID _nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr);
+
+/* Define the direct TCP established processing. This is used with TCP/IP offload feature. */
+UINT _nx_tcp_socket_driver_establish(NX_TCP_SOCKET *socket_ptr, NX_INTERFACE *interface_ptr, UINT remote_port);
+UINT _nx_tcp_server_socket_driver_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
/* Define TCP component internal function prototypes. */
VOID _nx_tcp_cleanup_deferred(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
diff --git a/common/inc/nx_udp.h b/common/inc/nx_udp.h
index 599af6b2..ca884f39 100644
--- a/common/inc/nx_udp.h
+++ b/common/inc/nx_udp.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* nx_udp.h PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
@@ -116,6 +119,11 @@ UINT _nx_udp_socket_unbind(NX_UDP_SOCKET *socket_ptr);
UINT _nx_udp_source_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *port);
UINT _nx_udp_packet_info_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *protocol, UINT *port, UINT *interface_index);
UINT _nxd_udp_source_extract(NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address, UINT *port);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/* Define the direct UDP packet receive processing. This is used with TCP/IP offload feature. */
+VOID _nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+ NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip, UINT remote_port);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
/* Define error checking shells for API services. These are only referenced by the
application. */
diff --git a/common/inc/nx_user_sample.h b/common/inc/nx_user_sample.h
index 978c2956..da4dd574 100644
--- a/common/inc/nx_user_sample.h
+++ b/common/inc/nx_user_sample.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* nx_user.h PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* */
/* AUTHOR */
/* */
@@ -47,6 +47,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
@@ -752,5 +755,11 @@
#define NX_MAX_STRING_LENGTH 1024
*/
+/* Defined, the TCP/IP offload feature is enabled.
+ NX_ENABLE_INTERFACE_CAPABILITY must be defined to enable this feature. */
+/*
+#define NX_ENABLE_TCPIP_OFFLOAD
+*/
+
#endif
diff --git a/common/src/nx_ip_address_set.c b/common/src/nx_ip_address_set.c
index 71a2081a..24a0e281 100644
--- a/common/src/nx_ip_address_set.c
+++ b/common/src/nx_ip_address_set.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_address_set PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -70,75 +70,13 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), */
+/* merged duplicated functions,*/
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_ip_address_set(NX_IP *ip_ptr, ULONG ip_address, ULONG network_mask)
{
-
-#ifndef NX_DISABLE_IPV4
-TX_INTERRUPT_SAVE_AREA
-
-VOID (*address_change_notify)(NX_IP *, VOID *);
-VOID *additional_info;
-ULONG previous_ip_address;
-ULONG previous_network_mask;
-
-
- /* If trace is enabled, insert this event into the trace buffer. */
- NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_ADDRESS_SET, ip_ptr, ip_address, network_mask, 0, NX_TRACE_IP_EVENTS, 0, 0);
-
- /* Get mutex protection. */
- tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
-
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Save previous IP address and network mask. This service assumes the
- operations on the primary interface. */
- previous_ip_address = ip_ptr -> nx_ip_interface[0].nx_interface_ip_address;
- previous_network_mask = ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask;
-
- /* Pickup the current notification callback and additional information pointers. */
- address_change_notify = ip_ptr -> nx_ip_address_change_notify;
- additional_info = ip_ptr -> nx_ip_address_change_notify_additional_info;
-
- /* Setup the IP address and the network mask. */
- ip_ptr -> nx_ip_interface[0].nx_interface_ip_address = ip_address;
- ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask = network_mask;
- ip_ptr -> nx_ip_interface[0].nx_interface_ip_network = ip_address & network_mask;
-
- /* Ensure the RARP function is disabled. */
- ip_ptr -> nx_ip_rarp_periodic_update = NX_NULL;
- ip_ptr -> nx_ip_rarp_queue_process = NX_NULL;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Release mutex protection. */
- tx_mutex_put(&(ip_ptr -> nx_ip_protection));
-
- /* Determine if the application should be notified of the IP address and/or
- network mask change. */
- if ((address_change_notify) &&
- ((ip_address != previous_ip_address) || (network_mask != previous_network_mask)))
- {
-
- /* Yes, call the application's IP address change notify function. */
- (address_change_notify)(ip_ptr, additional_info);
- }
-
- /* Initialize the ARP defend timeout. */
- ip_ptr -> nx_ip_interface[0].nx_interface_arp_defend_timeout = 0;
-
- /* Return completion status. */
- return(NX_SUCCESS);
-#else /* NX_DISABLE_IPV4 */
- NX_PARAMETER_NOT_USED(ip_ptr);
- NX_PARAMETER_NOT_USED(ip_address);
- NX_PARAMETER_NOT_USED(network_mask);
-
- return(NX_NOT_SUPPORTED);
-#endif /* !NX_DISABLE_IPV4 */
+ return(_nx_ip_interface_address_set(ip_ptr, 0, ip_address, network_mask));
}
diff --git a/common/src/nx_ip_header_add.c b/common/src/nx_ip_header_add.c
index 46758a0e..a638aac8 100644
--- a/common/src/nx_ip_header_add.c
+++ b/common/src/nx_ip_header_add.c
@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_header_add PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -52,6 +52,7 @@
/* */
/* ip_ptr Pointer to IP control block */
/* packet_ptr Pointer to packet to send */
+/* source_ip Source IP address */
/* destination_ip Destination IP address */
/* type_of_service Type of service for packet */
/* time_to_live Time to live value for packet */
@@ -79,9 +80,12 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
-UINT _nx_ip_header_add(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip,
+UINT _nx_ip_header_add(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG source_ip, ULONG destination_ip,
ULONG type_of_service, ULONG time_to_live, ULONG protocol, ULONG fragment)
{
ULONG router_alert = 0;
@@ -154,7 +158,7 @@ ULONG val;
ip_header_ptr -> nx_ip_header_word_2 = ((time_to_live << NX_IP_TIME_TO_LIVE_SHIFT) | protocol);
/* Place the source IP address in the IP header. */
- ip_header_ptr -> nx_ip_header_source_ip = packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address;
+ ip_header_ptr -> nx_ip_header_source_ip = source_ip;
/* Place the destination IP address in the IP header. */
ip_header_ptr -> nx_ip_header_destination_ip = destination_ip;
diff --git a/common/src/nx_ip_interface_attach.c b/common/src/nx_ip_interface_attach.c
index 23d20e76..5c62d951 100644
--- a/common/src/nx_ip_interface_attach.c
+++ b/common/src/nx_ip_interface_attach.c
@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_interface_attach PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -88,6 +88,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_ip_interface_attach(NX_IP *ip_ptr, CHAR *interface_name, ULONG ip_address, ULONG network_mask, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *))
@@ -159,12 +162,25 @@ ULONG address[4];
if (ip_ptr -> nx_ip_initialize_done == NX_TRUE)
{
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+ /* Clear capability flag. */
+ ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag = 0;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
/* First attach the interface to the device. */
driver_request.nx_ip_driver_ptr = ip_ptr;
driver_request.nx_ip_driver_command = NX_LINK_INTERFACE_ATTACH;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+ {
+
+ /* Set checksum capability for TCP/IP offload interface. */
+ ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_CHECKSUM_ALL;
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
/* Call the link driver to initialize the hardware. Among other
responsibilities, the driver is required to provide the
diff --git a/common/src/nx_ip_packet_receive.c b/common/src/nx_ip_packet_receive.c
index b9044e56..270ca7a5 100644
--- a/common/src/nx_ip_packet_receive.c
+++ b/common/src/nx_ip_packet_receive.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_receive PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -74,6 +74,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* added new ip filter, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
VOID _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
@@ -124,6 +127,20 @@ UCHAR version_byte;
return;
}
}
+
+ /* Check if the IP packet filter extended is set. */
+ if (ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, call the IP packet filter extended routine. */
+ if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_IN) != NX_SUCCESS)
+ {
+
+ /* Drop the packet. */
+ _nx_packet_release(packet_ptr);
+ return;
+ }
+ }
#endif /* NX_ENABLE_IP_PACKET_FILTER */
#ifndef NX_DISABLE_IPV4
diff --git a/common/src/nx_ip_packet_send.c b/common/src/nx_ip_packet_send.c
index 7847dbcd..7b258baf 100644
--- a/common/src/nx_ip_packet_send.c
+++ b/common/src/nx_ip_packet_send.c
@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_packet_send PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -83,6 +83,10 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* added new ip filter, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
VOID _nx_ip_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
@@ -133,6 +137,24 @@ ULONG val;
return;
}
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag &
+ NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+ {
+#ifndef NX_DISABLE_IP_INFO
+
+ /* Increment the IP invalid packet error. */
+ ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif
+
+ /* Ignore sending all packets for TCP/IP offload. Release the packet. */
+ _nx_packet_transmit_release(packet_ptr);
+
+ /* Return... nothing more can be done! */
+ return;
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
#ifdef NX_IPSEC_ENABLE
/* Check if this packet is continued after HW crypto engine. */
if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
@@ -191,7 +213,8 @@ ULONG val;
{
/* Add the IP Header to the packet. */
- _nx_ip_header_add(ip_ptr, packet_ptr, destination_ip, type_of_service, time_to_live, protocol, fragment);
+ _nx_ip_header_add(ip_ptr, packet_ptr, packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address,
+ destination_ip, type_of_service, time_to_live, protocol, fragment);
#ifdef NX_ENABLE_IP_PACKET_FILTER
/* Check if the IP packet filter is set. */
@@ -208,6 +231,20 @@ ULONG val;
return;
}
}
+
+ /* Check if the IP packet filter extended is set. */
+ if (ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, call the IP packet filter extended routine. */
+ if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Drop the packet. */
+ _nx_packet_transmit_release(packet_ptr);
+ return;
+ }
+ }
#endif /* NX_ENABLE_IP_PACKET_FILTER */
}
diff --git a/common/src/nx_ip_thread_entry.c b/common/src/nx_ip_thread_entry.c
index 69409683..9fab67d3 100644
--- a/common/src/nx_ip_thread_entry.c
+++ b/common/src/nx_ip_thread_entry.c
@@ -43,7 +43,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ip_thread_entry PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -114,6 +114,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
VOID _nx_ip_thread_entry(ULONG ip_ptr_value)
@@ -164,6 +167,15 @@ NXD_IPV6_ADDRESS *interface_ipv6_address;
driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
(ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+ {
+
+ /* Set checksum capability for TCP/IP offload interface. */
+ ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_CHECKSUM_ALL;
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Call the link driver to initialize the hardware. Among other
responsibilities, the driver is required to provide the
Maximum Transfer Unit (MTU) for the physical layer. The MTU
diff --git a/common/src/nx_ipv6_header_add.c b/common/src/nx_ipv6_header_add.c
index 3dcc2693..602ec001 100644
--- a/common/src/nx_ipv6_header_add.c
+++ b/common/src/nx_ipv6_header_add.c
@@ -43,7 +43,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ipv6_header_add PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -84,6 +84,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_ipv6_header_add(NX_IP *ip_ptr, NX_PACKET **packet_pptr,
@@ -251,22 +254,6 @@ USHORT short_val;
NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip);
NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip);
-#ifdef NX_ENABLE_IP_PACKET_FILTER
- /* Check if the IP packet filter is set. */
- if (ip_ptr -> nx_ip_packet_filter)
- {
-
- /* Yes, call the IP packet filter routine. */
- if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
- NX_IP_PACKET_OUT) != NX_SUCCESS)
- {
-
- /* Drop the packet. */
- _nx_packet_transmit_release(packet_ptr);
- return(NX_INVALID_PACKET);
- }
- }
-#endif /* NX_ENABLE_IP_PACKET_FILTER */
#ifdef NX_IPSEC_ENABLE
}
else
diff --git a/common/src/nx_ipv6_packet_send.c b/common/src/nx_ipv6_packet_send.c
index 8d03c1a6..2c17a67b 100644
--- a/common/src/nx_ipv6_packet_send.c
+++ b/common/src/nx_ipv6_packet_send.c
@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_ipv6_packet_send PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -93,6 +93,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
VOID _nx_ipv6_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
@@ -120,6 +123,23 @@ NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
/* Interface can not be NULL. */
NX_ASSERT(if_ptr != NX_NULL);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (if_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+ {
+#ifndef NX_DISABLE_IP_INFO
+
+ /* Increment the IP invalid packet error. */
+ ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif
+
+ /* Ignore sending all packets for TCP/IP offload. Release the packet. */
+ _nx_packet_transmit_release(packet_ptr);
+
+ /* Return... nothing more can be done! */
+ return;
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Add IPv6 header. */
if (_nx_ipv6_header_add(ip_ptr, &packet_ptr, protocol, payload_size,
hop_limit, src_address, dest_address, &fragment) != NX_SUCCESS)
@@ -129,6 +149,37 @@ NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
return;
}
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+ /* Check if the IP packet filter is set. */
+ if (ip_ptr -> nx_ip_packet_filter)
+ {
+
+ /* Yes, call the IP packet filter routine. */
+ if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+ NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Drop the packet. */
+ _nx_packet_transmit_release(packet_ptr);
+ return;
+ }
+ }
+
+ /* Check if the IP packet filter extended is set. */
+ if (ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, call the IP packet filter extended routine. */
+ if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Drop the packet. */
+ _nx_packet_transmit_release(packet_ptr);
+ return;
+ }
+ }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
next_hop_mtu = if_ptr -> nx_interface_ip_mtu_size;
packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
diff --git a/common/src/nx_tcp_server_socket_driver_listen.c b/common/src/nx_tcp_server_socket_driver_listen.c
new file mode 100644
index 00000000..f0c68cd7
--- /dev/null
+++ b/common/src/nx_tcp_server_socket_driver_listen.c
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** NetX Component */
+/** */
+/** Transmission Control Protocol (TCP) */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "nx_api.h"
+#include "nx_tcp.h"
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_tcp_server_socket_driver_listen PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function registers a listen request to all TCP/IP offload */
+/* interfaces. */
+/* */
+/* INPUT */
+/* */
+/* ip_ptr Pointer to IP instance */
+/* port TCP port number */
+/* socket_ptr Server socket pointer */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* None */
+/* */
+/* CALLED BY */
+/* */
+/* _nx_tcp_server_socket_listen Register a listen request */
+/* _nx_tcp_server_socket_relisten Register a listen request */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+UINT _nx_tcp_server_socket_driver_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr)
+{
+UINT status;
+UINT i;
+NX_INTERFACE *interface_ptr;
+
+ /* Loop all interfaces to listen to ones support TCP/IP offload. */
+ for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+ {
+
+ /* Use a local variable for convenience. */
+ interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+ /* Check for valid interfaces. */
+ if ((interface_ptr -> nx_interface_valid == NX_FALSE) ||
+ (interface_ptr -> nx_interface_link_up == NX_FALSE))
+ {
+
+ /* Skip interface not valid. */
+ continue;
+ }
+
+ /* Check for TCP/IP offload feature. */
+ if (((interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) == 0) ||
+ (interface_ptr -> nx_interface_tcpip_offload_handler == NX_NULL))
+ {
+
+ /* Skip interface not support TCP/IP offload. */
+ continue;
+ }
+
+ /* Let TCP/IP offload interface listen to port. */
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_LISTEN,
+ NX_NULL, NX_NULL, NX_NULL,
+ port, NX_NULL, NX_NO_WAIT);
+ if (status)
+ {
+
+ /* Return an already bound error code. */
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+ }
+
+ return(NX_SUCCESS);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */ \ No newline at end of file
diff --git a/common/src/nx_tcp_server_socket_listen.c b/common/src/nx_tcp_server_socket_listen.c
index 3a5162c2..52b6d6f3 100644
--- a/common/src/nx_tcp_server_socket_listen.c
+++ b/common/src/nx_tcp_server_socket_listen.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_server_socket_listen PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -74,6 +74,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_server_socket_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr, UINT listen_queue_size,
@@ -232,6 +235,22 @@ UINT bound;
listen_ptr -> nx_tcp_listen_next = listen_ptr;
}
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ /* Listen to TCP/IP offload interfaces. */
+ if (_nx_tcp_server_socket_driver_listen(ip_ptr, port, socket_ptr))
+ {
+
+ /* At least one of the interface fails to listen to port. */
+ _nx_tcp_server_socket_unlisten(ip_ptr, port);
+
+ /* Listen request failure, release the protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ /* Return an already bound error code. */
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Successful listen request, release the protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
diff --git a/common/src/nx_tcp_server_socket_relisten.c b/common/src/nx_tcp_server_socket_relisten.c
index 5bb5896c..b868eb6d 100644
--- a/common/src/nx_tcp_server_socket_relisten.c
+++ b/common/src/nx_tcp_server_socket_relisten.c
@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_server_socket_relisten PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_server_socket_relisten(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr)
@@ -150,6 +153,19 @@ VOID (*listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT
/* Yes, a listen request was found for this port, with an empty
socket designation. */
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ /* Listen to TCP/IP offload interfaces. */
+ if (_nx_tcp_server_socket_driver_listen(ip_ptr, port, socket_ptr))
+ {
+
+ /* Listen request failure, release the protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ /* Return an already bound error code. */
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Determine if there are any connection requests queued up. */
if (!listen_ptr -> nx_tcp_listen_queue_current)
{
diff --git a/common/src/nx_tcp_server_socket_unlisten.c b/common/src/nx_tcp_server_socket_unlisten.c
index c56191e6..7b5053d2 100644
--- a/common/src/nx_tcp_server_socket_unlisten.c
+++ b/common/src/nx_tcp_server_socket_unlisten.c
@@ -30,12 +30,96 @@
#include "nx_packet.h"
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_tcp_server_socket_driver_unlisten PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function handles the TCP server unlisten for TCP/IP offload */
+/* interface. */
+/* */
+/* INPUT */
+/* */
+/* ip_ptr Pointer to IP instance */
+/* socket_ptr Pointer to TCP socket */
+/* port TCP port number */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* tx_mutex_get Obtain protection */
+/* tx_mutex_put Release protection */
+/* */
+/* CALLED BY */
+/* */
+/* _nx_tcp_server_socket_unlisten */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nx_tcp_server_socket_driver_unlisten(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, UINT port)
+{
+UINT i;
+NX_INTERFACE *interface_ptr;
+
+ /* Loop all interfaces to unlisten to ones support TCP/IP offload. */
+ for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+ {
+
+ /* Use a local variable for convenience. */
+ interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+ /* Check for valid interfaces. */
+ if (interface_ptr -> nx_interface_valid == NX_FALSE)
+ {
+
+ /* Skip interface not valid. */
+ continue;
+ }
+
+ /* Check for TCP/IP offload feature. */
+ if (((interface_ptr -> nx_interface_capability_flag &
+ NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) == 0) ||
+ (interface_ptr -> nx_interface_tcpip_offload_handler == NX_NULL))
+ {
+
+ /* Skip interface not support TCP/IP offload. */
+ continue;
+ }
+
+ /* Let TCP/IP offload interface unlisten to port. */
+ interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_UNLISTEN,
+ NX_NULL, NX_NULL, NX_NULL,
+ port, NX_NULL, NX_NO_WAIT);
+ }
+
+ return(NX_SUCCESS);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_server_socket_unlisten PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -71,6 +155,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_server_socket_unlisten(NX_IP *ip_ptr, UINT port)
@@ -192,6 +279,10 @@ struct NX_TCP_LISTEN_STRUCT *listen_ptr;
listen_ptr -> nx_tcp_listen_next = ip_ptr -> nx_ip_tcp_available_listen_requests;
ip_ptr -> nx_ip_tcp_available_listen_requests = listen_ptr;
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ _nx_tcp_server_socket_driver_unlisten(ip_ptr, socket_ptr, port);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Release the protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
diff --git a/common/src/nx_tcp_socket_disconnect.c b/common/src/nx_tcp_socket_disconnect.c
index e04f4f09..bd49d3a3 100644
--- a/common/src/nx_tcp_socket_disconnect.c
+++ b/common/src/nx_tcp_socket_disconnect.c
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_socket_disconnect PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_socket_disconnect(NX_TCP_SOCKET *socket_ptr, ULONG wait_option)
@@ -88,6 +91,9 @@ UINT _nx_tcp_socket_disconnect(NX_TCP_SOCKET *socket_ptr, ULONG wait_option)
#ifndef NX_DISABLE_RESET_DISCONNECT
NX_TCP_HEADER tcp_header;
#endif
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+NX_INTERFACE *interface_ptr;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
UINT status;
NX_IP *ip_ptr;
@@ -129,6 +135,25 @@ NX_IP *ip_ptr;
socket_ptr -> nx_tcp_socket_keepalive_retries = 0;
#endif
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ interface_ptr = socket_ptr -> nx_tcp_socket_connect_interface;
+ if (interface_ptr &&
+ (interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) &&
+ (interface_ptr -> nx_interface_tcpip_offload_handler))
+ {
+
+ /* Let TCP/IP offload interface close the connection. */
+ interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_SOCKET_DISCONNECT,
+ NX_NULL, NX_NULL, NX_NULL, 0, NX_NULL,
+ wait_option);
+
+ /* Reset socket state. */
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_CLOSED;
+ }
+ else
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Determine if the connection wasn't fully completed. */
if ((socket_ptr -> nx_tcp_socket_state == NX_TCP_SYN_SENT) ||
(socket_ptr -> nx_tcp_socket_state == NX_TCP_SYN_RECEIVED))
diff --git a/common/src/nx_tcp_socket_driver_establish.c b/common/src/nx_tcp_socket_driver_establish.c
new file mode 100644
index 00000000..2be2a994
--- /dev/null
+++ b/common/src/nx_tcp_socket_driver_establish.c
@@ -0,0 +1,243 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** NetX Component */
+/** */
+/** Transmission Control Protocol (TCP) */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "nx_api.h"
+#include "nx_tcp.h"
+#include "nx_packet.h"
+#include "tx_thread.h"
+#include "nx_ip.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ipv6.h"
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_tcp_socket_driver_establish PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is invoked when a TCP connection is established. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to owning socket */
+/* interface_ptr Pointer to IP interface */
+/* remote_port Pointer to remote UDP port */
+/* */
+/* OUTPUT */
+/* */
+/* Status */
+/* */
+/* CALLS */
+/* */
+/* tx_mutex_get Obtain protection mutex */
+/* tx_mutex_put Release protection mutex */
+/* _nx_ip_packet_deferred_receive Defer IP packet receive */
+/* */
+/* CALLED BY */
+/* */
+/* Driver */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+UINT _nx_tcp_socket_driver_establish(NX_TCP_SOCKET *socket_ptr, NX_INTERFACE *interface_ptr, UINT remote_port)
+{
+NX_IP *ip_ptr;
+NXD_ADDRESS ip_address;
+UINT status;
+UINT index;
+UINT port;
+struct NX_TCP_LISTEN_STRUCT *listen_ptr;
+
+ /* Setup the IP pointer. */
+ ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
+
+ /* Obtain the IP internal mutex before processing the IP event. */
+ tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+ /* Check socket state first. */
+ if ((socket_ptr -> nx_tcp_socket_state != NX_TCP_SYN_SENT) &&
+ (socket_ptr -> nx_tcp_socket_state != NX_TCP_LISTEN_STATE)&&
+ (socket_ptr -> nx_tcp_socket_state != NX_TCP_SYN_RECEIVED))
+ {
+
+ /* Just ignore socket not in connecting state. */
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_NOT_SUCCESSFUL);
+ }
+
+ if (socket_ptr -> nx_tcp_socket_client_type == NX_FALSE)
+ {
+ if (socket_ptr -> nx_tcp_socket_bound_next)
+ {
+
+ /* TCP socket is connecting on other interface. */
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_NOT_SUCCESSFUL);
+ }
+
+ /* For TCP server socket, the connection is not established yet. */
+ port = socket_ptr -> nx_tcp_socket_port;
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_ACCEPT,
+ NX_NULL, NX_NULL, &ip_address, port,
+ &remote_port, NX_NO_WAIT);
+
+ if (status)
+ {
+
+ /* This should not happen as a connection is pendding. */
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+
+ /* Setup connection parameters. */
+ socket_ptr -> nx_tcp_socket_connect_interface = interface_ptr;
+
+ /* Save the server port and server IP address. */
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version = ip_address.nxd_ip_version;
+#ifndef NX_DISABLE_IPV4
+ if (ip_address.nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4 = ip_address.nxd_ip_address.v4;
+ socket_ptr -> nx_tcp_socket_mss =
+ (ULONG)((interface_ptr -> nx_interface_ip_mtu_size - sizeof(NX_IPV4_HEADER)) - sizeof(NX_TCP_HEADER));
+ }
+#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef FEATURE_NX_IPV6
+ if (ip_address.nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ COPY_IPV6_ADDRESS(ip_address.nxd_ip_address.v6,
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6);
+ socket_ptr -> nx_tcp_socket_mss =
+ (ULONG)((interface_ptr -> nx_interface_ip_mtu_size - sizeof(NX_IPV6_HEADER)) - sizeof(NX_TCP_HEADER));
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+ socket_ptr -> nx_tcp_socket_connect_port = remote_port;
+
+ /* Find listen callback function. */
+ listen_ptr = ip_ptr -> nx_ip_tcp_active_listen_requests;
+ if (listen_ptr)
+ {
+ do
+ {
+ if (listen_ptr -> nx_tcp_listen_port == port)
+ {
+ if (listen_ptr -> nx_tcp_listen_callback)
+ {
+
+ /* Clear the server socket pointer in the listen request. If the
+ application wishes to honor more server connections on this port,
+ the application must call relisten with a new server socket
+ pointer. */
+ listen_ptr->nx_tcp_listen_socket_ptr = NX_NULL;
+
+ /* Call the user's listen callback function. */
+ (listen_ptr ->nx_tcp_listen_callback)(socket_ptr, listen_ptr -> nx_tcp_listen_port);
+ break;
+ }
+ }
+
+ /* Move to the next listen request. */
+ listen_ptr = listen_ptr -> nx_tcp_listen_next;
+ } while (listen_ptr != ip_ptr -> nx_ip_tcp_active_listen_requests);
+ }
+
+ /* Calculate the hash index in the TCP port array of the associated IP instance. */
+ index = (UINT)((port + (port >> 8)) & NX_TCP_PORT_TABLE_MASK);
+
+ /* Determine if the list is NULL. */
+ if (ip_ptr -> nx_ip_tcp_port_table[index])
+ {
+
+ /* There are already sockets on this list... just add this one
+ to the end. */
+ socket_ptr -> nx_tcp_socket_bound_next =
+ ip_ptr -> nx_ip_tcp_port_table[index];
+ socket_ptr -> nx_tcp_socket_bound_previous =
+ (ip_ptr -> nx_ip_tcp_port_table[index]) -> nx_tcp_socket_bound_previous;
+ ((ip_ptr -> nx_ip_tcp_port_table[index]) -> nx_tcp_socket_bound_previous) -> nx_tcp_socket_bound_next =
+ socket_ptr;
+ (ip_ptr -> nx_ip_tcp_port_table[index]) -> nx_tcp_socket_bound_previous = socket_ptr;
+ }
+ else
+ {
+
+ /* Nothing is on the TCP port list. Add this TCP socket to an
+ empty list. */
+ socket_ptr -> nx_tcp_socket_bound_next = socket_ptr;
+ socket_ptr -> nx_tcp_socket_bound_previous = socket_ptr;
+ ip_ptr -> nx_ip_tcp_port_table[index] = socket_ptr;
+ }
+ }
+
+ /* Update socket state. */
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_ESTABLISHED;
+
+#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+
+ /* Is a connection completion callback registered with the TCP socket? */
+ if (socket_ptr -> nx_tcp_establish_notify)
+ {
+
+ /* Call the application's establish callback function. */
+ (socket_ptr -> nx_tcp_establish_notify)(socket_ptr);
+ }
+#endif
+
+ /* Determine if we need to wake a thread suspended on the connection. */
+ if (socket_ptr -> nx_tcp_socket_connect_suspended_thread)
+ {
+
+ /* Resume the suspended thread. */
+ _nx_tcp_socket_thread_resume(&(socket_ptr -> nx_tcp_socket_connect_suspended_thread), NX_SUCCESS);
+ }
+
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ return(NX_SUCCESS);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
diff --git a/common/src/nx_tcp_socket_driver_packet_receive.c b/common/src/nx_tcp_socket_driver_packet_receive.c
new file mode 100644
index 00000000..5c800215
--- /dev/null
+++ b/common/src/nx_tcp_socket_driver_packet_receive.c
@@ -0,0 +1,181 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** NetX Component */
+/** */
+/** Transmission Control Protocol (TCP) */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "nx_api.h"
+#include "nx_tcp.h"
+#include "nx_packet.h"
+#include "tx_thread.h"
+#include "nx_ip.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ipv6.h"
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_tcp_socket_driver_packet_receive PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function receives a TCP packet from the TCP/IP driver and add */
+/* fake TCP/IP header. Then pass the packet to IP deferred receive */
+/* routine. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to owning socket */
+/* packet_ptr Pointer to packet to process */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* tx_mutex_get Obtain protection mutex */
+/* tx_mutex_put Release protection mutex */
+/* _nx_ip_packet_deferred_receive Defer IP packet receive */
+/* */
+/* CALLED BY */
+/* */
+/* Driver */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+VOID _nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr)
+{
+NX_IP *ip_ptr;
+NX_TCP_HEADER *header_ptr;
+
+ /* Setup the IP pointer. */
+ ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
+
+ /* Obtain the IP internal mutex before processing the IP event. */
+ tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+ if (packet_ptr == NX_NULL)
+ {
+
+ /* Connection closed. */
+ if (socket_ptr -> nx_tcp_socket_state == NX_TCP_ESTABLISHED)
+ {
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_CLOSE_WAIT;
+
+ /* Loop to release all threads suspended while trying to receive on the socket. */
+ while (socket_ptr -> nx_tcp_socket_receive_suspension_list)
+ {
+
+ /* Release the head of the receive suspension list. */
+ _nx_tcp_receive_cleanup(socket_ptr -> nx_tcp_socket_receive_suspension_list NX_CLEANUP_ARGUMENT);
+ }
+
+ /* If given, call the application's disconnect callback function
+ for disconnect. */
+ if (socket_ptr -> nx_tcp_disconnect_callback)
+ {
+
+ /* Call the application's disconnect handling function. It is
+ responsible for calling the socket disconnect function. */
+ (socket_ptr -> nx_tcp_disconnect_callback)(socket_ptr);
+ }
+ }
+
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return;
+ }
+
+ /* Fake TCP and IP header. */
+ /* Prepend the TCP header to the packet. First, make room for the TCP header. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_TCP_HEADER);
+
+ /* Add the length of the TCP header. */
+ packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_TCP_HEADER);
+
+ /* Pickup the pointer to the head of the TCP packet. */
+ /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
+ header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+ /* Build the output request in the TCP header. */
+ header_ptr -> nx_tcp_header_word_0 = (((ULONG)(socket_ptr -> nx_tcp_socket_connect_port)) << NX_SHIFT_BY_16) |
+ (ULONG)socket_ptr -> nx_tcp_socket_port;
+ NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_0);
+ header_ptr -> nx_tcp_acknowledgment_number = 0;
+ header_ptr -> nx_tcp_sequence_number = 0;
+ header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_ACK_BIT | NX_TCP_PSH_BIT;
+ NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3);
+ header_ptr -> nx_tcp_header_word_4 = 0;
+
+#ifndef NX_DISABLE_IPV4
+ if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ _nx_ip_header_add(ip_ptr, packet_ptr, socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4,
+ packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address,
+ socket_ptr -> nx_tcp_socket_type_of_service,
+ socket_ptr -> nx_tcp_socket_time_to_live,
+ NX_IP_TCP,
+ socket_ptr -> nx_tcp_socket_fragment_enable);
+ }
+#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef FEATURE_NX_IPV6
+ if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ if (_nx_ipv6_header_add(ip_ptr, &packet_ptr,
+ NX_PROTOCOL_TCP,
+ packet_ptr -> nx_packet_length,
+ ip_ptr -> nx_ipv6_hop_limit,
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6,
+ socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address,
+ NX_NULL))
+ {
+
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return;
+ }
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
diff --git a/common/src/nx_tcp_socket_packet_process.c b/common/src/nx_tcp_socket_packet_process.c
index 085d8b47..878ff945 100644
--- a/common/src/nx_tcp_socket_packet_process.c
+++ b/common/src/nx_tcp_socket_packet_process.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_socket_packet_process PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -83,6 +83,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
VOID _nx_tcp_socket_packet_process(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr)
@@ -98,6 +101,12 @@ ULONG rx_sequence;
ULONG rx_window;
UINT outside_of_window;
ULONG mss = 0;
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ULONG tcpip_offload;
+
+ tcpip_offload = socket_ptr -> nx_tcp_socket_connect_interface -> nx_interface_capability_flag &
+ NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
/* Add debug information. */
NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
@@ -112,7 +121,11 @@ ULONG mss = 0;
header_length = (tcp_header_copy.nx_tcp_header_word_3 >> NX_TCP_HEADER_SHIFT) * (ULONG)sizeof(ULONG);
/* Process the segment if socket state is equal or greater than NX_TCP_SYN_RECEIVED. According to RFC 793, Section 3.9, Page 69. */
- if (socket_ptr -> nx_tcp_socket_state >= NX_TCP_SYN_RECEIVED)
+ if ((socket_ptr -> nx_tcp_socket_state >= NX_TCP_SYN_RECEIVED)
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ && (!tcpip_offload)
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ )
{
/* Step1: Check sequence number. According to RFC 793, Section 3.9, Page 69. */
@@ -366,12 +379,18 @@ ULONG mss = 0;
/* Check for data in the current packet. */
packet_queued = _nx_tcp_socket_state_data_check(socket_ptr, packet_ptr);
- /* Call the ESTABLISHED state handling function to process any state
- changes caused by this new packet. */
- _nx_tcp_socket_state_established(socket_ptr);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (!tcpip_offload)
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ {
- /* Determine if any transmit suspension can be lifted. */
- _nx_tcp_socket_state_transmit_check(socket_ptr);
+ /* Call the ESTABLISHED state handling function to process any state
+ changes caused by this new packet. */
+ _nx_tcp_socket_state_established(socket_ptr);
+
+ /* Determine if any transmit suspension can be lifted. */
+ _nx_tcp_socket_state_transmit_check(socket_ptr);
+ }
/* State processing is complete. */
break;
diff --git a/common/src/nx_tcp_socket_send_internal.c b/common/src/nx_tcp_socket_send_internal.c
index 4d176c6f..2d466857 100644
--- a/common/src/nx_tcp_socket_send_internal.c
+++ b/common/src/nx_tcp_socket_send_internal.c
@@ -38,12 +38,176 @@
#endif /* NX_IPSEC_ENABLE */
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_tcp_socket_driver_send PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function sends a TCP packet through TCP/IP offload interface. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to socket */
+/* packet_ptr Pointer to packet to send */
+/* wait_option Suspension option */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _nx_ip_packet_send Packet send function */
+/* _nx_ipv6_packet_send Packet send function */
+/* */
+/* CALLED BY */
+/* */
+/* _nx_tcp_socket_send_internal */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nx_tcp_socket_driver_send(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
+{
+UINT status;
+NX_IP *ip_ptr;
+NX_INTERFACE *interface_ptr = socket_ptr -> nx_tcp_socket_connect_interface;
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+UCHAR *original_ptr = packet_ptr -> nx_packet_prepend_ptr;
+ULONG original_length = packet_ptr -> nx_packet_length;
+NX_TCP_HEADER *header_ptr;
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+ /* Setup the pointer to the associated IP instance. */
+ ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+ /* Check if the IP packet filter is set. */
+ if (ip_ptr -> nx_ip_packet_filter || ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, add the TCP and IP Header to trigger filtering. */
+ /* Prepend the TCP header to the packet. First, make room for the TCP header. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_TCP_HEADER);
+
+ /* Add the length of the TCP header. */
+ packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_TCP_HEADER);
+
+ /* Pickup the pointer to the head of the TCP packet. */
+ /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
+ header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+ /* Build the output request in the TCP header. */
+ header_ptr -> nx_tcp_header_word_0 = (((ULONG)(socket_ptr -> nx_tcp_socket_port)) << NX_SHIFT_BY_16) |
+ (ULONG)socket_ptr -> nx_tcp_socket_connect_port;
+ header_ptr -> nx_tcp_acknowledgment_number = 0;
+ header_ptr -> nx_tcp_sequence_number = 0;
+ header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_ACK_BIT | NX_TCP_PSH_BIT;
+ header_ptr -> nx_tcp_header_word_4 = 0;
+
+ /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
+ swap the endian of the TCP header. */
+ NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_0);
+ NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3);
+
+#ifndef NX_DISABLE_IPV4
+ if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ _nx_ip_header_add(ip_ptr, packet_ptr,
+ socket_ptr -> nx_tcp_socket_connect_interface -> nx_interface_ip_address,
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4,
+ socket_ptr -> nx_tcp_socket_type_of_service,
+ socket_ptr -> nx_tcp_socket_time_to_live,
+ NX_IP_TCP,
+ socket_ptr -> nx_tcp_socket_fragment_enable);
+ }
+#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef FEATURE_NX_IPV6
+ if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ if (_nx_ipv6_header_add(ip_ptr, &packet_ptr,
+ NX_PROTOCOL_TCP,
+ packet_ptr -> nx_packet_length,
+ ip_ptr -> nx_ipv6_hop_limit,
+ socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address,
+ socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6,
+ NX_NULL))
+ {
+
+ /* Invalid interface address. Just return success. */
+ return(NX_SUCCESS);
+ }
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+ if (ip_ptr -> nx_ip_packet_filter)
+ {
+ if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+ NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Packet consumed by IP filter. Just return success. */
+ _nx_packet_transmit_release(packet_ptr);
+ return(NX_SUCCESS);
+ }
+ }
+
+ /* Check if the IP packet filter extended is set. */
+ if (ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, call the IP packet filter extended routine. */
+ if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Packet consumed by IP filter. Just return success. */
+ _nx_packet_transmit_release(packet_ptr);
+ return(NX_SUCCESS);
+ }
+ }
+
+ /* Reset UDP and IP header. */
+ packet_ptr -> nx_packet_prepend_ptr = original_ptr;
+ packet_ptr -> nx_packet_length = original_length;
+ }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+ /* Let TCP/IP offload interface send the packet. */
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_SOCKET_SEND,
+ packet_ptr, NX_NULL, NX_NULL, 0, NX_NULL,
+ wait_option);
+
+ if (status)
+ {
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+ else
+ {
+ return(NX_SUCCESS);
+ }
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_socket_send_internal PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -70,6 +234,7 @@
/* _nx_tcp_socket_thread_suspend Suspend calling thread */
/* tx_mutex_get Get protection mutex */
/* tx_mutex_put Put protection mutex */
+/* _nx_tcp_socket_driver_send TCP/IP offload send function */
/* */
/* CALLED BY */
/* */
@@ -88,6 +253,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_socket_send_internal(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
@@ -116,6 +284,10 @@ UCHAR preempted = NX_FALSE;
UCHAR adjust_packet;
UINT old_threshold = 0;
ULONG window_size;
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+UINT status;
+NX_INTERFACE *interface_ptr;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
#if defined(NX_DISABLE_TCP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
UINT compute_checksum = 1;
#endif /* defined(NX_DISABLE_TCP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
@@ -183,7 +355,7 @@ UINT compute_checksum = 1;
/* Set the source address. */
source_ip = &socket_ptr -> nx_tcp_socket_connect_interface -> nx_interface_ip_address;
- /* Set the destinatino address. */
+ /* Set the destination address. */
dest_ip = &socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4;
/* The outgoing interface should have been stored in the socket structure. */
@@ -210,7 +382,7 @@ UINT compute_checksum = 1;
/* Set the source address. */
source_ip = socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address;
- /* Set the destinatino address. */
+ /* Set the destination address. */
dest_ip = socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6;
/* The outgoing address should have been stored in the socket structure. */
@@ -221,6 +393,24 @@ UINT compute_checksum = 1;
}
#endif /* FEATURE_NX_IPV6 */
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ interface_ptr = socket_ptr -> nx_tcp_socket_connect_interface;
+ if ((interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) &&
+ (interface_ptr -> nx_interface_tcpip_offload_handler))
+ {
+
+ /* This interface supports TCP/IP offload. */
+ tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+ status = _nx_tcp_socket_driver_send(socket_ptr, packet_ptr, wait_option);
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ return(status);
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
#ifdef NX_IPSEC_ENABLE
/* Increase the data offset when IPsec is enabled. */
data_offset += socket_ptr -> nx_tcp_socket_egress_sa_data_offset;
@@ -907,5 +1097,4 @@ UINT compute_checksum = 1;
}
}
}
-}
-
+} \ No newline at end of file
diff --git a/common/src/nx_tcp_socket_state_data_check.c b/common/src/nx_tcp_socket_state_data_check.c
index 1f6475d1..d23b6c21 100644
--- a/common/src/nx_tcp_socket_state_data_check.c
+++ b/common/src/nx_tcp_socket_state_data_check.c
@@ -276,7 +276,7 @@ ULONG work_length;
/* FUNCTION RELEASE */
/* */
/* _nx_tcp_socket_state_data_check PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -317,6 +317,9 @@ ULONG work_length;
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_tcp_socket_state_data_check(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr)
@@ -339,6 +342,9 @@ ULONG trim_data_length;
TX_THREAD *thread_ptr;
ULONG acked_packets = 0;
UINT need_ack = NX_FALSE;
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ULONG tcpip_offload;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
#ifdef NX_ENABLE_LOW_WATERMARK
UCHAR drop_packet = NX_FALSE;
#endif /* NX_ENABLE_LOW_WATERMARK */
@@ -349,6 +355,10 @@ NX_IP *ip_ptr;
ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
#endif
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ tcpip_offload = socket_ptr -> nx_tcp_socket_connect_interface -> nx_interface_capability_flag &
+ NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
/* Pickup the pointer to the head of the TCP packet. */
/*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
@@ -370,7 +380,11 @@ NX_IP *ip_ptr;
packet_end_sequence = tcp_header_ptr -> nx_tcp_sequence_number + packet_data_length;
/* Trim the data that out of the receive window, make sure all data are in receive window. */
- if (packet_data_length)
+ if (packet_data_length
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ && (!tcpip_offload)
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ )
{
/* Step1. trim the data on the left side of the receive window. */
@@ -480,13 +494,17 @@ NX_IP *ip_ptr;
search_end_sequence = socket_ptr -> nx_tcp_socket_rx_sequence;
}
-#ifdef NX_ENABLE_LOW_WATERMARK
/* Does the number of queued packets exceed the maximum rx queue length, or the number of
* available packets in the default packet pool reaches low watermark? */
- if ((socket_ptr -> nx_tcp_socket_receive_queue_count >=
- socket_ptr -> nx_tcp_socket_receive_queue_maximum) ||
- (packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_available <
- packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_low_watermark))
+#ifdef NX_ENABLE_LOW_WATERMARK
+ if (((socket_ptr -> nx_tcp_socket_receive_queue_count >=
+ socket_ptr -> nx_tcp_socket_receive_queue_maximum) ||
+ (packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_available <
+ packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_low_watermark))
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ && (!tcpip_offload)
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ )
{
/* Yes it is. The last packet in queue should be dropped. */
@@ -497,8 +515,12 @@ NX_IP *ip_ptr;
/* Determine if we have a simple case of TCP data coming in the correct order. This means
the socket's sequence number matches the incoming packet sequence number and the last packet's
data on the socket's receive queue (if any) matches the current sequence number. */
- if ((tcp_header_ptr -> nx_tcp_sequence_number == socket_ptr -> nx_tcp_socket_rx_sequence) &&
- (search_end_sequence == socket_ptr -> nx_tcp_socket_rx_sequence))
+ if (((tcp_header_ptr -> nx_tcp_sequence_number == socket_ptr -> nx_tcp_socket_rx_sequence) &&
+ (search_end_sequence == socket_ptr -> nx_tcp_socket_rx_sequence))
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ || tcpip_offload
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ )
{
/* Yes, this is the simple case of adding receive packets in sequence. */
@@ -534,7 +556,12 @@ NX_IP *ip_ptr;
socket_ptr -> nx_tcp_socket_receive_queue_tail = packet_ptr;
/* Setup a new delayed ACK timeout. */
- socket_ptr -> nx_tcp_socket_delayed_ack_timeout = _nx_tcp_ack_timer_rate;
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (!tcpip_offload)
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ {
+ socket_ptr -> nx_tcp_socket_delayed_ack_timeout = _nx_tcp_ack_timer_rate;
+ }
}
/* Increment the receive TCP packet count. */
@@ -1059,7 +1086,7 @@ NX_IP *ip_ptr;
/* At this point, we can use the packet TCP header pointers since the received
packet is already queued. */
- /* Any packets for receving? */
+ /* Any packets for receiving? */
while (acked_packets && socket_ptr -> nx_tcp_socket_receive_suspension_list)
{
@@ -1134,7 +1161,11 @@ NX_IP *ip_ptr;
/* If the incoming packet caused the sequence number to move forward,
indicating the new piece of data is in order, in sequence, and valid for receiving. */
- if (original_rx_sequence != socket_ptr -> nx_tcp_socket_rx_sequence)
+ if ((original_rx_sequence != socket_ptr -> nx_tcp_socket_rx_sequence)
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ || tcpip_offload
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ )
{
/* Determine if there is a socket receive notification function specified. */
if (socket_ptr -> nx_tcp_receive_callback)
diff --git a/common/src/nx_udp_socket_bind.c b/common/src/nx_udp_socket_bind.c
index 6917a2a6..c1ad243c 100644
--- a/common/src/nx_udp_socket_bind.c
+++ b/common/src/nx_udp_socket_bind.c
@@ -30,12 +30,117 @@
#include "tx_thread.h"
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_udp_socket_driver_bind PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function binds to a UDP port through TCP/IP offload interface. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to UDP socket */
+/* port 16-bit UDP port number */
+/* wait_option Suspension option */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _nx_udp_socket_unbind Unbind UDP port */
+/* tx_mutex_get Obtain protection mutex */
+/* tx_mutex_put Release protection mutex */
+/* */
+/* CALLED BY */
+/* */
+/* _nx_udp_socket_bind */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nx_udp_socket_driver_bind(NX_UDP_SOCKET *socket_ptr, UINT port, ULONG wait_option)
+{
+UINT status = NX_SUCCESS;
+UINT i;
+NX_INTERFACE *interface_ptr;
+NX_IP *ip_ptr;
+
+
+ /* Setup the pointer to the associated IP instance. */
+ ip_ptr = socket_ptr -> nx_udp_socket_ip_ptr;
+
+ /* Obtain the IP mutex. */
+ tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+ /* Loop all interfaces to bind to ones support TCP/IP offload. */
+ for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+ {
+
+ /* Use a local variable for convenience. */
+ interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+ /* Check for valid interfaces. */
+ if ((interface_ptr -> nx_interface_valid == NX_FALSE) ||
+ (interface_ptr -> nx_interface_link_up == NX_FALSE))
+ {
+
+ /* Skip interface not valid. */
+ continue;
+ }
+
+ /* Check for TCP/IP offload feature. */
+ if (((interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) == 0) ||
+ (interface_ptr -> nx_interface_tcpip_offload_handler == NX_NULL))
+ {
+
+ /* Skip interface not support TCP/IP offload. */
+ continue;
+ }
+
+ /* Let TCP/IP offload interface bind to port. */
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr,
+ socket_ptr,
+ NX_TCPIP_OFFLOAD_UDP_SOCKET_BIND,
+ NX_NULL, NX_NULL, NX_NULL, port,
+ NX_NULL, wait_option);
+ if (status)
+ {
+
+ /* At least one of the interface fails to bind to port. */
+ _nx_udp_socket_unbind(socket_ptr);
+ status = NX_TCPIP_OFFLOAD_ERROR;
+ break;
+ }
+ }
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ return(status);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_udp_socket_bind PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -75,6 +180,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_udp_socket_bind(NX_UDP_SOCKET *socket_ptr, UINT port, ULONG wait_option)
@@ -89,6 +197,7 @@ NX_IP *ip_ptr;
TX_THREAD *thread_ptr;
NX_UDP_SOCKET *search_ptr;
NX_UDP_SOCKET *end_ptr;
+UINT status = NX_SUCCESS;
/* Setup the pointer to the associated IP instance. */
@@ -222,9 +331,6 @@ NX_UDP_SOCKET *end_ptr;
/* Release the mutex protection. */
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
-
- /* Return success to the caller. */
- return(NX_SUCCESS);
}
else if (wait_option)
{
@@ -296,7 +402,7 @@ NX_UDP_SOCKET *end_ptr;
_tx_thread_system_suspend(thread_ptr);
/* Return the completion status. */
- return(thread_ptr -> tx_thread_suspend_status);
+ status = thread_ptr -> tx_thread_suspend_status;
}
else
{
@@ -305,7 +411,19 @@ NX_UDP_SOCKET *end_ptr;
tx_mutex_put(&(ip_ptr -> nx_ip_protection));
/* Return the port unavailable error. */
- return(NX_PORT_UNAVAILABLE);
+ status = NX_PORT_UNAVAILABLE;
+ }
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if (status == NX_SUCCESS)
+ {
+
+ /* Bind to TCP/IP offload interface. */
+ status = _nx_udp_socket_driver_bind(socket_ptr, port, wait_option);
}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+ /* Return success to the caller. */
+ return(status);
}
diff --git a/common/src/nx_udp_socket_driver_packet_receive.c b/common/src/nx_udp_socket_driver_packet_receive.c
new file mode 100644
index 00000000..cfc9897f
--- /dev/null
+++ b/common/src/nx_udp_socket_driver_packet_receive.c
@@ -0,0 +1,158 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** NetX Component */
+/** */
+/** User Datagram Protocol (UDP) */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "nx_api.h"
+#include "tx_thread.h"
+#include "nx_udp.h"
+#include "nx_packet.h"
+#include "nx_ip.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ipv6.h"
+#endif /* FEATURE_NX_IPV6 */
+
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_udp_socket_driver_packet_receive PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function receives a UDP packet from the TCP/IP driver and add */
+/* fake TCP/IP header. Then pass the packet to IP deferred receive */
+/* routine. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to owning socket */
+/* packet_ptr Pointer to packet to process */
+/* local_ip Pointer to local IP address */
+/* remote_ip Pointer to remote IP address */
+/* remote_port Pointer to remote UDP port */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* tx_mutex_get Obtain protection mutex */
+/* tx_mutex_put Release protection mutex */
+/* _nx_ip_packet_deferred_receive Defer IP packet receive */
+/* */
+/* CALLED BY */
+/* */
+/* Driver */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+VOID _nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+ NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip, UINT remote_port)
+{
+
+NX_IP *ip_ptr;
+NX_UDP_HEADER *udp_header_ptr;
+
+ /* Setup the IP pointer. */
+ ip_ptr = socket_ptr -> nx_udp_socket_ip_ptr;
+
+ if (packet_ptr == NX_NULL)
+ {
+
+ /* Socket error. Just ignore. */
+ return;
+ }
+
+ /* Fake UDP and IP header. */
+ /* Prepend the UDP header to the packet. First, make room for the UDP header. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_UDP_HEADER);
+
+ /* Increase the packet length. */
+ packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_UDP_HEADER);
+
+ /* Setup the UDP header pointer. */
+ /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
+ udp_header_ptr = (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+ /* Build the first 32-bit word of the UDP header. */
+ udp_header_ptr -> nx_udp_header_word_0 =
+ ((ULONG)remote_port << NX_SHIFT_BY_16) | (ULONG)socket_ptr -> nx_udp_socket_port;
+
+ /* Build the second 32-bit word of the UDP header. */
+ udp_header_ptr -> nx_udp_header_word_1 = (packet_ptr -> nx_packet_length << NX_SHIFT_BY_16);
+
+ /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
+ swap the endian of the UDP header. */
+ NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
+ NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1);
+
+#ifndef NX_DISABLE_IPV4
+ if (remote_ip -> nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ _nx_ip_header_add(ip_ptr, packet_ptr, remote_ip -> nxd_ip_address.v4,
+ local_ip -> nxd_ip_address.v4,
+ socket_ptr -> nx_udp_socket_type_of_service,
+ socket_ptr -> nx_udp_socket_time_to_live,
+ NX_IP_UDP,
+ socket_ptr -> nx_udp_socket_fragment_enable);
+ }
+#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef FEATURE_NX_IPV6
+ if (remote_ip -> nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ if (_nx_ipv6_header_add(ip_ptr, &packet_ptr,
+ NX_PROTOCOL_UDP,
+ packet_ptr -> nx_packet_length,
+ ip_ptr -> nx_ipv6_hop_limit,
+ remote_ip -> nxd_ip_address.v6,
+ local_ip -> nxd_ip_address.v6,
+ NX_NULL))
+ {
+
+ /* Release the IP internal mutex. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return;
+ }
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+ _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
diff --git a/common/src/nx_udp_socket_unbind.c b/common/src/nx_udp_socket_unbind.c
index 145e2743..05953d1e 100644
--- a/common/src/nx_udp_socket_unbind.c
+++ b/common/src/nx_udp_socket_unbind.c
@@ -31,12 +31,98 @@
#include "tx_thread.h"
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_udp_socket_driver_unbind PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function unbinds a UDP port through TCP/IP offload interface. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to UDP socket */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* None */
+/* */
+/* CALLED BY */
+/* */
+/* _nx_udp_socket_bind */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nx_udp_socket_driver_unbind(NX_UDP_SOCKET *socket_ptr)
+{
+UINT i;
+NX_INTERFACE *interface_ptr;
+NX_IP *ip_ptr;
+
+
+ /* Setup the pointer to the associated IP instance. */
+ ip_ptr = socket_ptr -> nx_udp_socket_ip_ptr;
+
+ /* Loop all interfaces to unbind to ones support TCP/IP offload. */
+ for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+ {
+
+ /* Use a local variable for convenience. */
+ interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+ /* Check for valid interfaces. */
+ if (interface_ptr -> nx_interface_valid == NX_FALSE)
+ {
+
+ /* Skip interface not valid. */
+ continue;
+ }
+
+ /* Check for TCP/IP offload feature. */
+ if (((interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) == 0) ||
+ (interface_ptr -> nx_interface_tcpip_offload_handler == NX_NULL))
+ {
+
+ /* Skip interface not support TCP/IP offload. */
+ continue;
+ }
+
+ /* Let TCP/IP offload interface unbind port. Return value is ignored. */
+ interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr,
+ socket_ptr,
+ NX_TCPIP_OFFLOAD_UDP_SOCKET_UNBIND,
+ NX_NULL, NX_NULL, NX_NULL,
+ socket_ptr -> nx_udp_socket_port,
+ NX_NULL, NX_NO_WAIT);
+ }
+
+ return(NX_SUCCESS);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nx_udp_socket_unbind PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -74,6 +160,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nx_udp_socket_unbind(NX_UDP_SOCKET *socket_ptr)
@@ -138,6 +227,10 @@ NX_PACKET *next_packet_ptr;
/* Calculate the hash index in the UDP port array of the associated IP instance. */
index = (UINT)((port + (port >> 8)) & NX_UDP_PORT_TABLE_MASK);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ _nx_udp_socket_driver_unbind(socket_ptr);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/* Disable interrupts while we unlink the current socket. */
TX_DISABLE
diff --git a/common/src/nx_utility.c b/common/src/nx_utility.c
index b8d1a827..04c4bae0 100644
--- a/common/src/nx_utility.c
+++ b/common/src/nx_utility.c
@@ -204,6 +204,116 @@ UINT i;
/* */
/* FUNCTION RELEASE */
/* */
+/* _nx_utility_uint_to_string PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function converts the unsigned integer to string. */
+/* */
+/* INPUT */
+/* */
+/* number Input number */
+/* base Base of the conversion */
+/* 8 for OCT */
+/* 10 for DEC */
+/* 16 for HEX */
+/* string_buffer Pointer to string buffer */
+/* string_buffer_size Size of string buffer */
+/* */
+/* OUTPUT */
+/* */
+/* size The size of output string */
+/* */
+/* CALLS */
+/* */
+/* None */
+/* */
+/* CALLED BY */
+/* */
+/* Application Code */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+UINT _nx_utility_uint_to_string(UINT number, UINT base, CHAR *string_buffer, UINT string_buffer_size)
+{
+UINT i;
+UINT digit;
+UINT size;
+
+ /* Check for invalid input pointers. */
+ if ((string_buffer == NX_NULL) || (string_buffer_size == 0))
+ {
+ return(0);
+ }
+
+ /* Initialize. */
+ i = 0;
+ size = 0;
+
+ /* Loop to convert the number to ASCII. Minus 1 to put NULL terminal. */
+ while (size < string_buffer_size - 1)
+ {
+
+ /* Shift the current digits over one. */
+ for (i = size; i != 0; i--)
+ {
+
+ /* Move each digit over one place. */
+ string_buffer[i] = string_buffer[i-1];
+ }
+
+ /* Compute the next decimal digit. */
+ digit = number % base;
+
+ /* Update the input number. */
+ number = number / base;
+
+ /* Store the new digit in ASCII form. */
+ if (digit < 10)
+ {
+ string_buffer[0] = (CHAR) (digit + '0');
+ }
+ else
+ {
+ string_buffer[0] = (CHAR) (digit + 'a' - 0xa);
+ }
+
+ /* Increment the size. */
+ size++;
+
+ /* Determine if the number is now zero. */
+ if (number == 0)
+ break;
+ }
+
+ /* Determine if there is an overflow error. */
+ if (number)
+ {
+
+ /* Error, return bad values to user. */
+ size = 0;
+ }
+
+ /* Make the string NULL terminated. */
+ string_buffer[size] = (CHAR) NX_NULL;
+
+ /* Return size to caller. */
+ return(size);
+}
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
/* _nx_utility_base64_encode PORTABLE C */
/* 6.1.6 */
/* AUTHOR */
@@ -505,4 +615,4 @@ UINT source_size = base64name_size;
*bytes_copied = j;
return(NX_SUCCESS);
-}
+} \ No newline at end of file
diff --git a/common/src/nxd_tcp_client_socket_connect.c b/common/src/nxd_tcp_client_socket_connect.c
index 9cbd88ab..a2df3662 100644
--- a/common/src/nxd_tcp_client_socket_connect.c
+++ b/common/src/nxd_tcp_client_socket_connect.c
@@ -32,12 +32,163 @@
#include "nx_ipv4.h"
#include "nx_ip.h"
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nxd_tcp_client_socket_driver_connect PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function handles the connect request for TCP/IP offload */
+/* interface. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to TCP client socket */
+/* server_ip IP address of server */
+/* server_port Port number of server */
+/* wait_option Suspension option */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* tx_mutex_get Obtain protection */
+/* tx_mutex_put Release protection */
+/* */
+/* CALLED BY */
+/* */
+/* _nxd_tcp_client_socket_connect */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nxd_tcp_client_socket_driver_connect(NX_TCP_SOCKET *socket_ptr,
+ NXD_ADDRESS *server_ip,
+ UINT server_port,
+ ULONG wait_option)
+{
+UINT status;
+NX_INTERFACE *interface_ptr;
+NX_IP *ip_ptr;
+
+
+ /* Setup the pointer to the associated IP instance. */
+ ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
+
+ /* Clear the socket timeout. */
+ socket_ptr -> nx_tcp_socket_timeout = 0;
+
+ /* Let TCP/IP offload interface make the connection. */
+ interface_ptr = socket_ptr -> nx_tcp_socket_connect_interface;
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_TCP_CLIENT_SOCKET_CONNECT,
+ NX_NULL, NX_NULL, server_ip,
+ socket_ptr -> nx_tcp_socket_port,
+ &server_port, wait_option);
+ if ((status == NX_SUCCESS) || (status == NX_IN_PROGRESS))
+ {
+
+ /* Set MSS. */
+#ifndef NX_DISABLE_IPV4
+ if (server_ip -> nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ socket_ptr -> nx_tcp_socket_mss =
+ (ULONG)((interface_ptr -> nx_interface_ip_mtu_size - sizeof(NX_IPV4_HEADER)) - sizeof(NX_TCP_HEADER));
+ }
+#endif /* !NX_DISABLE_IPV4 */
+#ifdef FEATURE_NX_IPV6
+ if (server_ip -> nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ socket_ptr -> nx_tcp_socket_mss =
+ (ULONG)((interface_ptr -> nx_interface_ip_mtu_size - sizeof(NX_IPV6_HEADER)) - sizeof(NX_TCP_HEADER));
+ }
+#endif /* FEATURE_NX_IPV6 */
+ socket_ptr -> nx_tcp_socket_connect_mss = socket_ptr -> nx_tcp_socket_mss;
+ socket_ptr -> nx_tcp_socket_peer_mss = socket_ptr -> nx_tcp_socket_mss;
+
+ if (status == NX_SUCCESS)
+ {
+
+ /* Connected to server. */
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_ESTABLISHED;
+#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+
+ /* Is a connection completion callback registered with the TCP socket? */
+ if (socket_ptr -> nx_tcp_establish_notify)
+ {
+
+ /* Call the application's establish callback function. */
+ (socket_ptr -> nx_tcp_establish_notify)(socket_ptr);
+ }
+#endif
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_SUCCESS);
+ }
+ else
+ {
+
+ /* Connected to server. */
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_SYN_SENT;
+ }
+ }
+ else
+ {
+
+ /* Unable to connect to server. */
+
+#ifndef NX_DISABLE_TCP_INFO
+
+ /* Reduce the active connections count. */
+ ip_ptr -> nx_ip_tcp_active_connections--;
+
+ /* Reduce the TCP connections count. */
+ ip_ptr -> nx_ip_tcp_connections--;
+#endif
+
+ /* Restore the socket state. */
+ socket_ptr -> nx_tcp_socket_state = NX_TCP_CLOSED;
+
+ /* Reset server port and server IP address. */
+ memset(&socket_ptr -> nx_tcp_socket_connect_ip, 0, sizeof(NXD_ADDRESS));
+ socket_ptr -> nx_tcp_socket_connect_port = 0;
+
+ /* Reset the next_hop_address information. */
+ socket_ptr -> nx_tcp_socket_next_hop_address = 0;
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_SUCCESS);
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nxd_tcp_client_socket_connect PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -79,6 +230,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nxd_tcp_client_socket_connect(NX_TCP_SOCKET *socket_ptr,
@@ -307,8 +461,21 @@ ULONG ip_address_log = 0;
socket_ptr -> nx_tcp_socket_receive_queue_head = NX_NULL;
socket_ptr -> nx_tcp_socket_receive_queue_tail = NX_NULL;
- /* Send the SYN message. */
- _nx_tcp_packet_send_syn(socket_ptr, (socket_ptr -> nx_tcp_socket_tx_sequence - 1));
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if ((outgoing_interface -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) &&
+ (outgoing_interface -> nx_interface_tcpip_offload_handler))
+ {
+
+ /* This interface supports TCP/IP offload. */
+ return(_nxd_tcp_client_socket_driver_connect(socket_ptr, server_ip, server_port, wait_option));
+ }
+ else
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+ {
+
+ /* Send the SYN message. */
+ _nx_tcp_packet_send_syn(socket_ptr, (socket_ptr -> nx_tcp_socket_tx_sequence - 1));
+ }
/* Optionally suspend the thread. If timeout occurs, return a connection timeout status. If
immediate response is selected, return a connection in progress status. Only on a real
diff --git a/common/src/nxd_udp_socket_send.c b/common/src/nxd_udp_socket_send.c
index a32c21e9..2f661756 100644
--- a/common/src/nxd_udp_socket_send.c
+++ b/common/src/nxd_udp_socket_send.c
@@ -28,6 +28,7 @@
#include "nx_api.h"
#include "nx_udp.h"
#include "nx_ip.h"
+#include "nx_packet.h"
#ifdef FEATURE_NX_IPV6
#include "nx_ipv6.h"
#endif /* FEATURE_NX_IPV6 */
@@ -36,12 +37,177 @@
#include "nx_ipsec.h"
#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _nx_udp_socket_driver_send PORTABLE C */
+/* 6.1.8 */
+/* AUTHOR */
+/* */
+/* Yuxin Zhou, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function sends a UDP packet through TCP/IP offload interface. */
+/* */
+/* INPUT */
+/* */
+/* socket_ptr Pointer to UDP socket */
+/* packet_ptr Pointer to UDP packet */
+/* ip_src_address Source IP address */
+/* ip_dst_address Destination IP address */
+/* port 16-bit UDP port number */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _nx_ip_packet_send Packet send function */
+/* _nx_ipv6_packet_send Packet send function */
+/* */
+/* CALLED BY */
+/* */
+/* _nxd_udp_socket_send */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
+/* */
+/**************************************************************************/
+static UINT _nx_udp_socket_driver_send(NX_UDP_SOCKET *socket_ptr,
+ NX_PACKET *packet_ptr,
+ NXD_ADDRESS *ip_src_address,
+ NXD_ADDRESS *ip_dst_address,
+ UINT port)
+{
+UINT status;
+NX_IP *ip_ptr;
+NX_INTERFACE *interface_ptr = NX_NULL;
+UCHAR *original_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_UDP_HEADER);
+ULONG original_length = packet_ptr -> nx_packet_length - sizeof(NX_UDP_HEADER);
+
+ /* Set up the pointer to the associated IP instance. */
+ ip_ptr = socket_ptr -> nx_udp_socket_ip_ptr;
+
+ /* Get the outgoing interface. */
+#ifndef NX_DISABLE_IPV4
+ if (ip_dst_address -> nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ interface_ptr = packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
+ }
+#endif /* NX_DISABLE_IPV4 */
+#ifdef FEATURE_NX_IPV6
+ if (ip_dst_address -> nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ interface_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+ /* Check if the IP packet filter is set. */
+ if (ip_ptr -> nx_ip_packet_filter || ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Add the IP Header to trigger filtering. */
+#ifndef NX_DISABLE_IPV4
+ if (ip_dst_address -> nxd_ip_version == NX_IP_VERSION_V4)
+ {
+ _nx_ip_header_add(ip_ptr, packet_ptr,
+ ip_src_address -> nxd_ip_address.v4,
+ ip_dst_address -> nxd_ip_address.v4,
+ socket_ptr -> nx_udp_socket_type_of_service,
+ socket_ptr -> nx_udp_socket_time_to_live,
+ NX_IP_UDP, socket_ptr -> nx_udp_socket_fragment_enable);
+ }
+#endif /* !NX_DISABLE_IPV4 */
+
+#ifdef FEATURE_NX_IPV6
+ if (ip_dst_address -> nxd_ip_version == NX_IP_VERSION_V6)
+ {
+ if (_nx_ipv6_header_add(ip_ptr, &packet_ptr, NX_PROTOCOL_UDP,
+ packet_ptr -> nx_packet_length,
+ ip_ptr -> nx_ipv6_hop_limit,
+ ip_src_address -> nxd_ip_address.v6,
+ ip_dst_address -> nxd_ip_address.v6, NX_NULL))
+ {
+
+ /* Packet consumed by IPv6 layer. Just return success. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+ return(NX_SUCCESS);
+ }
+
+ /* Reset IP header. */
+ packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER);
+ packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - sizeof(NX_IPV6_HEADER);
+ }
+#endif /* FEATURE_NX_IPV6 */
+
+ if (ip_ptr -> nx_ip_packet_filter)
+ {
+ if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+ NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Packet consumed by IP filter. Just return success. */
+ _nx_packet_transmit_release(packet_ptr);
+ return(NX_SUCCESS);
+ }
+ }
+
+ /* Check if the IP packet filter extended is set. */
+ if (ip_ptr -> nx_ip_packet_filter_extended)
+ {
+
+ /* Yes, call the IP packet filter extended routine. */
+ if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+ {
+
+ /* Packet consumed by IP filter. Just return success. */
+ _nx_packet_transmit_release(packet_ptr);
+ return(NX_SUCCESS);
+ }
+ }
+ }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+ /* Reset UDP and IP header. */
+ packet_ptr -> nx_packet_prepend_ptr = original_ptr;
+ packet_ptr -> nx_packet_length = original_length;
+
+ /* Let TCP/IP offload interface send the packet. */
+ status = interface_ptr -> nx_interface_tcpip_offload_handler(ip_ptr, interface_ptr, socket_ptr,
+ NX_TCPIP_OFFLOAD_UDP_SOCKET_SEND,
+ packet_ptr, ip_src_address, ip_dst_address,
+ socket_ptr -> nx_udp_socket_port,
+ &port, NX_NO_WAIT);
+
+ /* Release the IP protection. */
+ tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+ if (status)
+ {
+ return(NX_TCPIP_OFFLOAD_ERROR);
+ }
+ else
+ {
+ return(NX_SUCCESS);
+ }
+}
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _nxd_udp_socket_send PORTABLE C */
-/* 6.1 */
+/* 6.1.8 */
/* AUTHOR */
/* */
/* Yuxin Zhou, Microsoft Corporation */
@@ -87,6 +253,9 @@
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
/* resulting in version 6.1 */
+/* 08-02-2021 Yuxin Zhou Modified comment(s), and */
+/* supported TCP/IP offload, */
+/* resulting in version 6.1.8 */
/* */
/**************************************************************************/
UINT _nxd_udp_socket_send(NX_UDP_SOCKET *socket_ptr,
@@ -109,6 +278,10 @@ NX_INTERFACE *interface_ptr = NX_NULL;
UINT status;
#endif /* FEATURE_NX_IPV6 */
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+NXD_ADDRESS ip_src_address;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
#ifdef NX_IPSEC_ENABLE
VOID *sa = NX_NULL;
ULONG data_offset;
@@ -199,6 +372,11 @@ UINT compute_checksum = 1;
/* Fill in the IP src/dest address */
ip_dest_addr = &ip_address -> nxd_ip_address.v4;
ip_src_addr = &interface_ptr -> nx_interface_ip_address;
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ ip_src_address.nxd_ip_version = NX_IP_VERSION_V4;
+ ip_src_address.nxd_ip_address.v4 = interface_ptr -> nx_interface_ip_address;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
}
#endif /* NX_DISABLE_IPV4 */
@@ -229,6 +407,11 @@ UINT compute_checksum = 1;
/* Get the packet interface information. */
interface_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ ip_src_address.nxd_ip_version = NX_IP_VERSION_V6;
+ COPY_IPV6_ADDRESS(ip_src_addr, ip_src_address.nxd_ip_address.v6);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
}
#endif /* FEATURE_NX_IPV6 */
@@ -281,7 +464,7 @@ UINT compute_checksum = 1;
}
}
#endif /* NX_IPSEC_ENABLE */
-
+
/* Prepend the UDP header to the packet. First, make room for the UDP header. */
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_UDP_HEADER);
@@ -320,16 +503,16 @@ UINT compute_checksum = 1;
NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_UDP_SEND, ip_ptr, socket_ptr, packet_ptr, udp_header_ptr -> nx_udp_header_word_0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
/* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will
- swap the endian of the UDP header. */
+ swap the endian of the UDP header. */
NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1);
/* Determine if we need to compute the UDP checksum.
- Note that with IPv6, UDP packet checksum is mandatory. However if the underly device
- driver is able to compute UDP checksum in hardware, let the driver handle the checksum
- computation.
- */
+ Note that with IPv6, UDP packet checksum is mandatory. However if the underly device
+ driver is able to compute UDP checksum in hardware, let the driver handle the checksum
+ computation.
+ */
if ((!socket_ptr -> nx_udp_socket_disable_checksum) ||
(ip_address -> nxd_ip_version == NX_IP_VERSION_V6))
@@ -343,8 +526,8 @@ UINT compute_checksum = 1;
#ifdef NX_IPSEC_ENABLE
/* In case this packet is going through the IPsec protected channel, the checksum would have to be computed
- in software even if the hardware checksum is available at driver layer. The checksum value must be present
- in order when applying IPsec process. */
+ in software even if the hardware checksum is available at driver layer. The checksum value must be present
+ in order when applying IPsec process. */
if ((packet_ptr -> nx_packet_ipsec_sa_ptr != NX_NULL) && (((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_encryption_method != NX_CRYPTO_NONE))
{
@@ -392,6 +575,14 @@ UINT compute_checksum = 1;
/* Get mutex protection. */
tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+ if ((interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD) &&
+ (interface_ptr -> nx_interface_tcpip_offload_handler))
+ {
+ return(_nx_udp_socket_driver_send(socket_ptr, packet_ptr, &ip_src_address, ip_address, port));
+ }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
#ifndef NX_DISABLE_IPV4
/* Send the UDP packet to the IPv4 component. */
if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)