summaryrefslogtreecommitdiffstats
path: root/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js')
-rw-r--r--netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js201
1 files changed, 201 insertions, 0 deletions
diff --git a/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js b/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
new file mode 100644
index 000000000..b94f67297
--- /dev/null
+++ b/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
@@ -0,0 +1,201 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/ExtensionUtils.jsm");
+Cu.import('resource://gre/modules/Services.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+let { PlatformInfo } = ExtensionUtils;
+
+if (PlatformInfo.os == "android" && !Services.prefs.getBoolPref("network.mdns.use_js_fallback")) {
+ Cu.import("resource://gre/modules/MulticastDNSAndroid.jsm");
+} else {
+ Cu.import("resource://gre/modules/MulticastDNS.jsm");
+}
+
+const DNSSERVICEDISCOVERY_CID = Components.ID("{f9346d98-f27a-4e89-b744-493843416480}");
+const DNSSERVICEDISCOVERY_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-sd;1";
+const DNSSERVICEINFO_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-info;1";
+
+function log(aMsg) {
+ dump("-*- nsDNSServiceDiscovery.js : " + aMsg + "\n");
+}
+
+function generateUuid() {
+ var uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"].
+ getService(Ci.nsIUUIDGenerator);
+ return uuidGenerator.generateUUID().toString();
+}
+
+// Helper class to transform return objects to correct type.
+function ListenerWrapper(aListener, aMdns) {
+ this.listener = aListener;
+ this.mdns = aMdns;
+
+ this.discoveryStarting = false;
+ this.stopDiscovery = false;
+
+ this.registrationStarting = false;
+ this.stopRegistration = false;
+
+ this.uuid = generateUuid();
+}
+
+ListenerWrapper.prototype = {
+ // Helper function for transforming an Object into nsIDNSServiceInfo.
+ makeServiceInfo: function (aServiceInfo) {
+ let serviceInfo = Cc[DNSSERVICEINFO_CONTRACT_ID].createInstance(Ci.nsIDNSServiceInfo);
+
+ for (let name of ['host', 'address', 'port', 'serviceName', 'serviceType']) {
+ try {
+ serviceInfo[name] = aServiceInfo[name];
+ } catch (e) {
+ // ignore exceptions
+ }
+ }
+
+ let attributes;
+ try {
+ attributes = _toPropertyBag2(aServiceInfo.attributes);
+ } catch (err) {
+ // Ignore unset attributes in object.
+ log("Caught unset attributes error: " + err + " - " + err.stack);
+ attributes = Cc['@mozilla.org/hash-property-bag;1']
+ .createInstance(Ci.nsIWritablePropertyBag2);
+ }
+ serviceInfo.attributes = attributes;
+
+ return serviceInfo;
+ },
+
+ /* transparent types */
+ onDiscoveryStarted: function(aServiceType) {
+ this.discoveryStarting = false;
+ this.listener.onDiscoveryStarted(aServiceType);
+
+ if (this.stopDiscovery) {
+ this.mdns.stopDiscovery(aServiceType, this);
+ }
+ },
+ onDiscoveryStopped: function(aServiceType) {
+ this.listener.onDiscoveryStopped(aServiceType);
+ },
+ onStartDiscoveryFailed: function(aServiceType, aErrorCode) {
+ log('onStartDiscoveryFailed: ' + aServiceType + ' (' + aErrorCode + ')');
+ this.discoveryStarting = false;
+ this.stopDiscovery = true;
+ this.listener.onStartDiscoveryFailed(aServiceType, aErrorCode);
+ },
+ onStopDiscoveryFailed: function(aServiceType, aErrorCode) {
+ log('onStopDiscoveryFailed: ' + aServiceType + ' (' + aErrorCode + ')');
+ this.listener.onStopDiscoveryFailed(aServiceType, aErrorCode);
+ },
+
+ /* transform types */
+ onServiceFound: function(aServiceInfo) {
+ this.listener.onServiceFound(this.makeServiceInfo(aServiceInfo));
+ },
+ onServiceLost: function(aServiceInfo) {
+ this.listener.onServiceLost(this.makeServiceInfo(aServiceInfo));
+ },
+ onServiceRegistered: function(aServiceInfo) {
+ this.registrationStarting = false;
+ this.listener.onServiceRegistered(this.makeServiceInfo(aServiceInfo));
+
+ if (this.stopRegistration) {
+ this.mdns.unregisterService(aServiceInfo, this);
+ }
+ },
+ onServiceUnregistered: function(aServiceInfo) {
+ this.listener.onServiceUnregistered(this.makeServiceInfo(aServiceInfo));
+ },
+ onServiceResolved: function(aServiceInfo) {
+ this.listener.onServiceResolved(this.makeServiceInfo(aServiceInfo));
+ },
+
+ onRegistrationFailed: function(aServiceInfo, aErrorCode) {
+ log('onRegistrationFailed: (' + aErrorCode + ')');
+ this.registrationStarting = false;
+ this.stopRegistration = true;
+ this.listener.onRegistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
+ },
+ onUnregistrationFailed: function(aServiceInfo, aErrorCode) {
+ log('onUnregistrationFailed: (' + aErrorCode + ')');
+ this.listener.onUnregistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
+ },
+ onResolveFailed: function(aServiceInfo, aErrorCode) {
+ log('onResolveFailed: (' + aErrorCode + ')');
+ this.listener.onResolveFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
+ }
+};
+
+function nsDNSServiceDiscovery() {
+ log("nsDNSServiceDiscovery");
+ this.mdns = new MulticastDNS();
+}
+
+nsDNSServiceDiscovery.prototype = {
+ classID: DNSSERVICEDISCOVERY_CID,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIDNSServiceDiscovery]),
+
+ startDiscovery: function(aServiceType, aListener) {
+ log("startDiscovery");
+ let listener = new ListenerWrapper(aListener, this.mdns);
+ listener.discoveryStarting = true;
+ this.mdns.startDiscovery(aServiceType, listener);
+
+ return {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
+ cancel: (function() {
+ if (this.discoveryStarting || this.stopDiscovery) {
+ this.stopDiscovery = true;
+ return;
+ }
+ this.mdns.stopDiscovery(aServiceType, listener);
+ }).bind(listener)
+ };
+ },
+
+ registerService: function(aServiceInfo, aListener) {
+ log("registerService");
+ let listener = new ListenerWrapper(aListener, this.mdns);
+ listener.registrationStarting = true;
+ this.mdns.registerService(aServiceInfo, listener);
+
+ return {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
+ cancel: (function() {
+ if (this.registrationStarting || this.stopRegistration) {
+ this.stopRegistration = true;
+ return;
+ }
+ this.mdns.unregisterService(aServiceInfo, listener);
+ }).bind(listener)
+ };
+ },
+
+ resolveService: function(aServiceInfo, aListener) {
+ log("resolveService");
+ this.mdns.resolveService(aServiceInfo, new ListenerWrapper(aListener));
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDNSServiceDiscovery]);
+
+function _toPropertyBag2(obj)
+{
+ if (obj.QueryInterface) {
+ return obj.QueryInterface(Ci.nsIPropertyBag2);
+ }
+
+ let result = Cc['@mozilla.org/hash-property-bag;1']
+ .createInstance(Ci.nsIWritablePropertyBag2);
+ for (let name in obj) {
+ result.setPropertyAsAString(name, obj[name]);
+ }
+ return result;
+}