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_ip.h"
29 #include "nx_packet.h"
30 #include "nx_tcp.h"
31 #include "tx_thread.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_tcp_packet_receive PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function receives a TCP packet from the IP receive */
47 /* processing. If this routine is called from an ISR, it simply */
48 /* places the new message on the TCP message queue, and wakes up the */
49 /* IP processing thread. If this routine is called from the IP helper */
50 /* thread, then the TCP message is processed directly. */
51 /* */
52 /* INPUT */
53 /* */
54 /* ip_ptr Pointer to IP control block */
55 /* packet_ptr Pointer to packet to send */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* None */
60 /* */
61 /* CALLS */
62 /* */
63 /* _nx_tcp_packet_process Process TCP packet */
64 /* tx_event_flags_set Set event flags for IP helper */
65 /* thread */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* _nx_ip_packet_receive Dispatch received IP packets */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
76 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
77 /* resulting in version 6.1 */
78 /* */
79 /**************************************************************************/
_nx_tcp_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)80 VOID _nx_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
81 {
82
83 TX_INTERRUPT_SAVE_AREA
84
85
86 /* Add debug information. */
87 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
88
89 #ifndef NX_DISABLE_RX_SIZE_CHECKING
90
91 /* Check for valid packet length. */
92 if (packet_ptr -> nx_packet_length < sizeof(NX_TCP_HEADER))
93 {
94
95 #ifndef NX_DISABLE_TCP_INFO
96 /* Increment the TCP invalid packet error. */
97 ip_ptr -> nx_ip_tcp_invalid_packets++;
98 #endif
99
100 /* Invalid packet length, just release it. */
101 _nx_packet_release(packet_ptr);
102
103 /* The function is complete, just return! */
104 return;
105 }
106 #endif
107
108 /* Determine if this routine is being called from an ISR. */
109 if ((TX_THREAD_GET_SYSTEM_STATE()) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr))
110 {
111
112 /* If system state is non-zero, we are in an ISR. If the current thread is not the IP thread,
113 we need to prevent unnecessary recursion in loopback. Just place the message at the
114 end of the TCP message queue and wakeup the IP helper thread. */
115
116 /* Disable interrupts. */
117 TX_DISABLE
118
119 /* Add the packet to the TCP message queue. */
120 if (ip_ptr -> nx_ip_tcp_queue_head)
121 {
122
123 /* Link the current packet at the end of the queue. */
124 (ip_ptr -> nx_ip_tcp_queue_tail) -> nx_packet_queue_next = packet_ptr;
125 ip_ptr -> nx_ip_tcp_queue_tail = packet_ptr;
126 packet_ptr -> nx_packet_queue_next = NX_NULL;
127
128 /* Increment the count of incoming TCP packets queued. */
129 ip_ptr -> nx_ip_tcp_received_packet_count++;
130 }
131 else
132 {
133
134 /* Empty queue, add to the head of the TCP message queue. */
135 ip_ptr -> nx_ip_tcp_queue_head = packet_ptr;
136 ip_ptr -> nx_ip_tcp_queue_tail = packet_ptr;
137 packet_ptr -> nx_packet_queue_next = NX_NULL;
138
139 /* Set the initial count TCP packets queued. */
140 ip_ptr -> nx_ip_tcp_received_packet_count = 1;
141 }
142
143 /* Restore interrupts. */
144 TX_RESTORE
145
146 /* Wakeup IP thread for processing one or more messages in the TCP queue. */
147 tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_TCP_EVENT, TX_OR);
148 }
149 else
150 {
151
152 /* The IP message was deferred, so this routine is called from the IP helper
153 thread and thus may call the TCP processing directly. */
154 _nx_tcp_packet_process(ip_ptr, packet_ptr);
155 }
156 }
157
158