This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 30b1c024a1d1c59f4b7108643bead85616b4334a Author: Tim Hardisty <56726697+tim...@users.noreply.github.com> AuthorDate: Wed May 14 15:27:30 2025 +0100 apps/netutils: add mdns library support This commit allows an external mDNS library to be included in NuttX. It originates from here: <https://github.com/mjansson/mdns> It is declared as being in the Public Domain as per <http://unlicense.org> Signed-off-by: Tim Hardisty <t...@jti.uk.com> --- include/netutils/mdnsd.h | 58 ++++++++++++ netutils/mdns/Kconfig | 81 +++++++++++++++++ netutils/mdns/Make.defs | 25 +++++ netutils/mdns/Makefile | 106 +++++++++++++++++++++ netutils/mdns/mdnsd.c | 182 +++++++++++++++++++++++++++++++++++++ netutils/mdns/verbose_option.patch | 16 ++++ 6 files changed, 468 insertions(+) diff --git a/include/netutils/mdnsd.h b/include/netutils/mdnsd.h new file mode 100644 index 000000000..1900fb9db --- /dev/null +++ b/include/netutils/mdnsd.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * apps/netutils/mdnsd.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_INCLUDE_NETUTILS_MDNSD_H +#define __APPS_INCLUDE_NETUTILS_MDNSD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +int mdnsd_start(FAR char *service_name, FAR char *service_port); +int mdnsd_stop(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_INCLUDE_NETUTILS_MDNSD_H */ diff --git a/netutils/mdns/Kconfig b/netutils/mdns/Kconfig new file mode 100644 index 000000000..bd2003bdb --- /dev/null +++ b/netutils/mdns/Kconfig @@ -0,0 +1,81 @@ +config LIB_MDNS + bool "MDNS library" + default n + ---help--- + Enable the mDNS library. This allows calls to the library to be made. + + This external library is "unlicensed" using the methodology from + http://unlicense.org + + You should be sure that this license is acceptable for your usage. + + By default, the "built-in" demo is added as an application that can + be run from nsh <mdns>. + + This is also needed for the optional daemon that allows the demo + app's mDNS functionality to be started and stopped from user + applications. There is an associated example app + (CONFIG_EXAMPLES_MDNSD) to allow the daemon to be tried from nsh. + + Ultimately, this should be used simply as a library, and neither the + demo app nor the daemon utilised. If just built as a library,the + relevant header file <mdns.h> is copied to the usual netutils + include location and can be utilised be including it: + + #include <netutils/mdns.h> + +if LIB_MDNS + +config NETUTILS_MDNS + tristate "Enable mdns built-in demo app" + default n + ---help--- + Enable the author's original built-in MDNS demo app. This allows the + functionality of the library to be demonstrated. Information on using + it is available from the original git repo for this external library: + + https://github.com/mjansson/mdns + +if NETUTILS_MDNS + +config NETUTILS_MDNS_PROGNAME + string "mDNS program name" + default "mdns" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config NETUTILS_MDNS_PRIORITY + int "mDNS task priority" + default 100 + +config NETUTILS_MDNS_STACKSIZE + int "mDNS stack size" + default DEFAULT_TASK_STACKSIZE + ---help--- + The default (4KiB) is adequate for simple networks but this will + most likely need to be increased if there are many network devices + attached that could send queries. + +config NETUTILS_MDNS_VERBOSE + bool "Enable verbose printf output from built-in mdns demo" + default y +endif + +config NETUTILS_MDNS_DAEMON + tristate "Wrap mdns demo app as a daemon, which can be started/stopped" + default n + depends on NETUTILS_MDNS + ---help--- + This option wraps the mdns demo app as a daemon, so requires + CONFIG_NETUTILS_MDNS to be selected. + + There is also an example app (CONFIG_EXAMPLES_MDNSD) to allow the + mdns daemon to be started/stopped via the NuttX shell. + +config NETUTILS_MDNS_DAEMON_STOP_SIGNAL + int "Signal used to stop the MDNSD daemon" + default 22 + depends on NETUTILS_MDNS_DAEMON + +endif #NETUTILS_MDNS diff --git a/netutils/mdns/Make.defs b/netutils/mdns/Make.defs new file mode 100644 index 000000000..9bc358982 --- /dev/null +++ b/netutils/mdns/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/netutils/mdns/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LIB_MDNS),) +CONFIGURED_APPS += $(APPDIR)/netutils/mdns +endif diff --git a/netutils/mdns/Makefile b/netutils/mdns/Makefile new file mode 100644 index 000000000..2a69531a9 --- /dev/null +++ b/netutils/mdns/Makefile @@ -0,0 +1,106 @@ +############################################################################ +# netutils/mdns/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# mDNS application + +############################################################################ +# Flags +############################################################################ + +MDNS_URL ?= "https://github.com/mjansson/mdns/archive" + +MDNS_VERSION = main +MDNS_ZIP = $(MDNS_VERSION).zip + +MDNS_UNPACKNAME = mdns +UNPACK ?= unzip -q -o + +VPATH += $(MDNS_UNPACKNAME) +VPATH += $(MDNS_UNPACKNAME)$(DELIM)posix +DEPPATH += --dep-path $(MDNS_UNPACKNAME) +DEPPATH += --dep-path $(MDNS_UNPACKNAME)$(DELIM)posix + +CFLAGS += -Wno-strict-prototypes -Wno-undef -Wno-format + +APPS_INCDIR = $(APPDIR)$(DELIM)include$(DELIM)netutils + +############################################################################ +# Targets +############################################################################ + +$(MDNS_ZIP): + @echo "Downloading: $(MDNS_URL)/$(MDNS_ZIP)" + $(Q) curl -O -L $(MDNS_URL)/$(MDNS_ZIP) + +$(MDNS_UNPACKNAME): $(MDNS_ZIP) + @echo "Unpacking: $(MDNS_ZIP) -> $(MDNS_UNPACKNAME)" + $(Q) $(UNPACK) $(MDNS_ZIP) + $(Q) mv mdns-$(MDNS_VERSION) $(MDNS_UNPACKNAME) + $(Q) cp $(MDNS_UNPACKNAME)$(DELIM)mdns.h $(APPS_INCDIR) + $(Q) patch -p0 < verbose_option.patch # Update to enable non-verbose mode + $(Q) touch $(MDNS_UNPACKNAME) + +clean:: + $(call DELFILE, $(OBJS)) + +# Download and unpack tarball if no git repo found + +ifeq ($(wildcard $(MDNS_UNPACKNAME)/.git),) +context:: $(MDNS_UNPACKNAME) + +distclean:: + $(call DELFILE, $(OBJS)) + $(call DELDIR, $(MDNS_UNPACKNAME)) + $(call DELFILE, $(APPS_INCDIR)$(DELIM)mdns.h) + $(call DELFILE, $(MDNS_ZIP)) +endif + +############################################################################ +# Applications Configuration +############################################################################ + +include $(APPDIR)/Make.defs + +ifneq ($(CONFIG_NETUTILS_MDNS),) +PROGNAME = $(CONFIG_NETUTILS_MDNS_PROGNAME) +PRIORITY = $(CONFIG_NETUTILS_MDNS_PRIORITY) +STACKSIZE = $(CONFIG_NETUTILS_MDNS_STACKSIZE) +MODULE = $(CONFIG_NETUTILS_MDNS) + +MAINSRC = mdns/mdns.c +else +CSRCS += mdns/mdns.c +endif + +ifneq ($(CONFIG_NETUTILS_MDNS_DAEMON),) +CSRCS += mdnsd.c +endif + +# This is an external library so we accept NuttX style violations + +CFLAGS += -Wno-undef -Wno-strict-prototypes -Wno-unused-variable \ + -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-shadow \ + -Wno-format + +include $(APPDIR)/Application.mk \ No newline at end of file diff --git a/netutils/mdns/mdnsd.c b/netutils/mdns/mdnsd.c new file mode 100644 index 000000000..1f648950b --- /dev/null +++ b/netutils/mdns/mdnsd.c @@ -0,0 +1,182 @@ +/**************************************************************************** + * apps/netutils/mdns/mdnsd.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <limits.h> +#include <semaphore.h> +#include <debug.h> /* For nerr, info */ + +#include "netutils/netlib.h" +#include "netutils/mdnsd.h" + +#include <spawn.h> + +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This enumeration describes the state of the MDNSD daemon */ + +enum mdnsd_daemon_e +{ + MDNSD_NOT_RUNNING = 0, + MDNSD_STARTING, + MDNSD_RUNNING, + MDNSD_STOP_REQUESTED, +}; + +struct mdnsd_config_s +{ + pid_t pid; /* Task ID of the spawned MDNSD daemon */ + enum mdnsd_daemon_e state; /* State of the daemon */ + sem_t lock; /* Used to protect the whole structure */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct mdnsd_config_s g_mdnsd_config = +{ + -1, + MDNSD_NOT_RUNNING, + SEM_INITIALIZER(1), +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int mdnsd_stop(void) +{ + int ret; + + sem_wait(&g_mdnsd_config.lock); + if (g_mdnsd_config.state == MDNSD_RUNNING) + { + g_mdnsd_config.state = MDNSD_STOP_REQUESTED; + do + { + ret = (kill(g_mdnsd_config.pid, + CONFIG_NETUTILS_MDNS_DAEMON_STOP_SIGNAL)); + if (ret < 0) + { + nerr("ERROR: kill pid %d failed: %d\n", + g_mdnsd_config.pid, errno); + break; + } + } + while (g_mdnsd_config.state == MDNSD_STOP_REQUESTED); + } + + g_mdnsd_config.state = MDNSD_NOT_RUNNING; + sem_post(&g_mdnsd_config.lock); + return OK; +} + +int mdnsd_start(FAR char *service_name, FAR char *service_port) +{ + int ret; + char hostname_buffer[HOST_NAME_MAX]; + const char *hostname = "nuttx"; + FAR char *argv[7]; + + /* Are we in a non-running state? */ + + sem_wait(&g_mdnsd_config.lock); + if (g_mdnsd_config.state == MDNSD_NOT_RUNNING) + { + g_mdnsd_config.state = MDNSD_STARTING; + + /* Configure our mDNS service */ + + /* The mdns library function will check the hostname too, but this + * ensures the default is our, not the library author's, choice. + */ + + if (gethostname(hostname_buffer, HOST_NAME_MAX) == 0) + { + if (strlen(hostname_buffer) != 0) + { + hostname = hostname_buffer; + } + } + + argv[0] = "--service"; + argv[1] = service_name; + argv[2] = "--hostname"; + argv[3] = (char *)hostname; + argv[4] = "--port"; + argv[5] = service_port; + argv[6] = NULL; + + /* Spawn mdns app */ + + ret = posix_spawn(&g_mdnsd_config.pid, /* Returned Task ID */ + "mdns", /* Task Path */ + NULL, /* File actions */ + NULL, /* Attributes */ + argv, /* Arguments */ + NULL); /* No */ + + if (ret < 0) + { + int errval = errno; + syslog(LOG_ERR, "Failed to spawn mdns daemon\n"); + g_mdnsd_config.state = MDNSD_NOT_RUNNING; + return -errval; + } + + ninfo("Started\n"); + + g_mdnsd_config.state = MDNSD_RUNNING; + } + + sem_post(&g_mdnsd_config.lock); + return OK; +} + diff --git a/netutils/mdns/verbose_option.patch b/netutils/mdns/verbose_option.patch new file mode 100644 index 000000000..63e09fffd --- /dev/null +++ b/netutils/mdns/verbose_option.patch @@ -0,0 +1,16 @@ +--- mdns/mdns.c ++++ mdns/mdns/mdns.c +@@ -22,7 +22,9 @@ + // Alias some things to simulate recieving data to fuzz library + #if defined(MDNS_FUZZING) + #define recvfrom(sock, buffer, capacity, flags, src_addr, addrlen) ((mdns_ssize_t)capacity) +-#define printf ++#endif ++#if defined(MDNS_FUZZING) || !defined(CONFIG_NETUTILS_MDNS_VERBOSE) ++#define printf(...) + #endif + + #include "mdns.h" +-- +2.34.1 +