Browse Source

fix 428 by ignoring error when trying to setLocalOffer when receiving

Jairo 7 years ago
parent
commit
380646fcb7
4 changed files with 332 additions and 232 deletions
  1. 166 116
      dist/peer.js
  2. 0 0
      dist/peer.min.js
  3. 166 115
      lib/negotiator.js
  4. 0 1
      lib/peer.js

+ 166 - 116
dist/peer.js

@@ -385,10 +385,10 @@ MediaConnection.prototype.close = function() {
 module.exports = MediaConnection;
 module.exports = MediaConnection;
 
 
 },{"./negotiator":5,"./util":8,"eventemitter3":9}],5:[function(require,module,exports){
 },{"./negotiator":5,"./util":8,"eventemitter3":9}],5:[function(require,module,exports){
-var util = require('./util');
-var RTCPeerConnection = require('./adapter').RTCPeerConnection;
-var RTCSessionDescription = require('./adapter').RTCSessionDescription;
-var RTCIceCandidate = require('./adapter').RTCIceCandidate;
+var util = require("./util");
+var RTCPeerConnection = require("./adapter").RTCPeerConnection;
+var RTCSessionDescription = require("./adapter").RTCSessionDescription;
+var RTCIceCandidate = require("./adapter").RTCIceCandidate;
 
 
 /**
 /**
  * Manages all negotiations between Peers.
  * Manages all negotiations between Peers.
@@ -400,9 +400,9 @@ var Negotiator = {
   }, // type => {peerId: {pc_id: pc}}.
   }, // type => {peerId: {pc_id: pc}}.
   //providers: {}, // provider's id => providers (there may be multiple providers/client.
   //providers: {}, // provider's id => providers (there may be multiple providers/client.
   queue: [] // connections that are delayed due to a PC being in use.
   queue: [] // connections that are delayed due to a PC being in use.
-}
+};
 
 
-Negotiator._idPrefix = 'pc_';
+Negotiator._idPrefix = "pc_";
 
 
 /** Returns a PeerConnection object set up correctly (for data, media). */
 /** Returns a PeerConnection object set up correctly (for data, media). */
 Negotiator.startConnection = function(connection, options) {
 Negotiator.startConnection = function(connection, options) {
@@ -411,14 +411,14 @@ Negotiator.startConnection = function(connection, options) {
   // Set the connection's PC.
   // Set the connection's PC.
   connection.pc = connection.peerConnection = pc;
   connection.pc = connection.peerConnection = pc;
 
 
-  if (connection.type === 'media' && options._stream) {
+  if (connection.type === "media" && options._stream) {
     // Add the stream.
     // Add the stream.
     pc.addStream(options._stream);
     pc.addStream(options._stream);
   }
   }
 
 
   // What do we need to do now?
   // What do we need to do now?
   if (options.originator) {
   if (options.originator) {
-    if (connection.type === 'data') {
+    if (connection.type === "data") {
       // Create the datachannel.
       // Create the datachannel.
       var config = {};
       var config = {};
       // Dropping reliable:false support, since it seems to be crashing
       // Dropping reliable:false support, since it seems to be crashing
@@ -429,7 +429,7 @@ Negotiator.startConnection = function(connection, options) {
       }*/
       }*/
       // Fallback to ensure older browsers don't crash.
       // Fallback to ensure older browsers don't crash.
       if (!util.supports.sctp) {
       if (!util.supports.sctp) {
-        config = {reliable: options.reliable};
+        config = { reliable: options.reliable };
       }
       }
       var dc = pc.createDataChannel(connection.label, config);
       var dc = pc.createDataChannel(connection.label, config);
       connection.initialize(dc);
       connection.initialize(dc);
@@ -439,13 +439,16 @@ Negotiator.startConnection = function(connection, options) {
       Negotiator._makeOffer(connection);
       Negotiator._makeOffer(connection);
     }
     }
   } else {
   } else {
-    Negotiator.handleSDP('OFFER', connection, options.sdp);
+    Negotiator.handleSDP("OFFER", connection, options.sdp);
   }
   }
-}
+};
 
 
 Negotiator._getPeerConnection = function(connection, options) {
 Negotiator._getPeerConnection = function(connection, options) {
   if (!Negotiator.pcs[connection.type]) {
   if (!Negotiator.pcs[connection.type]) {
-    util.error(connection.type + ' is not a valid connection type. Maybe you overrode the `type` property somewhere.');
+    util.error(
+      connection.type +
+        " is not a valid connection type. Maybe you overrode the `type` property somewhere."
+    );
   }
   }
 
 
   if (!Negotiator.pcs[connection.type][connection.peer]) {
   if (!Negotiator.pcs[connection.type][connection.peer]) {
@@ -464,15 +467,16 @@ Negotiator._getPeerConnection = function(connection, options) {
       }
       }
     }
     }
   } else */
   } else */
-  if (options.pc) { // Simplest case: PC id already provided for us.
+  if (options.pc) {
+    // Simplest case: PC id already provided for us.
     pc = Negotiator.pcs[connection.type][connection.peer][options.pc];
     pc = Negotiator.pcs[connection.type][connection.peer][options.pc];
   }
   }
 
 
-  if (!pc || pc.signalingState !== 'stable') {
+  if (!pc || pc.signalingState !== "stable") {
     pc = Negotiator._startPeerConnection(connection);
     pc = Negotiator._startPeerConnection(connection);
   }
   }
   return pc;
   return pc;
-}
+};
 
 
 /*
 /*
 Negotiator._addProvider = function(provider) {
 Negotiator._addProvider = function(provider) {
@@ -486,19 +490,18 @@ Negotiator._addProvider = function(provider) {
   }
   }
 }*/
 }*/
 
 
-
 /** Start a PC. */
 /** Start a PC. */
 Negotiator._startPeerConnection = function(connection) {
 Negotiator._startPeerConnection = function(connection) {
-  util.log('Creating RTCPeerConnection.');
+  util.log("Creating RTCPeerConnection.");
 
 
   var id = Negotiator._idPrefix + util.randomToken();
   var id = Negotiator._idPrefix + util.randomToken();
   var optional = {};
   var optional = {};
 
 
-  if (connection.type === 'data' && !util.supports.sctp) {
-    optional = {optional: [{RtpDataChannels: true}]};
-  } else if (connection.type === 'media') {
+  if (connection.type === "data" && !util.supports.sctp) {
+    optional = { optional: [{ RtpDataChannels: true }] };
+  } else if (connection.type === "media") {
     // Interop req for chrome.
     // Interop req for chrome.
-    optional = {optional: [{DtlsSrtpKeyAgreement: true}]};
+    optional = { optional: [{ DtlsSrtpKeyAgreement: true }] };
   }
   }
 
 
   var pc = new RTCPeerConnection(connection.provider.options.config, optional);
   var pc = new RTCPeerConnection(connection.provider.options.config, optional);
@@ -507,7 +510,7 @@ Negotiator._startPeerConnection = function(connection) {
   Negotiator._setupListeners(connection, pc, id);
   Negotiator._setupListeners(connection, pc, id);
 
 
   return pc;
   return pc;
-}
+};
 
 
 /** Set up various WebRTC listeners. */
 /** Set up various WebRTC listeners. */
 Negotiator._setupListeners = function(connection, pc, pc_id) {
 Negotiator._setupListeners = function(connection, pc, pc_id) {
@@ -516,12 +519,12 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
   var provider = connection.provider;
   var provider = connection.provider;
 
 
   // ICE CANDIDATES.
   // ICE CANDIDATES.
-  util.log('Listening for ICE candidates.');
+  util.log("Listening for ICE candidates.");
   pc.onicecandidate = function(evt) {
   pc.onicecandidate = function(evt) {
     if (evt.candidate) {
     if (evt.candidate) {
-      util.log('Received ICE candidates for:', connection.peer);
+      util.log("Received ICE candidates for:", connection.peer);
       provider.socket.send({
       provider.socket.send({
-        type: 'CANDIDATE',
+        type: "CANDIDATE",
         payload: {
         payload: {
           candidate: evt.candidate,
           candidate: evt.candidate,
           type: connection.type,
           type: connection.type,
@@ -534,16 +537,23 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
 
 
   pc.oniceconnectionstatechange = function() {
   pc.oniceconnectionstatechange = function() {
     switch (pc.iceConnectionState) {
     switch (pc.iceConnectionState) {
-      case 'failed':
-        util.log('iceConnectionState is disconnected, closing connections to ' + peerId);
-        connection.emit('error', new Error('Negotiation of connection to ' + peerId + ' failed.'));
+      case "failed":
+        util.log(
+          "iceConnectionState is disconnected, closing connections to " + peerId
+        );
+        connection.emit(
+          "error",
+          new Error("Negotiation of connection to " + peerId + " failed.")
+        );
         connection.close();
         connection.close();
         break;
         break;
-      case 'disconnected':
-        util.log('iceConnectionState is disconnected, closing connections to ' + peerId);
+      case "disconnected":
+        util.log(
+          "iceConnectionState is disconnected, closing connections to " + peerId
+        );
         connection.close();
         connection.close();
         break;
         break;
-      case 'completed':
+      case "completed":
         pc.onicecandidate = util.noop;
         pc.onicecandidate = util.noop;
         break;
         break;
     }
     }
@@ -553,31 +563,33 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
   pc.onicechange = pc.oniceconnectionstatechange;
   pc.onicechange = pc.oniceconnectionstatechange;
 
 
   // ONNEGOTIATIONNEEDED (Chrome)
   // ONNEGOTIATIONNEEDED (Chrome)
-  util.log('Listening for `negotiationneeded`');
+  util.log("Listening for `negotiationneeded`");
   pc.onnegotiationneeded = function() {
   pc.onnegotiationneeded = function() {
-    util.log('`negotiationneeded` triggered');
-    if (pc.signalingState == 'stable') {
+    util.log("`negotiationneeded` triggered");
+    if (pc.signalingState == "stable") {
       Negotiator._makeOffer(connection);
       Negotiator._makeOffer(connection);
     } else {
     } else {
-      util.log('onnegotiationneeded triggered when not stable. Is another connection being established?');
+      util.log(
+        "onnegotiationneeded triggered when not stable. Is another connection being established?"
+      );
     }
     }
   };
   };
 
 
   // DATACONNECTION.
   // DATACONNECTION.
-  util.log('Listening for data channel');
+  util.log("Listening for data channel");
   // Fired between offer and answer, so options should already be saved
   // Fired between offer and answer, so options should already be saved
   // in the options hash.
   // in the options hash.
   pc.ondatachannel = function(evt) {
   pc.ondatachannel = function(evt) {
-    util.log('Received data channel');
+    util.log("Received data channel");
     var dc = evt.channel;
     var dc = evt.channel;
     var connection = provider.getConnection(peerId, connectionId);
     var connection = provider.getConnection(peerId, connectionId);
     connection.initialize(dc);
     connection.initialize(dc);
   };
   };
 
 
   // MEDIACONNECTION.
   // MEDIACONNECTION.
-  util.log('Listening for remote stream');
+  util.log("Listening for remote stream");
   pc.onaddstream = function(evt) {
   pc.onaddstream = function(evt) {
-    util.log('Received remote stream');
+    util.log("Received remote stream");
     var stream = evt.stream;
     var stream = evt.stream;
     var connection = provider.getConnection(peerId, connectionId);
     var connection = provider.getConnection(peerId, connectionId);
     // 10/10/2014: looks like in Chrome 38, onaddstream is triggered after
     // 10/10/2014: looks like in Chrome 38, onaddstream is triggered after
@@ -585,118 +597,157 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
     // is actually a DATA connection, so addStream fails.
     // is actually a DATA connection, so addStream fails.
     // TODO: This is hopefully just a temporary fix. We should try to
     // TODO: This is hopefully just a temporary fix. We should try to
     // understand why this is happening.
     // understand why this is happening.
-    if (connection.type === 'media') {
+    if (connection.type === "media") {
       connection.addStream(stream);
       connection.addStream(stream);
     }
     }
   };
   };
-}
+};
 
 
 Negotiator.cleanup = function(connection) {
 Negotiator.cleanup = function(connection) {
-  util.log('Cleaning up PeerConnection to ' + connection.peer);
+  util.log("Cleaning up PeerConnection to " + connection.peer);
 
 
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  if (!!pc && ((pc.readyState && pc.readyState !== 'closed') || pc.signalingState !== 'closed')) {
+  if (
+    !!pc &&
+    ((pc.readyState && pc.readyState !== "closed") ||
+      pc.signalingState !== "closed")
+  ) {
     pc.close();
     pc.close();
     connection.pc = null;
     connection.pc = null;
   }
   }
-}
+};
 
 
 Negotiator._makeOffer = function(connection) {
 Negotiator._makeOffer = function(connection) {
   var pc = connection.pc;
   var pc = connection.pc;
-  pc.createOffer(function(offer) {
-    util.log('Created offer.');
-
-    if (!util.supports.sctp && connection.type === 'data' && connection.reliable) {
-      offer.sdp = Reliable.higherBandwidthSDP(offer.sdp);
-    }
+  pc.createOffer(
+    function(offer) {
+      util.log("Created offer.");
+
+      if (
+        !util.supports.sctp &&
+        connection.type === "data" &&
+        connection.reliable
+      ) {
+        offer.sdp = Reliable.higherBandwidthSDP(offer.sdp);
+      }
 
 
-    pc.setLocalDescription(offer, function() {
-      util.log('Set localDescription: offer', 'for:', connection.peer);
-      connection.provider.socket.send({
-        type: 'OFFER',
-        payload: {
-          sdp: offer,
-          type: connection.type,
-          label: connection.label,
-          connectionId: connection.id,
-          reliable: connection.reliable,
-          serialization: connection.serialization,
-          metadata: connection.metadata,
-          browser: util.browser
+      pc.setLocalDescription(
+        offer,
+        function() {
+          util.log("Set localDescription: offer", "for:", connection.peer);
+          connection.provider.socket.send({
+            type: "OFFER",
+            payload: {
+              sdp: offer,
+              type: connection.type,
+              label: connection.label,
+              connectionId: connection.id,
+              reliable: connection.reliable,
+              serialization: connection.serialization,
+              metadata: connection.metadata,
+              browser: util.browser
+            },
+            dst: connection.peer
+          });
         },
         },
-        dst: connection.peer
-      });
-    }, function(err) {
-      connection.provider.emitError('webrtc', err);
-      util.log('Failed to setLocalDescription, ', err);
-    });
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to createOffer, ', err);
-  }, connection.options.constraints);
-}
+        function(err) {
+          // TODO: investigate why _makeOffer is being called from the answer
+          if (
+            err !=
+            "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"
+          ) {
+            connection.provider.emitError("webrtc", err);
+            util.log("Failed to setLocalDescription, ", err);
+          }
+        }
+      );
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to createOffer, ", err);
+    },
+    connection.options.constraints
+  );
+};
 
 
 Negotiator._makeAnswer = function(connection) {
 Negotiator._makeAnswer = function(connection) {
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  pc.createAnswer(function(answer) {
-    util.log('Created answer.');
+  pc.createAnswer(
+    function(answer) {
+      util.log("Created answer.");
 
 
-    if (!util.supports.sctp && connection.type === 'data' && connection.reliable) {
-      answer.sdp = Reliable.higherBandwidthSDP(answer.sdp);
-    }
+      if (
+        !util.supports.sctp &&
+        connection.type === "data" &&
+        connection.reliable
+      ) {
+        answer.sdp = Reliable.higherBandwidthSDP(answer.sdp);
+      }
 
 
-    pc.setLocalDescription(answer, function() {
-      util.log('Set localDescription: answer', 'for:', connection.peer);
-      connection.provider.socket.send({
-        type: 'ANSWER',
-        payload: {
-          sdp: answer,
-          type: connection.type,
-          connectionId: connection.id,
-          browser: util.browser
+      pc.setLocalDescription(
+        answer,
+        function() {
+          util.log("Set localDescription: answer", "for:", connection.peer);
+          connection.provider.socket.send({
+            type: "ANSWER",
+            payload: {
+              sdp: answer,
+              type: connection.type,
+              connectionId: connection.id,
+              browser: util.browser
+            },
+            dst: connection.peer
+          });
         },
         },
-        dst: connection.peer
-      });
-    }, function(err) {
-      connection.provider.emitError('webrtc', err);
-      util.log('Failed to setLocalDescription, ', err);
-    });
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to create answer, ', err);
-  });
-}
+        function(err) {
+          connection.provider.emitError("webrtc", err);
+          util.log("Failed to setLocalDescription, ", err);
+        }
+      );
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to create answer, ", err);
+    }
+  );
+};
 
 
 /** Handle an SDP. */
 /** Handle an SDP. */
 Negotiator.handleSDP = function(type, connection, sdp) {
 Negotiator.handleSDP = function(type, connection, sdp) {
   sdp = new RTCSessionDescription(sdp);
   sdp = new RTCSessionDescription(sdp);
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  util.log('Setting remote description', sdp);
-  pc.setRemoteDescription(sdp, function() {
-    util.log('Set remoteDescription:', type, 'for:', connection.peer);
+  util.log("Setting remote description", sdp);
+  pc.setRemoteDescription(
+    sdp,
+    function() {
+      util.log("Set remoteDescription:", type, "for:", connection.peer);
 
 
-    if (type === 'OFFER') {
-      Negotiator._makeAnswer(connection);
+      if (type === "OFFER") {
+        Negotiator._makeAnswer(connection);
+      }
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to setRemoteDescription, ", err);
     }
     }
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to setRemoteDescription, ', err);
-  });
-}
+  );
+};
 
 
 /** Handle a candidate. */
 /** Handle a candidate. */
 Negotiator.handleCandidate = function(connection, ice) {
 Negotiator.handleCandidate = function(connection, ice) {
   var candidate = ice.candidate;
   var candidate = ice.candidate;
   var sdpMLineIndex = ice.sdpMLineIndex;
   var sdpMLineIndex = ice.sdpMLineIndex;
-  connection.pc.addIceCandidate(new RTCIceCandidate({
-    sdpMLineIndex: sdpMLineIndex,
-    candidate: candidate
-  }));
-  util.log('Added ICE candidate for:', connection.peer);
-}
+  connection.pc.addIceCandidate(
+    new RTCIceCandidate({
+      sdpMLineIndex: sdpMLineIndex,
+      candidate: candidate
+    })
+  );
+  util.log("Added ICE candidate for:", connection.peer);
+};
 
 
 module.exports = Negotiator;
 module.exports = Negotiator;
 
 
@@ -941,7 +992,6 @@ Peer.prototype._handleMessage = function(message) {
       if (connection) {
       if (connection) {
         connection.close();
         connection.close();
         util.warn("Offer received for existing Connection ID:", connectionId);
         util.warn("Offer received for existing Connection ID:", connectionId);
-        //connection.handleMessage(message);
       }
       }
 
 
       // Create a new connection.
       // Create a new connection.

File diff suppressed because it is too large
+ 0 - 0
dist/peer.min.js


+ 166 - 115
lib/negotiator.js

@@ -1,7 +1,7 @@
-var util = require('./util');
-var RTCPeerConnection = require('./adapter').RTCPeerConnection;
-var RTCSessionDescription = require('./adapter').RTCSessionDescription;
-var RTCIceCandidate = require('./adapter').RTCIceCandidate;
+var util = require("./util");
+var RTCPeerConnection = require("./adapter").RTCPeerConnection;
+var RTCSessionDescription = require("./adapter").RTCSessionDescription;
+var RTCIceCandidate = require("./adapter").RTCIceCandidate;
 
 
 /**
 /**
  * Manages all negotiations between Peers.
  * Manages all negotiations between Peers.
@@ -13,9 +13,9 @@ var Negotiator = {
   }, // type => {peerId: {pc_id: pc}}.
   }, // type => {peerId: {pc_id: pc}}.
   //providers: {}, // provider's id => providers (there may be multiple providers/client.
   //providers: {}, // provider's id => providers (there may be multiple providers/client.
   queue: [] // connections that are delayed due to a PC being in use.
   queue: [] // connections that are delayed due to a PC being in use.
-}
+};
 
 
-Negotiator._idPrefix = 'pc_';
+Negotiator._idPrefix = "pc_";
 
 
 /** Returns a PeerConnection object set up correctly (for data, media). */
 /** Returns a PeerConnection object set up correctly (for data, media). */
 Negotiator.startConnection = function(connection, options) {
 Negotiator.startConnection = function(connection, options) {
@@ -24,14 +24,14 @@ Negotiator.startConnection = function(connection, options) {
   // Set the connection's PC.
   // Set the connection's PC.
   connection.pc = connection.peerConnection = pc;
   connection.pc = connection.peerConnection = pc;
 
 
-  if (connection.type === 'media' && options._stream) {
+  if (connection.type === "media" && options._stream) {
     // Add the stream.
     // Add the stream.
     pc.addStream(options._stream);
     pc.addStream(options._stream);
   }
   }
 
 
   // What do we need to do now?
   // What do we need to do now?
   if (options.originator) {
   if (options.originator) {
-    if (connection.type === 'data') {
+    if (connection.type === "data") {
       // Create the datachannel.
       // Create the datachannel.
       var config = {};
       var config = {};
       // Dropping reliable:false support, since it seems to be crashing
       // Dropping reliable:false support, since it seems to be crashing
@@ -42,7 +42,7 @@ Negotiator.startConnection = function(connection, options) {
       }*/
       }*/
       // Fallback to ensure older browsers don't crash.
       // Fallback to ensure older browsers don't crash.
       if (!util.supports.sctp) {
       if (!util.supports.sctp) {
-        config = {reliable: options.reliable};
+        config = { reliable: options.reliable };
       }
       }
       var dc = pc.createDataChannel(connection.label, config);
       var dc = pc.createDataChannel(connection.label, config);
       connection.initialize(dc);
       connection.initialize(dc);
@@ -52,13 +52,16 @@ Negotiator.startConnection = function(connection, options) {
       Negotiator._makeOffer(connection);
       Negotiator._makeOffer(connection);
     }
     }
   } else {
   } else {
-    Negotiator.handleSDP('OFFER', connection, options.sdp);
+    Negotiator.handleSDP("OFFER", connection, options.sdp);
   }
   }
-}
+};
 
 
 Negotiator._getPeerConnection = function(connection, options) {
 Negotiator._getPeerConnection = function(connection, options) {
   if (!Negotiator.pcs[connection.type]) {
   if (!Negotiator.pcs[connection.type]) {
-    util.error(connection.type + ' is not a valid connection type. Maybe you overrode the `type` property somewhere.');
+    util.error(
+      connection.type +
+        " is not a valid connection type. Maybe you overrode the `type` property somewhere."
+    );
   }
   }
 
 
   if (!Negotiator.pcs[connection.type][connection.peer]) {
   if (!Negotiator.pcs[connection.type][connection.peer]) {
@@ -77,15 +80,16 @@ Negotiator._getPeerConnection = function(connection, options) {
       }
       }
     }
     }
   } else */
   } else */
-  if (options.pc) { // Simplest case: PC id already provided for us.
+  if (options.pc) {
+    // Simplest case: PC id already provided for us.
     pc = Negotiator.pcs[connection.type][connection.peer][options.pc];
     pc = Negotiator.pcs[connection.type][connection.peer][options.pc];
   }
   }
 
 
-  if (!pc || pc.signalingState !== 'stable') {
+  if (!pc || pc.signalingState !== "stable") {
     pc = Negotiator._startPeerConnection(connection);
     pc = Negotiator._startPeerConnection(connection);
   }
   }
   return pc;
   return pc;
-}
+};
 
 
 /*
 /*
 Negotiator._addProvider = function(provider) {
 Negotiator._addProvider = function(provider) {
@@ -99,19 +103,18 @@ Negotiator._addProvider = function(provider) {
   }
   }
 }*/
 }*/
 
 
-
 /** Start a PC. */
 /** Start a PC. */
 Negotiator._startPeerConnection = function(connection) {
 Negotiator._startPeerConnection = function(connection) {
-  util.log('Creating RTCPeerConnection.');
+  util.log("Creating RTCPeerConnection.");
 
 
   var id = Negotiator._idPrefix + util.randomToken();
   var id = Negotiator._idPrefix + util.randomToken();
   var optional = {};
   var optional = {};
 
 
-  if (connection.type === 'data' && !util.supports.sctp) {
-    optional = {optional: [{RtpDataChannels: true}]};
-  } else if (connection.type === 'media') {
+  if (connection.type === "data" && !util.supports.sctp) {
+    optional = { optional: [{ RtpDataChannels: true }] };
+  } else if (connection.type === "media") {
     // Interop req for chrome.
     // Interop req for chrome.
-    optional = {optional: [{DtlsSrtpKeyAgreement: true}]};
+    optional = { optional: [{ DtlsSrtpKeyAgreement: true }] };
   }
   }
 
 
   var pc = new RTCPeerConnection(connection.provider.options.config, optional);
   var pc = new RTCPeerConnection(connection.provider.options.config, optional);
@@ -120,7 +123,7 @@ Negotiator._startPeerConnection = function(connection) {
   Negotiator._setupListeners(connection, pc, id);
   Negotiator._setupListeners(connection, pc, id);
 
 
   return pc;
   return pc;
-}
+};
 
 
 /** Set up various WebRTC listeners. */
 /** Set up various WebRTC listeners. */
 Negotiator._setupListeners = function(connection, pc, pc_id) {
 Negotiator._setupListeners = function(connection, pc, pc_id) {
@@ -129,12 +132,12 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
   var provider = connection.provider;
   var provider = connection.provider;
 
 
   // ICE CANDIDATES.
   // ICE CANDIDATES.
-  util.log('Listening for ICE candidates.');
+  util.log("Listening for ICE candidates.");
   pc.onicecandidate = function(evt) {
   pc.onicecandidate = function(evt) {
     if (evt.candidate) {
     if (evt.candidate) {
-      util.log('Received ICE candidates for:', connection.peer);
+      util.log("Received ICE candidates for:", connection.peer);
       provider.socket.send({
       provider.socket.send({
-        type: 'CANDIDATE',
+        type: "CANDIDATE",
         payload: {
         payload: {
           candidate: evt.candidate,
           candidate: evt.candidate,
           type: connection.type,
           type: connection.type,
@@ -147,16 +150,23 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
 
 
   pc.oniceconnectionstatechange = function() {
   pc.oniceconnectionstatechange = function() {
     switch (pc.iceConnectionState) {
     switch (pc.iceConnectionState) {
-      case 'failed':
-        util.log('iceConnectionState is disconnected, closing connections to ' + peerId);
-        connection.emit('error', new Error('Negotiation of connection to ' + peerId + ' failed.'));
+      case "failed":
+        util.log(
+          "iceConnectionState is disconnected, closing connections to " + peerId
+        );
+        connection.emit(
+          "error",
+          new Error("Negotiation of connection to " + peerId + " failed.")
+        );
         connection.close();
         connection.close();
         break;
         break;
-      case 'disconnected':
-        util.log('iceConnectionState is disconnected, closing connections to ' + peerId);
+      case "disconnected":
+        util.log(
+          "iceConnectionState is disconnected, closing connections to " + peerId
+        );
         connection.close();
         connection.close();
         break;
         break;
-      case 'completed':
+      case "completed":
         pc.onicecandidate = util.noop;
         pc.onicecandidate = util.noop;
         break;
         break;
     }
     }
@@ -166,31 +176,33 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
   pc.onicechange = pc.oniceconnectionstatechange;
   pc.onicechange = pc.oniceconnectionstatechange;
 
 
   // ONNEGOTIATIONNEEDED (Chrome)
   // ONNEGOTIATIONNEEDED (Chrome)
-  util.log('Listening for `negotiationneeded`');
+  util.log("Listening for `negotiationneeded`");
   pc.onnegotiationneeded = function() {
   pc.onnegotiationneeded = function() {
-    util.log('`negotiationneeded` triggered');
-    if (pc.signalingState == 'stable') {
+    util.log("`negotiationneeded` triggered");
+    if (pc.signalingState == "stable") {
       Negotiator._makeOffer(connection);
       Negotiator._makeOffer(connection);
     } else {
     } else {
-      util.log('onnegotiationneeded triggered when not stable. Is another connection being established?');
+      util.log(
+        "onnegotiationneeded triggered when not stable. Is another connection being established?"
+      );
     }
     }
   };
   };
 
 
   // DATACONNECTION.
   // DATACONNECTION.
-  util.log('Listening for data channel');
+  util.log("Listening for data channel");
   // Fired between offer and answer, so options should already be saved
   // Fired between offer and answer, so options should already be saved
   // in the options hash.
   // in the options hash.
   pc.ondatachannel = function(evt) {
   pc.ondatachannel = function(evt) {
-    util.log('Received data channel');
+    util.log("Received data channel");
     var dc = evt.channel;
     var dc = evt.channel;
     var connection = provider.getConnection(peerId, connectionId);
     var connection = provider.getConnection(peerId, connectionId);
     connection.initialize(dc);
     connection.initialize(dc);
   };
   };
 
 
   // MEDIACONNECTION.
   // MEDIACONNECTION.
-  util.log('Listening for remote stream');
+  util.log("Listening for remote stream");
   pc.onaddstream = function(evt) {
   pc.onaddstream = function(evt) {
-    util.log('Received remote stream');
+    util.log("Received remote stream");
     var stream = evt.stream;
     var stream = evt.stream;
     var connection = provider.getConnection(peerId, connectionId);
     var connection = provider.getConnection(peerId, connectionId);
     // 10/10/2014: looks like in Chrome 38, onaddstream is triggered after
     // 10/10/2014: looks like in Chrome 38, onaddstream is triggered after
@@ -198,117 +210,156 @@ Negotiator._setupListeners = function(connection, pc, pc_id) {
     // is actually a DATA connection, so addStream fails.
     // is actually a DATA connection, so addStream fails.
     // TODO: This is hopefully just a temporary fix. We should try to
     // TODO: This is hopefully just a temporary fix. We should try to
     // understand why this is happening.
     // understand why this is happening.
-    if (connection.type === 'media') {
+    if (connection.type === "media") {
       connection.addStream(stream);
       connection.addStream(stream);
     }
     }
   };
   };
-}
+};
 
 
 Negotiator.cleanup = function(connection) {
 Negotiator.cleanup = function(connection) {
-  util.log('Cleaning up PeerConnection to ' + connection.peer);
+  util.log("Cleaning up PeerConnection to " + connection.peer);
 
 
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  if (!!pc && ((pc.readyState && pc.readyState !== 'closed') || pc.signalingState !== 'closed')) {
+  if (
+    !!pc &&
+    ((pc.readyState && pc.readyState !== "closed") ||
+      pc.signalingState !== "closed")
+  ) {
     pc.close();
     pc.close();
     connection.pc = null;
     connection.pc = null;
   }
   }
-}
+};
 
 
 Negotiator._makeOffer = function(connection) {
 Negotiator._makeOffer = function(connection) {
   var pc = connection.pc;
   var pc = connection.pc;
-  pc.createOffer(function(offer) {
-    util.log('Created offer.');
-
-    if (!util.supports.sctp && connection.type === 'data' && connection.reliable) {
-      offer.sdp = Reliable.higherBandwidthSDP(offer.sdp);
-    }
+  pc.createOffer(
+    function(offer) {
+      util.log("Created offer.");
+
+      if (
+        !util.supports.sctp &&
+        connection.type === "data" &&
+        connection.reliable
+      ) {
+        offer.sdp = Reliable.higherBandwidthSDP(offer.sdp);
+      }
 
 
-    pc.setLocalDescription(offer, function() {
-      util.log('Set localDescription: offer', 'for:', connection.peer);
-      connection.provider.socket.send({
-        type: 'OFFER',
-        payload: {
-          sdp: offer,
-          type: connection.type,
-          label: connection.label,
-          connectionId: connection.id,
-          reliable: connection.reliable,
-          serialization: connection.serialization,
-          metadata: connection.metadata,
-          browser: util.browser
+      pc.setLocalDescription(
+        offer,
+        function() {
+          util.log("Set localDescription: offer", "for:", connection.peer);
+          connection.provider.socket.send({
+            type: "OFFER",
+            payload: {
+              sdp: offer,
+              type: connection.type,
+              label: connection.label,
+              connectionId: connection.id,
+              reliable: connection.reliable,
+              serialization: connection.serialization,
+              metadata: connection.metadata,
+              browser: util.browser
+            },
+            dst: connection.peer
+          });
         },
         },
-        dst: connection.peer
-      });
-    }, function(err) {
-      connection.provider.emitError('webrtc', err);
-      util.log('Failed to setLocalDescription, ', err);
-    });
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to createOffer, ', err);
-  }, connection.options.constraints);
-}
+        function(err) {
+          // TODO: investigate why _makeOffer is being called from the answer
+          if (
+            err !=
+            "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"
+          ) {
+            connection.provider.emitError("webrtc", err);
+            util.log("Failed to setLocalDescription, ", err);
+          }
+        }
+      );
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to createOffer, ", err);
+    },
+    connection.options.constraints
+  );
+};
 
 
 Negotiator._makeAnswer = function(connection) {
 Negotiator._makeAnswer = function(connection) {
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  pc.createAnswer(function(answer) {
-    util.log('Created answer.');
+  pc.createAnswer(
+    function(answer) {
+      util.log("Created answer.");
 
 
-    if (!util.supports.sctp && connection.type === 'data' && connection.reliable) {
-      answer.sdp = Reliable.higherBandwidthSDP(answer.sdp);
-    }
+      if (
+        !util.supports.sctp &&
+        connection.type === "data" &&
+        connection.reliable
+      ) {
+        answer.sdp = Reliable.higherBandwidthSDP(answer.sdp);
+      }
 
 
-    pc.setLocalDescription(answer, function() {
-      util.log('Set localDescription: answer', 'for:', connection.peer);
-      connection.provider.socket.send({
-        type: 'ANSWER',
-        payload: {
-          sdp: answer,
-          type: connection.type,
-          connectionId: connection.id,
-          browser: util.browser
+      pc.setLocalDescription(
+        answer,
+        function() {
+          util.log("Set localDescription: answer", "for:", connection.peer);
+          connection.provider.socket.send({
+            type: "ANSWER",
+            payload: {
+              sdp: answer,
+              type: connection.type,
+              connectionId: connection.id,
+              browser: util.browser
+            },
+            dst: connection.peer
+          });
         },
         },
-        dst: connection.peer
-      });
-    }, function(err) {
-      connection.provider.emitError('webrtc', err);
-      util.log('Failed to setLocalDescription, ', err);
-    });
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to create answer, ', err);
-  });
-}
+        function(err) {
+          connection.provider.emitError("webrtc", err);
+          util.log("Failed to setLocalDescription, ", err);
+        }
+      );
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to create answer, ", err);
+    }
+  );
+};
 
 
 /** Handle an SDP. */
 /** Handle an SDP. */
 Negotiator.handleSDP = function(type, connection, sdp) {
 Negotiator.handleSDP = function(type, connection, sdp) {
   sdp = new RTCSessionDescription(sdp);
   sdp = new RTCSessionDescription(sdp);
   var pc = connection.pc;
   var pc = connection.pc;
 
 
-  util.log('Setting remote description', sdp);
-  pc.setRemoteDescription(sdp, function() {
-    util.log('Set remoteDescription:', type, 'for:', connection.peer);
+  util.log("Setting remote description", sdp);
+  pc.setRemoteDescription(
+    sdp,
+    function() {
+      util.log("Set remoteDescription:", type, "for:", connection.peer);
 
 
-    if (type === 'OFFER') {
-      Negotiator._makeAnswer(connection);
+      if (type === "OFFER") {
+        Negotiator._makeAnswer(connection);
+      }
+    },
+    function(err) {
+      connection.provider.emitError("webrtc", err);
+      util.log("Failed to setRemoteDescription, ", err);
     }
     }
-  }, function(err) {
-    connection.provider.emitError('webrtc', err);
-    util.log('Failed to setRemoteDescription, ', err);
-  });
-}
+  );
+};
 
 
 /** Handle a candidate. */
 /** Handle a candidate. */
 Negotiator.handleCandidate = function(connection, ice) {
 Negotiator.handleCandidate = function(connection, ice) {
   var candidate = ice.candidate;
   var candidate = ice.candidate;
   var sdpMLineIndex = ice.sdpMLineIndex;
   var sdpMLineIndex = ice.sdpMLineIndex;
-  connection.pc.addIceCandidate(new RTCIceCandidate({
-    sdpMLineIndex: sdpMLineIndex,
-    candidate: candidate
-  }));
-  util.log('Added ICE candidate for:', connection.peer);
-}
+  connection.pc.addIceCandidate(
+    new RTCIceCandidate({
+      sdpMLineIndex: sdpMLineIndex,
+      candidate: candidate
+    })
+  );
+  util.log("Added ICE candidate for:", connection.peer);
+};
 
 
 module.exports = Negotiator;
 module.exports = Negotiator;

+ 0 - 1
lib/peer.js

@@ -238,7 +238,6 @@ Peer.prototype._handleMessage = function(message) {
       if (connection) {
       if (connection) {
         connection.close();
         connection.close();
         util.warn("Offer received for existing Connection ID:", connectionId);
         util.warn("Offer received for existing Connection ID:", connectionId);
-        //connection.handleMessage(message);
       }
       }
 
 
       // Create a new connection.
       // Create a new connection.

Some files were not shown because too many files changed in this diff