Skip to content

Commit 880888f

Browse files
committed
zephyr/mdns_service: Add mdns broadcast service.
Signed-off-by: Jason Kridner <jkridner@beagleboard.org> Cc: Chris Friedt <cfriedt@meta.com>
1 parent 26bfc5e commit 880888f

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

ports/zephyr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ set(MICROPY_SOURCE_PORT
4141
machine_spi.c
4242
machine_pin.c
4343
machine_uart.c
44+
mdns_service.c
4445
modbluetooth_zephyr.c
4546
modmachine.c
4647
modusocket.c

ports/zephyr/mdns_service.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <errno.h>
8+
#include <zephyr/net/dns_sd.h>
9+
#include <zephyr/net/socket.h>
10+
#include <zephyr/posix/netinet/in.h>
11+
#include <stdint.h>
12+
#include <stdio.h>
13+
#include <string.h>
14+
#include <zephyr/kernel.h>
15+
16+
#include <zephyr/logging/log.h>
17+
LOG_MODULE_REGISTER(mdns_echo_service, LOG_LEVEL_DBG);
18+
19+
/* A default port of 0 causes bind(2) to request an ephemeral port */
20+
#define DEFAULT_PORT 12345
21+
22+
static int welcome(int fd) {
23+
static const char msg[] = "Bonjour world!\n";
24+
25+
return zsock_send(fd, msg, sizeof(msg), 0);
26+
}
27+
28+
/* This is mainly here to bind to a port to get service advertisement
29+
* to work.. but since we're already here we might as well do something
30+
* useful.
31+
*/
32+
void mdns_service(void) {
33+
int r;
34+
int server_fd;
35+
int client_fd;
36+
socklen_t len;
37+
void *addrp;
38+
uint16_t *portp;
39+
struct sockaddr client_addr;
40+
char addrstr[INET6_ADDRSTRLEN];
41+
uint8_t line[64];
42+
43+
static struct sockaddr server_addr;
44+
45+
#if DEFAULT_PORT == 0
46+
/* The advanced use case: ephemeral port */
47+
#if defined(CONFIG_NET_IPV6)
48+
DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME,
49+
"_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT,
50+
&((struct sockaddr_in6 *)&server_addr)->sin6_port);
51+
#elif defined(CONFIG_NET_IPV4)
52+
DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME,
53+
"_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT,
54+
&((struct sockaddr_in *)&server_addr)->sin_port);
55+
#endif
56+
#else
57+
/* The simple use case: fixed port */
58+
DNS_SD_REGISTER_TCP_SERVICE(zephyr, CONFIG_NET_HOSTNAME,
59+
"_zephyr", "local", DNS_SD_EMPTY_TXT, DEFAULT_PORT);
60+
#endif
61+
62+
if (IS_ENABLED(CONFIG_NET_IPV6)) {
63+
net_sin6(&server_addr)->sin6_family = AF_INET6;
64+
net_sin6(&server_addr)->sin6_addr = in6addr_any;
65+
net_sin6(&server_addr)->sin6_port = sys_cpu_to_be16(DEFAULT_PORT);
66+
} else if (IS_ENABLED(CONFIG_NET_IPV4)) {
67+
net_sin(&server_addr)->sin_family = AF_INET;
68+
net_sin(&server_addr)->sin_addr.s_addr = htonl(INADDR_ANY);
69+
net_sin(&server_addr)->sin_port = sys_cpu_to_be16(DEFAULT_PORT);
70+
} else {
71+
__ASSERT(false, "Neither IPv6 nor IPv4 are enabled");
72+
}
73+
74+
r = zsock_socket(server_addr.sa_family, SOCK_STREAM, 0);
75+
if (r == -1) {
76+
NET_DBG("socket() failed (%d)", errno);
77+
return;
78+
}
79+
80+
server_fd = r;
81+
NET_DBG("server_fd is %d", server_fd);
82+
83+
r = zsock_bind(server_fd, &server_addr, sizeof(server_addr));
84+
if (r == -1) {
85+
NET_DBG("bind() failed (%d)", errno);
86+
zsock_close(server_fd);
87+
return;
88+
}
89+
90+
if (server_addr.sa_family == AF_INET6) {
91+
addrp = &net_sin6(&server_addr)->sin6_addr;
92+
portp = &net_sin6(&server_addr)->sin6_port;
93+
} else {
94+
addrp = &net_sin(&server_addr)->sin_addr;
95+
portp = &net_sin(&server_addr)->sin_port;
96+
}
97+
98+
zsock_inet_ntop(server_addr.sa_family, addrp, addrstr, sizeof(addrstr));
99+
NET_DBG("bound to [%s]:%u",
100+
addrstr, ntohs(*portp));
101+
102+
r = zsock_listen(server_fd, 1);
103+
if (r == -1) {
104+
NET_DBG("listen() failed (%d)", errno);
105+
zsock_close(server_fd);
106+
return;
107+
}
108+
109+
for (;;) {
110+
len = sizeof(client_addr);
111+
r = zsock_accept(server_fd, (struct sockaddr *)&client_addr, &len);
112+
if (r == -1) {
113+
NET_DBG("accept() failed (%d)", errno);
114+
continue;
115+
}
116+
117+
client_fd = r;
118+
119+
zsock_inet_ntop(server_addr.sa_family, addrp, addrstr, sizeof(addrstr));
120+
NET_DBG("accepted connection from [%s]:%u",
121+
addrstr, ntohs(*portp));
122+
123+
/* send a banner */
124+
r = welcome(client_fd);
125+
if (r == -1) {
126+
NET_DBG("send() failed (%d)", errno);
127+
zsock_close(client_fd);
128+
return;
129+
}
130+
131+
for (;;) {
132+
/* echo 1 line at a time */
133+
r = zsock_recv(client_fd, line, sizeof(line), 0);
134+
if (r == -1) {
135+
NET_DBG("recv() failed (%d)", errno);
136+
zsock_close(client_fd);
137+
break;
138+
}
139+
len = r;
140+
141+
r = zsock_send(client_fd, line, len, 0);
142+
if (r == -1) {
143+
NET_DBG("send() failed (%d)", errno);
144+
zsock_close(client_fd);
145+
break;
146+
}
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy