#include <avahi-common/error.h>
#define MESHLINK_MDNS_SERVICE_TYPE "_meshlink._tcp"
-#define MESHLINK_MDNS_SERVICE_NAME "Meshlink"
+//#define MESHLINK_MDNS_SERVICE_NAME "Meshlink"
+#define MESHLINK_MDNS_FINGERPRINT_KEY "fingerprint"
+
+static void discovery_resolve_callback(
+ AvahiSServiceResolver *resolver,
+ AVAHI_GCC_UNUSED AvahiIfIndex interface,
+ AVAHI_GCC_UNUSED AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *host_name,
+ const AvahiAddress *address,
+ uint16_t port,
+ AvahiStringList *txt,
+ AvahiLookupResultFlags flags,
+ AVAHI_GCC_UNUSED void* userdata)
+{
+ meshlink_handle_t *mesh = userdata;
+
+ /* Called whenever a service has been resolved successfully or timed out */
+
+ switch (event)
+ {
+ case AVAHI_RESOLVER_FAILURE:
+ fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ break;
+
+ case AVAHI_RESOLVER_FOUND:
+ {
+ char straddr[AVAHI_ADDRESS_STR_MAX], *strtxt;
+
+ fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
+
+ avahi_address_snprint(straddr, sizeof(straddr), address);
+ strtxt = avahi_string_list_to_string(txt);
+ fprintf(stderr,
+ "\t%s:%u (%s)\n"
+ "\tTXT=%s\n"
+ "\tcookie is %u\n"
+ "\tis_local: %i\n"
+ "\twide_area: %i\n"
+ "\tmulticast: %i\n"
+ "\tcached: %i\n",
+ host_name, port, straddr,
+ strtxt,
+ avahi_string_list_get_service_cookie(txt),
+ !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
+ !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
+ !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
+ !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
+ avahi_free(strtxt);
+
+ // retrieve fingerprint
+ AvahiStringList *fgli = avahi_string_list_find(txt, MESHLINK_MDNS_FINGERPRINT_KEY);
+ meshlink_node_t *node = meshlink_get_node(mesh, name);
+
+ fprintf(stderr, "%p, %p, %s, %s\n", fgli, node, avahi_string_list_get_text(fgli), meshlink_get_fingerprint(mesh, node));
+
+ if( node && fgli && strcmp(avahi_string_list_get_text(fgli)+strlen(MESHLINK_MDNS_FINGERPRINT_KEY)+1, meshlink_get_fingerprint(mesh, node)) == 0 )
+ {
+ fprintf(stderr, "Node %s is part of the mesh network - updating ip address.\n", node->name);
+ }
+ else
+ {
+ fprintf(stderr, "Node %s is not part of the mesh network - ignoring ip address.\n", node->name);
+ }
+ }
+ }
+
+ avahi_s_service_resolver_free(resolver);
+}
static void discovery_entry_group_callback(AvahiServer *server, AvahiSEntryGroup *group, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata)
{
{
case AVAHI_ENTRY_GROUP_ESTABLISHED:
/* The entry group has been established successfully */
- fprintf(stderr, "Service '%s' successfully established.\n", MESHLINK_MDNS_SERVICE_NAME);
+ fprintf(stderr, "Service '%s' successfully established.\n", /*MESHLINK_MDNS_SERVICE_NAME*/ mesh->name);
break;
case AVAHI_ENTRY_GROUP_COLLISION:
- fprintf(stderr, "Service name collision '%s'\n", MESHLINK_MDNS_SERVICE_NAME);
+ fprintf(stderr, "Service name collision '%s'\n", /*MESHLINK_MDNS_SERVICE_NAME*/ mesh->name);
break;
case AVAHI_ENTRY_GROUP_FAILURE :
static void discovery_create_services(meshlink_handle_t *mesh)
{
+ fprintf(stderr, "Adding service '%s'\n", /*MESHLINK_MDNS_SERVICE_NAME*/ mesh->name);
+
/* If this is the first time we're called, let's create a new entry group */
if (!mesh->avahi_group)
- if (!(mesh->avahi_group = avahi_s_entry_group_new(mesh->avahi_server, discovery_entry_group_callback, NULL))) {
+ if (!(mesh->avahi_group = avahi_s_entry_group_new(mesh->avahi_server, discovery_entry_group_callback, mesh))) {
fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
goto fail;
}
- fprintf(stderr, "Adding service '%s'\n", MESHLINK_MDNS_SERVICE_NAME);
-
/* Create some random TXT data */
- char fingerprint[1024];
- snprintf(fingerprint, sizeof(fingerprint), "fingerprint=%s", /*meshlink_get_fingerprint(mesh, mesh->self)*/ "");
+ char fingerprint[1024] = "";
+ snprintf(fingerprint, sizeof(fingerprint), "%s=%s", MESHLINK_MDNS_FINGERPRINT_KEY, meshlink_get_fingerprint(mesh, meshlink_get_node(mesh, mesh->name)));
/* Add the service for IPP */
int ret = 0;
- if ((ret = avahi_server_add_service(mesh->avahi_server, mesh->avahi_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, MESHLINK_MDNS_SERVICE_NAME, MESHLINK_MDNS_SERVICE_TYPE, NULL, NULL, mesh->myport ? atoi(mesh->myport) : 655, fingerprint, NULL)) < 0) {
+ if ((ret = avahi_server_add_service(mesh->avahi_server, mesh->avahi_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, /*MESHLINK_MDNS_SERVICE_NAME*/ mesh->name, MESHLINK_MDNS_SERVICE_TYPE, NULL, NULL, mesh->myport ? atoi(mesh->myport) : 655, fingerprint, NULL)) < 0) {
fprintf(stderr, "Failed to add _ipp._tcp service: %s\n", avahi_strerror(ret));
goto fail;
}
function we free it. If the server is terminated before
the callback function is called the server will free
the resolver for us. */
- //if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, server)))
- // fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(server)));
+ if (!(avahi_s_service_resolver_new(mesh->avahi_server, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, discovery_resolve_callback, mesh)))
+ fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
break;
case AVAHI_BROWSER_REMOVE:
/* Allocate a new server */
int error;
- mesh->avahi_server = avahi_server_new(avahi_simple_poll_get(mesh->avahi_poll), &config, discovery_server_callback, NULL, &error);
+ mesh->avahi_server = avahi_server_new(avahi_simple_poll_get(mesh->avahi_poll), &config, discovery_server_callback, mesh, &error);
/* Free the configuration data */
avahi_server_config_free(&config);