// Copyright 2015 The Weave Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "examples/provider/avahi_client.h" #include #include #include namespace weave { namespace examples { namespace { void GroupCallback(AvahiEntryGroup* g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void* userdata) { CHECK_NE(state, AVAHI_ENTRY_GROUP_COLLISION); CHECK_NE(state, AVAHI_ENTRY_GROUP_FAILURE); } std::string GetId() { return "WEAVE" + std::to_string(gethostid()); } } // namespace AvahiClient::AvahiClient() { thread_pool_.reset(avahi_threaded_poll_new()); CHECK(thread_pool_); LOG(INFO) << "connecting to avahi-daemon"; int ret = 0; client_.reset(avahi_client_new(avahi_threaded_poll_get(thread_pool_.get()), {}, nullptr, this, &ret)); CHECK(client_) << "failed to connect to avahi-daemon: " << avahi_strerror(ret); avahi_threaded_poll_start(thread_pool_.get()); group_.reset(avahi_entry_group_new(client_.get(), GroupCallback, nullptr)); CHECK(group_) << avahi_strerror(avahi_client_errno(client_.get())) << ". Check avahi-daemon configuration"; } AvahiClient::~AvahiClient() { if (thread_pool_) avahi_threaded_poll_stop(thread_pool_.get()); } void AvahiClient::PublishService(const std::string& service_type, uint16_t port, const std::vector& txt) { LOG(INFO) << "Publishing service"; CHECK(group_); // Create txt record. std::unique_ptr txt_list{ nullptr, &avahi_string_list_free}; if (!txt.empty()) { std::vector txt_vector_ptr; for (const auto& i : txt) txt_vector_ptr.push_back(i.c_str()); txt_list.reset(avahi_string_list_new_from_array(txt_vector_ptr.data(), txt_vector_ptr.size())); CHECK(txt_list); } int ret = 0; if (prev_port_ == port && prev_type_ == service_type) { ret = avahi_entry_group_update_service_txt_strlst( group_.get(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, {}, GetId().c_str(), service_type.c_str(), nullptr, txt_list.get()); CHECK_GE(ret, 0) << avahi_strerror(ret); } else { prev_port_ = port; prev_type_ = service_type; avahi_entry_group_reset(group_.get()); CHECK(avahi_entry_group_is_empty(group_.get())); ret = avahi_entry_group_add_service_strlst( group_.get(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, {}, GetId().c_str(), service_type.c_str(), nullptr, nullptr, port, txt_list.get()); CHECK_GE(ret, 0) << avahi_strerror(ret); ret = avahi_entry_group_commit(group_.get()); CHECK_GE(ret, 0) << avahi_strerror(ret); } } void AvahiClient::StopPublishing(const std::string& service_name) { CHECK(group_); avahi_entry_group_reset(group_.get()); } } // namespace examples } // namespace weave