Skip to content

Commit a8d8b2a

Browse files
committed
doc: net: Add socket service API usage documentation
Add information how to use socket service API from application point of view. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 2e23dfd commit a8d8b2a

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

doc/connectivity/networking/api/apis.rst

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Network APIs
77
:maxdepth: 1
88

99
sockets.rst
10+
socket_service.rst
1011
ip_4_6.rst
1112
dns_resolve.rst
1213
net_mgmt.rst
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
.. _socket_service_interface:
2+
3+
Socket Service
4+
##############
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
Overview
11+
********
12+
13+
The socket service API can be used to install a handler that is called if there
14+
is data received to a socket. The API helps to avoid creating a dedicated thread
15+
for each TCP or UDP services that the application provides. Instead one thread
16+
is created which can serve data to multiple listening sockets which saves memory
17+
as only one thread needs to be created in the system in this case.
18+
19+
See :zephyr:code-sample:`sockets-service-echo` sample application to learn how
20+
to create a simple BSD socket based server application using the sockets service API.
21+
The source code for this sample application can be found at:
22+
:zephyr_file:`samples/net/sockets/echo_service`.
23+
24+
API Description
25+
***************
26+
27+
Socket service API is enabled using :kconfig:option:`CONFIG_NET_SOCKETS_SERVICE`
28+
config option and implements the following operations:
29+
30+
* :c:macro:`NET_SOCKET_SERVICE_SYNC_DEFINE`
31+
32+
Define a network socket service. This socket service is created with extern
33+
scope so it can be used from multiple C source files.
34+
35+
* :c:macro:`NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC`
36+
37+
Define a network socket service with static scope. This socket service can only
38+
be used within one C source file.
39+
40+
* :c:func:`net_socket_service_register`
41+
42+
Register pollable sockets for this service. User must create the sockets
43+
before this call.
44+
45+
* :c:func:`net_socket_service_unregister`
46+
47+
Remove pollable sockets for this service. User can close the sockets after
48+
this call.
49+
50+
* :c:type:`net_socket_service_handler_t`
51+
52+
User specified callback which is called when data is received to the
53+
listening socket.
54+
55+
Application Overview
56+
********************
57+
58+
When socket service API is enabled, the application must create the service like
59+
this:
60+
61+
.. code-block:: c
62+
63+
#define MAX_BUF_LEN 1500
64+
#define MAX_SERVICES 1
65+
66+
static void udp_service_handler(struct net_socket_service_event *pev)
67+
{
68+
struct pollfd *pfd = &pev->event;
69+
int client = pfd->fd;
70+
struct sockaddr_in6 addr;
71+
socklen_t addrlen = sizeof(addr);
72+
73+
/* In this example we use one static buffer in order to avoid
74+
* having large stack.
75+
*/
76+
static char buf[MAX_BUF_LEN];
77+
78+
len = recvfrom(client, buf, sizeof(buf), 0,
79+
(struct sockaddr *)&addr, &addrlen);
80+
if (len <= 0) {
81+
/* Error */
82+
...
83+
return;
84+
}
85+
86+
/* Do something with the received data. The pev variable contains
87+
* user data that was saved in the socket service was registered.
88+
*/
89+
}
90+
91+
NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(udp_service, udp_service_handler, MAX_SERVICES);
92+
93+
The application needs to create the sockets, then register them to the socket
94+
service after which the socket service thread will start to call the callback
95+
for any incoming data.
96+
97+
.. code-block:: c
98+
99+
/* Create one or multiple sockets */
100+
101+
struct pollfd sockfd_udp[1] = { 0 };
102+
int sock, ret;
103+
104+
sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
105+
if (sock < 0) {
106+
LOG_ERR("socket: %d", -errno);
107+
return -errno;
108+
}
109+
110+
/* Set possible socket options after creation */
111+
...
112+
113+
/* Then bind the socket to local address */
114+
if (bind(sock, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
115+
LOG_ERR("bind: %d", -errno);
116+
return -errno;
117+
}
118+
119+
/* Set the polled sockets */
120+
sockfd_udp[0].fd = sock;
121+
sockfd_udp[0].events = POLLIN;
122+
123+
/* Register UDP socket to service handler */
124+
ret = net_socket_service_register(&service_udp, sockfd_udp,
125+
ARRAY_SIZE(sockfd_udp), NULL);
126+
if (ret < 0) {
127+
LOG_ERR("Cannot register socket service handler (%d)", ret);
128+
return ret;
129+
}
130+
131+
/* Application logic happens here. When application is ready to
132+
* quit, one should unregister the socket service and close the
133+
* socket.
134+
*/
135+
136+
(void)net_socket_service_unregister(&service_udp);
137+
close(sock);
138+
139+
API Reference
140+
*************
141+
142+
.. doxygengroup:: bsd_socket_service

0 commit comments

Comments
 (0)