jens@27: // jens@27: // MYDNSService.h jens@27: // MYNetwork jens@27: // jens@27: // Created by Jens Alfke on 4/23/09. jens@27: // Copyright 2009 Jens Alfke. All rights reserved. jens@27: // jens@27: jens@27: #import jens@27: #import jens@31: @class MYDNSConnection; jens@27: jens@27: jens@27: /** Abstract superclass for services based on DNSServiceRefs, such as MYPortMapper. */ jens@27: @interface MYDNSService : NSObject jens@27: { jens@27: @private jens@31: BOOL _usePrivateConnection; jens@31: MYDNSConnection *_connection; jens@27: struct _DNSServiceRef_t *_serviceRef; jens@27: CFSocketRef _socket; jens@27: CFRunLoopSourceRef _socketSource; jens@27: SInt32 _error; jens@31: BOOL _continuous, _gotResponse; jens@27: } jens@27: jens@28: /** If NO (the default), the service will stop after it gets a result. jens@28: If YES, it will continue to run until stopped. */ jens@28: @property BOOL continuous; jens@28: jens@27: /** Starts the service. jens@27: Returns immediately; you can find out when the service actually starts (or fails to) jens@27: by observing the isOpen and error properties. jens@27: It's very unlikely that this call itself will fail (return NO). If it does, it jens@27: probably means that the mDNSResponder process isn't working. */ jens@28: - (BOOL) start; jens@27: jens@28: /** Stops the service. */ jens@28: - (void) stop; jens@27: jens@50: /** Has the service started up? */ jens@50: @property (readonly) BOOL isRunning; jens@50: jens@27: jens@27: /** The error status, a DNSServiceErrorType enum; nonzero if something went wrong. jens@27: This property is KV observable. */ jens@28: @property int32_t error; jens@27: jens@31: jens@31: /** Utility to construct a service's full name. */ jens@31: + (NSString*) fullNameOfService: (NSString*)serviceName jens@31: ofType: (NSString*)type jens@31: inDomain: (NSString*)domain; jens@31: jens@31: jens@32: /** @name Protected jens@32: * Methods for use only by subclasses jens@32: */ jens@32: //@{ jens@31: jens@32: /** Normally, all DNSService objects use a shared IPC connection to the mDNSResponder daemon. jens@32: If an instance wants to use its own connection instead, it can set this property to YES before jens@32: it starts. If it does so, it must NOT set the kDNSServiceFlagsShareConnection flag when creating jens@32: its underlying DNSService. jens@32: This functionality is only provided because MYBonjourRegistration needs it -- there's a bug jens@32: that prevents DNSServiceUpdateRecord from working with a shared connection. */ jens@31: @property BOOL usePrivateConnection; jens@31: jens@27: /** Subclass must implement this abstract method to create a new DNSServiceRef. jens@27: This method is called by -open. jens@31: The implementation MUST pass the given sdRefPtr directly to the DNSService function jens@31: that creates the new ref, without setting it to NULL first. jens@32: It MUST also set the kDNSServiceFlagsShareConnection flag, unless it's already set the jens@32: usePrivateConnection property. */ jens@31: - (int32_t/*DNSServiceErrorType*/) createServiceRef: (struct _DNSServiceRef_t**)sdRefPtr; jens@31: jens@31: /** Subclass's callback must call this method after doing its own work. jens@31: This method will update the error state, and will stop the service if it's not set to be jens@31: continuous. */ jens@31: - (void) gotResponse: (int32_t/*DNSServiceErrorType*/)errorCode; jens@27: jens@32: /** The underlying DNSServiceRef. This will be NULL except while the service is running. */ jens@28: @property (readonly) struct _DNSServiceRef_t* serviceRef; jens@28: jens@28: /** Same as -stop, but does not clear the error property. jens@28: (The stop method actually calls this first.) */ jens@28: - (void) cancel; jens@28: jens@28: /** Block until a message is received from the daemon. jens@28: This will cause the service's callback (defined by the subclass) to be invoked. jens@28: @return YES if a message is received, NO on error (or if the service isn't started) */ jens@28: - (BOOL) waitForReply; jens@27: jens@32: //@} jens@31: jens@27: @end jens@31: jens@31: jens@31: jens@31: jens@31: @interface MYDNSConnection : NSObject jens@31: { jens@31: struct _DNSServiceRef_t* _connectionRef; jens@31: CFSocketRef _socket; jens@31: CFRunLoopSourceRef _runLoopSource; jens@31: } jens@31: jens@31: + (MYDNSConnection*) sharedConnection; jens@31: - (id) initWithServiceRef: (struct _DNSServiceRef_t *)serviceRef; jens@31: @property (readonly) struct _DNSServiceRef_t* connectionRef; jens@31: - (BOOL) processResult; jens@31: - (void) close; jens@31: jens@31: @end