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