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_tcp.h"
31
32
33 /* Bring in externs for caller checking code. */
34
35 NX_CALLER_CHECKING_EXTERNS
36
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _nxe_tcp_socket_create PORTABLE C */
43 /* 6.1 */
44 /* AUTHOR */
45 /* */
46 /* Yuxin Zhou, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function checks for errors in the TCP socket create */
51 /* function call. */
52 /* */
53 /* INPUT */
54 /* */
55 /* ip_ptr IP instance pointer */
56 /* socket_ptr Pointer to new TCP socket */
57 /* name Name of new TCP socket */
58 /* type_of_service Type of service for this TCP */
59 /* socket */
60 /* fragment Flag to enable IP fragmenting */
61 /* time_to_live Time to live value for socket */
62 /* window_size Size of socket's receive */
63 /* window */
64 /* tcp_urgent_data_callback Routine to call when urgent */
65 /* data is received */
66 /* tcp_disconnect_callback Routine to call when a */
67 /* disconnect occurs */
68 /* tcp_socket_size Size of TCP socket */
69 /* */
70 /* OUTPUT */
71 /* */
72 /* status Completion status */
73 /* */
74 /* CALLS */
75 /* */
76 /* _nx_tcp_socket_create Actual TCP socket create */
77 /* function */
78 /* tx_mutex_get Get protection mutex */
79 /* tx_mutex_put Put protection mutex */
80 /* */
81 /* CALLED BY */
82 /* */
83 /* Application Code */
84 /* */
85 /* RELEASE HISTORY */
86 /* */
87 /* DATE NAME DESCRIPTION */
88 /* */
89 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
90 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
91 /* resulting in version 6.1 */
92 /* */
93 /**************************************************************************/
_nxe_tcp_socket_create(NX_IP * ip_ptr,NX_TCP_SOCKET * socket_ptr,CHAR * name,ULONG type_of_service,ULONG fragment,UINT time_to_live,ULONG window_size,VOID (* tcp_urgent_data_callback)(NX_TCP_SOCKET * socket_ptr),VOID (* tcp_disconnect_callback)(NX_TCP_SOCKET * socket_ptr),UINT tcp_socket_size)94 UINT _nxe_tcp_socket_create(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, CHAR *name,
95 ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG window_size,
96 VOID (*tcp_urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
97 VOID (*tcp_disconnect_callback)(NX_TCP_SOCKET *socket_ptr),
98 UINT tcp_socket_size)
99 {
100
101 UINT status;
102 NX_TCP_SOCKET *created_socket;
103 ULONG created_count;
104
105
106 /* Check for invalid input pointers. */
107 if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) || (socket_ptr == NX_NULL) ||
108 (tcp_socket_size != (UINT)sizeof(NX_TCP_SOCKET)))
109 {
110 return(NX_PTR_ERROR);
111 }
112
113 /* Check for appropriate caller. */
114 NX_INIT_AND_THREADS_CALLER_CHECKING
115
116 /* Get protection mutex. */
117 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
118
119 /* Pickup created count and created socket pointer. */
120 created_count = ip_ptr -> nx_ip_tcp_created_sockets_count;
121 created_socket = ip_ptr -> nx_ip_tcp_created_sockets_ptr;
122
123 /* Loop to look for socket already created. */
124 while (created_count--)
125 {
126
127 /* Compare the new socket with the already created socket. */
128 if (socket_ptr == created_socket)
129 {
130
131 /* Error, socket already created! */
132
133 /* Release protection mutex. */
134 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
135
136 /* Return error. */
137 return(NX_PTR_ERROR);
138 }
139
140 /* Move to next created socket. */
141 created_socket = created_socket -> nx_tcp_socket_created_next;
142 }
143
144 /* Release protection mutex. */
145 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
146
147 /* Check to see if TCP is enabled. */
148 if (!ip_ptr -> nx_ip_tcp_packet_receive)
149 {
150 return(NX_NOT_ENABLED);
151 }
152
153 /* Check for valid type of service. */
154 if (type_of_service & ~(NX_IP_TOS_MASK))
155 {
156 return(NX_OPTION_ERROR);
157 }
158
159 /* Check for valid fragment option. */
160 if ((fragment != NX_FRAGMENT_OKAY) &&
161 (fragment != NX_DONT_FRAGMENT))
162 {
163 return(NX_OPTION_ERROR);
164 }
165
166 /* Check for valid time to live option. */
167 if (((ULONG)time_to_live) > NX_IP_TIME_TO_LIVE_MASK)
168 {
169 return(NX_OPTION_ERROR);
170 }
171
172 /* Check for valid window size. */
173 if (!window_size)
174 {
175 return(NX_OPTION_ERROR);
176 }
177
178 #ifndef NX_ENABLE_TCP_WINDOW_SCALING
179 if (window_size > NX_LOWER_16_MASK)
180 {
181 return(NX_OPTION_ERROR);
182 }
183 #else
184 /* The maximum scale exponent is limited to 14. Section 2.2, RFC 7323. */
185 if (window_size > ((1 << 30) - 1))
186 {
187 return(NX_OPTION_ERROR);
188 }
189 #endif /* NX_ENABLE_TCP_WINDOW_SCALING */
190
191 /* Call actual TCP socket create function. */
192 status = _nx_tcp_socket_create(ip_ptr, socket_ptr, name, type_of_service, fragment, time_to_live,
193 window_size, tcp_urgent_data_callback, tcp_disconnect_callback);
194
195 /* Return completion status. */
196 return(status);
197 }
198
199