UNPKG

thali

Version:
331 lines (297 loc) 19.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: NextGeneration/thaliWifiInfrastructure.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: NextGeneration/thaliWifiInfrastructure.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>'use strict'; var Promise = require('lie'); /** @module ThaliWifiInfrastructure */ /** * @file * * This is the interface used to manage local discover of peers over a Wi-Fi * Infrastructure mode access point. * * All the methods defined in this file are asynchronous. However any time a * method is called the invocation will immediately return but the request will * actually be put on a queue and all incoming requests will be run out of that * queue. This means that if one calls two start methods on say advertising or * discovery then the first start method will execute, call back its promise and * only then will the second start method start running. This restriction is in * place to simplify the state model and reduce testing. * * All stop methods in this file are idempotent so they can be called multiple * times in a row without causing a state change. */ /** * This creates an object to manage a WiFi instance. During production we will * have exactly one instance running but for testing purposes it's very useful * to be able to run multiple instances. So long as the SSDP code uses a * different port to advertise for responses for each instance and as the router * instances are already specified to use whatever ports are available the * different instances should not run into each other. * * __Open Issue:__ We need to confirm that the different instances will see * each other's SSDP advertisements and queries. * * @public * @constructor * @fires event:wifiPeerAvailabilityChanged * @fires event:networkChangedWifi * @fires discoveryAdvertisingStateUpdateWifiEvent */ function ThaliWifiInfrastructure() { } /** * This method MUST be called before any other method here other than * registering for events on the emitter. This method only registers the router * object but otherwise doesn't really do anything. It's just here to mirror how * {@link module:thaliMobileNativeWrapper} works. * * If the start fails then the object is not in start state. * * This method is not idempotent (even though it could be). If called two * times in a row without an intervening stop a "Call Stop!" Error MUST be * returned. * * This method can be called after stop since this is a singleton object. * * @param {Object} router This is an Express Router object (for example, * express-pouchdb is a router object) that the caller wants the WiFi * connections to be terminated with. This code will put that router at '/' so * make sure your paths are set up appropriately. * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.start = function (router) { return new Promise(); }; /** * This method will call all the stop methods and stop the TCP server hosting * the router. * * Once called the object is in the stop state. * * This method is idempotent and so MUST be able to be called multiple timex * in a row without changing state. * * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.stop = function () { return new Promise(); }; /** * This will start the local Wi-Fi Infrastructure Mode discovery mechanism * (currently SSDP). Calling this method will trigger {@link * event:wifiPeerAvailabilityChanged} to fire. This method only causes SSDP * queries to be fired and cause us to listen to other service's SSDP:alive and * SSDP:byebye messages. It doesn't advertise the service itself. * * This method is idempotent so multiple consecutive calls without an * intervening call to stop will not cause a state change. * * | Error String | Description | * |--------------|-------------| * | No Wifi radio | This device doesn't support Wifi | * | Radio Turned Off | Wifi is turned off. | * | Unspecified Error with Radio infrastructure | Something went wrong trying to use WiFi. Check the logs. | * | Call Start! | The object is not in start state. | * * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.startListeningForAdvertisements = function () { return new Promise(); }; /** * This will stop the local Wi-Fi Infrastructure Mode discovery mechanism * (currently SSDP). Calling this method will stop {@link * event:wifiPeerAvailabilityChanged} from firing. That is, we will not issue * any further SSDP queries nor will we listen for other service's SSDP:alive or * SSDP:byebye messages. * * Note that this method does not affect any existing TCP connections. Not * that we could really do anything with them since they are handled directly by * Node, not us. * * | Error String | Description | * |--------------|-------------| * | Failed | Somehow the stop method couldn't do its job. Check the logs. | * * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.stopListeningForAdvertisements = function () { return new Promise(); }; /** * This method will start advertising the peer's presence over the local Wi-Fi * Infrastructure Mode discovery mechanism (currently SSDP). When creating the * UDP socket for SSDP the socket MUST be "udp4". When socket.bind is called to * bind the socket to the SSDP multicast address and port, a random port will * automatically be picked by Node.js to bind the UDP port to locally. This * address is needed in order to set the location header in SSDP messages. This * port can be discovered via socket.address().port in the callback to the * socket.bind call. Note that we MUST make sure that the SSDP local UDP port is * picked randomly so we do not have collisions between multiple instances of * {@link module:ThaliWifiInfrastructure}. Also note that the implementation of * SSDP MUST recognize advertisements from its own instance and ignore them. * However it is possible to have multiple independent instances of * ThaliWiFiInfrastructure on the same device and we MUST process advertisements * from other instances of ThaliWifiInfrastructure on the same device. * * This method will also cause the Express app passed in to be hosted in a * HTTP server configured with the device's local IP. In other words, the * externally available HTTP server is not actually started and made externally * available until this method is called. This is different than {@link * module:thaliMobileNative} where the server is started on 127.0.0.1 as soon as * {@link module:thaliMobileNative.start} is called but isn't made externally * available over the non-TCP transport until the equivalent of this method is * called. If the device switches access points (e.g. the BSSID changes) or if * WiFi is lost then the server will be shut down. It is up to the caller to * catch the networkChanged event and to call start advertising again. * * __OPEN ISSUE:__ If we have a properly configured multiple AP network then * all the APs will have different BSSID values but identical SSID values and * the device should be able to keep the same IP. In that case do we want to * specify that if the BSSID changes but the SSID does not then we shouldn't * shut down the server? * * Each time this method is called it will cause the local advertisement to * change just enough to notify other peers that this peer has new data to * retrieve. No details will be provided about the peer on who the changes are * for. All that is provided is a flag just indicating that something has * changed. It is up to other peer to connect and retrieve details on what has * changed if they are interested. * * * By design this method is intended to be called multiple times without * calling stop as each call causes the currently notification flag to change. * * | Error String | Description | * |--------------|-------------| * | Bad Router | router is null or otherwise wasn't accepted by Express | * | No Wifi radio | This device doesn't support Wifi | * | Radio Turned Off | Wifi is turned off. | * | Unspecified Error with Radio infrastructure | Something went wrong trying to use WiFi. Check the logs. | * | Call Start! | The object is not in start state. | * * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.startUpdateAdvertisingAndListening = function() { return new Promise(); }; /** * This method MUST stop advertising the peer's presence over the local Wi-Fi * Infrastructure Mode discovery mechanism (currently SSDP). This method MUST * also stop the HTTP server started by the start method. * * So long as the device isn't advertising the peer and the server is stopped * (even if the system was always in that state) then this method MUST succeed. * * | Error String | Description | * |--------------|-------------| * | Failed | Somehow the stop method couldn't do its job. Check the logs. | * * @returns {Promise&lt;?Error>} */ ThaliWifiInfrastructure.prototype.stopAdvertisingAndListening = function() { return new Promise(); }; /** * This event specifies that a peer was discovered over Wi-Fi Infrastructure. * Please keep in mind that IP address bindings can change randomly amongst * peers and of course peers can disappear. So this should be considered more of * a hint than anything else. If the peer has gone (e.g. ssdp:byebye) then both * hostAddress and portNumber MUST be set to null. * * Note that when sending SSDP queries we MUST use a randomly assigned address * for the local UDP port as described in {@link * moduleThaliWifiInfrastructure.startUpdateAdvertisingAndListenForIncomingConne * ctions}. It is not necessary that this be the same UDP port as used in the * previously mentioned function. * * __Open Issue:__ There is a pretty obvious security hole here that a bad * actor could advertise a bunch of IP or DNS addresses of some innocent target * on a local network in order to trigger a connection storm. Given the various * limitations in place it's unclear how effective this would really be. There * are things we can to ameliorate the attack including only accepting IP * address that match the local network mask and also rate limiting how quickly * we are willing to connect to discovered peers. * * @event wifiPeerAvailabilityChanged * @public * @property {string} peerIdentifier This is the USN value * @property {string} hostAddress This can be either an IP address or a DNS * address encoded as a string * @property {number} portNumber The port on the hostAddress to use to connect * to the peer */ /** * For the definition of this event please see {@link * module:thaliMobileNativeWrapper~discoveryAdvertisingStateUpdateEvent} * * This notifies the listener whenever the state of discovery or advertising * changes. In {@link module:thaliMobileNativeWrapper} the equivalent of this * event is fired from the native layer and then works its way through {@link * module:thaliMobileNative} to {@link module:thaliMobileNativeWrapper}. But in * the case of Wifi there is no native layer. Therefore if there is a call to * start/stop discovery/advertising or if a network change event forces a change * in status (e.g. someone turned off Wifi) then this class MUST issue this * event itself. That is, it must have hooked into the start/stop methods, * start/stop discovery/advertising methods, {@link * module:thaliMobileNativeWrapper.nonTCPPeerAvailabilityChangedEvent} events * when we are on mobile devices and {@link * module:ThaliWifiInfrastructure.networkChangedWifi} when we are on desktop to * figure out when status has changed and this event needs to be fired. * * @public * @event discoveryAdvertisingStateUpdateWifiEvent * @type {Object} * @property {module:thaliMobileNative~discoveryAdvertisingStateUpdate} discoveryAdvertisingStateUpdateValue */ /** * For the definition of this event please see {@link * module:thaliMobileNativeWrapper~discoveryAdvertisingStateUpdateEvent}. * * The WiFi layer MUST NOT emit this event unless we are running on Linux, * OS/X or Windows. In the case that we are running on those platforms then If * we are running on those platforms then blueToothLowEnergy and blueTooth MUST * both return radioState set to `doNotCare`. Also note that these platforms * don't generally support a push based way to detect WiFi state (at least not * without writing native code). So for now we can use polling and something * like [network-scanner](https://www.npmjs.com/package/network-scanner) to give * us some sense of the system's state. * * @public * @event networkChangedWifi * @type {Object} * @property {module:thaliMobileNative~networkChanged} networkChangedValue * */ module.exports = ThaliWifiInfrastructure; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-TCPServersManager.html">TCPServersManager</a></li><li><a href="module-thaliMobile.html">thaliMobile</a></li><li><a href="module-thaliMobileNative.html">thaliMobileNative</a></li><li><a href="module-thaliMobileNativeWrapper.html">thaliMobileNativeWrapper</a></li><li><a href="module-thaliNotificationAction.html">thaliNotificationAction</a></li><li><a href="module-thaliNotificationBeacons.html">thaliNotificationBeacons</a></li><li><a href="module-thaliNotificationClient.html">thaliNotificationClient</a></li><li><a href="module-thaliNotificationServer.html">thaliNotificationServer</a></li><li><a href="module-thaliPeerAction.html">thaliPeerAction</a></li><li><a href="module-thaliPeerDictionary.html">thaliPeerDictionary</a></li><li><a href="module-thaliPeerPoolInterface.html">thaliPeerPoolInterface</a></li><li><a href="module-ThaliWifiInfrastructure.html">ThaliWifiInfrastructure</a></li><li><a href="module-WifiBasedNativeMock.html">WifiBasedNativeMock</a></li></ul><h3>Externals</h3><ul><li><a href="external-_Mobile(_connect_)_.html">Mobile('connect')</a></li><li><a href="external-_Mobile(_discoveryAdvertisingStateUpdateNonTCP_)_.html">Mobile('discoveryAdvertisingStateUpdateNonTCP')</a></li><li><a href="external-_Mobile(_incomingConnectionToPortNumberFailed_)_.html">Mobile('incomingConnectionToPortNumberFailed')</a></li><li><a href="external-_Mobile(_killConnections_)_.html">Mobile('killConnections')</a></li><li><a href="external-_Mobile(_networkChanged_)_.html">Mobile('networkChanged')</a></li><li><a href="external-_Mobile(_peerAvailabilityChanged_)_.html">Mobile('peerAvailabilityChanged')</a></li><li><a href="external-_Mobile(_startListeningForAdvertisements_)_.html">Mobile('startListeningForAdvertisements')</a></li><li><a href="external-_Mobile(_startUpdateAdvertisingAndListening_)_.html">Mobile('startUpdateAdvertisingAndListening')</a></li><li><a href="external-_Mobile(_stopAdvertisingAndListening_)_.html">Mobile('stopAdvertisingAndListening')</a></li><li><a href="external-_Mobile(_stopListeningForAdvertisements_)_.html">Mobile('stopListeningForAdvertisements')</a></li></ul><h3>Classes</h3><ul><li><a href="ConnectionTable.html">ConnectionTable</a></li><li><a href="module-TCPServersManager-TCPServersManager.html">TCPServersManager</a></li><li><a href="module-thaliNotificationAction-NotificationAction.html">NotificationAction</a></li><li><a href="module-thaliNotificationBeacons-ParseBeaconsResponse.html">ParseBeaconsResponse</a></li><li><a href="module-thaliNotificationClient-ThaliNotificationClient.html">ThaliNotificationClient</a></li><li><a href="module-thaliNotificationServer-ThaliNotificationServer.html">ThaliNotificationServer</a></li><li><a href="module-thaliPeerAction-PeerAction.html">PeerAction</a></li><li><a href="module-thaliPeerDictionary-NotificationPeerDictionaryEntry.html">NotificationPeerDictionaryEntry</a></li><li><a href="module-thaliPeerDictionary-PeerConnectionInformation.html">PeerConnectionInformation</a></li><li><a href="module-thaliPeerDictionary-PeerDictionary.html">PeerDictionary</a></li><li><a href="module-thaliPeerPoolInterface-ThaliPeerPoolInterface.html">ThaliPeerPoolInterface</a></li><li><a href="module-ThaliWifiInfrastructure-ThaliWifiInfrastructure.html">ThaliWifiInfrastructure</a></li><li><a href="module-WifiBasedNativeMock-MobileCallInstance.html">MobileCallInstance</a></li><li><a href="module-WifiBasedNativeMock-WifiBasedNativeMock.html">WifiBasedNativeMock</a></li></ul><h3>Events</h3><ul><li><a href="module-thaliMobileNativeWrapper.html#~event:discoveryAdvertisingStateUpdateNonTCPEvent">discoveryAdvertisingStateUpdateNonTCPEvent</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:discoveryAdvertisingStateUpdateWifiEvent">discoveryAdvertisingStateUpdateWifiEvent</a></li><li><a href="module-TCPServersManager.html#~event:failedConnection">failedConnection</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:incomingConnectionToPortNumberFailed">incomingConnectionToPortNumberFailed</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:networkChangedNonTCP">networkChangedNonTCP</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:networkChangedWifi">networkChangedWifi</a></li><li><a href="module-thaliMobileNativeWrapper.html#~event:nonTCPPeerAvailabilityChangedEvent">nonTCPPeerAvailabilityChangedEvent</a></li><li><a href="module-TCPServersManager.html#~event:routerPortConnectionFailed">routerPortConnectionFailed</a></li><li><a href="module-ThaliWifiInfrastructure.html#~event:wifiPeerAvailabilityChanged">wifiPeerAvailabilityChanged</a></li><li><a href="module-thaliMobile.html#.event:event:discoveryAdvertisingStateUpdate">discoveryAdvertisingStateUpdate</a></li><li><a href="module-thaliMobile.html#.event:event:networkChanged">networkChanged</a></li><li><a href="module-thaliMobile.html#.event:event:peerAvailabilityChanged">peerAvailabilityChanged</a></li><li><a href="module-thaliNotificationAction-NotificationAction.html#.event:event:Resolved">Resolved</a></li><li><a href="module-thaliNotificationClient.html#.event:event:peerAdvertisesDataForUs">peerAdvertisesDataForUs</a></li></ul><h3>Global</h3><ul><li><a href="global.html#getPKCS12Content">getPKCS12Content</a></li><li><a href="global.html#getPublicKeyHash">getPublicKeyHash</a></li><li><a href="global.html#stopThaliReplicationManager">stopThaliReplicationManager</a></li><li><a href="global.html#ThaliEmitter">ThaliEmitter</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Mon Jan 18 2016 11:19:31 GMT+0200 (EET) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>