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