void SBCFromTXT(CPhidgetSBCHandle sbc, uint16_t txtLen, const char *txtRecord)
{
	char *hversion = NULL, *txtver = NULL;
	
	uint8_t valLen = 0;
	const char *valPtr = NULL;
	
	//txt version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "txtvers", &valLen))) return;
	if(!(txtver = malloc(valLen+1))) return;
	ZEROMEM(txtver, valLen+1);
	memcpy(txtver, valPtr, valLen);
	sbc->txtver = (short)strtol(txtver, NULL, 10);
	free(txtver);
	
	//Firmware version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "fversion", &valLen))) return;
	if(valLen > 12) valLen = 12;
	memcpy(sbc->fversion, valPtr, valLen);
	sbc->fversion[valLen] = '\0';
	
	//Hardware version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "hversion", &valLen))) return;
	if(!(hversion = malloc(valLen+1))) return;
	ZEROMEM(hversion, valLen+1);
	memcpy(hversion, valPtr, valLen);
	sbc->hversion = (short)strtol(hversion, NULL, 10);
	free(hversion);
	
	// things added in version 2 of the txt
	if(sbc->txtver >= 2)
	{
		//Hostname
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "hostname", &valLen))) return;
		if(valLen > 128) valLen = 128;
		memcpy(sbc->hostname, valPtr, valLen);
		sbc->hostname[valLen] = '\0';
	}
	
	// things added in version 3 of the txt
	if(sbc->txtver >= 3)
	{
		//Device Name
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return;
		if(valLen > 128) valLen = 128;
		memcpy(sbc->deviceName, valPtr, valLen);
		sbc->deviceName[valLen] = '\0';
	}
	else
	{
		sprintf(sbc->deviceName, "PhidgetSBC");
	}
}
Ejemplo n.º 2
0
STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value)
{
	std::string		keyUTF8;
	const void	*	rawValue;
	uint8_t			rawValueLen;
	BOOL			ok	= TRUE;
	HRESULT			hr	= S_OK;

	VariantClear( value );

	if ( m_byteArray.size() > 0 )
	{
		ok = BSTRToUTF8( key, keyUTF8 );
		require_action( ok, exit, hr = S_FALSE );

		rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen );

		if ( rawValue )
		{
			ok = ByteArrayToVariant( rawValue, rawValueLen, value );
			require_action( ok, exit, hr = S_FALSE );
		}
	}

exit:

	return hr;
}
Ejemplo n.º 3
0
void 
resolveCB(DNSServiceRef sdRef, 
          DNSServiceFlags flags, 
          uint32_t interfaceIndex, 
          DNSServiceErrorType errorCode, 
          const char *fullname, 
          const char *hosttarget, 
          uint16_t port, 
          uint16_t txtLen, 
          const char *txtRecord, 
          void *context)
{
  player_sd_dev_t* sddev = (player_sd_dev_t*)context;
  const char* value;
  uint8_t value_len;
  char* colon;
  char buf[PLAYER_SD_TXT_MAXLEN];

  // Handle resolution result
  if(errorCode == kDNSServiceErr_NoError)
  {
    // Fill in the address info
    memset(sddev->hostname,0,sizeof(sddev->hostname));
    strncpy(sddev->hostname,hosttarget,sizeof(sddev->hostname)-1);
    sddev->robot = port;
    if(!(value = (const char*)TXTRecordGetValuePtr(txtLen,
                                                   txtRecord,
                                                   PLAYER_SD_DEVICE_TXTNAME,
                                                   &value_len)))
    {
      PLAYER_ERROR1("Failed to find TXT info for service %s\n", sddev->name);
      sddev->addr_fail = 1;
      return;
    }
    if(!(colon = strchr(value,':')) ||
       ((colon-value) <= 0) ||
       ((value_len - (colon-value+1)) <= 0))
    {
      PLAYER_ERROR2("Failed to parse TXT info \"%s\" for service %s\n",
                    value, sddev->name);
      sddev->addr_fail = 1;
      return;
    }
    memset(buf,0,sizeof(buf));
    strncpy(buf,value,(colon-value));
    sddev->interf = str_to_interf(buf);

    memset(buf,0,sizeof(buf));
    strncpy(buf,colon+1,(value_len-(colon-value+1)));
    sddev->index = atoi(buf);

    sddev->addr_valid = 1;
  }
  else
  {
    // Something went wrong.
    sddev->addr_fail = 1;
  }
}
Ejemplo n.º 4
0
OSStatus
CPrinterSetupWizardSheet::ParseTextRecord( Service * service, Queue * q, uint16_t inTXTSize, const char * inTXT )
{
	check( service );
	check( q );

	// <rdar://problem/3946587> Use TXTRecord APIs declared in dns_sd.h
	
	bool			qtotalDefined	= false;
	const void	*	val;
	char			buf[256];
	uint8_t			len;
	OSStatus		err				= kNoErr;

	// <rdar://problem/3987680> Default to queue "lp"

	q->name = L"lp";

	// <rdar://problem/4003710> Default pdl key to be "application/postscript"

	q->pdl = L"application/postscript";

	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "rp", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->name );
		require_noerr( err, exit );
	}
	
	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "pdl", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->pdl );
		require_noerr( err, exit );
	}
	
	if ( ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_mfg", &len ) ) != NULL ) ||
	     ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_manufacturer", &len ) ) != NULL ) )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->usb_MFG );
		require_noerr( err, exit );
	}
	
	if ( ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_mdl", &len ) ) != NULL ) ||
	     ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "usb_model", &len ) ) != NULL ) )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->usb_MDL );
		require_noerr( err, exit );
	}

	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "ty", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->description );
		require_noerr( err, exit );
	}
		
	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "product", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->product );
		require_noerr( err, exit );
	}

	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "note", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		err = UTF8StringToStringObject( buf, q->location );
		require_noerr( err, exit );
	}

	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "qtotal", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		service->qtotal = (unsigned short) atoi( buf );
		qtotalDefined = true;
	}

	if ( ( val = TXTRecordGetValuePtr( inTXTSize, inTXT, "priority", &len ) ) != NULL )
	{
		// Stringize val ( doesn't have trailing '\0' yet )

		memcpy( buf, val, len );
		buf[len] = '\0';

		q->priority = atoi( buf );
	}

	// <rdar://problem/4124524> Was this printer discovered via OS X Printer Sharing?

	if ( TXTRecordContainsKey( inTXTSize, inTXT, "printer-state" ) || TXTRecordContainsKey( inTXTSize, inTXT, "printer-type" ) )
	{
		service->printer->isSharedFromOSX = true;
	}

exit:

	// The following code is to fix a problem with older HP 
	// printers that don't include "qtotal" in their text
	// record.  We'll check to see if the q->name is "TEXT"
	// and if so, we're going to modify it to be "lp" so
	// that we don't use the wrong queue

	if ( !err && !qtotalDefined && ( q->name == L"TEXT" ) )
	{
		q->name = "lp";
	}

	return err;
}
static void
resolve_callback(
    DNSServiceRef       sdRef,		/* I - Service reference */
    DNSServiceFlags     flags,		/* I - Data flags */
    uint32_t            interfaceIndex,	/* I - Interface */
    DNSServiceErrorType errorCode,	/* I - Error, if any */
    const char          *fullName,	/* I - Full service name */
    const char          *hostTarget,	/* I - Hostname */
    uint16_t            port,		/* I - Port number (network byte order) */
    uint16_t            txtLen,		/* I - Length of TXT record data */
    const unsigned char *txtRecord,	/* I - TXT record data */
    void                *context)	/* I - Device */
{
  char		temp[257],		/* TXT key value */
		uri[1024];		/* Printer URI */
  const void	*value;			/* Value from TXT record */
  uint8_t	valueLen;		/* Length of value */
  cups_device_t	*device = (cups_device_t *)context;
					/* Device */


#ifdef DEBUG
  fprintf(stderr, "\rresolve_callback(sdRef=%p, flags=%x, "
                  "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", "
		  "hostTarget=\"%s\", port=%d, txtLen=%u, txtRecord=%p, "
		  "context=%p)\n",
          sdRef, flags, interfaceIndex, errorCode,
	  fullName ? fullName : "(null)", hostTarget ? hostTarget : "(null)",
	  ntohs(port), txtLen, txtRecord, context);
#endif /* DEBUG */

 /*
  * Only process "add" data...
  */

  if (errorCode != kDNSServiceErr_NoError)
    return;

  device->got_resolve = 1;
  device->host        = strdup(hostTarget);
  device->port        = ntohs(port);

 /*
  * Extract the "remote printer" key from the TXT record and save the URI...
  */

  if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp",
                                    &valueLen)) != NULL)
  {
    if (((char *)value)[0] == '/')
    {
     /*
      * "rp" value (incorrectly) has a leading slash already...
      */

      memcpy(temp, value, valueLen);
      temp[valueLen] = '\0';
    }
    else
    {
     /*
      * Convert to resource by concatenating with a leading "/"...
      */

      temp[0] = '/';
      memcpy(temp + 1, value, valueLen);
      temp[valueLen + 1] = '\0';
    }
  }
  else
  {
   /*
    * Default "rp" value is blank, mapping to a path of "/"...
    */

    temp[0] = '/';
    temp[1] = '\0';
  }

  if (!strncmp(temp, "/printers/", 10))
    device->cups_shared = -1;

  httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp",
                  NULL, hostTarget, ntohs(port), temp);
  device->uri = strdup(uri);
  device->rp  = strdup(temp);

  if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "ty",
                                    &valueLen)) != NULL)
  {
    memcpy(temp, value, valueLen);
    temp[valueLen] = '\0';

    device->ty = strdup(temp);
  }

  if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "pdl",
                                    &valueLen)) != NULL)
  {
    memcpy(temp, value, valueLen);
    temp[valueLen] = '\0';

    device->pdl = strdup(temp);
  }

  if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "printer-type",
                                    &valueLen)) != NULL)
    device->cups_shared = 1;

  if (device->cups_shared)
    fprintf(stderr, "\rIgnoring CUPS printer %s\n", uri);
  else
    fprintf(stderr, "\rFound IPP printer %s\n", uri);

  progress();
}
Ejemplo n.º 6
0
LONG	ExplorerBarWindow::OnResolve( ResolveInfo * resolve )
{
	CString				url;
	uint8_t *			path;
	uint8_t				pathSize;
	char *				pathPrefix;
	CString				username;
	CString				password;
	
	
	check( resolve );
		
	// Get login info if needed.
	
	if( resolve->handler->needsLogin )
	{
		LoginDialog		dialog;
		
		if( !dialog.GetLogin( username, password ) )
		{
			goto exit;
		}
	}
	
	// If the HTTP TXT record is a "path=" entry, use it as the resource path. Otherwise, use "/".
	
	pathPrefix = "";
	if( strcmp( resolve->handler->type, "_http._tcp" ) == 0 )
	{
		uint8_t	*	txtData;
		uint16_t	txtLen;	

		resolve->txt.GetData( &txtData, &txtLen );

		path	 = (uint8_t*) TXTRecordGetValuePtr(txtLen, txtData, kTXTRecordKeyPath, &pathSize);

		if (path == NULL)
		{
			path = (uint8_t*) "";
			pathSize = 1;
		}
	}
	else
	{
		path		= (uint8_t *) "";
		pathSize	= 1;
	}

	// Build the URL in the following format:
	//
	// <urlScheme>[<username>[:<password>]@]<name/ip>[<path>]

	url.AppendFormat( TEXT( "%S" ), resolve->handler->urlScheme );					// URL Scheme
	if( username.GetLength() > 0 )
	{
		url.AppendFormat( TEXT( "%s" ), username );									// Username
		if( password.GetLength() > 0 )
		{
			url.AppendFormat( TEXT( ":%s" ), password );							// Password
		}
		url.AppendFormat( TEXT( "@" ) );
	}
	
	url += resolve->host;															// Host
	url.AppendFormat( TEXT( ":%d" ), resolve->port );								// :Port
	url.AppendFormat( TEXT( "%S" ), pathPrefix );									// Path Prefix ("/" or empty).
	url.AppendFormat( TEXT( "%.*S" ), (int) pathSize, (char *) path );				// Path (possibly empty).
	
	// Tell Internet Explorer to go to the URL.
	
	check( mOwner );
	mOwner->GoToURL( url );

exit:
	delete resolve;
	return( 0 );
}
void PhidFromTXT(CPhidgetHandle phid, uint16_t txtLen, const char *txtRecord)
{
	int i = 0;
	short txtver;
	
	uint8_t valLen = 0;
	const char *valPtr = NULL;
	
	//txt version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "txtvers", &valLen))) return;
	txtver = (short)strtol(valPtr, NULL, 10);
	
	//Serial Number
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "serial", &valLen))) return;
	phid->serialNumber = strtol(valPtr, NULL, 10);
	phid->specificDevice = PTRUE;
	
	//version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "version", &valLen))) return;
	phid->deviceVersion = strtol(valPtr, NULL, 10);
	
	//label
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "label", &valLen))) return;
	if(valLen > 10) valLen = 10;
	memcpy(phid->label, valPtr, valLen);
	phid->label[valLen] = '\0';
	
	//server_id
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "server_id", &valLen))) return;
	free(phid->networkInfo->zeroconf_server_id);
	if(!(phid->networkInfo->zeroconf_server_id = malloc(valLen+1))) return;
	ZEROMEM(phid->networkInfo->zeroconf_server_id, valLen+1);
	memcpy(phid->networkInfo->zeroconf_server_id, valPtr, valLen);
	
	// things added in version 2 of the txt
	if(txtver >= 2)
	{
		//Device ID
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "id", &valLen))) return;
		phid->deviceIDSpec = strtol(valPtr, NULL, 10);
		
		for(i = 1;i<PHIDGET_DEVICE_COUNT;i++)
			if(phid->deviceIDSpec == Phid_Device_Def[i].pdd_sdid) break;
		phid->deviceDef = &Phid_Device_Def[i];
		phid->attr = Phid_Device_Def[i].pdd_attr;
		
		//Device Class
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "class", &valLen))) return;
		phid->deviceID = strtol(valPtr, NULL, 10);
		phid->deviceType = Phid_DeviceName[phid->deviceID];
	}
	//Old version uses string searching, but some devices have the same name with different IDs
	else
	{
		char *name = NULL;
		char *type = NULL;
		
		//name
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return;
		if(!(name = malloc(valLen+1))) return;
		ZEROMEM(name, valLen+1);
		memcpy(name, valPtr, valLen);
		for(i = 0;i<PHIDGET_DEVICE_COUNT;i++)
		{
			if(!strcmp(name, Phid_Device_Def[i].pdd_name))
			{
				phid->deviceIDSpec = Phid_Device_Def[i].pdd_sdid;
				phid->deviceDef = &Phid_Device_Def[i];
				phid->attr = Phid_Device_Def[i].pdd_attr;
				break;
			}
		}
		free(name);
		
		//type
		if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "type", &valLen))) return;
		if(!(type = malloc(valLen+1))) return;
		ZEROMEM(type, valLen+1);
		memcpy(type, valPtr, valLen);
		phid->deviceID = phidget_type_to_id(type);
		phid->deviceType = Phid_DeviceName[phid->deviceID];
		free(type);
	}
	
	phid->networkInfo->mdns = PTRUE;
	
}
Ejemplo n.º 8
0
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
    const char *r;
    TXTRecordRef ref;
    uint8_t l;
    const void *p;
    char k[256];

    TXTRecordCreate(&ref, 0, NULL);

    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "foo", 7, "lennart");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "waldo", 5, "rocks");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "quux", 9, "the_house");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "yeah", 0, NULL);
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "waldo", 6, "rocked");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordRemoveValue(&ref, "foo");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordRemoveValue(&ref, "waldo");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "kawumm", 6, "bloerb");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "one", 1, "1");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "two", 1, "2");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "three", 1, "3");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    assert(TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "two"));
    assert(!TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "four"));

    r = TXTRecordGetValuePtr(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "kawumm", &l);

    hexdump(r, l);

    assert(TXTRecordGetCount(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref)) == 6);

    TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 2, sizeof(k), k, &l, &p);

    fprintf(stderr, "key=<%s>\n", k);

    hexdump(p, l);

    assert(TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 20, sizeof(k), k, &l, &p) == kDNSServiceErr_Invalid);

    TXTRecordDeallocate(&ref);
}
Ejemplo n.º 9
0
void PhidFromTXT(CPhidgetHandle phid, uint16_t txtLen, const char *txtRecord)
{
	int i = 0;
	char *type = NULL;
	char *serial = NULL;
	char *version = NULL;
	char *name = NULL;

	uint8_t valLen = 0;
	const char *valPtr = NULL;

	//Serial Number
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "serial", &valLen))) return;
	if(!(serial = malloc(valLen+1))) return;
	ZEROMEM(serial, valLen+1);
	memcpy(serial, valPtr, valLen);
	phid->serialNumber = strtol(serial, NULL, 10);
	phid->specificDevice = PTRUE;
	free(serial);

	//name
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "name", &valLen))) return;
	if(!(name = malloc(valLen+1))) return;
	ZEROMEM(name, valLen+1);
	memcpy(name, valPtr, valLen);
	for(i = 0;i<PHIDGET_DEVICE_COUNT;i++)
	{
		if(!strcmp(name, Phid_DeviceSpecificName[i]))
		{
			phid->deviceIDSpec = i;
			phid->attr = Phid_Device_Def[i].pdd_attr;
			break;
		}
	}
	free(name);

	//type
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "type", &valLen))) return;
	if(!(type = malloc(valLen+1))) return;
	ZEROMEM(type, valLen+1);
	memcpy(type, valPtr, valLen);
	phid->deviceID = phidget_type_to_id(type);
	phid->deviceType = Phid_DeviceName[phid->deviceID];
	free(type);

	//version
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "version", &valLen))) return;
	if(!(version = malloc(valLen+1))) return;
	ZEROMEM(version, valLen+1);
	memcpy(version, valPtr, valLen);
	phid->deviceVersion = strtol(version, NULL, 10);
	free(version);

	//label
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "label", &valLen))) return;
	if(valLen > 10) valLen = 10;
	memcpy(phid->label, valPtr, valLen);
	phid->label[valLen] = '\0';

	//server_id
	if(!(valPtr = TXTRecordGetValuePtr(txtLen, txtRecord, "server_id", &valLen))) return;
	if(!(phid->networkInfo->zeroconf_server_id = malloc(valLen+1))) return;
	ZEROMEM(phid->networkInfo->zeroconf_server_id, valLen+1);
	memcpy(phid->networkInfo->zeroconf_server_id, valPtr, valLen);

	phid->networkInfo->mdns = PTRUE;

}