jens@28: // jens@28: // MYBonjourQuery.m jens@28: // MYNetwork jens@28: // jens@28: // Created by Jens Alfke on 4/24/09. jens@28: // Copyright 2009 Jens Alfke. All rights reserved. jens@28: // jens@28: jens@28: #import "MYBonjourQuery.h" jens@28: #import "MYBonjourService.h" jens@28: #import "Test.h" jens@28: #import "Logging.h" jens@28: #import "ExceptionUtils.h" jens@28: #import jens@28: jens@28: jens@28: static NSString* kRecordTypeNames[] = { jens@28: @"0", jens@28: @"A", // = 1, /* Host address. */ jens@28: @"NS", // = 2, /* Authoritative server. */ jens@28: @"MD", // = 3, /* Mail destination. */ jens@28: @"MF", // = 4, /* Mail forwarder. */ jens@28: @"CNAME", // = 5, /* Canonical name. */ jens@28: @"SOA", // = 6, /* Start of authority zone. */ jens@28: @"MB", // = 7, /* Mailbox domain name. */ jens@28: @"MG", // = 8, /* Mail group member. */ jens@28: @"MR", // = 9, /* Mail rename name. */ jens@28: @"NULL", // = 10, /* Null resource record. */ jens@28: @"WKS", // = 11, /* Well known service. */ jens@28: @"PTR", // = 12, /* Domain name pointer. */ jens@28: @"HINFO", // = 13, /* Host information. */ jens@28: @"MINFO", // = 14, /* Mailbox information. */ jens@28: @"MX", // = 15, /* Mail routing information. */ jens@28: @"TXT" // = 16, /* One or more text strings (NOT "zero or more..."). */ jens@28: // this isn't a complete list; it just includes the most common ones. jens@28: // For the full list, see the "kDNSServiceType_..." constants in . jens@28: }; jens@28: jens@28: @interface MYBonjourQuery () jens@28: @property (copy) NSData *recordData; jens@28: @end jens@28: jens@28: jens@28: @implementation MYBonjourQuery jens@28: jens@28: jens@28: - (id) initWithBonjourService: (MYBonjourService*)service recordType: (uint16_t)recordType; jens@28: { jens@28: self = [super init]; jens@28: if (self) { jens@28: _bonjourService = service; jens@28: _recordType = recordType; jens@28: } jens@28: return self; jens@28: } jens@28: jens@28: - (void) dealloc jens@28: { jens@28: [_recordData release]; jens@28: [super dealloc]; jens@28: } jens@28: jens@28: jens@28: - (NSString*) description jens@28: { jens@28: NSString *typeName; jens@28: if (_recordType <= 16) jens@28: typeName = kRecordTypeNames[_recordType]; jens@28: else jens@28: typeName = $sprintf(@"%u", _recordType); jens@28: return $sprintf(@"%@[%@ /%@]", self.class, _bonjourService.name, typeName); jens@28: } jens@28: jens@28: jens@28: @synthesize recordData=_recordData; jens@28: jens@28: jens@28: - (void) priv_gotRecordBytes: (const void *)rdata jens@28: length: (uint16_t)rdlen jens@28: type: (uint16_t)rrtype jens@28: ttl: (uint32_t)ttl jens@28: flags: (DNSServiceFlags)flags jens@28: { jens@28: NSData *data = [NSData dataWithBytes: rdata length: rdlen]; jens@28: if (!$equal(data,_recordData)) { jens@28: if (data.length <= 16) jens@28: LogTo(Bonjour,@"%@ = %@", self, data); jens@28: else jens@28: LogTo(Bonjour,@"%@ = %@...", self, [data subdataWithRange: NSMakeRange(0,16)]); jens@28: self.recordData = data; jens@28: } jens@28: [_bonjourService queryDidUpdate: self]; jens@28: } jens@28: jens@28: jens@28: static void queryCallback( DNSServiceRef DNSServiceRef, jens@28: DNSServiceFlags flags, jens@28: uint32_t interfaceIndex, jens@28: DNSServiceErrorType errorCode, jens@28: const char *fullname, jens@28: uint16_t rrtype, jens@28: uint16_t rrclass, jens@28: uint16_t rdlen, jens@28: const void *rdata, jens@28: uint32_t ttl, jens@28: void *context) jens@28: { jens@28: @try{ jens@28: //LogTo(Bonjour, @"queryCallback for %@ (err=%i)", context,errorCode); jens@28: if (errorCode) jens@28: [(MYBonjourQuery*)context setError: errorCode]; jens@28: else jens@28: [(MYBonjourQuery*)context priv_gotRecordBytes: rdata jens@28: length: rdlen jens@28: type: rrtype jens@28: ttl: ttl jens@28: flags: flags]; jens@28: }catchAndReport(@"MYBonjourResolver query callback"); jens@28: } jens@28: jens@28: jens@28: - (DNSServiceRef) createServiceRef { jens@28: DNSServiceRef serviceRef = NULL; jens@28: const char *fullName = _bonjourService.fullName.UTF8String; jens@28: if (fullName) jens@28: self.error = DNSServiceQueryRecord(&serviceRef, 0, jens@28: _bonjourService.interfaceIndex, jens@28: fullName, jens@28: _recordType, kDNSServiceClass_IN, jens@28: &queryCallback, self); jens@28: return serviceRef; jens@28: } jens@28: jens@28: jens@28: @end