Conveying messages over MQTT protocol.

@namespace webduino.transport
@class MqttTransport
@constructor
@param {Object} options Options to build a proper transport
@extends webduino.Transport
171837
function MqttTransport(options) {
    Transport.call(this, options);

    this._options = options;
    this._client = null;
    this._timer = null;
    this._sendTimer = null;
    this._buf = [];

    this._status = '';

    this._connHandler = onConnect.bind(this);
    this._connFailedHandler = onConnectFailed.bind(this);
    this._messageHandler = onMessage.bind(this);
    this._sendOutHandler = sendOut.bind(this);
    this._disconnHandler = onDisconnect.bind(this);

    init(this);
  }
943778
function Device(options) {

  EventEmitter.call(this);

  // Check required fields.
  if(!options || !options.id) {
    throw new Error('ID is required.');
  }

  this.options = options;
  this.id = options.id;

  // Default the options and remove whitespace.
  options.id = (options.id || '').replace(/ /g, '');
  options.key = (options.key || '').replace(/ /g, '');
  options.secret = (options.secret || '').replace(/ /g, '');

  // The MQTT topics that this device will use.
  this.commandTopic = util.format(config.topicFormatCommand, options.id);
  this.stateTopic = util.format(config.topicFormatState, options.id);

  this.mqtt = options.mqtt || new MQTT();
  this.mqtt.on('message', this.handleMessage.bind(this));

  // Only want 'connect' to be emitted the first time. Every time after
  // will only emit the reconnected event.
  var firstConnect = true;
  this.mqtt.on('connect', (function() {
    this.handleConnect();
    if(firstConnect) {
      firstConnect = false;
      this.emit('connect');
    }
    else {
      this.emit('reconnected');
    }
  }).bind(this));

  this.mqtt.on('reconnect', (function() {
    this.emit('reconnect');
  }).bind(this));

  this.mqtt.on('close', (function() {
    this.emit('close');
  }).bind(this));

  this.mqtt.on('offline', (function() {
    this.emit('offline');
  }).bind(this));

  this.mqtt.on('error', (function(err) {
    this.emit('error', err);
  }).bind(this));
}
423606
function Router(socket, options) {
  stream.Transform.call(this, { objectMode: true });

  this.options = merge(Object.create(Router.DEFAULTS), options || {});
  this.socket = socket;
}
947101
function ( options ) {
			this.protocol = options.protocol || 'http';
			this.port = options.port;
			this.server = options.server;
			this.path = options.path;
			this.proxy = options.proxy;
			this.jar = request.jar(); // create new cookie jar for each instance

			this.debug = options.debug;

			// set up logging
			const winston = require( 'winston' ),
				// file logging
				path = require( 'path' ),
				fs = require( 'fs' ),
				logDir = path.dirname( process.argv[ 1 ] ) + '/log/',
				logFile = logDir + path.basename( process.argv[ 1 ], '.js' ) + '.log',
				// how many tasks (i.e. requests) to run in parallel
				concurrency = options.concurrency || 3;

			this.logger = new ( winston.Logger )();

			// console logging
			if ( this.debug ) {
				this.logger.add( winston.transports.Console, {
					level: 'debug'
				} );
			}

			this.logger.cli();

			if ( fs.existsSync( logDir ) ) {
				this.logger.add( winston.transports.File, {
					colorize: true,
					filename: logFile,
					json: false,
					level: this.debug ? 'debug' : 'info'
				} );
			}

			// requests queue
			// @see https://github.com/caolan/async#queue
			this.queue = async.queue( function ( task, callback ) {
			// process the task (and call the provided callback once it's completed)
				task( callback );
			}, concurrency );

			// HTTP client
			this.formatUrl = require( 'url' ).format;

			this.userAgent = options.userAgent || ( `nodemw/${VERSION} (node.js ${process.version}; ${process.platform} ${process.arch})` );
			this.version = VERSION;

			// debug info
			this.info( process.argv.join( ' ' ) );
			this.info( this.userAgent );

			let port = this.port ? `:${this.port}` : '';

			this.info( `Using <${this.protocol}://${this.server}${port}${this.path}/api.php> as API entry point` );
			this.info( '----' );
		}
3508
function ( options, callback ) {
    
    if ( typeof options == 'function' && typeof callback != 'function' ) {
        callback = options;
    }
    var callback = callback || function (){};

    // Validate arguments
    if ( typeof options != 'object' || options.constructor != Object ) {
        callback( Error( 'AmqpStream requires the first argument to an options object.' ) );
        return false;
    }

    // If module was called as a function, return a new AmqpStream object
    if ( !(this instanceof AmqpStream) ) 
        return new AmqpStream( options, callback );

    // Variables / Properties
    var stream          = this;
    var err             = null;

    // Make sure we have a valid connection
    if ( !(amqpObjectType(options.connection)=='Connection') && !(amqpObjectType(options.exchange)=='Exchange') && !(amqpObjectType(options.queue)=='Queue') ) {
        callback( Error( 'AmqpStream requires at least one amqp object (Connection, Exchange, or Queue).' ) );
        return false;
    }

    // Determine connection bearing object
    var connection = amqpObjectType(options.connection)=='Connection' ? options.connection : 
        amqpObjectType(options.exchange)=='Exchange' ? options.exchange.connection :
        amqpObjectType(options.queue)=='Queue' ? options.queue.connection : null;

    // AMQP related configuration properties
    this.connection     = null;
    this.exchange       = null;
    this.queue          = null;
    this.routingKey     = options.routingKey || '#';
    this.ctag           = null;
    this.originId       = uniqueIdentifier();
    this.autoBind       = typeof options.autoBind != 'undefined' ? options.autoBind : true;

    this.correlations   = [];
    //this.correlationId  = (options.correlationId && options.correlationId === true) ? uniqueIdentifier() : (options.correlationId || null);

    this.publishOptions         = options.publishOptions || {};
    this.publishOptions.headers = this.publishOptions.headers || {};
    this.publishOptions.headers['x-stream-origin'] = this.originId;

    // Stream interface properties
    this.writable       = false;    // Enabled once exchange is set
    this.readable       = false;
    this.paused         = false;    // Start in an un-paused state
    this.ended          = false;
    this.destroyed      = false;
    this.buffer         = [];

    this.initializing   = true;

    var connectionReady = false;
    var exchangeReady   = false;
    var queueReady      = false;
    var onReady = function () {
        if ( stream.initializing && connectionReady && (exchangeReady || !options.exchange) && (queueReady || (typeof options.queue != 'undefined' && options.queue === false) ) ) {
            stream.initializing = false;
            callback( err, stream );
            process.nextTick( function () { stream.emit( 'ready' ); } );
        }
    }

    var configureStream = function ( connection, options ) {
        var connectionReady = function () {
            setConnection( connection );

            if ( amqpObjectType(options.exchange) == 'Exchange' ) setExchange( options.exchange );
            else if ( options.exchange && typeof options.exchange == 'string' ) {
                connection.exchange( options.exchange, options.exchangeOptions||{durable:false,autoDelete:true}, function (exchange) {
                    setExchange( exchange );
                });
            } 

            if ( amqpObjectType(options.queue) == 'Queue' ) { 
                if ( !options.exchange && options.queue.exchange ) {
                    options.exchange = options.queue.exchange;
                    setExchange( options.exchange );
                }
                setQueue( options.queue );
            }
            else if ( options.queue && typeof options.queue == 'string' ) {
                connection.queue( options.queue, options.queueOptions||{durable:false,autoDelete:true}, function (queue) {
                    setQueue( queue );
                });
            }
            // Skip binding to a queue if queue:false, will create write-only stream 
            else if ( typeof options.queue != 'undefined' && options.queue === false ) {
                options.queue = null;
            }
            else {
                options.queue = buildQueue();
            }

        }
        if ( !connection._connecting && connection.channels && Object.keys(connection.channels).length > 0 ) {
            connectionReady();
        }
        else {
            connection.on( 'ready', connectionReady );
        }
    }

    var setConnection = function ( connection ) {
        stream.connection = connection;
        stream.emit( 'connectionReady' );

        connectionReady = true;
        onReady();
    }
    var setExchange = function ( exchange ) {
        if ( stream.exchange )
            return;
        assert.equal( amqpObjectType(exchange), 'Exchange', 'setExchange expected an Exchange object' );
        stream.exchange = exchange;
        stream.writable = true;
        stream.emit( 'exchangeReady' );
        stream.exchange.on( 'error', function (err) { stream.emit( 'error', err); });

        exchangeReady = true;
        onReady();
    }
    var setQueue = function ( queue ) {
        if ( stream.queue ) 
            return;
        assert.equal( amqpObjectType(queue), 'Queue', 'setQueue expected a Queue object' );
        stream.queue = queue;
        stream.readable = true;
        stream.emit( 'queueReady' );
        queue.on( 'error', function (err) { stream.emit( 'error', err); });
        queue.subscribe( messageHandler ).addCallback( function(ok) { 
            stream.ctag = ok.consumerTag;
        });

        // if ( stream.correlationId ) {
        //     stream.publishOptions.replyTo = queue.name;
        //     stream.publishOptions.correlationId = stream.correlationId;
        // }

        queueReady = true;
        onReady();
    }
    var buildQueue = function ( ) {
        var queue = stream.connection.queue( '', {durable: false, exclusive: true, autoDelete: true}, function () {
            if ( stream.autoBind )
                queue.bind( stream.exchange, stream.routingKey );
            queue.bind( stream.exchange, queue.name );
            queue.on( 'queueBindOk', function () { setQueue(queue); });
        });
        return queue;
    }
    var onEnd = function () {
        stream.writable = stream.readable  = false;
        stream.ended = true;
        stream.emit( 'end' );
    }
    var messageHandler = function ( message, headers, deliveryInfo ) {
        if ( 'x-stream-origin' in headers && headers['x-stream-origin'] == stream.originId )
            return; // Do not emit our own writes ( this is for duplex streams )
        if ( deliveryInfo.correlationId ) {
            if ( deliveryInfo.correlationId in stream.correlations ) {
                var emitter = stream.correlations[ deliveryInfo.correlationId ];
            }
            else {
                var emitter = stream.createCorrelatedResponse( deliveryInfo.replyTo, deliveryInfo.correlationId, function ( err, emitter ) {
                    stream.emit( 'correlatedRequest', emitter );
                });
            }
            if ( 'x-stream-event' in headers && headers['x-stream-event'] == 'end') {
                if ( message.data && message.data.toString().trim() != '' )
                    emitter.emit( 'data', message.data );
                emitter.emit( 'end' );
                process.nextTick( function () { delete stream.correlations[deliveryInfo.correlationId] } );
            }
        }
        else {
            var emitter = stream;
            if ( 'x-stream-event' in headers && headers['x-stream-event'] == 'end' ) {

                if ( message.data && message.data.toString().trim() != '' )
                    emitter.emit( 'data', message.data );

                if( !( emitter.paused || emitter.buffer.length ) )
                    return onEnd();
                else
                    emitter.once( 'drain', onEnd );
                emitter.drain();
            }
        }
        
        if ( 'x-stream-event' in headers && headers['x-stream-event'] == 'error') {
            if ( message.data && message.data.toString().trim() != '' )
                emitter.emit( 'data', message.data );
            emitter.emit( 'error' );
        }
        else if ( ( !('x-stream-event' in headers) || ('x-stream-event' in headers && headers['x-stream-event'] == 'data') ) && 
            message.data && message.data.toString().trim() != '' 
        ) {
            if ( emitter.paused ) {
                emitter.buffer.push( message.data );
            }
            else {
                emitter.emit( 'data', message.data );
            }
        }
    }
    
    // Configure the stream
    configureStream( connection, options );
}
311920
function(options) {

   	/**
   	 * Configuration object to set the options for this class and the parent classes. See constructor details for options added by this class.
   	 */
   	this.options = {};
   	
   	// Basic options
   	this.options.name = options.name;
   	this.options.value = options.value;
   	this.options.id = options.id || Dom.generateId();
   	this.options.label = options.label;
   	this.options.description = options.description;
   
      // Define default messages
	   this.options.messages = {};
	   this.options.messages.required = (options.messages && options.messages.required) ? options.messages.required : inputEx.messages.required;
	   this.options.messages.invalid = (options.messages && options.messages.invalid) ? options.messages.invalid : inputEx.messages.invalid;
	   //this.options.messages.valid = (options.messages && options.messages.valid) ? options.messages.valid : inputEx.messages.valid;
	
	   // Other options
	   this.options.className = options.className ? options.className : 'inputEx-Field';
	   this.options.required = lang.isUndefined(options.required) ? false : options.required;
	   this.options.showMsg = lang.isUndefined(options.showMsg) ? false : options.showMsg;
	}
735398
function ServerConnection (options) {

    this.log = options.log;
    this.port = options.port;
    this.proxyUrl = options.proxyUrl;

    if (!(options.udp4 === false)) {
        this.listenUDP4();
    }
    if (!(options.tcp === false)) {
        this.listenTCP();
    }
    if (!(options.socketio === false)) {
        this.listenSocketIO();
    }

    EventEmitter.call(this);

}
1086160
function WebClientConnection(options) {

    var url = window.location.host.split(':')[0];
    if (options && options.proxyUrl) {
        url = options.proxyUrl;
    }

    this.createProxySocket('http://' + url, 33331);

    EventEmitter.call(this);
}
196924
function Transport (opts) {
  this.path = opts.path;
  this.host = opts.host;
  this.port = opts.port;
  this.secure = opts.secure;
  this.query = opts.query;
  this.timestampParam = opts.timestampParam;
  this.timestampRequests = opts.timestampRequests;
  this.readyState = '';
}
762429
function SMTPTransport(options) {
    EventEmitter.call(this);

    options = options || {};
    if (typeof options === 'string') {
        options = {
            url: options
        };
    }

    var urlData;
    var service = options.service;

    if (typeof options.getSocket === 'function') {
        this.getSocket = options.getSocket;
    }

    if (options.url) {
        urlData = shared.parseConnectionUrl(options.url);
        service = service || urlData.service;
    }

    this.options = assign(
        false, // create new object
        options, // regular options
        urlData, // url options
        service && wellknown(service) // wellknown options
    );

    this.logger = shared.getLogger(this.options);

    // temporary object
    var connection = new SMTPConnection(this.options);

    this.name = 'SMTP';
    this.version = packageData.version + '[client:' + connection.version + ']';
}
521466
function (url) {
            var self = this;
            this._ws = new WebSocket(url);

            // One potential source of confusion: the transport sends two "types" of messages -
            // these are distinct from the protocol's own messages. This is because this transport
            // needs to send an initial "connect" message telling the Brackets side of the transport
            // the URL of the page that it's connecting from, distinct from the actual protocol
            // message traffic. Actual protocol messages are sent as a JSON payload in a message of
            // type "message".
            //
            // Other transports might not need to do this - for example, a transport that simply
            // talks to an iframe within the same process already knows what URL that iframe is
            // pointing to, so the only comunication that needs to happen via postMessage() is the
            // actual protocol message strings, and no extra wrapping is necessary.

            this._ws.onopen = function (event) {
                // Send the initial "connect" message to tell the other end what URL we're from.
                self._ws.send(JSON.stringify({
                    type: "connect",
                    url: global.location.href
                }));
                console.log("[Brackets LiveDev] Connected to Brackets at " + url);
                if (self._callbacks && self._callbacks.connect) {
                    self._callbacks.connect();
                }
            };
            this._ws.onmessage = function (event) {
                console.log("[Brackets LiveDev] Got message: " + event.data);
                if (self._callbacks && self._callbacks.message) {
                    self._callbacks.message(event.data);
                }
            };
            this._ws.onclose = function (event) {
                self._ws = null;
                if (self._callbacks && self._callbacks.close) {
                    self._callbacks.close();
                }
            };
            // TODO: onerror
        }
680208
function SockJS(url, protocols, options) {
  if (!(this instanceof SockJS)) {
    return new SockJS(url, protocols, options);
  }
  if (arguments.length < 1) {
    throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");
  }
  EventTarget.call(this);

  this.readyState = SockJS.CONNECTING;
  this.extensions = '';
  this.protocol = '';

  // non-standard extension
  options = options || {};
  if (options.protocols_whitelist) {
    log.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead.");
  }
  this._transportsWhitelist = options.transports;
  this._transportOptions = options.transportOptions || {};

  var sessionId = options.sessionId || 8;
  if (typeof sessionId === 'function') {
    this._generateSessionId = sessionId;
  } else if (typeof sessionId === 'number') {
    this._generateSessionId = function() {
      return random.string(sessionId);
    };
  } else {
    throw new TypeError('If sessionId is used in the options, it needs to be a number or a function.');
  }

  this._server = options.server || random.numberString(1000);

  // Step 1 of WS spec - parse and validate the url. Issue #8
  var parsedUrl = new URL(url);
  if (!parsedUrl.host || !parsedUrl.protocol) {
    throw new SyntaxError("The URL '" + url + "' is invalid");
  } else if (parsedUrl.hash) {
    throw new SyntaxError('The URL must not contain a fragment');
  } else if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
    throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '" + parsedUrl.protocol + "' is not allowed.");
  }

  var secure = parsedUrl.protocol === 'https:';
  // Step 2 - don't allow secure origin with an insecure protocol
  if (loc.protocol === 'https:' && !secure) {
    throw new Error('SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS');
  }

  // Step 3 - check port access - no need here
  // Step 4 - parse protocols argument
  if (!protocols) {
    protocols = [];
  } else if (!Array.isArray(protocols)) {
    protocols = [protocols];
  }

  // Step 5 - check protocols argument
  var sortedProtocols = protocols.sort();
  sortedProtocols.forEach(function(proto, i) {
    if (!proto) {
      throw new SyntaxError("The protocols entry '" + proto + "' is invalid.");
    }
    if (i < (sortedProtocols.length - 1) && proto === sortedProtocols[i + 1]) {
      throw new SyntaxError("The protocols entry '" + proto + "' is duplicated.");
    }
  });

  // Step 6 - convert origin
  var o = urlUtils.getOrigin(loc.href);
  this._origin = o ? o.toLowerCase() : null;

  // remove the trailing slash
  parsedUrl.set('pathname', parsedUrl.pathname.replace(/\/+$/, ''));

  // store the sanitized url
  this.url = parsedUrl.href;

  // Step 7 - start connection in background
  // obtain server info
  // http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-26
  this._urlInfo = {
    nullOrigin: !browser.hasDomain()
  , sameOrigin: urlUtils.isOriginEqual(this.url, loc.href)
  , sameScheme: urlUtils.isSchemeEqual(this.url, loc.href)
  };

  this._ir = new InfoReceiver(this.url, this._urlInfo);
  this._ir.once('finish', this._receiveInfo.bind(this));
}
891292
function SocketServices( options ){
	options = options || {};

	var self = this;

	this.logger = Logger.createLogger( 'socket', {'socket-services': VERSION}, options.logger );

	self.server = options.server || { };

	this.messageValidator = options.messageValidator || isCommunication;

	this.channel = options.channel || 'api';
	this.event = options.event || 'rester';

	self.logger.info('Will accepting communication on channel \'' + self.channel + '\' emitting to event \'' + self.event + '\'' );

	this.inflicter = new Inflicter( { logger: self.logger, idLength: options.idLength || 16 } );

	self.logger.info( 'Event system activated.' );
}
390989
function (options) {
        W.extend(this, W.eventMixin);
        this.socketUrl = options.socketUrl;
        this._connectionDesired = false;
        this.attemptReconnectionAfterMS = (typeof options.attemptReconnectionAfterMS !== 'undefined') ? options.attemptReconnectionAfterMS : 10000;
    }
417502
function OSMStream(options) {
  if (!(this instanceof OSMStream)) return new OSMStream(options);

  Transform.call(this, options);

  var primaryElements = ['node', 'way', 'relation']; // emit-ables
  var subElementName = ['tag', 'nd', 'member'];

  // size of bytes read from source so far
  this.bytesRead = 0;
  // size of bytes written to stream so far
  this.bytesWritten = 0;

  // initialize parser and its event handlers
  this._parser = new expat.Parser();

  this._parser.on('pipe', (function onParserPipe(src) {
    logger('_parser received pipe from ', src.path || '<unknown pipe>');
  }).bind(this));

  this._parser.on('startElement', (function onParserStartElement(name, attrs) {
    var funcname = ['__parse_', name].join('');
    if ((primaryElements.indexOf(name) > -1 && (OSMStream.prototype[funcname])) ||
      (subElementName.indexOf(name) > -1 && this._currentElement !== null && (OSMStream.prototype[funcname]))) {
      OSMStream.prototype[funcname].call(this, attrs);
    }
  }).bind(this));

  this._parser.on('endElement', (function onParserEndElement(name) {
    if ((primaryElements.indexOf(name) < 0)) return;

    var clone = extend({}, this._currentElement);
    this._currentElement = null;

    var pushData = function pushData(data) {
      if (!data) return;

      if (this.listeners('writeable').length > 0) {
        this.emit('writeable', data, (function onWriteable(data) {
          this.__push(data);
        }).bind(this));
      } else {
        this.__push(data);
      }

    }.bind(this);

    if (this.listeners(name).length > 0) {
      this.emit(name, clone, (function onElement(data) {
        pushData(data);
      }.bind(this)));
    } else {
      pushData(clone);
    }
  }).bind(this));

  this._parser.on('error', (function onParserError(err) {
    this.emit('error', err);
  }).bind(this));

  this._parser.on('end', (function onParserEnd() {
  }).bind(this));

  this.on('pipe', (function onPipe(src) {
    if (src === this._parser) return;
    // attaching stream pipe to parser
    logger('Received pipe from ', src.toString(), ', attaching pipe to _parser');
    src.pipe(this._parser);
    this._parser.pipe(this);
  }).bind(this));

}
572150
function Sender(prefix) {
        if (!prefix) {

            // Transports can't work without a prefix/namespace
            throw new Error(enplug.classes.Transport.prototype.TAG + 'Senders must specify a method prefix.');
        }

        /**
         * {@link Transport} namespace.
         * @type {string}
         */
        this.prefix = prefix;

        /**
         * Disables validation of method params. Used for testing.
         * @type {boolean}
         */
        this.novalidate = false;

        /**
         * Sends and receives messages to/from the parent window.
         * @type {Transport}
         */
        this.transport = new enplug.classes.Transport(window, prefix);
    }
337741
function LocalTransport(config) {
  this.id = config && config.id || null;
  this.networkId = this.id || null;
  this['default'] = config && config['default'] || false;
  this.agents = {};
}