Name

cyg_mdns_service_register — Register set of services

Synopsis

#include <mdns.h>

cyg_bool cyg_mdns_service_register(cyg_uint8 count, const cyg_mdns_service *vector);

Description

This function registers the set of service(s) in the supplied vector array. count gives the number of vector entries. If any of the referenced services were already registered for a different service then an error is returned and none of the services in the supplied vector are registered. If there are no free (CDL CYGNUM_MDNS_NUM_SERVICE_VECTORS controlled) vector slots available then an error is returned.

A unique 3-tuple will be used to identify services registered. The tuple consists of the UTF-8 service and proto strings, plus the 16-bit service port number. A simple descriptor structure is defined to hold these values, along with the “Weight” and “Priority” values (which are not considered part of the unique identification). It is the responsibility of the caller to ensure the lifetime of the string objects referenced, and that they are immutable when registered with the mDNS Responder; similarly that the passed service descriptors in vector are immutable.

If all of the vector tuples match an already registered vector then the held pointer is updated. This allows the application to supply new “Priority” and “Weight” values.

Or to put it another way, you can update the “Priority” and “Weight” values for a service only if you pass in a vector that replaces all the same services as the vector that was used to previously register that service.

[Note]Note

Furthermore, since the API requires that the registered vector is immutable this updating of “Weight” and “Priority” can only happen when the supplied vector pointer is different. This ensures that the application client code is not tempted to update the registered services data (which should be immutable) under-the-feet of the mDNS world.

We do not need to return a handle when registering services since the service tuple is used to uniquely identify each service.

Normally, for simple systems, the application will just have a single cyg_mdns_service_register() call with the fixed, hardwired, vector of service descriptors to be announced for the application.

The cyg_mdns_service structure is used to define a service tuple. It is the responsibility of the client application to ensure valid data is passed to the mDNS sub-system.

typedef struct cyg_mdns_service {
  const struct cyg_mdns_service_identity *id;
  const cyg_uint8 *default_label;
  const cyg_mdns_txt_record *txt_vector;
  cyg_uint16 priority;
  cyg_uint16 weight;
  cyg_uint8 txt_count;
} cyg_mdns_service;

The service descriptor id field is a pointer to a cyg_mdns_service_identity structure descriptor.

typedef struct cyg_mdns_service_identity {
  const cyg_uint8 *service;
  const cyg_uint8 *proto;
  cyg_uint16 port;
} cyg_mdns_service_identity;

The service and proto fields are pointers to a vector containing the 1-byte label length followed by 1..MDNS_MAX_LABEL UTF-8 characters. The client must ensure that the labels are prefixed with the '_' character. Defining these vectors using constant literal strings in C is unlikely to be appropriate as strings will include an additional NUL terminator character.

[Note]Note

For simplicity, and to avoid having to maintain an internal database, it is the responsibility of the client application to ensure the correct service and protocol label assignments.

The mDNS system exports the cyg_mdns_label_tcp and cyg_mdns_label_udp labels since they are common and are likely to be needed by most applications. They also avoid the cost associated with the developer having to provide duplicate string definitions in the application when defining their service vectors. In fact, for DNS-SD conforming worlds, only the “_tcp” and “_udp” protocol specifiers should be used.

If the txt_vector pointer is NULL then whenever a TXT field is required then a single 1-byte NUL character TXT response will be provided. If it is non-NULL then the txt_count field specifies the number of cyg_mdns_txt_record TXT table entries provided.

typedef struct cyg_mdns_txt_record {
  const cyg_uint8 *table;
  cyg_uint8 len;
} cyg_mdns_txt_record;

The table field of each TXT descriptor references a sequence of 1-byte length followed by 1…MDNS_MAX_LABEL UTF-8 character strings. The len field specifies the overall individual table length. The mDNS standard does NOT require the table to be terminated by a zero-length (NUL) indicator, since the TXT resource record contains the length. The following is an incomplete service example, but does show the provision of two TXT records (though, in reality, this simple example would be merged into a single TXT entry). Due to the use of the type cyg_uint8 for the len field individual TXT tables are limited to a maximum of 255-bytes in length. Care must also be taken if registering services with multiple, large, TXT tables that the resulting data will fit within the memory available to the mDNS packet transmission code.

static const cyg_uint8 txttab_example_1[] = {
  0x09,'t','x','t','v','e','r','s','=','1',
  0x0B,'O','p','t','i','o','n','s','=','o','n','e'
};

static const cyg_uint8 txttab_example_2[] = {
  0x09,'F','e','a','t','u','r','e','O','n'
};

static const cyg_mdns_txt_record txt_records[] = {
  {
    .table = txttab_example_1,
    .len = sizeof(txttab_example_1)
  },
  {
    .table = txttab_example_2,
    .len = sizeof(txttab_example_2)
  }
};

static const cyg_mdns_service services[] = {
  {
    .txt_vector = txt_records,
    .txt_count = (sizeof(txt_records) / sizeof(txt_records[0])),
    // ... other fields as required
  }
};

Return value

Boolean true on success, and false on error.