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