mirror of https://github.com/wb2osz/direwolf.git
Merge branch 'hessu-feature/dns-sd' into dev
This commit is contained in:
commit
14d6eed205
|
@ -157,6 +157,10 @@ elseif(APPLE)
|
|||
set(CMAKE_MACOSX_RPATH ON)
|
||||
message(STATUS "RPATH support: ${CMAKE_MACOSX_RPATH}")
|
||||
|
||||
# just blindly enable dns-sd
|
||||
set(USE_MACOS_DNSSD ON)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_MACOS_DNSSD")
|
||||
|
||||
elseif (WIN32)
|
||||
if(NOT VS2015 AND NOT VS2017)
|
||||
message(FATAL_ERROR "You must use Microsoft Visual Studio 2015 or 2017 as compiler")
|
||||
|
@ -277,6 +281,11 @@ if(LINUX)
|
|||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_CM108")
|
||||
endif()
|
||||
|
||||
find_package(Avahi)
|
||||
if(AVAHI_CLIENT_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_AVAHI_CLIENT")
|
||||
endif()
|
||||
|
||||
elseif (NOT WIN32 AND NOT CYGWIN)
|
||||
find_package(Portaudio REQUIRED)
|
||||
if(PORTAUDIO_FOUND)
|
||||
|
|
13
README.md
13
README.md
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
# Dire Wolf #
|
||||
|
||||
### Decoded Information from Radio Emissions for Windows Or Linux Fans ###
|
||||
|
@ -39,6 +39,7 @@ It can also be used as a virtual TNC for other applications such as [APRSIS32](h
|
|||
Send periodic beacons to provide information to others. For tracking the location is provided by a GPS receiver.
|
||||
Build your own telemetry applications with the toolkit.
|
||||
|
||||
|
||||
- **APRStt Gateway.**
|
||||
|
||||
Very few hams have portable equipment for APRS but nearly everyone has a handheld radio that can send DTMF tones. APRStt allows a user, equipped with only DTMF (commonly known as Touch Tone) generation capability, to enter information into the global APRS data network. Responses can be sent by Morse Code or synthesized speech.
|
||||
|
@ -130,15 +131,17 @@ On Debian / Ubuntu / Raspbian / Raspberry Pi OS:
|
|||
sudo apt-get install cmake
|
||||
sudo apt-get install libasound2-dev
|
||||
sudo apt-get install libudev-dev
|
||||
sudo apt-get install libavahi-client-dev
|
||||
|
||||
Or on Red Hat / Fedora / CentOS:
|
||||
|
||||
sudo yum install git
|
||||
sudo yum install gcc
|
||||
sudo yum install gcc-c++
|
||||
sudo yum install make
|
||||
sudo yum install git
|
||||
sudo yum install gcc
|
||||
sudo yum install gcc-c++
|
||||
sudo yum install make
|
||||
sudo yum install alsa-lib-devel
|
||||
sudo yum install libudev-devel
|
||||
sudo yum install avahi-devel
|
||||
|
||||
CentOS 6 & 7 currently have cmake 2.8 but we need 3.1 or later.
|
||||
First you need to enable the EPEL repository. Add a symlink if you don't already have the older version and want to type cmake rather than cmake3.
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
find_library(AVAHI_COMMON_LIBRARY NAMES avahi-common PATHS ${PC_AVAHI_CLIENT_LIBRARY_DIRS})
|
||||
if(AVAHI_COMMON_LIBRARY)
|
||||
set(AVAHI_COMMON_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
find_library(AVAHI_CLIENT_LIBRARY NAMES avahi-client PATHS ${PC_AVAHI_CLIENT_LIBRARY_DIRS})
|
||||
if(AVAHI_CLIENT_LIBRARY)
|
||||
set(AVAHI_CLIENT_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(AVAHI DEFAULT_MSG AVAHI_COMMON_FOUND AVAHI_CLIENT_FOUND)
|
||||
|
||||
if (AVAHI_FOUND)
|
||||
set(AVAHI_INCLUDE_DIRS ${AVAHI_UI_INCLUDE_DIR})
|
||||
set(AVAHI_LIBRARIES ${AVAHI_COMMON_LIBRARY} ${AVAHI_CLIENT_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(AVAHI_INCLUDE_DIRS AVAHI_LIBRARIES)
|
|
@ -1,4 +1,4 @@
|
|||
# Documentation for Dire Wolf #
|
||||
# Documentation for Dire Wolf #
|
||||
|
||||
Click on the document name to view in your web browser or the link following to download the PDF file.
|
||||
|
||||
|
@ -11,11 +11,11 @@ Brief summary of packet radio / APRS history and the capbilities of Dire Wolf.
|
|||
|
||||
## Essential Reading ##
|
||||
|
||||
- [**User Guide**](User-Guide.pdf) [ [*download*](../../../raw/dev/doc/User-Guide.pdf) ]
|
||||
- [**User Guide**](User-Guide.pdf) [ [*download*](../../../raw/master/doc/User-Guide.pdf) ]
|
||||
|
||||
This is your primary source of information about installation, operation, and configuration.
|
||||
|
||||
- [**Raspberry Pi APRS**](Raspberry-Pi-APRS.pdf) [ [*download*](../../../raw/dev/doc/Raspberry-Pi-APRS.pdf) ]
|
||||
- [**Raspberry Pi APRS**](Raspberry-Pi-APRS.pdf) [ [*download*](../../../raw/master/doc/Raspberry-Pi-APRS.pdf) ]
|
||||
|
||||
The Raspberry Pi has some special considerations that
|
||||
make it different from other generic Linux systems.
|
||||
|
@ -46,38 +46,40 @@ These dive into more detail for specialized topics or typical usage scenarios.
|
|||
|
||||
- [**Successful APRS IGate Operation**](Successful-APRS-IGate-Operation.pdf) [ [*download*](../../../raw/dev/doc/Successful-APRS-IGate-Operation.pdf) ]
|
||||
|
||||
|
||||
Dire Wolf can serve as a gateway between the APRS radio network and APRS-IS servers on the Internet.
|
||||
|
||||
This explains how it all works, proper configuration, and troubleshooting.
|
||||
|
||||
- [**Bluetooth KISS TNC**](Bluetooth-KISS-TNC.pdf) [ [*download*](../../../raw/dev/doc/Bluetooth-KISS-TNC.pdf) ]
|
||||
- [**Bluetooth KISS TNC**](Bluetooth-KISS-TNC.pdf) [ [*download*](../../../raw/master/doc/Bluetooth-KISS-TNC.pdf) ]
|
||||
|
||||
Eliminate the cable between your TNC and application. Use Bluetooth instead.
|
||||
|
||||
- [**APRStt Implementation Notes**](APRStt-Implementation-Notes.pdf) [ [*download*](../../../raw/dev/doc/APRStt-Implementation-Notes.pdf) ]
|
||||
- [**APRStt Implementation Notes**](APRStt-Implementation-Notes.pdf) [ [*download*](../../../raw/master/doc/APRStt-Implementation-Notes.pdf) ]
|
||||
|
||||
Very few hams have portable equipment for APRS but nearly everyone has a handheld radio that can send DTMF tones. APRStt allows a user, equipped with only DTMF (commonly known as Touch Tone) generation capability, to enter information into the global APRS data network.
|
||||
This document explains how the APRStt concept was implemented in the Dire Wolf application.
|
||||
- [**APRStt Interface for SARTrack**](APRStt-interface-for-SARTrack.pdf) [ [*download*](../../../raw/dev/doc/APRStt-interface-for-SARTrack.pdf) ]
|
||||
|
||||
- [**APRStt Interface for SARTrack**](APRStt-interface-for-SARTrack.pdf) [ [*download*](../../../raw/master/doc/APRStt-interface-for-SARTrack.pdf) ]
|
||||
|
||||
This example illustrates how APRStt can be integrated with other applications such as SARTrack, APRSISCE/32, YAAC, or Xastir.
|
||||
|
||||
- [**APRStt Listening Example**](APRStt-Listening-Example.pdf) [ [*download*](../../../raw/dev/doc/APRStt-Listening-Example.pdf) ]
|
||||
- [**APRStt Listening Example**](APRStt-Listening-Example.pdf) [ [*download*](../../../raw/master/doc/APRStt-Listening-Example.pdf) ]
|
||||
|
||||
|
||||
WB4APR described a useful application for the [QIKCOM-2 Satallite Transponder](http://www.tapr.org/pipermail/aprssig/2015-November/045035.html).
|
||||
|
||||
Don’t have your own QIKCOM-2 Satellite Transponder? No Problem. You can do the same thing with an ordinary computer and the APRStt gateway built into Dire Wolf. Here’s how.
|
||||
|
||||
- [**Raspberry Pi APRS Tracker**](Raspberry-Pi-APRS-Tracker.pdf) [ [*download*](../../../raw/dev/doc/Raspberry-Pi-APRS-Tracker.pdf) ]
|
||||
- [**Raspberry Pi APRS Tracker**](Raspberry-Pi-APRS-Tracker.pdf) [ [*download*](../../../raw/master/doc/Raspberry-Pi-APRS-Tracker.pdf) ]
|
||||
|
||||
Build a tracking device which transmits position from a GPS receiver.
|
||||
|
||||
- [**Raspberry Pi SDR IGate**](Raspberry-Pi-SDR-IGate.pdf) [ [*download*](../../../raw/dev/doc/Raspberry-Pi-SDR-IGate.pdf) ]
|
||||
- [**Raspberry Pi SDR IGate**](Raspberry-Pi-SDR-IGate.pdf) [ [*download*](../../../raw/master/doc/Raspberry-Pi-SDR-IGate.pdf) ]
|
||||
|
||||
It's easy to build a receive-only APRS Internet Gateway (IGate) with only a Raspberry Pi and a software defined radio (RTL-SDR) dongle. Here’s how.
|
||||
|
||||
- [**APRS Telemetry Toolkit**](APRS-Telemetry-Toolkit.pdf) [ [*download*](../../../raw/dev/doc/APRS-Telemetry-Toolkit.pdf) ]
|
||||
- [**APRS Telemetry Toolkit**](APRS-Telemetry-Toolkit.pdf) [ [*download*](../../../raw/master/doc/APRS-Telemetry-Toolkit.pdf) ]
|
||||
|
||||
Describes scripts and methods to generate telemetry.
|
||||
Includes a complete example of attaching an analog to
|
||||
|
@ -86,12 +88,12 @@ These dive into more detail for specialized topics or typical usage scenarios.
|
|||
|
||||
|
||||
|
||||
- [**2400 & 4800 bps PSK for APRS / Packet Radio**](2400-4800-PSK-for-APRS-Packet-Radio.pdf) [ [*download*](../../../raw/dev/doc/2400-4800-PSK-for-APRS-Packet-Radio.pdf) ]
|
||||
- [**2400 & 4800 bps PSK for APRS / Packet Radio**](2400-4800-PSK-for-APRS-Packet-Radio.pdf) [ [*download*](../../../raw/master/doc/2400-4800-PSK-for-APRS-Packet-Radio.pdf) ]
|
||||
|
||||
|
||||
Double or quadruple your data rate by sending multiple bits at the same time.
|
||||
|
||||
- [**Going beyond 9600 baud**](Going-beyond-9600-baud.pdf) [ [*download*](../../../raw/dev/doc/Going-beyond-9600-baud.pdf) ]
|
||||
- [**Going beyond 9600 baud**](Going-beyond-9600-baud.pdf) [ [*download*](../../../raw/master/doc/Going-beyond-9600-baud.pdf) ]
|
||||
|
||||
|
||||
Why stop at 9600 baud? Go faster if your soundcard and radio can handle it.
|
||||
|
@ -120,7 +122,7 @@ These dive into more detail for specialized topics or typical usage scenarios.
|
|||
|
||||
There have been other occasional mentions of merging Ham Radio with the Internet of Things but only ad hoc incompatible narrowly focused applications. Here is a proposal for a standardized more flexible method so different systems can communicate with each other.
|
||||
|
||||
- [**A Better APRS Packet Demodulator, part 1, 1200 baud**](A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf) [ [*download*](../../../raw/dev/doc/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf) ]
|
||||
- [**A Better APRS Packet Demodulator, part 1, 1200 baud**](A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf) [ [*download*](../../../raw/master/doc/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf) ]
|
||||
|
||||
Sometimes it's a little mystifying why an
|
||||
APRS / AX.25 Packet TNC will decode some signals
|
||||
|
@ -132,7 +134,7 @@ and a couple things that can be done about it.
|
|||
|
||||
|
||||
|
||||
- [**A Better APRS Packet Demodulator, part 2, 9600 baud**](A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf) [ [*download*](../../../raw/dev/doc/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf) ]
|
||||
- [**A Better APRS Packet Demodulator, part 2, 9600 baud**](A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf) [ [*download*](../../../raw/master/doc/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf) ]
|
||||
|
||||
In the first part of this series we discussed 1200 baud audio frequency shift keying (AFSK). The mismatch
|
||||
between FM transmitter pre-emphasis and the
|
||||
|
@ -141,13 +143,13 @@ and a couple things that can be done about it.
|
|||
This makes it more difficult to demodulate them accurately.
|
||||
9600 baud operation is an entirely different animal. ...
|
||||
|
||||
- [**WA8LMF TNC Test CD Results a.k.a. Battle of the TNCs**](WA8LMF-TNC-Test-CD-Results.pdf) [ [*download*](../../../raw/dev/doc/WA8LMF-TNC-Test-CD-Results.pdf) ]
|
||||
- [**WA8LMF TNC Test CD Results a.k.a. Battle of the TNCs**](WA8LMF-TNC-Test-CD-Results.pdf) [ [*download*](../../../raw/master/doc/WA8LMF-TNC-Test-CD-Results.pdf) ]
|
||||
|
||||
How can we compare how well the TNCs perform under real world conditions?
|
||||
The de facto standard of measurement is the number of packets decoded from [WA8LMF’s TNC Test CD](http://wa8lmf.net/TNCtest/index.htm).
|
||||
Many have published the number of packets they have been able to decode from this test. Here they are, all gathered in one place, for your reading pleasure.
|
||||
|
||||
- [**A Closer Look at the WA8LMF TNC Test CD**](A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf) [ [*download*](../../../raw/dev/doc/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf) ]
|
||||
- [**A Closer Look at the WA8LMF TNC Test CD**](A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf) [ [*download*](../../../raw/master/doc/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf) ]
|
||||
|
||||
Here, we take a closer look at some of the frames on the TNC Test CD in hopes of gaining some insights into why some are easily decoded and others are more difficult.
|
||||
There are a lot of ugly signals out there. Many can be improved by decreasing the transmit volume. Others are just plain weird and you have to wonder how they are being generated.
|
||||
|
|
|
@ -109,6 +109,12 @@ if(LINUX)
|
|||
cm108.c
|
||||
)
|
||||
endif()
|
||||
if(AVAHI_CLIENT_FOUND)
|
||||
list(APPEND direwolf_SOURCES
|
||||
dns_sd_common.c
|
||||
dns_sd_avahi.c
|
||||
)
|
||||
endif()
|
||||
elseif(WIN32 OR CYGWIN) # windows
|
||||
list(APPEND direwolf_SOURCES
|
||||
audio_win.c
|
||||
|
@ -124,6 +130,12 @@ if(LINUX)
|
|||
list(APPEND direwolf_SOURCES
|
||||
audio_portaudio.c
|
||||
)
|
||||
if(USE_MACOS_DNSSD)
|
||||
list(APPEND direwolf_SOURCES
|
||||
dns_sd_common.c
|
||||
dns_sd_macos.c
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(direwolf
|
||||
|
@ -140,6 +152,7 @@ target_link_libraries(direwolf
|
|||
${ALSA_LIBRARIES}
|
||||
${UDEV_LIBRARIES}
|
||||
${PORTAUDIO_LIBRARIES}
|
||||
${AVAHI_LIBRARIES}
|
||||
)
|
||||
|
||||
if(WIN32 OR CYGWIN)
|
||||
|
|
39
src/config.c
39
src/config.c
|
@ -856,6 +856,8 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
p_misc_config->enable_kiss_pt = 0; /* -p option */
|
||||
p_misc_config->kiss_copy = 0;
|
||||
|
||||
p_misc_config->dns_sd_enabled = 1;
|
||||
|
||||
/* Defaults from http://info.aprs.net/index.php?title=SmartBeaconing */
|
||||
|
||||
p_misc_config->sb_configured = 0; /* TRUE if SmartBeaconing is configured. */
|
||||
|
@ -4564,6 +4566,43 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* DNSSD - Enable or disable (1/0) dns-sd, DNS Service Discovery announcements
|
||||
* DNSSDNAME - Set DNS-SD service name, defaults to "Dire Wolf on <hostname>"
|
||||
*/
|
||||
|
||||
else if (strcasecmp(t, "DNSSD") == 0) {
|
||||
int n;
|
||||
t = split(NULL,0);
|
||||
if (t == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Line %d: Missing integer value for DNSSD command.\n", line);
|
||||
continue;
|
||||
}
|
||||
n = atoi(t);
|
||||
if (n == 0 || n == 1) {
|
||||
p_misc_config->dns_sd_enabled = n;
|
||||
} else {
|
||||
p_misc_config->dns_sd_enabled = 0;
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Line %d: Invalid integer value for DNSSD. Disabling dns-sd.\n", line);
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcasecmp(t, "DNSSDNAME") == 0) {
|
||||
t = split(NULL, 1);
|
||||
if (t == NULL) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Line %d: Missing service name for DNSSDNAME.\n", line);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
strlcpy(p_misc_config->dns_sd_name, t, sizeof(p_misc_config->dns_sd_name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GPSNMEA - Device name for reading from GPS receiver.
|
||||
*/
|
||||
|
|
|
@ -88,6 +88,9 @@ struct misc_config_s {
|
|||
|
||||
char log_path[80]; /* Either directory or full file name depending on above. */
|
||||
|
||||
int dns_sd_enabled; /* DNS Service Discovery announcement enabled. */
|
||||
char dns_sd_name[64]; /* Name announced on dns-sd; defaults to "Dire Wolf on <hostname>" */
|
||||
|
||||
int sb_configured; /* TRUE if SmartBeaconing is configured. */
|
||||
int sb_fast_speed; /* MPH */
|
||||
int sb_fast_rate; /* seconds */
|
||||
|
|
|
@ -125,6 +125,7 @@
|
|||
#include "dtime_now.h"
|
||||
#include "fx25.h"
|
||||
#include "dwsock.h"
|
||||
#include "dns_sd_dw.h"
|
||||
|
||||
|
||||
//static int idx_decoded = 0;
|
||||
|
@ -1029,6 +1030,11 @@ int main (int argc, char *argv[])
|
|||
server_init (&audio_config, &misc_config);
|
||||
kissnet_init (&misc_config);
|
||||
|
||||
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
||||
if (misc_config.kiss_port > 0 && misc_config.dns_sd_enabled)
|
||||
dns_sd_announce(&misc_config);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a pseudo terminal and KISS TNC emulator.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2020 Heikki Hannikainen, OH7LZB
|
||||
//
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Module: dns_sd_avahi.c
|
||||
*
|
||||
* Purpose: Announce the KISS over TCP service using DNS-SD via Avahi
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Most people have typed in enough IP addresses and ports by now, and
|
||||
* would rather just select an available TNC that is automatically
|
||||
* discovered on the local network. Even more so on a mobile device
|
||||
* such an Android or iOS phone or tablet.
|
||||
*
|
||||
* On Linux, the announcement can be made through Avahi, the mDNS
|
||||
* framework commonly deployed on Linux systems.
|
||||
*
|
||||
* This is largely based on the publishing example of the Avahi library.
|
||||
*/
|
||||
|
||||
#ifdef USE_AVAHI_CLIENT
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <avahi-client/client.h>
|
||||
#include <avahi-client/publish.h>
|
||||
#include <avahi-common/simple-watch.h>
|
||||
#include <avahi-common/alternative.h>
|
||||
#include <avahi-common/malloc.h>
|
||||
#include <avahi-common/error.h>
|
||||
|
||||
#include "dns_sd_dw.h"
|
||||
#include "dns_sd_common.h"
|
||||
#include "textcolor.h"
|
||||
|
||||
static AvahiEntryGroup *group = NULL;
|
||||
static AvahiSimplePoll *simple_poll = NULL;
|
||||
static AvahiClient *client = NULL;
|
||||
static char *name = NULL;
|
||||
static int kiss_port = 0;
|
||||
|
||||
pthread_t avahi_thread;
|
||||
|
||||
static void create_services(AvahiClient *c);
|
||||
|
||||
#define PRINT_PREFIX "DNS-SD: Avahi: "
|
||||
|
||||
static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata)
|
||||
{
|
||||
assert(g == group || group == NULL);
|
||||
group = g;
|
||||
|
||||
/* Called whenever the entry group state changes */
|
||||
switch (state) {
|
||||
case AVAHI_ENTRY_GROUP_ESTABLISHED :
|
||||
/* The entry group has been established successfully */
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf(PRINT_PREFIX "Service '%s' successfully registered.\n", name);
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_COLLISION: {
|
||||
char *n;
|
||||
/* A service name collision with a remote service
|
||||
* happened. Let's pick a new name. */
|
||||
n = avahi_alternative_service_name(name);
|
||||
avahi_free(name);
|
||||
name = n;
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf(PRINT_PREFIX "Service name collision, renaming service to '%s'\n", name);
|
||||
/* And recreate the services */
|
||||
create_services(avahi_entry_group_get_client(g));
|
||||
break;
|
||||
}
|
||||
case AVAHI_ENTRY_GROUP_FAILURE:
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
|
||||
/* Some kind of failure happened while we were registering our services */
|
||||
avahi_simple_poll_quit(simple_poll);
|
||||
break;
|
||||
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
||||
case AVAHI_ENTRY_GROUP_REGISTERING:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void create_services(AvahiClient *c)
|
||||
{
|
||||
char *n;
|
||||
int ret;
|
||||
assert(c);
|
||||
/* If this is the first time we're called, let's create a new
|
||||
* entry group if necessary */
|
||||
if (!group) {
|
||||
if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
avahi_entry_group_reset(group);
|
||||
}
|
||||
|
||||
/* If the group is empty (either because it was just created, or
|
||||
* because it was reset previously, add our entries. */
|
||||
if (avahi_entry_group_is_empty(group)) {
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf(PRINT_PREFIX "Announcing KISS TCP on port %d as '%s'\n", kiss_port, name);
|
||||
|
||||
/* Announce with AVAHI_PROTO_INET instead of AVAHI_PROTO_UNSPEC, since Dire Wolf currently
|
||||
* only listens on IPv4.
|
||||
*/
|
||||
|
||||
if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, 0, name, DNS_SD_SERVICE, NULL, NULL, kiss_port, NULL)) < 0) {
|
||||
if (ret == AVAHI_ERR_COLLISION)
|
||||
goto collision;
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Failed to add _kiss-tnc._tcp service: %s\n", avahi_strerror(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Tell the server to register the service */
|
||||
if ((ret = avahi_entry_group_commit(group)) < 0) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Failed to commit entry group: %s\n", avahi_strerror(ret));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
collision:
|
||||
/* A service name collision with a local service happened. Let's
|
||||
* pick a new name */
|
||||
n = avahi_alternative_service_name(name);
|
||||
avahi_free(name);
|
||||
name = n;
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf(PRINT_PREFIX "Service name collision, renaming service to '%s'\n", name);
|
||||
avahi_entry_group_reset(group);
|
||||
create_services(c);
|
||||
return;
|
||||
|
||||
fail:
|
||||
avahi_simple_poll_quit(simple_poll);
|
||||
}
|
||||
|
||||
static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata)
|
||||
{
|
||||
assert(c);
|
||||
/* Called whenever the client or server state changes */
|
||||
switch (state) {
|
||||
case AVAHI_CLIENT_S_RUNNING:
|
||||
/* The server has startup successfully and registered its host
|
||||
* name on the network, so it's time to create our services */
|
||||
create_services(c);
|
||||
break;
|
||||
case AVAHI_CLIENT_FAILURE:
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Client failure: %s\n", avahi_strerror(avahi_client_errno(c)));
|
||||
avahi_simple_poll_quit(simple_poll);
|
||||
break;
|
||||
case AVAHI_CLIENT_S_COLLISION:
|
||||
/* Let's drop our registered services. When the server is back
|
||||
* in AVAHI_SERVER_RUNNING state we will register them
|
||||
* again with the new host name. */
|
||||
case AVAHI_CLIENT_S_REGISTERING:
|
||||
/* The server records are now being established. This
|
||||
* might be caused by a host name change. We need to wait
|
||||
* for our own records to register until the host name is
|
||||
* properly esatblished. */
|
||||
if (group)
|
||||
avahi_entry_group_reset(group);
|
||||
break;
|
||||
case AVAHI_CLIENT_CONNECTING:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup(void)
|
||||
{
|
||||
/* Cleanup things */
|
||||
if (client)
|
||||
avahi_client_free(client);
|
||||
|
||||
if (simple_poll)
|
||||
avahi_simple_poll_free(simple_poll);
|
||||
|
||||
avahi_free(name);
|
||||
}
|
||||
|
||||
|
||||
static void *avahi_mainloop(void *arg)
|
||||
{
|
||||
/* Run the main loop */
|
||||
avahi_simple_poll_loop(simple_poll);
|
||||
|
||||
cleanup();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dns_sd_announce (struct misc_config_s *mc)
|
||||
{
|
||||
text_color_set(DW_COLOR_DEBUG);
|
||||
kiss_port = mc->kiss_port;
|
||||
|
||||
int error;
|
||||
|
||||
/* Allocate main loop object */
|
||||
if (!(simple_poll = avahi_simple_poll_new())) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Failed to create Avahi simple poll object.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mc->dns_sd_name[0]) {
|
||||
name = avahi_strdup(mc->dns_sd_name);
|
||||
} else {
|
||||
name = dns_sd_default_service_name();
|
||||
}
|
||||
|
||||
/* Allocate a new client */
|
||||
client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
|
||||
|
||||
/* Check wether creating the client object succeeded */
|
||||
if (!client) {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf(PRINT_PREFIX "Failed to create Avahi client: %s\n", avahi_strerror(error));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pthread_create(&avahi_thread, NULL, &avahi_mainloop, NULL);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
cleanup();
|
||||
}
|
||||
|
||||
#endif // USE_AVAHI_CLIENT
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2020 Heikki Hannikainen, OH7LZB
|
||||
//
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Module: dns_sd_common.c
|
||||
*
|
||||
* Purpose: Announce the KISS over TCP service using DNS-SD, common functions
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Most people have typed in enough IP addresses and ports by now, and
|
||||
* would rather just select an available TNC that is automatically
|
||||
* discovered on the local network. Even more so on a mobile device
|
||||
* such an Android or iOS phone or tablet.
|
||||
*
|
||||
* This module contains common functions needed on Linux and MacOS.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Get a default service name to publish. By default,
|
||||
* "Dire Wolf on <hostname>", or just "Dire Wolf" if hostname cannot
|
||||
* be obtained.
|
||||
*/
|
||||
char *dns_sd_default_service_name(void)
|
||||
{
|
||||
char hostname[51];
|
||||
char sname[64];
|
||||
|
||||
int i = gethostname(hostname, sizeof(hostname));
|
||||
if (i == 0) {
|
||||
hostname[sizeof(hostname)-1] = 0;
|
||||
|
||||
// on some systems, an FQDN is returned; remove domain part
|
||||
char *dot = strchr(hostname, '.');
|
||||
if (dot)
|
||||
*dot = 0;
|
||||
|
||||
snprintf(sname, sizeof(sname), "Dire Wolf on %s", hostname);
|
||||
return strdup(sname);
|
||||
}
|
||||
|
||||
return strdup("Dire Wolf");
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
||||
|
||||
char *dns_sd_default_service_name(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define DNS_SD_SERVICE "_kiss-tnc._tcp"
|
||||
|
||||
void dns_sd_announce (struct misc_config_s *mc);
|
||||
|
||||
#endif // USE_AVAHI_CLIENT
|
|
@ -0,0 +1,88 @@
|
|||
//
|
||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||
//
|
||||
// Copyright (C) 2020 Heikki Hannikainen, OH7LZB
|
||||
//
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* Module: dns_sd_macos.c
|
||||
*
|
||||
* Purpose: Announce the KISS over TCP service using MacOS dns-sd
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Most people have typed in enough IP addresses and ports by now, and
|
||||
* would rather just select an available TNC that is automatically
|
||||
* discovered on the local network. Even more so on a mobile device
|
||||
* such an Android or iOS phone or tablet.
|
||||
*
|
||||
* On MacOs, the announcement can be made through dns-sd.
|
||||
*/
|
||||
|
||||
#ifdef USE_MACOS_DNSSD
|
||||
|
||||
#include <string.h>
|
||||
#include <dns_sd.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "dns_sd_dw.h"
|
||||
#include "dns_sd_common.h"
|
||||
#include "textcolor.h"
|
||||
|
||||
static char *name = NULL;
|
||||
|
||||
static void registerServiceCallBack(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
|
||||
const char* name, const char* regType, const char* domain, void* context)
|
||||
{
|
||||
if (errorCode == kDNSServiceErr_NoError) {
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf("DNS-SD: Successfully registered '%s'\n", name);
|
||||
} else {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf("DNS-SD: Failed to register '%s': %d\n", name, errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
void dns_sd_announce (struct misc_config_s *mc)
|
||||
{
|
||||
int kiss_port = mc->kiss_port;
|
||||
|
||||
if (mc->dns_sd_name[0]) {
|
||||
name = strdup(mc->dns_sd_name);
|
||||
} else {
|
||||
name = dns_sd_default_service_name();
|
||||
}
|
||||
|
||||
uint16_t port_nw = htons(kiss_port);
|
||||
|
||||
DNSServiceRef registerRef;
|
||||
DNSServiceErrorType err = DNSServiceRegister(
|
||||
®isterRef, 0, 0, name, DNS_SD_SERVICE, NULL, NULL,
|
||||
port_nw, 0, NULL, registerServiceCallBack, NULL);
|
||||
|
||||
if (err == kDNSServiceErr_NoError) {
|
||||
text_color_set(DW_COLOR_INFO);
|
||||
dw_printf("DNS-SD: Announcing KISS TCP on port %d as '%s'\n", kiss_port, name);
|
||||
} else {
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf("DNS-SD: Failed to announce '%s': %d\n", name, err);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_MACOS_DNSSD
|
||||
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
#include <gps.h>
|
||||
|
||||
|
||||
|
||||
// An incompatibility was introduced with version 7
|
||||
// and again with 9 and again with 10.
|
||||
|
||||
|
|
Loading…
Reference in New Issue