1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Transmission Control Protocol (TCP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_tcp.h"
29 #include "nx_packet.h"
30 #include "tx_thread.h"
31 #include "nx_ip.h"
32 #ifdef FEATURE_NX_IPV6
33 #include "nx_ipv6.h"
34 #endif /* FEATURE_NX_IPV6 */
35
36 #ifdef NX_ENABLE_TCPIP_OFFLOAD
37 /**************************************************************************/
38 /* */
39 /* FUNCTION RELEASE */
40 /* */
41 /* _nx_tcp_socket_driver_packet_receive PORTABLE C */
42 /* 6.1.8 */
43 /* AUTHOR */
44 /* */
45 /* Yuxin Zhou, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* This function receives a TCP packet from the TCP/IP driver and add */
50 /* fake TCP/IP header. Then pass the packet to IP deferred receive */
51 /* routine. */
52 /* */
53 /* INPUT */
54 /* */
55 /* socket_ptr Pointer to owning socket */
56 /* packet_ptr Pointer to packet to process */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* None */
61 /* */
62 /* CALLS */
63 /* */
64 /* tx_mutex_get Obtain protection mutex */
65 /* tx_mutex_put Release protection mutex */
66 /* _nx_ip_packet_deferred_receive Defer IP packet receive */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* Driver */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 08-02-2021 Yuxin Zhou Initial Version 6.1.8 */
77 /* */
78 /**************************************************************************/
_nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET * socket_ptr,NX_PACKET * packet_ptr)79 VOID _nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr)
80 {
81 NX_IP *ip_ptr;
82 NX_TCP_HEADER *header_ptr;
83
84 /* Setup the IP pointer. */
85 ip_ptr = socket_ptr -> nx_tcp_socket_ip_ptr;
86
87 /* Obtain the IP internal mutex before processing the IP event. */
88 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
89
90 if (packet_ptr == NX_NULL)
91 {
92
93 /* Connection closed. */
94 if (socket_ptr -> nx_tcp_socket_state == NX_TCP_ESTABLISHED)
95 {
96 socket_ptr -> nx_tcp_socket_state = NX_TCP_CLOSE_WAIT;
97
98 /* Loop to release all threads suspended while trying to receive on the socket. */
99 while (socket_ptr -> nx_tcp_socket_receive_suspension_list)
100 {
101
102 /* Release the head of the receive suspension list. */
103 _nx_tcp_receive_cleanup(socket_ptr -> nx_tcp_socket_receive_suspension_list NX_CLEANUP_ARGUMENT);
104 }
105
106 /* If given, call the application's disconnect callback function
107 for disconnect. */
108 if (socket_ptr -> nx_tcp_disconnect_callback)
109 {
110
111 /* Call the application's disconnect handling function. It is
112 responsible for calling the socket disconnect function. */
113 (socket_ptr -> nx_tcp_disconnect_callback)(socket_ptr);
114 }
115 }
116
117 /* Release the IP internal mutex. */
118 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
119 return;
120 }
121
122 /* Fake TCP and IP header. */
123 /* Prepend the TCP header to the packet. First, make room for the TCP header. */
124 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_TCP_HEADER);
125
126 /* Add the length of the TCP header. */
127 packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_TCP_HEADER);
128
129 /* Pickup the pointer to the head of the TCP packet. */
130 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
131 header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
132
133 /* Build the output request in the TCP header. */
134 header_ptr -> nx_tcp_header_word_0 = (((ULONG)(socket_ptr -> nx_tcp_socket_connect_port)) << NX_SHIFT_BY_16) |
135 (ULONG)socket_ptr -> nx_tcp_socket_port;
136 NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_0);
137 header_ptr -> nx_tcp_acknowledgment_number = 0;
138 header_ptr -> nx_tcp_sequence_number = 0;
139 header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_ACK_BIT | NX_TCP_PSH_BIT;
140 NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3);
141 header_ptr -> nx_tcp_header_word_4 = 0;
142
143 #ifndef NX_DISABLE_IPV4
144 if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V4)
145 {
146 _nx_ip_header_add(ip_ptr, packet_ptr, socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4,
147 packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address,
148 socket_ptr -> nx_tcp_socket_type_of_service,
149 socket_ptr -> nx_tcp_socket_time_to_live,
150 NX_IP_TCP,
151 socket_ptr -> nx_tcp_socket_fragment_enable);
152 }
153 #endif /* !NX_DISABLE_IPV4 */
154
155 #ifdef FEATURE_NX_IPV6
156 if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
157 {
158 if (_nx_ipv6_header_add(ip_ptr, &packet_ptr,
159 NX_PROTOCOL_TCP,
160 packet_ptr -> nx_packet_length,
161 ip_ptr -> nx_ipv6_hop_limit,
162 socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6,
163 socket_ptr -> nx_tcp_socket_ipv6_addr -> nxd_ipv6_address,
164 NX_NULL))
165 {
166
167 /* Release the IP internal mutex. */
168 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
169 return;
170 }
171 }
172 #endif /* FEATURE_NX_IPV6 */
173
174 /* Release the IP internal mutex. */
175 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
176
177 _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr);
178 }
179 #endif /* NX_ENABLE_TCPIP_OFFLOAD */
180
181