2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 Change History (most recent first):
28 Revision 1.2 2004/05/20 17:43:18 cheshire
29 Fix invalid UTF-8 characters in file
31 Revision 1.1 2004/04/30 16:32:34 rpantos
35 This file declares and implements DNSSD, the central Java factory class
36 for doing DNS Service Discovery. It includes the mostly-abstract public
37 interface, as well as the Apple* implementation subclasses.
40 - implement network interface mappings
45 package com
.apple
.dnssd
;
49 DNSSD provides access to DNS Service Discovery features of ZeroConf networking.<P>
51 It is a factory class that is used to invoke registration and discovery-related
52 operations. Most operations are non-blocking; clients are called back through an interface
53 with the result of an operation. Callbacks are made from a separate worker thread.<P>
55 For example, in this program<P>
57 class MyClient implements BrowseListener {
58 void lookForWebServers() {
59 myBrowser = DNSSD.browse("_http_.tcp", this);
62 public void serviceFound(DNSSDService browser, int flags, int ifIndex,
63 String serviceName, String regType, String domain) {}
66 <CODE>MyClient.serviceFound()</CODE> would be called for every HTTP server discovered in the
67 default browse domain(s).
70 abstract public class DNSSD
72 /** Flag indicates to a {@link BrowseListener} that another result is
73 queued. Applications should not update their UI to display browse
74 results if the MORE_COMING flag is set; they will be called at least once
75 more with the flag clear.
77 public static final int MORE_COMING
= ( 1 << 0 );
79 /** If flag is set in a {@link DomainListener} callback, indicates that the result is the default domain. */
80 public static final int DEFAULT
= ( 1 << 2 );
82 /** If flag is set, a name conflict will trigger an exception when registering non-shared records.<P>
83 A name must be explicitly specified when registering a service if this bit is set
84 (i.e. the default name may not not be used).
86 public static final int NO_AUTO_RENAME
= ( 1 << 3 );
88 /** If flag is set, allow multiple records with this name on the network (e.g. PTR records)
89 when registering individual records on a {@link DNSSDRegistration}.
91 public static final int SHARED
= ( 1 << 4 );
93 /** If flag is set, records with this name must be unique on the network (e.g. SRV records). */
94 public static final int UNIQUE
= ( 1 << 5 );
96 /** Set flag when calling enumerateDomains() to restrict results to domains recommended for browsing. */
97 public static final int BROWSE_DOMAINS
= ( 1 << 6 );
98 /** Set flag when calling enumerateDomains() to restrict results to domains recommended for registration. */
99 public static final int REGISTRATION_DOMAINS
= ( 1 << 7 );
101 /** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
102 public static final int MAX_DOMAIN_NAME
= 1005;
104 /** Pass for ifIndex to specify all available interfaces. */
105 public static final int ALL_INTERFACES
= 0;
107 /** Pass for ifIndex to specify the localhost interface. */
108 public static final int LOCALHOST_ONLY
= -1;
110 /** Browse for instances of a service.<P>
112 Note: browsing consumes network bandwidth. Call {@link DNSSDService#stop} when you have finished browsing.<P>
115 Currently ignored, reserved for future use.
118 If non-zero, specifies the interface on which to browse for services
119 (the index for a given interface is determined via the if_nametoindex()
120 family of calls.) Most applications will pass 0 to browse on all available
121 interfaces. Pass -1 to only browse for services provided on the local host.
124 The registration type being browsed for followed by the protocol, separated by a
125 dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
128 If non-null, specifies the domain on which to browse for services.
129 Most applications will not specify a domain, instead browsing on the
133 This object will get called when instances of the service are discovered (or disappear).
135 @return A {@link DNSSDService} that represents the active browse operation.
137 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
138 @see RuntimePermission
140 public static DNSSDService
browse( int flags
, int ifIndex
, String regType
, String domain
, BrowseListener listener
)
141 throws DNSSDException
142 { return getInstance()._makeBrowser( flags
, ifIndex
, regType
, domain
, listener
); }
144 /** Browse for instances of a service. Use default flags, ifIndex and domain.<P>
147 The registration type being browsed for followed by the protocol, separated by a
148 dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
151 This object will get called when instances of the service are discovered (or disappear).
153 @return A {@link DNSSDService} that represents the active browse operation.
155 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
156 @see RuntimePermission
158 public static DNSSDService
browse( String regType
, BrowseListener listener
)
159 throws DNSSDException
160 { return browse( 0, 0, regType
, "", listener
); }
162 /** Resolve a service name discovered via browse() to a target host name, port number, and txt record.<P>
164 Note: Applications should NOT use resolve() solely for txt record monitoring - use
165 queryRecord() instead, as it is more efficient for this task.<P>
167 Note: When the desired results have been returned, the client MUST terminate the resolve by
168 calling {@link DNSSDService#stop}.<P>
170 Note: resolve() behaves correctly for typical services that have a single SRV record and
171 a single TXT record (the TXT record may be empty.) To resolve non-standard services with
172 multiple SRV or TXT records, use queryRecord().<P>
175 Currently ignored, reserved for future use.
178 The interface on which to resolve the service. The client should
179 pass the interface on which the serviceName was discovered (i.e.
180 the ifIndex passed to the serviceFound() callback)
181 or 0 to resolve the named service on all available interfaces.
184 The servicename to be resolved.
187 The registration type being resolved followed by the protocol, separated by a
188 dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
191 The domain on which the service is registered, i.e. the domain passed
192 to the serviceFound() callback.
195 This object will get called when the service is resolved.
197 @return A {@link DNSSDService} that represents the active resolve operation.
199 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
200 @see RuntimePermission
202 public static DNSSDService
resolve( int flags
, int ifIndex
, String serviceName
, String regType
,
203 String domain
, ResolveListener listener
)
204 throws DNSSDException
205 { return getInstance()._resolve( flags
, ifIndex
, serviceName
, regType
, domain
, listener
); }
207 /** Register a service, to be discovered via browse() and resolve() calls.<P>
209 Possible values are: NO_AUTO_RENAME.
212 If non-zero, specifies the interface on which to register the service
213 (the index for a given interface is determined via the if_nametoindex()
214 family of calls.) Most applications will pass 0 to register on all
215 available interfaces. Pass -1 to register a service only on the local
216 machine (service will not be visible to remote hosts).
219 If non-null, specifies the service name to be registered.
220 Applications need not specify a name, in which case the
221 computer name is used (this name is communicated to the client via
222 the serviceRegistered() callback).
225 The registration type being registered followed by the protocol, separated by a
226 dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
229 If non-null, specifies the domain on which to advertise the service.
230 Most applications will not specify a domain, instead automatically
231 registering in the default domain(s).
234 If non-null, specifies the SRV target host name. Most applications
235 will not specify a host, instead automatically using the machine's
236 default host name(s). Note that specifying a non-null host does NOT
237 create an address record for that host - the application is responsible
238 for ensuring that the appropriate address record exists, or creating it
239 via {@link DNSSDRegistration#addRecord}.
242 The port on which the service accepts connections. Pass 0 for a
243 "placeholder" service (i.e. a service that will not be discovered by
244 browsing, but will cause a name conflict if another client tries to
245 register that same name.) Most clients will not use placeholder services.
248 The txt record rdata. May be null. Note that a non-null txtRecord
249 MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
250 <length byte> <data> ...
253 This object will get called when the service is registered.
255 @return A {@link DNSSDRegistration} that controls the active registration.
257 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
258 @see RuntimePermission
260 public static DNSSDRegistration
register( int flags
, int ifIndex
, String serviceName
, String regType
,
261 String domain
, String host
, int port
, TXTRecord txtRecord
, RegisterListener listener
)
262 throws DNSSDException
263 { return getInstance()._register( flags
, ifIndex
, serviceName
, regType
, domain
, host
, port
, txtRecord
, listener
); }
265 /** Register a service, to be discovered via browse() and resolve() calls. Use default flags, ifIndex, domain, host and txtRecord.<P>
267 If non-null, specifies the service name to be registered.
268 Applications need not specify a name, in which case the
269 computer name is used (this name is communicated to the client via
270 the serviceRegistered() callback).
273 The registration type being registered followed by the protocol, separated by a
274 dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
277 The port on which the service accepts connections. Pass 0 for a
278 "placeholder" service (i.e. a service that will not be discovered by
279 browsing, but will cause a name conflict if another client tries to
280 register that same name.) Most clients will not use placeholder services.
283 This object will get called when the service is registered.
285 @return A {@link DNSSDRegistration} that controls the active registration.
287 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
288 @see RuntimePermission
290 public static DNSSDRegistration
register( String serviceName
, String regType
, int port
, RegisterListener listener
)
291 throws DNSSDException
292 { return register( 0, 0, serviceName
, regType
, null, null, port
, null, listener
); }
294 /** Query for an arbitrary DNS record.<P>
296 Possible values are: MORE_COMING.
299 If non-zero, specifies the interface on which to issue the query
300 (the index for a given interface is determined via the if_nametoindex()
301 family of calls.) Passing 0 causes the name to be queried for on all
302 interfaces. Passing -1 causes the name to be queried for only on the
306 The full domain name of the resource record to be queried for.
309 The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
310 as defined in nameser.h.
313 The class of the resource record, as defined in nameser.h
314 (usually 1 for the Internet class).
317 This object will get called when the query completes.
319 @return A {@link DNSSDService} that controls the active query.
321 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
322 @see RuntimePermission
324 public static DNSSDService
queryRecord( int flags
, int ifIndex
, String serviceName
, int rrtype
,
325 int rrclass
, QueryListener listener
)
326 throws DNSSDException
327 { return getInstance()._queryRecord( flags
, ifIndex
, serviceName
, rrtype
, rrclass
, listener
); }
329 /** Asynchronously enumerate domains available for browsing and registration.<P>
331 Currently, the only domain returned is "local.", but other domains will be returned in future.<P>
333 The enumeration MUST be cancelled by calling {@link DNSSDService#stop} when no more domains
336 Possible values are: BROWSE_DOMAINS, REGISTRATION_DOMAINS.
339 If non-zero, specifies the interface on which to look for domains.
340 (the index for a given interface is determined via the if_nametoindex()
341 family of calls.) Most applications will pass 0 to enumerate domains on
345 This object will get called when domains are found.
347 @return A {@link DNSSDService} that controls the active enumeration.
349 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
350 @see RuntimePermission
352 public static DNSSDService
enumerateDomains( int flags
, int ifIndex
, DomainListener listener
)
353 throws DNSSDException
354 { return getInstance()._enumerateDomains( flags
, ifIndex
, listener
); }
356 /** Concatenate a three-part domain name (as provided to the listeners) into a
357 properly-escaped full domain name. Note that strings passed to listeners are
358 ALREADY ESCAPED where necessary.<P>
360 The service name - any dots or slashes must NOT be escaped.
361 May be null (to construct a PTR record name, e.g. "_ftp._tcp.apple.com").
364 The registration type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
367 The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
369 @return The full domain name.
371 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
372 @see RuntimePermission
374 public static String
constructFullName( String serviceName
, String regType
, String domain
)
375 throws DNSSDException
376 { return getInstance()._constructFullName( serviceName
, regType
, domain
); }
378 /** Instruct the daemon to verify the validity of a resource record that appears to
379 be out of date. (e.g. because tcp connection to a service's target failed.) <P>
381 Causes the record to be flushed from the daemon's cache (as well as all other
382 daemons' caches on the network) if the record is determined to be invalid.<P>
384 Currently unused, reserved for future use.
387 If non-zero, specifies the interface on which to reconfirm the record
388 (the index for a given interface is determined via the if_nametoindex()
389 family of calls.) Passing 0 causes the name to be reconfirmed on all
390 interfaces. Passing -1 causes the name to be reconfirmed only on the
394 The resource record's full domain name.
397 The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
400 The class of the resource record, as defined in nameser.h (usually 1).
403 The raw rdata of the resource record.
405 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
406 @see RuntimePermission
408 public static void reconfirmRecord( int flags
, int ifIndex
, String fullName
, int rrtype
,
409 int rrclass
, byte[] rdata
)
410 { getInstance()._reconfirmRecord( flags
, ifIndex
, fullName
, rrtype
, rrclass
, rdata
); }
412 /** Return the canonical name of a particular interface index.<P>
414 A valid interface index. Must not be ALL_INTERFACES.
416 @return The name of the interface, which should match java.net.NetworkInterface.getName().
418 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
419 @see RuntimePermission
421 public static String
getNameForIfIndex( int ifIndex
)
422 { return getInstance()._getNameForIfIndex( ifIndex
); }
424 /** Return the index of a named interface.<P>
426 A valid interface name. An example is java.net.NetworkInterface.getName().
428 @return The interface index.
430 @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
431 @see RuntimePermission
433 public static int getIfIndexForName( String ifName
)
434 { return getInstance()._getIfIndexForName( ifName
); }
436 protected DNSSD() {} // prevent direct instantiation
438 /** Return the single instance of DNSSD. */
439 static protected final DNSSD
getInstance()
441 SecurityManager sm
= System
.getSecurityManager();
443 sm
.checkPermission( new RuntimePermission( "getDNSSDInstance"));
447 abstract protected DNSSDService
_makeBrowser( int flags
, int ifIndex
, String regType
, String domain
, BrowseListener listener
)
448 throws DNSSDException
;
450 abstract protected DNSSDService
_resolve( int flags
, int ifIndex
, String serviceName
, String regType
,
451 String domain
, ResolveListener listener
)
452 throws DNSSDException
;
454 abstract protected DNSSDRegistration
_register( int flags
, int ifIndex
, String serviceName
, String regType
,
455 String domain
, String host
, int port
, TXTRecord txtRecord
, RegisterListener listener
)
456 throws DNSSDException
;
458 abstract protected DNSSDService
_queryRecord( int flags
, int ifIndex
, String serviceName
, int rrtype
,
459 int rrclass
, QueryListener listener
)
460 throws DNSSDException
;
462 abstract protected DNSSDService
_enumerateDomains( int flags
, int ifIndex
, DomainListener listener
)
463 throws DNSSDException
;
465 abstract protected String
_constructFullName( String serviceName
, String regType
, String domain
)
466 throws DNSSDException
;
468 abstract protected void _reconfirmRecord( int flags
, int ifIndex
, String fullName
, int rrtype
,
469 int rrclass
, byte[] rdata
);
471 abstract protected String
_getNameForIfIndex( int ifIndex
);
473 abstract protected int _getIfIndexForName( String ifName
);
475 protected static DNSSD fInstance
;
481 String name
= System
.getProperty( "com.apple.dnssd.DNSSD" );
483 name
= "com.apple.dnssd.AppleDNSSD"; // Fall back to Apple-provided class.
484 fInstance
= (DNSSD
) Class
.forName( name
).newInstance();
488 throw new InternalError( "cannot instantiate DNSSD" + e
);
494 // Concrete implementation of DNSSDException
495 class AppleDNSSDException
extends DNSSDException
497 public AppleDNSSDException( int errorCode
) { fErrorCode
= errorCode
; }
499 public int getErrorCode() { return fErrorCode
; }
501 public String
getMessage()
503 final String kMessages
[] = { // should probably be put into a resource or something
513 "", // there is NO number 6
514 "ALREADY_REGISTERED",
519 "BAD_INTERFACE_INDEX"
522 if ( fErrorCode
<= UNKNOWN
&& fErrorCode
> ( UNKNOWN
- kMessages
.length
))
524 return "DNS-SD Error " + String
.valueOf( fErrorCode
) + ": " + kMessages
[ UNKNOWN
- fErrorCode
];
527 return super.getMessage() + "(" + String
.valueOf( fErrorCode
) + ")";
530 protected int fErrorCode
;
533 // The concrete, default implementation.
534 class AppleDNSSD
extends DNSSD
538 System
.loadLibrary( "jdns_sd");
540 int libInitResult
= InitLibrary( 1);
542 if ( libInitResult
!= DNSSDException
.NO_ERROR
)
543 throw new InternalError( "cannot instantiate DNSSD: " + new AppleDNSSDException( libInitResult
).getMessage());
546 static public boolean hasAutoCallbacks
; // Set by InitLibrary() to value of AUTO_CALLBACKS
548 protected DNSSDService
_makeBrowser( int flags
, int ifIndex
, String regType
, String domain
, BrowseListener client
)
549 throws DNSSDException
551 return new AppleBrowser( flags
, ifIndex
, regType
, domain
, client
);
554 protected DNSSDService
_resolve( int flags
, int ifIndex
, String serviceName
, String regType
,
555 String domain
, ResolveListener client
)
556 throws DNSSDException
558 return new AppleResolver( flags
, ifIndex
, serviceName
, regType
, domain
, client
);
561 protected DNSSDRegistration
_register( int flags
, int ifIndex
, String serviceName
, String regType
,
562 String domain
, String host
, int port
, TXTRecord txtRecord
, RegisterListener client
)
563 throws DNSSDException
565 return new AppleRegistration( flags
, ifIndex
, serviceName
, regType
, domain
, host
, port
,
566 ( txtRecord
!= null) ? txtRecord
.getRawBytes() : null, client
);
569 protected DNSSDService
_queryRecord( int flags
, int ifIndex
, String serviceName
, int rrtype
,
570 int rrclass
, QueryListener client
)
571 throws DNSSDException
573 return new AppleQuery( flags
, ifIndex
, serviceName
, rrtype
, rrclass
, client
);
576 protected DNSSDService
_enumerateDomains( int flags
, int ifIndex
, DomainListener listener
)
577 throws DNSSDException
579 return new AppleDomainEnum( flags
, ifIndex
, listener
);
582 protected String
_constructFullName( String serviceName
, String regType
, String domain
)
583 throws DNSSDException
585 String
[] responseHolder
= new String
[1]; // lame maneuver to get around Java's lack of reference parameters
587 int rc
= ConstructName( serviceName
, regType
, domain
, responseHolder
);
589 throw new AppleDNSSDException( rc
);
591 return responseHolder
[0];
594 protected void _reconfirmRecord( int flags
, int ifIndex
, String fullName
, int rrtype
,
595 int rrclass
, byte[] rdata
)
597 ReconfirmRecord( flags
, ifIndex
, fullName
, rrtype
, rrclass
, rdata
);
600 protected String
_getNameForIfIndex( int ifIndex
)
602 return null; // ••Fix me - RNP
605 protected int _getIfIndexForName( String ifName
)
607 return 0; // ••Fix me - RNP
611 protected native int ConstructName( String serviceName
, String regType
, String domain
, String
[] pOut
);
613 protected native void ReconfirmRecord( int flags
, int ifIndex
, String fullName
, int rrtype
,
614 int rrclass
, byte[] rdata
);
616 protected static native int InitLibrary( int callerVersion
);
619 class AppleService
implements DNSSDService
, Runnable
621 public AppleService() { fNativeContext
= 0; }
623 public void stop() { this.HaltOperation(); }
625 public void finalize() throws Throwable
631 /* The run() method is used internally to schedule an update from another thread */
634 this.ProcessResults();
637 /* Block for timeout ms (or forever if -1). Returns 1 if data present, 0 if timed out, -1 if not browsing. */
638 protected native int BlockForData( int msTimeout
);
640 /* Call ProcessResults when data appears on socket descriptor. */
641 protected native void ProcessResults();
643 protected native void HaltOperation();
645 protected void ThrowOnErr( int rc
) throws DNSSDException
648 throw new AppleDNSSDException( rc
);
651 protected int /* warning */ fNativeContext
; // Private storage for native side
655 // A ServiceThread calls AppleService.BlockForData() and schedules its client
656 // when data appears.
657 class ServiceThread
extends Thread
659 public ServiceThread( AppleService owner
) { fOwner
= owner
; }
667 result
= fOwner
.BlockForData( -1);
673 break; // terminate thread
677 protected AppleService fOwner
;
681 class AppleBrowser
extends AppleService
683 public AppleBrowser( int flags
, int ifIndex
, String regType
, String domain
, BrowseListener client
)
684 throws DNSSDException
687 this.ThrowOnErr( this.CreateBrowser( flags
, ifIndex
, regType
, domain
));
688 if ( !AppleDNSSD
.hasAutoCallbacks
)
689 new ServiceThread( this).start();
692 // Sets fNativeContext. Returns non-zero on error.
693 protected native int CreateBrowser( int flags
, int ifIndex
, String regType
, String domain
);
695 protected BrowseListener fClient
;
698 class AppleResolver
extends AppleService
700 public AppleResolver( int flags
, int ifIndex
, String serviceName
, String regType
,
701 String domain
, ResolveListener client
)
702 throws DNSSDException
705 this.ThrowOnErr( this.CreateResolver( flags
, ifIndex
, serviceName
, regType
, domain
));
706 if ( !AppleDNSSD
.hasAutoCallbacks
)
707 new ServiceThread( this).start();
710 // Sets fNativeContext. Returns non-zero on error.
711 protected native int CreateResolver( int flags
, int ifIndex
, String serviceName
, String regType
,
714 protected ResolveListener fClient
;
717 // An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
718 class AppleDNSRecord
extends DNSRecord
720 public int fRecord
; // Really a DNSRecord; sizeof(int) == sizeof(void*) ?
723 class AppleRegistration
extends AppleService
implements DNSSDRegistration
725 public AppleRegistration( int flags
, int ifIndex
, String serviceName
, String regType
, String domain
,
726 String host
, int port
, byte[] txtRecord
, RegisterListener client
)
727 throws DNSSDException
730 this.ThrowOnErr( this.BeginRegister( ifIndex
, flags
, serviceName
, regType
, domain
, host
, port
, txtRecord
));
731 if ( !AppleDNSSD
.hasAutoCallbacks
)
732 new ServiceThread( this).start();
735 public DNSRecord
addRecord( int flags
, int rrType
, byte[] rData
, int ttl
)
736 throws DNSSDException
738 AppleDNSRecord newRecord
= new AppleDNSRecord();
740 this.ThrowOnErr( this.AddRecord( flags
, rrType
, rData
, ttl
, newRecord
));
745 public void updateRecord( DNSRecord record
, int flags
, byte[] rData
, int ttl
)
746 throws DNSSDException
748 this.ThrowOnErr( this.UpdateRecord( (AppleDNSRecord
) record
, flags
, rData
, ttl
));
751 public void removeRecord( DNSRecord record
, int flags
)
752 throws DNSSDException
754 this.ThrowOnErr( this.RemoveRecord( (AppleDNSRecord
) record
, flags
));
757 // Sets fNativeContext. Returns non-zero on error.
758 protected native int BeginRegister( int ifIndex
, int flags
, String serviceName
, String regType
,
759 String domain
, String host
, int port
, byte[] txtRecord
);
761 // Sets fNativeContext. Returns non-zero on error.
762 protected native int AddRecord( int flags
, int rrType
, byte[] rData
, int ttl
, AppleDNSRecord destObj
);
764 protected native int UpdateRecord( AppleDNSRecord destObj
, int flags
, byte[] rData
, int ttl
);
766 protected native int RemoveRecord( AppleDNSRecord destObj
, int flags
);
768 protected RegisterListener fClient
;
771 class AppleQuery
extends AppleService
773 public AppleQuery( int flags
, int ifIndex
, String serviceName
, int rrtype
,
774 int rrclass
, QueryListener client
)
775 throws DNSSDException
778 this.ThrowOnErr( this.CreateQuery( flags
, ifIndex
, serviceName
, rrtype
, rrclass
));
779 if ( !AppleDNSSD
.hasAutoCallbacks
)
780 new ServiceThread( this).start();
783 // Sets fNativeContext. Returns non-zero on error.
784 protected native int CreateQuery( int flags
, int ifIndex
, String serviceName
, int rrtype
, int rrclass
);
786 protected QueryListener fClient
;
789 class AppleDomainEnum
extends AppleService
791 public AppleDomainEnum( int flags
, int ifIndex
, DomainListener listener
)
792 throws DNSSDException
795 this.ThrowOnErr( this.BeginEnum( flags
, ifIndex
));
796 if ( !AppleDNSSD
.hasAutoCallbacks
)
797 new ServiceThread( this).start();
800 // Sets fNativeContext. Returns non-zero on error.
801 protected native int BeginEnum( int flags
, int ifIndex
);
803 protected DomainListener fClient
;