socket_misc.c
Go to the documentation of this file.
1 /**
2  * @file socket_misc.c
3  * @brief Helper functions for sockets
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2022 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.2.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SOCKET_TRACE_LEVEL
33 
34 //Dependencies
35 #include <string.h>
36 #include "core/net.h"
37 #include "core/socket.h"
38 #include "core/socket_misc.h"
39 #include "core/raw_socket.h"
40 #include "core/udp.h"
41 #include "core/tcp.h"
42 #include "core/tcp_misc.h"
43 #include "debug.h"
44 
45 
46 /**
47  * @brief Allocate a socket
48  * @param[in] type Type specification for the new socket
49  * @param[in] protocol Protocol to be used
50  * @return Handle referencing the new socket
51  **/
52 
54 {
55  error_t error;
56  uint_t i;
57  uint16_t port;
58  Socket *socket;
59  OsEvent event;
60 
61  //Initialize socket handle
62  socket = NULL;
63 
64 #if (TCP_SUPPORT == ENABLED)
65  //Connection-oriented socket?
67  {
68  //Always use TCP as underlying transport protocol
70  //Get an ephemeral port number
72  //Continue processing
73  error = NO_ERROR;
74  }
75  else
76 #endif
77 #if (UDP_SUPPORT == ENABLED)
78  //Connectionless socket?
79  if(type == SOCKET_TYPE_DGRAM)
80  {
81  //Always use UDP as underlying transport protocol
83  //Get an ephemeral port number
85  //Continue processing
86  error = NO_ERROR;
87  }
88  else
89 #endif
90 #if (RAW_SOCKET_SUPPORT == ENABLED)
91  //Raw socket?
93  {
94  //Port numbers are not relevant for raw sockets
95  port = 0;
96  //Continue processing
97  error = NO_ERROR;
98  }
99  else
100 #endif
101  {
102  //The socket type is not supported
103  error = ERROR_INVALID_PARAMETER;
104  }
105 
106  //Check status code
107  if(!error)
108  {
109  //Loop through socket descriptors
110  for(i = 0; i < SOCKET_MAX_COUNT; i++)
111  {
112  //Unused socket found?
114  {
115  //Save socket handle
116  socket = &socketTable[i];
117  //We are done
118  break;
119  }
120  }
121 
122 #if (TCP_SUPPORT == ENABLED)
123  //No more sockets available?
124  if(socket == NULL)
125  {
126  //Kill the oldest connection in the TIME-WAIT state whenever the
127  //socket table runs out of space
129  }
130 #endif
131 
132  //Check whether the current entry is free
133  if(socket != NULL)
134  {
135  //Save socket descriptor
136  i = socket->descriptor;
137 
138  //Save event object instance
139  osMemcpy(&event, &socket->event, sizeof(OsEvent));
140  //Clear associated structure
141  osMemset(socket, 0, sizeof(Socket));
142  //Reuse event objects and avoid recreating them whenever possible
143  osMemcpy(&socket->event, &event, sizeof(OsEvent));
144 
145  //Save socket characteristics
146  socket->descriptor = i;
147  socket->type = type;
148  socket->protocol = protocol;
149  socket->localPort = port;
150  socket->timeout = INFINITE_DELAY;
151 
152 #if (ETH_VLAN_SUPPORT == ENABLED)
153  //Default VLAN PCP and DEI fields
154  socket->vlanPcp = -1;
155  socket->vlanDei = -1;
156 #endif
157 
158 #if (ETH_VMAN_SUPPORT == ENABLED)
159  //Default VMAN PCP and DEI fields
160  socket->vmanPcp = -1;
161  socket->vmanDei = -1;
162 #endif
163 
164 #if (TCP_SUPPORT == ENABLED && TCP_KEEP_ALIVE_SUPPORT == ENABLED)
165  //TCP keep-alive mechanism must be disabled by default (refer to
166  //RFC 1122, section 4.2.3.6)
167  socket->keepAliveEnabled = FALSE;
168 
169  //Default TCP keep-alive parameters
170  socket->keepAliveIdle = TCP_DEFAULT_KEEP_ALIVE_IDLE;
171  socket->keepAliveInterval = TCP_DEFAULT_KEEP_ALIVE_INTERVAL;
172  socket->keepAliveMaxProbes = TCP_DEFAULT_KEEP_ALIVE_PROBES;
173 #endif
174 
175 #if (TCP_SUPPORT == ENABLED)
176  //Default TX and RX buffer size
179 #endif
180  }
181  }
182 
183  //Return a handle to the freshly created socket
184  return socket;
185 }
186 
187 
188 /**
189  * @brief Subscribe to the specified socket events
190  * @param[in] socket Handle that identifies a socket
191  * @param[in] event Event object used to receive notifications
192  * @param[in] eventMask Logic OR of the requested socket events
193  **/
194 
196 {
197  //Valid socket handle?
198  if(socket != NULL)
199  {
200  //Get exclusive access
202 
203  //An user event may have been previously registered...
204  if(socket->userEvent != NULL)
205  {
206  socket->eventMask |= eventMask;
207  }
208  else
209  {
210  socket->eventMask = eventMask;
211  }
212 
213  //Suscribe to get notified of events
214  socket->userEvent = event;
215 
216 #if (TCP_SUPPORT == ENABLED)
217  //Handle TCP specific events
218  if(socket->type == SOCKET_TYPE_STREAM)
219  {
221  }
222 #endif
223 #if (UDP_SUPPORT == ENABLED)
224  //Handle UDP specific events
225  if(socket->type == SOCKET_TYPE_DGRAM)
226  {
228  }
229 #endif
230 #if (RAW_SOCKET_SUPPORT == ENABLED)
231  //Handle events that are specific to raw sockets
232  if(socket->type == SOCKET_TYPE_RAW_IP ||
233  socket->type == SOCKET_TYPE_RAW_ETH)
234  {
236  }
237 #endif
238 
239  //Release exclusive access
241  }
242 }
243 
244 
245 /**
246  * @brief Unsubscribe previously registered events
247  * @param[in] socket Handle that identifies a socket
248  **/
249 
251 {
252  //Valid socket handle?
253  if(socket != NULL)
254  {
255  //Get exclusive access
257 
258  //Unsuscribe socket events
259  socket->userEvent = NULL;
260 
261  //Release exclusive access
263  }
264 }
265 
266 
267 /**
268  * @brief Retrieve event flags for a specified socket
269  * @param[in] socket Handle that identifies a socket
270  * @return Logic OR of events in the signaled state
271  **/
272 
274 {
275  uint_t eventFlags;
276 
277  //Valid socket handle?
278  if(socket != NULL)
279  {
280  //Get exclusive access
282 
283  //Read event flags for the specified socket
284  eventFlags = socket->eventFlags;
285 
286  //Release exclusive access
288  }
289  else
290  {
291  //The socket handle is not valid
292  eventFlags = 0;
293  }
294 
295  //Return the events in the signaled state
296  return eventFlags;
297 }
@ SOCKET_IP_PROTO_UDP
Definition: socket.h:94
#define netMutex
Definition: net_legacy.h:266
void udpUpdateEvents(Socket *socket)
Update UDP related events.
Definition: udp.c:831
Event object.
@ SOCKET_TYPE_DGRAM
Definition: socket.h:79
@ SOCKET_TYPE_STREAM
Definition: socket.h:78
#define TCP_DEFAULT_KEEP_ALIVE_INTERVAL
Definition: tcp.h:222
#define TCP_DEFAULT_TX_BUFFER_SIZE
Definition: tcp.h:68
#define FALSE
Definition: os_port.h:46
Helper functions for TCP.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:137
char_t type
error_t
Error codes.
Definition: error.h:43
Socket * tcpKillOldestConnection(void)
Kill the oldest socket in the TIME-WAIT state.
Definition: tcp.c:991
#define TCP_MAX_RX_BUFFER_SIZE
Definition: tcp.h:89
uint8_t protocol
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:63
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:80
void tcpUpdateEvents(Socket *socket)
Update TCP related events.
Definition: tcp_misc.c:2009
#define MIN(a, b)
Definition: os_port.h:62
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:50
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:925
#define TCP_MAX_TX_BUFFER_SIZE
Definition: tcp.h:75
uint16_t udpGetDynamicPort(void)
Get an ephemeral port number.
Definition: udp.c:81
TCP/IP raw sockets.
uint16_t port
Definition: dns_common.h:251
#define TCP_DEFAULT_KEEP_ALIVE_PROBES
Definition: tcp.h:229
Socket * socketAllocate(uint_t type, uint_t protocol)
Allocate a socket.
Definition: socket_misc.c:53
void socketRegisterEvents(Socket *socket, OsEvent *event, uint_t eventMask)
Subscribe to the specified socket events.
Definition: socket_misc.c:195
uint16_t tcpGetDynamicPort(void)
Get an ephemeral port number.
Definition: tcp.c:76
Helper functions for sockets.
TCP (Transmission Control Protocol)
@ SOCKET_TYPE_UNUSED
Definition: socket.h:77
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
UDP (User Datagram Protocol)
#define Socket
Definition: socket.h:36
Socket API.
@ SOCKET_TYPE_RAW_ETH
Definition: socket.h:81
#define TCP_DEFAULT_KEEP_ALIVE_IDLE
Definition: tcp.h:215
#define TCP_DEFAULT_RX_BUFFER_SIZE
Definition: tcp.h:82
unsigned int uint_t
Definition: compiler_port.h:45
void socketUnregisterEvents(Socket *socket)
Unsubscribe previously registered events.
Definition: socket_misc.c:250
#define osMemset(p, value, length)
Definition: os_port.h:131
TCP/IP stack core.
#define SOCKET_MAX_COUNT
Definition: socket.h:46
@ SOCKET_IP_PROTO_TCP
Definition: socket.h:93
uint_t socketGetEvents(Socket *socket)
Retrieve event flags for a specified socket.
Definition: socket_misc.c:273
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define INFINITE_DELAY
Definition: os_port.h:74