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 /** User Datagram Protocol (UDP) */
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_udp.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _nx_udp_socket_create PORTABLE C */
36 /* 6.4.0 */
37 /* AUTHOR */
38 /* */
39 /* Yuxin Zhou, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function creates a UDP socket for the specified IP instance. */
44 /* */
45 /* INPUT */
46 /* */
47 /* ip_ptr IP instance pointer */
48 /* socket_ptr Pointer to new UDP socket */
49 /* name Name of new UDP socket */
50 /* type_of_service Type of service for this UDP */
51 /* socket */
52 /* fragment Flag to enable IP fragmenting */
53 /* time_to_live Time to live value for socket */
54 /* queue_maximum Maximum depth of receive queue*/
55 /* */
56 /* OUTPUT */
57 /* */
58 /* status Completion status */
59 /* */
60 /* CALLS */
61 /* */
62 /* tx_mutex_get Obtain protection mutex */
63 /* tx_mutex_put Release protection mutex */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Application Code */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
74 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* 12-31-2023 Yajun Xia Modified comment(s), */
77 /* supported VLAN, */
78 /* resulting in version 6.4.0 */
79 /* */
80 /**************************************************************************/
_nx_udp_socket_create(NX_IP * ip_ptr,NX_UDP_SOCKET * socket_ptr,CHAR * name,ULONG type_of_service,ULONG fragment,UINT time_to_live,ULONG queue_maximum)81 UINT _nx_udp_socket_create(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name,
82 ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG queue_maximum)
83 {
84 TX_INTERRUPT_SAVE_AREA
85
86 NX_UDP_SOCKET *tail_ptr;
87
88
89 /* Initialize the TCP control block to zero. */
90 memset((void *)socket_ptr, 0, sizeof(NX_UDP_SOCKET));
91
92 /* Fill in the basic information in the new UDP socket structure. */
93
94 /* Remember the associated IP structure. */
95 socket_ptr -> nx_udp_socket_ip_ptr = ip_ptr;
96
97 /* Save the UDP socket's name. */
98 socket_ptr -> nx_udp_socket_name = name;
99
100 /* Save the type of service input parameter. */
101 socket_ptr -> nx_udp_socket_type_of_service = type_of_service;
102
103 /* Save the fragment input parameter. */
104 socket_ptr -> nx_udp_socket_fragment_enable = fragment & NX_DONT_FRAGMENT;
105
106 /* Save the time-to-live input parameter. */
107 socket_ptr -> nx_udp_socket_time_to_live = time_to_live;
108
109 /* By default, have UDP checksum logic enabled. To disable checksum logic, the
110 application must call the nx_udp_checksum disable function for this UDP socket. */
111 socket_ptr -> nx_udp_socket_disable_checksum = NX_FALSE;
112
113 /* Clear the socket bind in progress flag. */
114 socket_ptr -> nx_udp_socket_bind_in_progress = NX_FALSE;
115
116 /* Set various list pointers to NULL. */
117 socket_ptr -> nx_udp_socket_bound_next = NX_NULL;
118 socket_ptr -> nx_udp_socket_bound_previous = NX_NULL;
119 socket_ptr -> nx_udp_socket_bind_suspension_list = NX_NULL;
120 socket_ptr -> nx_udp_socket_bind_suspended_count = 0;
121
122 /* Initialize the receive queue parameters. */
123 socket_ptr -> nx_udp_socket_receive_count = 0;
124 socket_ptr -> nx_udp_socket_queue_maximum = queue_maximum;
125 socket_ptr -> nx_udp_socket_receive_head = NX_NULL;
126 socket_ptr -> nx_udp_socket_receive_tail = NX_NULL;
127
128 /* Clear the receive notify function pointer. */
129 socket_ptr -> nx_udp_receive_callback = NX_NULL;
130
131 #ifdef NX_ENABLE_VLAN
132 /* Initialize the udp socket vlan priority. */
133 socket_ptr -> nx_udp_socket_vlan_priority = NX_VLAN_PRIORITY_INVALID;
134 #endif /* NX_ENABLE_VLAN */
135
136 /* If trace is enabled, register this object. */
137 NX_TRACE_OBJECT_REGISTER(NX_TRACE_OBJECT_TYPE_UDP_SOCKET, socket_ptr, name, type_of_service, queue_maximum);
138
139 /* If trace is enabled, insert this event into the trace buffer. */
140 NX_TRACE_IN_LINE_INSERT(NX_TRACE_UDP_SOCKET_CREATE, ip_ptr, socket_ptr, type_of_service, queue_maximum, NX_TRACE_IP_EVENTS, 0, 0);
141
142 /* Obtain the IP mutex so we can add socket to IP structure. */
143 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
144
145 /* Disable interrupts while we link the new UDP socket to the IP structure. */
146 TX_DISABLE
147
148 /* Load the UDP ID field in the UDP control block. */
149 socket_ptr -> nx_udp_socket_id = NX_UDP_ID;
150
151 /* Place the new UDP control block on the list of created UDP sockets for this IP. First,
152 check for an empty list. */
153 if (ip_ptr -> nx_ip_udp_created_sockets_ptr)
154 {
155
156 /* Pickup tail pointer. */
157 tail_ptr = (ip_ptr -> nx_ip_udp_created_sockets_ptr) -> nx_udp_socket_created_previous;
158
159 /* Place the new UDP socket control block in the list. */
160 (ip_ptr -> nx_ip_udp_created_sockets_ptr) -> nx_udp_socket_created_previous = socket_ptr;
161 tail_ptr -> nx_udp_socket_created_next = socket_ptr;
162
163 /* Setup this UDP socket's created links. */
164 socket_ptr -> nx_udp_socket_created_previous = tail_ptr;
165 socket_ptr -> nx_udp_socket_created_next = ip_ptr -> nx_ip_udp_created_sockets_ptr;
166 }
167 else
168 {
169
170 /* The created UDP socket list is empty. Add UDP socket control block to empty list. */
171 ip_ptr -> nx_ip_udp_created_sockets_ptr = socket_ptr;
172 socket_ptr -> nx_udp_socket_created_previous = socket_ptr;
173 socket_ptr -> nx_udp_socket_created_next = socket_ptr;
174 }
175
176 /* Increment the created UDP socket counter. */
177 ip_ptr -> nx_ip_udp_created_sockets_count++;
178
179 /* Restore previous interrupt posture. */
180 TX_RESTORE
181
182 /* Release the IP protection mutex. */
183 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
184
185 /* Return successful completion. */
186 return(NX_SUCCESS);
187 }
188
189