Exemplo n.º 1
0
void CZeroconfAvahi::groupCallback(AvahiEntryGroup *fp_group, AvahiEntryGroupState f_state, void * fp_data)
{
  CZeroconfAvahi* p_instance = static_cast<CZeroconfAvahi*>(fp_data);
  //store our thread ID and check for shutdown -> check details in destructor
  p_instance->m_thread_id = pthread_self();
  if (p_instance->m_shutdown)
  {
    avahi_threaded_poll_quit(p_instance->mp_poll);
    return;
  }

  switch (f_state)
  {
  case AVAHI_ENTRY_GROUP_ESTABLISHED :
    // The entry group has been established successfully
    CLog::Log(LOGDEBUG, "CZeroconfAvahi::groupCallback: Service successfully established");
    break;

  case AVAHI_ENTRY_GROUP_COLLISION :
  {
    //need to find the ServiceInfo struct for this group
    tServiceMap::iterator it = p_instance->m_services.begin();
    for(; it != p_instance->m_services.end(); ++it)
    {
      if (it->second->mp_group == fp_group)
        break;
    }
    if( it != p_instance->m_services.end() ) {
      char* alt_name = avahi_alternative_service_name( it->second->m_name.c_str() );
      it->second->m_name = alt_name;
      avahi_free(alt_name);
      CLog::Log(LOGNOTICE, "CZeroconfAvahi::groupCallback: Service name collision. Renamed to: %s", it->second->m_name.c_str());
      p_instance->addService(it->second, p_instance->mp_client);
    }
    break;
  }

  case AVAHI_ENTRY_GROUP_FAILURE:
    CLog::Log(LOGERROR, "CZeroconfAvahi::groupCallback: Entry group failure: %s ",
              (fp_group) ?
              avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(fp_group)))
              : "Unknown");
    //free the group and set to 0 so it may be added later
    if (fp_group)
    {
      //need to find the ServiceInfo struct for this group
      tServiceMap::iterator it = p_instance->m_services.begin();
      for (; it != p_instance->m_services.end(); ++it)
      {
        if (it->second->mp_group == fp_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;
          }
          break;
        }
      }
    }
    break;

  case AVAHI_ENTRY_GROUP_UNCOMMITED:
  case AVAHI_ENTRY_GROUP_REGISTERING:
  default:
    break;
  }
}
Exemplo n.º 2
0
void PublishAvahi::create_services(AvahiClient *c)
{
	char *n, r[128];
	int ret;
	assert(c);

	/* If this is the first time we're called, let's create a new
		* entry group if necessary */

	if (!group)
	{
		if (!(group = avahi_entry_group_new(c, entry_group_callback, this)))
		{
			logE << "avahi_entry_group_new() failed: " << avahi_strerror(avahi_client_errno(c)) << "\n";
			goto fail;
		}
	}
	/* If the group is empty (either because it was just created, or
		* because it was reset previously, add our entries.  */

	if (avahi_entry_group_is_empty(group))
	{
		logO << "Adding service '" << name << "'\n";

		/* Create some random TXT data */
		snprintf(r, sizeof(r), "random=%i", rand());

		/* We will now add two services and one subtype to the entry
			* group. The two services have the same name, but differ in
			* the service type (IPP vs. BSD LPR). Only services with the
			* same name should be put in the same entry group. */

		/* Add the service for IPP */
/*        if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_PUBLISH_UNIQUE, name, "_ipp._tcp", NULL, NULL, 651, "test=blah", r, NULL)) < 0)
		{

			if (ret == AVAHI_ERR_COLLISION)
				goto collision;

			fprintf(stderr, "Failed to add _ipp._tcp service: %s\n", avahi_strerror(ret));
			goto fail;
		}
*/
		/* Add the same service for BSD LPR */
		for (size_t n=0; n<services.size(); ++n)
		{
			if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, services[n].proto_, AvahiPublishFlags(0), name, services[n].name_.c_str(), NULL, NULL, services[n].port_, NULL)) < 0)
			{

				if (ret == AVAHI_ERR_COLLISION)
					goto collision;

				logE << "Failed to add " << services[n].name_ << " service: " << avahi_strerror(ret) << "\n";
				goto fail;
			}
		}

		/* Add an additional (hypothetic) subtype */
/*        if ((ret = avahi_entry_group_add_service_subtype(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags(0), name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0))
		{
			fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret));
			goto fail;
		}
*/
		/* Tell the server to register the service */
		if ((ret = avahi_entry_group_commit(group)) < 0)
		{
			logE << "Failed to commit entry group: " << avahi_strerror(ret) << "\n";
			goto fail;
		}
	}

	return;

collision:

	/* A service name collision with a local service happened. Let's
		* pick a new name */
	n = avahi_alternative_service_name(name);
	avahi_free(name);
	name = n;

	logO << "Service name collision, renaming service to '" << name << "'\n";

	avahi_entry_group_reset(group);

	create_services(c);
	return;

fail:
	avahi_simple_poll_quit(simple_poll);
}
Exemplo n.º 3
0
static void
create_service (AurAvahi * avahi)
{
  AurAvahiPrivate *priv = avahi->priv;
  int ret;

  do {
    if (priv->group == NULL) {
      priv->group =
          avahi_entry_group_new (priv->client, entry_group_callback, avahi);
      if (priv->group == NULL) {
        g_critical ("avahi_entry_group_new() failed: %s\n",
            avahi_strerror (avahi_client_errno (priv->client)));
        goto fail;
      }
    }

    /* If the group is empty (either because it was just created, or
     * because it was reset previously, add our entries.  */
    if (avahi_entry_group_is_empty (priv->group)) {
      g_message ("Adding service '%s' on port %d", priv->service_name, priv->port);

      ret =
          avahi_entry_group_add_service (priv->group, AVAHI_IF_UNSPEC,
          AVAHI_PROTO_UNSPEC, 0, priv->service_name, "_aurena._tcp", NULL,
          NULL, priv->port, NULL);
      if (ret < 0) {
        if (ret == AVAHI_ERR_COLLISION) {
          /* A service name collision with a local service happened. Let's
           * pick a new name */
          char *n = avahi_alternative_service_name (priv->service_name);
          g_free (priv->service_name);
          priv->service_name = n;
          g_message ("Service name collision, renaming service to '%s'\n",
              priv->service_name);
          avahi_entry_group_reset (priv->group);
          continue;
        } else {
          g_critical ("Failed to add _aurena._tcp service: %s",
              avahi_strerror (ret));
          goto fail;
        }
      }
#if 0
      /* Add an additional (hypothetic) subtype */
      if ((ret =
              avahi_entry_group_add_service_subtype (group, AVAHI_IF_UNSPEC,
                  AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL,
                  "_magic._sub._printer._tcp") < 0)) {
        fprintf (stderr,
            "Failed to add subtype _magic._sub._printer._tcp: %s\n",
            avahi_strerror (ret));
        goto fail;
      }
#endif

      if ((ret = avahi_entry_group_commit (priv->group)) < 0) {
        g_critical ("Failed to commit entry group: %s\n", avahi_strerror (ret));
      }
    }
    return;
  } while (TRUE);

fail:
  return;
}
Exemplo n.º 4
0
void AvahiSession::RenameService()
{
	char* name = avahi_alternative_service_name(mServiceName);
	avahi_free(mServiceName);
	mServiceName = name;
}
Exemplo n.º 5
0
void announcer::async_announce(const aware::contact& contact,
                               async_announce_handler h)
{
    assert(ptr != 0);

    handler = h;

    const AvahiPublishFlags flags = AvahiPublishFlags(0);
    const aware::contact::endpoint_type endpoint = contact.get_endpoint();
    // Use all network interfaces
    const AvahiIfIndex interface_index = AVAHI_IF_UNSPEC;
    // Use only a specific protocol
    const AvahiProtocol protocol =
        contact.get_endpoint().protocol() == boost::asio::ip::tcp::v6()
        ? AVAHI_PROTO_INET6
        : AVAHI_PROTO_INET;
    std::string name = contact.get_name();
    // FIXME: from contact (endpoint.protocol())
    std::string type = "_" + contact.get_type() + "._tcp";
    // Use .local
    const char *domain = 0;
    // Host name
    boost::asio::ip::address address = endpoint.address();
    std::string host = address.is_unspecified()
        ? "" // Use default host name
        : address.to_string();

    property_list properties;
    if (!contact.get_properties().empty())
    {
        properties = contact.get_properties();
        if (properties == 0)
        {
            boost::system::error_code error(boost::system::errc::not_enough_memory,
                                            boost::system::system_category());
            handler(error);
            return;
        }
    }

    while (true)
    {
        int rc = avahi_entry_group_add_service_strlst(ptr,
                                                      interface_index,
                                                      protocol,
                                                      flags,
                                                      name.c_str(),
                                                      type.c_str(),
                                                      domain,
                                                      host.empty() ? 0 : host.c_str(),
                                                      endpoint.port(),
                                                      properties);
        if (rc == AVAHI_ERR_COLLISION)
        {
            char *alternative = avahi_alternative_service_name(name.c_str());
            name = alternative;
            avahi_free(alternative);
        }
        else if (rc != AVAHI_OK)
        {
            handler(convert_error(rc));
            return;
        }
        else
        {
            break;
        }
    }
    commit(ptr);
}
	void CommunicationManager::createServices(AvahiClient *c) {
		char *n, r[128];
		int ret;

		/* If this is the first time we're called, let's create a new
		 * entry group if necessary */

		if (!this->group) {
			if (!(group = avahi_entry_group_new(c,
					CommunicationManager::entryGroupCallback, NULL))) {
				cout << "avahi_entry_group_new() failed: " <<
						avahi_strerror(avahi_client_errno(c)) << endl;
				avahi_simple_poll_quit(simplePoll);
				return;
			}
		}

		/* If the group is empty (either because it was just created, or
		 * because it was reset previously, add our entries.  */

		if (avahi_entry_group_is_empty(group)) {
			cout << "Adding service '" << name << "'" << endl;;

			/* Create some random TXT data */
			snprintf(r, sizeof(r), "random=%i", rand());

			/* We will now add two services and one subtype to the entry
			 * group. The two services have the same name, but differ in
			 * the service type (IPP vs. BSD LPR). Only services with the
			 * same name should be put in the same entry group. */

			/* Add the service for GingaMultimodalEvent*/
			if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC,
					AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, name,
					"_GingaMultimodalEvent._tcp", NULL, NULL, 1234, "test=blah",
					r, NULL)) < 0) {

				if (ret == AVAHI_ERR_COLLISION) {
					/* A service name collision with a local service happened.
					 * Let's pick a new name */
					n = avahi_alternative_service_name(name);
					avahi_free(name);
					name = n;

					cout << "Service name collision, renaming service to '" <<
							name << "'" << endl;

					avahi_entry_group_reset(group);
					createServices(c);
					return;
				}

				cout << "Failed to add _GingaMultimodalEvent._tcp service: " <<
						avahi_strerror(ret) << endl;
				avahi_simple_poll_quit(simplePoll);
				return;
			}

			/* Tell the server to register the service */
			if ((ret = avahi_entry_group_commit(group)) < 0) {
				cout << "Failed to commit entry group: " << avahi_strerror(ret)
						<< endl;
				avahi_simple_poll_quit(simplePoll);
			}
		}
	}
Exemplo n.º 7
0
static void create_services(AvahiClient *c) {
    char *n, r[128];
    int ret;
    assert(c);

    /* If this is the first time we're called, let's create a new
     * entry group if necessary */

    if (!group)
        if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
            fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
            goto fail;
        }

    /* If the group is empty (either because it was just created, or
     * because it was reset previously, add our entries.  */

    if (avahi_entry_group_is_empty(group)) {
        fprintf(stderr, "Adding service '%s'\n", name);

        /* Create some random TXT data */
        snprintf(r, sizeof(r), "random=%i", rand());

        /* We will now add two services and one subtype to the entry
         * group. The two services have the same name, but differ in
         * the service type (IPP vs. BSD LPR). Only services with the
         * same name should be put in the same entry group. */

        /* Add the service for IPP */
        if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, name, "_faustcompiler._tcp", NULL, NULL, 7777, "test=blah", r, NULL)) < 0) {

            if (ret == AVAHI_ERR_COLLISION)
                goto collision;

            fprintf(stderr, "Failed to add _faustcompiler._tcp service: %s\n", avahi_strerror(ret));
            goto fail;
        }

        /* Tell the server to register the service */
        if ((ret = avahi_entry_group_commit(group)) < 0) {
            fprintf(stderr, "Failed to commit entry group: %s\n", avahi_strerror(ret));
            goto fail;
        }
    }

    return;

collision:

    /* A service name collision with a local service happened. Let's
     * pick a new name */
    n = avahi_alternative_service_name(name);
    avahi_free(name);
    name = n;

    fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);

    avahi_entry_group_reset(group);

    create_services(c);
    return;

fail:
    avahi_simple_poll_quit(simple_poll);
}
Exemplo n.º 8
0
static void create_services(AvahiClient *c) {
    char *n, r[128];
    int ret;
    AvahiProtocol protocol;
    assert(c);

    /* If this is the first time we're called, let's create a new
     * entry group if necessary */

    if (!group)
        if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
            logging_printf( LOGGING_ERROR, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
            goto fail;
        }

    /* If the group is empty (either because it was just created, or
     * because it was reset previously, add our entries.  */

    if (avahi_entry_group_is_empty(group)) {
        logging_printf(LOGGING_INFO, "Adding service '%s.%s'\n", sd_name_copy, sd_service_copy );

        /* Create some random TXT data */
        snprintf(r, sizeof(r), "random=%i", rand());

	if( use_ipv4 && use_ipv6 )
	{
		protocol = AVAHI_PROTO_UNSPEC;
	} else if( use_ipv4 ) {
		protocol = AVAHI_PROTO_INET;
	} else {
		protocol = AVAHI_PROTO_INET6;
	}

        if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, protocol, 0,  sd_name_copy , sd_service_copy , NULL, NULL,  sd_port, "test=blah", r, NULL)) < 0) {

            if (ret == AVAHI_ERR_COLLISION)
                goto collision;

            logging_printf(LOGGING_ERROR, "Failed to add %s service: %s\n", sd_service_copy,avahi_strerror(ret));
            goto fail;
        }

        /* Tell the server to register the service */
        if ((ret = avahi_entry_group_commit(group)) < 0) {
            logging_printf(LOGGING_ERROR, "Failed to commit entry group: %s\n", avahi_strerror(ret));
            goto fail;
        }
    }

    return;

collision:

    /* A service name collision with a local service happened. Let's
     * pick a new name */
    n = avahi_alternative_service_name( sd_name_copy );
    avahi_free(sd_name_copy);
    sd_name_copy = n;

    logging_printf(LOGGING_WARN, "Service name collision, renaming service to '%s'\n", sd_name_copy );

    avahi_entry_group_reset(group);

    create_services(c);
    return;

fail:
    avahi_threaded_poll_quit(threaded_poll);
}
Exemplo n.º 9
0
static void 
create_services(AvahiClient *c) 
{
  char *n;
  char *path = NULL;
  int ret;
  assert(c);

  /* If this is the first time we're called, let's create a new
   * entry group if necessary */

  if (!group)
    if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
      tvhlog(LOG_ERR, "AVAHI",
	     "avahi_enty_group_new() failed: %s", 
	     avahi_strerror(avahi_client_errno(c)));
      goto fail;
    }

  /* If the group is empty (either because it was just created, or
   * because it was reset previously, add our entries.  */

  if (avahi_entry_group_is_empty(group)) {
     tvhlog(LOG_DEBUG, "AVAHI", "Adding service '%s'", name);

    /* Add the service for HTSP */
    if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, 
					     AVAHI_PROTO_UNSPEC, 0, name, 
					     "_htsp._tcp", NULL, NULL,tvheadend_htsp_port,
					     NULL)) < 0) {

      if (ret == AVAHI_ERR_COLLISION)
	goto collision;

      tvhlog(LOG_ERR, "AVAHI",
	     "Failed to add _htsp._tcp service: %s", 
	     avahi_strerror(ret));
      goto fail;
    }

    if (tvheadend_webroot) {
      path = malloc(strlen(tvheadend_webroot) + 6);
      sprintf(path, "path=%s", tvheadend_webroot);
    } else {
      path = strdup("path=/");
    }

    /* Add the service for HTTP */
    if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, 
					     AVAHI_PROTO_UNSPEC, 0, name, 
					     "_http._tcp", NULL, NULL, tvheadend_webui_port,
					     path,
					     NULL)) < 0) {

      if (ret == AVAHI_ERR_COLLISION)
	goto collision;

      tvhlog(LOG_ERR, "AVAHI",
	     "Failed to add _http._tcp service: %s", 
	     avahi_strerror(ret));
      goto fail;
    }

    /* Tell the server to register the service */
    if ((ret = avahi_entry_group_commit(group)) < 0) {
      tvhlog(LOG_ERR, "AVAHI",
	     "Failed to commit entry group: %s", 
	     avahi_strerror(ret));
      goto fail;
    }
  }

  free(path);
  return;

 collision:

  /* A service name collision with a local service happened. Let's
   * pick a new name */
  n = avahi_alternative_service_name(name);
  avahi_free(name);
  name = n;

  tvhlog(LOG_ERR, "AVAHI",
	 "Service name collision, renaming service to '%s'", name);

  avahi_entry_group_reset(group);

  create_services(c);
  return;

 fail:
  free(path);
}
Exemplo n.º 10
0
void Publisher::nextName() {
	char *newName = avahi_alternative_service_name(info.getServiceName().c_str());
	info.setServiceName(std::string(newName));
	avahi_free(newName);
}