Bonjour/MYBonjourService.m
changeset 36 5165944a89b3
parent 28 732576fa8a0d
child 43 aab592ac36fc
     1.1 --- a/Bonjour/MYBonjourService.m	Mon Apr 27 09:03:56 2009 -0700
     1.2 +++ b/Bonjour/MYBonjourService.m	Tue May 05 14:46:42 2009 -0700
     1.3 @@ -30,36 +30,41 @@
     1.4  - (id) initWithName: (NSString*)serviceName
     1.5                 type: (NSString*)type
     1.6               domain: (NSString*)domain
     1.7 -          interface: (uint32)interfaceIndex
     1.8 +          interface: (UInt32)interfaceIndex
     1.9  {
    1.10 +    Assert(serviceName);
    1.11 +    Assert(type);
    1.12 +    Assert(domain);
    1.13      self = [super init];
    1.14      if (self != nil) {
    1.15          _name = [serviceName copy];
    1.16          _type = [type copy];
    1.17          _domain = [domain copy];
    1.18 +        _fullName = [[[self class] fullNameOfService: _name ofType: _type inDomain: _domain] retain];
    1.19          _interfaceIndex = interfaceIndex;
    1.20      }
    1.21      return self;
    1.22  }
    1.23  
    1.24  - (void) dealloc {
    1.25 -    [_name release];
    1.26 -    [_type release];
    1.27 -    [_domain release];
    1.28 -    [_hostname release];
    1.29      [_txtQuery stop];
    1.30      [_txtQuery release];
    1.31      [_addressLookup stop];
    1.32      [_addressLookup release];
    1.33 +    [_name release];
    1.34 +    [_type release];
    1.35 +    [_domain release];
    1.36 +    [_fullName release];
    1.37 +    [_hostname release];
    1.38      [super dealloc];
    1.39  }
    1.40  
    1.41  
    1.42 -@synthesize name=_name, type=_type, domain=_domain, interfaceIndex=_interfaceIndex;
    1.43 +@synthesize name=_name, type=_type, domain=_domain, fullName=_fullName, interfaceIndex=_interfaceIndex;
    1.44  
    1.45  
    1.46  - (NSString*) description {
    1.47 -    return $sprintf(@"%@['%@'.%@%@]", self.class,_name,_type,_domain);
    1.48 +    return $sprintf(@"%@[%@]", self.class,self.fullName);
    1.49  }
    1.50  
    1.51  
    1.52 @@ -101,18 +106,13 @@
    1.53  
    1.54  
    1.55  - (void) priv_finishResolve {
    1.56 -    // If I haven't finished my resolve yet, run it synchronously now so I can return a valid value:
    1.57 +    // If I haven't finished my resolve yet, run it *synchronously* now so I can return a valid value:
    1.58      if (!_startedResolve )
    1.59          [self start];
    1.60      if (self.serviceRef)
    1.61          [self waitForReply];
    1.62  }    
    1.63  
    1.64 -- (NSString*) fullName {
    1.65 -    if (!_fullName) [self priv_finishResolve];
    1.66 -    return _fullName;
    1.67 -}
    1.68 -
    1.69  - (NSString*) hostname {
    1.70      if (!_hostname) [self priv_finishResolve];
    1.71      return _hostname;
    1.72 @@ -129,9 +129,12 @@
    1.73  
    1.74  
    1.75  - (NSDictionary*) txtRecord {
    1.76 -    // If I haven't started my resolve yet, start it now. (_txtRecord will be nil till it finishes.)
    1.77 -    if (!_startedResolve)
    1.78 -        [self start];
    1.79 +    if (!_txtQuery) {
    1.80 +        _txtQuery = [[MYBonjourQuery alloc] initWithBonjourService: self 
    1.81 +                                                        recordType: kDNSServiceType_TXT];
    1.82 +        _txtQuery.continuous = YES;
    1.83 +        [_txtQuery start];
    1.84 +    }
    1.85      return _txtRecord;
    1.86  }
    1.87  
    1.88 @@ -172,32 +175,24 @@
    1.89  
    1.90  
    1.91  #pragma mark -
    1.92 -#pragma mark FULLNAME/HOSTNAME/PORT RESOLUTION:
    1.93 +#pragma mark HOSTNAME/PORT RESOLUTION:
    1.94  
    1.95  
    1.96 -- (void) priv_resolvedFullName: (NSString*)fullName
    1.97 -                      hostname: (NSString*)hostname
    1.98 +- (void) priv_resolvedHostname: (NSString*)hostname
    1.99                            port: (uint16_t)port
   1.100                       txtRecord: (NSData*)txtData
   1.101  {
   1.102 -    LogTo(Bonjour, @"%@: fullname='%@', hostname=%@, port=%u, txt=%u bytes", 
   1.103 -          self, fullName, hostname, port, txtData.length);
   1.104 +    LogTo(Bonjour, @"%@: hostname=%@, port=%u, txt=%u bytes", 
   1.105 +          self, hostname, port, txtData.length);
   1.106  
   1.107      // Don't call a setter method to set these properties: the getters are synchronous, so
   1.108      // I might already be blocked in a call to one of them, in which case creating a KV
   1.109      // notification could cause trouble...
   1.110 -    _fullName = fullName.copy;
   1.111      _hostname = hostname.copy;
   1.112      _port = port;
   1.113      
   1.114      // TXT getter is async, though, so I can use a setter to announce the data's availability:
   1.115      [self setTxtData: txtData];
   1.116 -    
   1.117 -    // Now that I know my full name, I can start a persistent query to track the TXT:
   1.118 -    _txtQuery = [[MYBonjourQuery alloc] initWithBonjourService: self 
   1.119 -                                                    recordType: kDNSServiceType_TXT];
   1.120 -    _txtQuery.continuous = YES;
   1.121 -    [_txtQuery start];
   1.122  }
   1.123  
   1.124  
   1.125 @@ -215,29 +210,26 @@
   1.126      MYBonjourService *service = context;
   1.127      @try{
   1.128          //LogTo(Bonjour, @"resolveCallback for %@ (err=%i)", service,errorCode);
   1.129 -        if (errorCode) {
   1.130 -            [service setError: errorCode];
   1.131 -        } else {
   1.132 +        if (!errorCode) {
   1.133              NSData *txtData = nil;
   1.134              if (txtRecord)
   1.135                  txtData = [NSData dataWithBytes: txtRecord length: txtLen];
   1.136 -            [service priv_resolvedFullName: [NSString stringWithUTF8String: fullname]
   1.137 -                                  hostname: [NSString stringWithUTF8String: hosttarget]
   1.138 +            [service priv_resolvedHostname: [NSString stringWithUTF8String: hosttarget]
   1.139                                        port: ntohs(port)
   1.140                                   txtRecord: txtData];
   1.141          }
   1.142      }catchAndReport(@"MYBonjourResolver query callback");
   1.143 +    [service gotResponse: errorCode];
   1.144  }
   1.145  
   1.146  
   1.147 -- (DNSServiceRef) createServiceRef {
   1.148 +- (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
   1.149      _startedResolve = YES;
   1.150 -    DNSServiceRef serviceRef = NULL;
   1.151 -    self.error = DNSServiceResolve(&serviceRef, 0,
   1.152 -                                   _interfaceIndex, 
   1.153 -                                   _name.UTF8String, _type.UTF8String, _domain.UTF8String,
   1.154 -                                   &resolveCallback, self);
   1.155 -    return serviceRef;
   1.156 +    return DNSServiceResolve(sdRefPtr,
   1.157 +                             kDNSServiceFlagsShareConnection,
   1.158 +                             _interfaceIndex, 
   1.159 +                             _name.UTF8String, _type.UTF8String, _domain.UTF8String,
   1.160 +                             &resolveCallback, self);
   1.161  }
   1.162  
   1.163