Bonjour/MYBonjourQuery.m
changeset 29 59689fbdcf77
child 31 1d6924779df7
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Bonjour/MYBonjourQuery.m	Tue Apr 28 10:36:28 2009 -0700
     1.3 @@ -0,0 +1,135 @@
     1.4 +//
     1.5 +//  MYBonjourQuery.m
     1.6 +//  MYNetwork
     1.7 +//
     1.8 +//  Created by Jens Alfke on 4/24/09.
     1.9 +//  Copyright 2009 Jens Alfke. All rights reserved.
    1.10 +//
    1.11 +
    1.12 +#import "MYBonjourQuery.h"
    1.13 +#import "MYBonjourService.h"
    1.14 +#import "Test.h"
    1.15 +#import "Logging.h"
    1.16 +#import "ExceptionUtils.h"
    1.17 +#import <dns_sd.h>
    1.18 +
    1.19 +
    1.20 +static NSString* kRecordTypeNames[] = {
    1.21 +    @"0",
    1.22 +    @"A", //         = 1,      /* Host address. */
    1.23 +    @"NS", //        = 2,      /* Authoritative server. */
    1.24 +    @"MD", //        = 3,      /* Mail destination. */
    1.25 +    @"MF", //        = 4,      /* Mail forwarder. */
    1.26 +    @"CNAME", //     = 5,      /* Canonical name. */
    1.27 +    @"SOA", //       = 6,      /* Start of authority zone. */
    1.28 +    @"MB", //        = 7,      /* Mailbox domain name. */
    1.29 +    @"MG", //        = 8,      /* Mail group member. */
    1.30 +    @"MR", //        = 9,      /* Mail rename name. */
    1.31 +    @"NULL", //      = 10,     /* Null resource record. */
    1.32 +    @"WKS", //       = 11,     /* Well known service. */
    1.33 +    @"PTR", //       = 12,     /* Domain name pointer. */
    1.34 +    @"HINFO", //     = 13,     /* Host information. */
    1.35 +    @"MINFO", //     = 14,     /* Mailbox information. */
    1.36 +    @"MX", //        = 15,     /* Mail routing information. */
    1.37 +    @"TXT" //       = 16,     /* One or more text strings (NOT "zero or more..."). */
    1.38 +    // this isn't a complete list; it just includes the most common ones.
    1.39 +    // For the full list, see the "kDNSServiceType_..." constants in <dns_sd.h>.
    1.40 +};
    1.41 +
    1.42 +@interface MYBonjourQuery ()
    1.43 +@property (copy) NSData *recordData;
    1.44 +@end
    1.45 +
    1.46 +
    1.47 +@implementation MYBonjourQuery
    1.48 +
    1.49 +
    1.50 +- (id) initWithBonjourService: (MYBonjourService*)service recordType: (uint16_t)recordType;
    1.51 +{
    1.52 +    self = [super init];
    1.53 +    if (self) {
    1.54 +        _bonjourService = service;
    1.55 +        _recordType = recordType;
    1.56 +    }
    1.57 +    return self;
    1.58 +}
    1.59 +
    1.60 +- (void) dealloc
    1.61 +{
    1.62 +    [_recordData release];
    1.63 +    [super dealloc];
    1.64 +}
    1.65 +
    1.66 +
    1.67 +- (NSString*) description
    1.68 +{
    1.69 +    NSString *typeName;
    1.70 +    if (_recordType <= 16)
    1.71 +        typeName = kRecordTypeNames[_recordType];
    1.72 +    else
    1.73 +        typeName = $sprintf(@"%u", _recordType);
    1.74 +    return $sprintf(@"%@[%@ /%@]", self.class, _bonjourService.name, typeName);
    1.75 +}
    1.76 +
    1.77 +
    1.78 +@synthesize recordData=_recordData;
    1.79 +
    1.80 +
    1.81 +- (void) priv_gotRecordBytes: (const void *)rdata
    1.82 +                      length: (uint16_t)rdlen
    1.83 +                        type: (uint16_t)rrtype
    1.84 +                         ttl: (uint32_t)ttl
    1.85 +                       flags: (DNSServiceFlags)flags
    1.86 +{
    1.87 +    NSData *data = [NSData dataWithBytes: rdata length: rdlen];
    1.88 +    if (!$equal(data,_recordData)) {
    1.89 +        if (data.length <= 16)
    1.90 +            LogTo(Bonjour,@"%@ = %@", self, data);
    1.91 +        else
    1.92 +            LogTo(Bonjour,@"%@ = %@...", self, [data subdataWithRange: NSMakeRange(0,16)]);
    1.93 +        self.recordData = data;
    1.94 +    }
    1.95 +    [_bonjourService queryDidUpdate: self];
    1.96 +}
    1.97 +
    1.98 +
    1.99 +static void queryCallback( DNSServiceRef                       DNSServiceRef,
   1.100 +                           DNSServiceFlags                     flags,
   1.101 +                           uint32_t                            interfaceIndex,
   1.102 +                           DNSServiceErrorType                 errorCode,
   1.103 +                           const char                          *fullname,
   1.104 +                           uint16_t                            rrtype,
   1.105 +                           uint16_t                            rrclass,
   1.106 +                           uint16_t                            rdlen,
   1.107 +                           const void                          *rdata,
   1.108 +                           uint32_t                            ttl,
   1.109 +                           void                                *context)
   1.110 +{
   1.111 +    @try{
   1.112 +        //LogTo(Bonjour, @"queryCallback for %@ (err=%i)", context,errorCode);
   1.113 +        if (errorCode)
   1.114 +            [(MYBonjourQuery*)context setError: errorCode];
   1.115 +        else
   1.116 +            [(MYBonjourQuery*)context priv_gotRecordBytes: rdata
   1.117 +                                                      length: rdlen
   1.118 +                                                        type: rrtype
   1.119 +                                                         ttl: ttl
   1.120 +                                                       flags: flags];
   1.121 +    }catchAndReport(@"MYBonjourResolver query callback");
   1.122 +}
   1.123 +
   1.124 +
   1.125 +- (DNSServiceRef) createServiceRef {
   1.126 +    DNSServiceRef serviceRef = NULL;
   1.127 +    const char *fullName = _bonjourService.fullName.UTF8String;
   1.128 +    if (fullName)
   1.129 +        self.error = DNSServiceQueryRecord(&serviceRef, 0, 
   1.130 +                                           _bonjourService.interfaceIndex, 
   1.131 +                                           fullName,
   1.132 +                                           _recordType, kDNSServiceClass_IN, 
   1.133 +                                           &queryCallback, self);
   1.134 +    return serviceRef;
   1.135 +}
   1.136 +
   1.137 +
   1.138 +@end