Example #1
0
CZeroconfAvahi::~CZeroconfAvahi()
{
  CLog::Log(LOGDEBUG, "CZeroconfAvahi::~CZeroconfAvahi() Going down! cleaning up...");

  if (mp_poll)
  {
    //normally we would stop the avahi thread here and do our work, but
    //it looks like this does not work -> www.avahi.org/ticket/251
    //so instead of calling
    //avahi_threaded_poll_stop(mp_poll);
    //we set m_shutdown=true, post an event and wait for it to stop itself
    struct timeval tv = { 0, 0 }; //TODO: does tv survive the thread?
    AvahiTimeout* lp_timeout;
    {
      ScopedEventLoopBlock l_block(mp_poll);
      const AvahiPoll* cp_apoll = avahi_threaded_poll_get(mp_poll);
      m_shutdown = true;
      lp_timeout = cp_apoll->timeout_new(cp_apoll,
                                         &tv,
                                         shutdownCallback,
                                         this);
    }

    //now wait for the thread to stop
    assert(m_thread_id);
    pthread_join(m_thread_id, NULL);
    avahi_threaded_poll_get(mp_poll)->timeout_free(lp_timeout);
  }

  //free the client (frees all browsers, groups, ...)
  if (mp_client)
    avahi_client_free(mp_client);
  if (mp_poll)
    avahi_threaded_poll_free(mp_poll);
}
Example #2
0
bool CZeroconfAvahi::doRemoveService(const std::string& fcr_ident)
{
  CLog::Log(LOGDEBUG, "CZeroconfAvahi::doRemoveService named: %s", fcr_ident.c_str());
  ScopedEventLoopBlock l_block(mp_poll);
  tServiceMap::iterator it = m_services.find(fcr_ident);
  if (it == m_services.end())
  {
    return false;
  }
  
  if (it->second->mp_group)
  {
    avahi_entry_group_free(it->second->mp_group);
    it->second->mp_group = 0;
  }
  
  if(it->second->mp_txt)
  {
    avahi_string_list_free(it->second->mp_txt);
    it->second->mp_txt = NULL;
  }
  
  m_services.erase(it);
  return true;
}
Example #3
0
void CZeroconfAvahi::doStop()
{
  ScopedEventLoopBlock l_block(mp_poll);
  for(tServiceMap::const_iterator it = m_services.begin(); it != m_services.end(); ++it)
  {
    if (it->second->mp_group)
    {
      avahi_entry_group_free(it->second->mp_group);
      it->second->mp_group = 0;
    }
    
    if(it->second->mp_txt)
    {
      avahi_string_list_free(it->second->mp_txt);
      it->second->mp_txt = NULL;
    }
  }
  m_services.clear();
}
Example #4
0
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;
}
Example #5
0
bool CZeroconfAvahi::doPublishService(const std::string& fcr_identifier,
                              const std::string& fcr_type,
                              const std::string& fcr_name,
                              unsigned int f_port,
                              std::map<std::string, std::string> txt)
{
  CLog::Log(LOGDEBUG, "CZeroconfAvahi::doPublishService identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port);

  ScopedEventLoopBlock l_block(mp_poll);
  tServiceMap::iterator it = m_services.find(fcr_identifier);
  if (it != m_services.end())
  {
    //fcr_identifier exists, no update functionality yet, so exit
    return false;
  }

  //txt records to AvahiStringList
  AvahiStringList *txtList = NULL;
  for(std::map<std::string, std::string>::iterator it=txt.begin(); it!=txt.end(); it++)
  {
    txtList = avahi_string_list_add_pair(txtList, it->first.c_str(), it->second.c_str());
  }

  //create service info and add it to service map
  tServiceMap::mapped_type p_service_info(new CZeroconfAvahi::ServiceInfo(fcr_type, fcr_name, f_port, txtList));
  it = m_services.insert(it, std::make_pair(fcr_identifier, p_service_info));

  //if client is already running, directly try to add the new service
  if ( mp_client && avahi_client_get_state(mp_client) ==  AVAHI_CLIENT_S_RUNNING )
  {
    //client's already running, add this new service
    addService(p_service_info, mp_client);
  }
  else
  {
    CLog::Log(LOGDEBUG, "CZeroconfAvahi::doPublishService: client not running, queued for publishing");
  }
  return true;
}