bool CZeroconfBrowserAvahi::doResolveService ( CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout )
{
  {
    //wait for lock on event-loop to schedule resolving
    ScopedEventLoopBlock lock ( mp_poll );
    //avahi can only resolve already discovered services, as it needs info from there
    tDiscoveredServices::const_iterator it = m_discovered_services.find( fr_service );
    if ( it == m_discovered_services.end() )
    {
      CLog::Log ( LOGERROR, "CZeroconfBrowserAvahi::doResolveService called with undiscovered service, resolving is NOT possible" );
      return false;
    }
    //start resolving
    m_resolving_service = fr_service;
    m_resolved_event.Reset();
    if ( !avahi_service_resolver_new ( mp_client, it->second.interface, it->second.protocol,
      it->first.GetName().c_str(), it->first.GetType().c_str(), it->first.GetDomain().c_str(),
                                       AVAHI_PROTO_UNSPEC, AvahiLookupFlags ( 0 ), resolveCallback, this ) )
    {
      CLog::Log ( LOGERROR, "CZeroconfBrowserAvahi::doResolveService Failed to resolve service '%s': %s\n", it->first.GetName().c_str(),
                  avahi_strerror ( avahi_client_errno ( mp_client ) ) );
      return false;
    }
  } // end of this block releases lock of eventloop

  //wait for resolve to return or timeout
  m_resolved_event.WaitMSec(f_timeout*1000);
  {
    ScopedEventLoopBlock lock ( mp_poll );
    fr_service = m_resolving_service;
    return (!fr_service.GetIP().empty());
  }
}
bool CZeroconfBrowserAndroid::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout)
{
  jni::CJNINsdServiceInfo service;
  service.setServiceName(fr_service.GetName());
  service.setServiceType(fr_service.GetType());
  
  CZeroconfBrowserAndroidResolve resolver;
  m_manager.resolveService(service, resolver);
  
  if (!resolver.m_resolutionDone.WaitMSec(f_timeout * 1000))
  {
    CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve Timeout error");
    return false;
  }

  if (resolver.m_errorCode != -1)
  {
    CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve returned (error = %ld)", resolver.m_errorCode);
    return false;
  }
   
  fr_service.SetHostname(resolver.m_retServiceInfo.getHost().getHostName());
  fr_service.SetIP(resolver.m_retServiceInfo.getHost().getHostAddress());
  fr_service.SetPort(resolver.m_retServiceInfo.getPort());
  
  CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap; 
  jni::CJNISet<jni::jhstring> txtKey = resolver.m_retServiceInfo.getAttributes().keySet();
  jni::CJNIIterator<jni::jhstring> it = txtKey.iterator();
  while (it.hasNext())
  {
    jni::jhstring k = it.next();
    jni::jhbyteArray v = resolver.m_retServiceInfo.getAttributes().get(k);
  
    std::string key = jni::jcast<std::string>(k);
    std::vector<char> vv = jni::jcast<std::vector<char>>(v);
    std::string value = std::string(vv.begin(), vv.end());

    CLog::Log(LOGDEBUG, "ZeroconfBrowserAndroid: TXT record %s = %s (%d)", key.c_str(), value.c_str(), vv.size());
    
    recordMap.insert(std::make_pair(key, value));
  }
  fr_service.SetTxtRecords(recordMap);
  return (!fr_service.GetIP().empty());
}
Example #3
0
bool CZeroconfBrowserMDNS::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout)
{
  DNSServiceErrorType err;
  DNSServiceRef sdRef = NULL;
  
  //start resolving
  m_resolving_service = fr_service;
  m_resolved_event.Reset();

  err = DNSServiceResolve(&sdRef, 0, kDNSServiceInterfaceIndexAny, fr_service.GetName(), fr_service.GetType(), fr_service.GetDomain(), ResolveCallback, this);

  if( err != kDNSServiceErr_NoError )
  {
    if (sdRef)
      DNSServiceRefDeallocate(sdRef);

    CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: DNSServiceResolve returned (error = %ld)", (int) err);
    return false;
  }

  err = DNSServiceProcessResult(sdRef);

  if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, "ZeroconfBrowserMDNS::doResolveService DNSServiceProcessResult returned (error = %ld)", (int) err);

  if (sdRef)
    DNSServiceRefDeallocate(sdRef);

#if defined(HAS_MDNS_EMBEDDED)
  // when using the embedded mdns service the call to DNSServiceProcessResult
  // above will not block until the resolving was finished - instead we have to
  // wait for resolve to return or timeout  
  m_resolved_event.WaitMSec(f_timeout * 1000);
#endif //HAS_MDNS_EMBEDDED
  fr_service = m_resolving_service;
  return (!fr_service.GetIP().empty());
}
Example #4
0
bool CZeroconfBrowserMDNS::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout)
{
  DNSServiceErrorType err;
  DNSServiceRef sdRef = NULL;
  
  //start resolving
  m_resolving_service = fr_service;
  m_resolved_event.Reset();

  err = DNSServiceResolve(&sdRef, 0, kDNSServiceInterfaceIndexAny, fr_service.GetName(), fr_service.GetType(), fr_service.GetDomain(), ResolveCallback, this);

  if( err != kDNSServiceErr_NoError )
  {
    if (sdRef)
      DNSServiceRefDeallocate(sdRef);

    CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: DNSServiceResolve returned (error = %ld)", (int) err);
    return false;
  }

  err = DNSServiceProcessResult(sdRef);

  if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, "ZeroconfBrowserMDNS::doResolveService DNSServiceProcessResult returned (error = %ld)", (int) err);

#if defined(HAS_MDNS_EMBEDDED)
  // when using the embedded mdns service the call to DNSServiceProcessResult
  // above will not block until the resolving was finished - instead we have to
  // wait for resolve to return or timeout  
  m_resolved_event.WaitMSec(f_timeout * 1000);
#endif //HAS_MDNS_EMBEDDED
  fr_service = m_resolving_service;

  if (sdRef)
    DNSServiceRefDeallocate(sdRef);

  // resolve the hostname
  if (!fr_service.GetHostname().empty())
  {
    CStdString strIP;

    // use mdns resolving
    m_addrinfo_event.Reset();
    sdRef = NULL;

    err = DNSServiceGetAddrInfo(&sdRef, 0, kDNSServiceInterfaceIndexAny, kDNSServiceProtocol_IPv4, fr_service.GetHostname(), GetAddrInfoCallback, this);

    if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: DNSServiceGetAddrInfo returned (error = %ld)", (int) err);

    err = DNSServiceProcessResult(sdRef);

    if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, "ZeroconfBrowserMDNS::doResolveService DNSServiceProcessResult returned (error = %ld)", (int) err);

#if defined(HAS_MDNS_EMBEDDED)
    // when using the embedded mdns service the call to DNSServiceProcessResult
    // above will not block until the resolving was finished - instead we have to
    // wait for resolve to return or timeout
    // give it 2 secs for resolving (resolving in mdns is cached and queued
    // in timeslices off 1 sec
    m_addrinfo_event.WaitMSec(2000);
#endif //HAS_MDNS_EMBEDDED
    fr_service = m_resolving_service;

    if (sdRef)
      DNSServiceRefDeallocate(sdRef);

    // fall back to our resolver
    if (fr_service.GetIP().empty())
    {
      CLog::Log(LOGWARNING, "ZeroconfBrowserMDNS: Could not resolve hostname %s falling back to CDNSNameCache", fr_service.GetHostname().c_str());
      if (CDNSNameCache::Lookup(fr_service.GetHostname(), strIP))
        fr_service.SetIP(strIP);
      else
        CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: Could not resolve hostname %s", fr_service.GetHostname().c_str());
    }
  }

  return (!fr_service.GetIP().empty());
}