static int append_string_list(DBusMessage *message, AvahiStringList *txt) { DBusMessageIter iter, sub; int r = -1; AvahiStringList *p; assert(message); dbus_message_iter_init_append(message, &iter); /* Reverse the string list, so that we can pass it in-order to the server */ txt = avahi_string_list_reverse(txt); if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub)) goto fail; /* Assemble the AvahiStringList into an Array of Array of Bytes to send over dbus */ for (p = txt; p != NULL; p = p->next) { DBusMessageIter sub2; const uint8_t *data = p->text; if (!(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2)) || !(dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size)) || !(dbus_message_iter_close_container(&sub, &sub2))) goto fail; } if (!dbus_message_iter_close_container(&iter, &sub)) goto fail; r = 0; fail: /* Reverse the string list to the original state */ txt = avahi_string_list_reverse(txt); return r; }
bool CZeroconfAvahi::doForceReAnnounceService(const std::string& fcr_identifier) { bool ret = false; ScopedEventLoopBlock l_block(mp_poll); tServiceMap::iterator it = m_services.find(fcr_identifier); if (it != m_services.end() && it->second->mp_group) { // to force a reannounce on avahi its enough to reverse the txtrecord list it->second->mp_txt = avahi_string_list_reverse(it->second->mp_txt); // this will trigger the reannouncement if ((avahi_entry_group_update_service_txt_strlst(it->second->mp_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), it->second->m_name.c_str(), it->second->m_type.c_str(), NULL, it->second->mp_txt)) >= 0) ret = true; } return ret; }
AvahiDomainBrowser* avahi_domain_browser_new( AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *domain, AvahiDomainBrowserType btype, AvahiLookupFlags flags, AvahiDomainBrowserCallback callback, void *userdata) { AvahiDomainBrowser *db = NULL; DBusMessage *message = NULL, *reply = NULL; DBusError error; char *path; int32_t i_interface, i_protocol, bt; uint32_t u_flags; assert(client); assert(callback); dbus_error_init (&error); if (!avahi_client_is_connected(client)) { avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE); goto fail; } if (!domain) domain = ""; if (!(db = avahi_new (AvahiDomainBrowser, 1))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } db->ref = 1; db->client = client; db->callback = callback; db->userdata = userdata; db->path = NULL; db->interface = interface; db->protocol = protocol; db->static_browse_domains = NULL; db->defer_timeout = NULL; AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db); if (!(client->flags & AVAHI_CLIENT_IGNORE_USER_CONFIG)) { parse_environment(db); parse_domain_file(db); } db->static_browse_domains = avahi_string_list_reverse(db->static_browse_domains); if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "DomainBrowserNew"))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } i_interface = (int32_t) interface; i_protocol = (int32_t) protocol; u_flags = (uint32_t) flags; bt = btype; if (!(dbus_message_append_args( message, DBUS_TYPE_INT32, &i_interface, DBUS_TYPE_INT32, &i_protocol, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INT32, &bt, DBUS_TYPE_UINT32, &u_flags, DBUS_TYPE_INVALID))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } if (!(reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error)) || dbus_error_is_set(&error)) { avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); goto fail; } if (!dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error) || !path) { avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR); goto fail; } if (!(db->path = avahi_strdup(path))) { /* FIXME: We don't remove the object on the server side */ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } if (db->static_browse_domains && btype == AVAHI_DOMAIN_BROWSER_BROWSE) { struct timeval tv = { 0, 0 }; if (!(db->defer_timeout = client->poll_api->timeout_new(client->poll_api, &tv, defer_timeout_callback, db))) { avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY); goto fail; } } dbus_message_unref(message); dbus_message_unref(reply); return db; fail: if (dbus_error_is_set(&error)) { avahi_client_set_dbus_error(client, &error); dbus_error_free(&error); } if (db) avahi_domain_browser_free(db); if (message) dbus_message_unref(message); if (reply) dbus_message_unref(reply); return NULL; }