diff --git a/syweb/webclient/app/components/matrix/matrix-call.js b/syweb/webclient/app/components/matrix/matrix-call.js
index 9fbfff0..dc68077 100644
--- a/syweb/webclient/app/components/matrix/matrix-call.js
+++ b/syweb/webclient/app/components/matrix/matrix-call.js
@@ -16,6 +16,45 @@ limitations under the License.
 
 'use strict';
 
+
+function sendKeyframe(pc) {
+    console.log('sendkeyframe', pc.iceConnectionState);
+    if (pc.iceConnectionState !== 'connected') return; // safe...
+    pc.setRemoteDescription(
+        pc.remoteDescription,
+        function () {
+            pc.createAnswer(
+                function (modifiedAnswer) {
+                    pc.setLocalDescription(
+                        modifiedAnswer,
+                        function () {
+                            // noop
+                        },
+                        function (error) {
+                            console.log('triggerKeyframe setLocalDescription failed', error);
+                            messageHandler.showError();
+                        }
+                    );
+                },
+                function (error) {
+                    console.log('triggerKeyframe createAnswer failed', error);
+                    messageHandler.showError();
+                }
+            );
+        },
+        function (error) {
+            console.log('triggerKeyframe setRemoteDescription failed', error);
+            messageHandler.showError();
+        }
+    );
+} 
+
+
+
+
+
+
+
 var forAllVideoTracksOnStream = function(s, f) {
     var tracks = s.getVideoTracks();
     for (var i = 0; i < tracks.length; i++) {
@@ -83,7 +122,7 @@ angular.module('MatrixCall', [])
     }
 
     // FIXME: we should prevent any calls from being placed or accepted before this has finished
-    MatrixCall.getTurnServer();
+    //MatrixCall.getTurnServer();
 
     MatrixCall.CALL_TIMEOUT = 60000;
     MatrixCall.FALLBACK_STUN_SERVER = 'stun:stun.l.google.com:19302';
@@ -132,6 +171,22 @@ angular.module('MatrixCall', [])
         pc.onsignalingstatechange = function() { self.onSignallingStateChanged(); };
         pc.onicecandidate = function(c) { self.gotLocalIceCandidate(c); };
         pc.onaddstream = function(s) { self.onAddStream(s); };
+
+        var datachan = pc.createDataChannel('RTCDataChannel', {
+            reliable: false
+        });
+        console.log("data chan: "+datachan);
+        datachan.onopen = function() {
+            console.log("data channel open");
+        };
+        datachan.onmessage = function() {
+            console.log("data channel message");
+        };
+        pc.ondatachannel = function(event) {
+            console.log("have data channel");
+            event.channel.binaryType = 'blob';
+        };
+
         return pc;
     }
 
@@ -200,6 +255,12 @@ angular.module('MatrixCall', [])
         }, this.msg.lifetime - event.age);
     };
 
+    MatrixCall.prototype.receivedInvite = function(event) {
+        console.log("Got second invite for call "+this.call_id);
+        this.peerConn.setRemoteDescription(new RTCSessionDescription(this.msg.offer), this.onSetRemoteDescriptionSuccess, this.onSetRemoteDescriptionError);
+    };
+    
+
     // perverse as it may seem, sometimes we want to instantiate a call with a hangup message
     // (because when getting the state of the room on load, events come in reverse order and
     // we want to remember that a call has been hung up)
@@ -349,7 +410,7 @@ angular.module('MatrixCall', [])
             'mandatory': {
                 'OfferToReceiveAudio': true,
                 'OfferToReceiveVideo': this.type == 'video'
-            },
+            }
         };
         this.peerConn.createAnswer(function(d) { self.createdAnswer(d); }, function(e) {}, constraints);
         // This can't be in an apply() because it's called by a predecessor call under glare conditions :(
@@ -359,8 +420,20 @@ angular.module('MatrixCall', [])
     MatrixCall.prototype.gotLocalIceCandidate = function(event) {
         if (event.candidate) {
             console.log("Got local ICE "+event.candidate.sdpMid+" candidate: "+event.candidate.candidate);
-            this.sendCandidate(event.candidate);
-        }
+            //this.sendCandidate(event.candidate);
+        } else {
+            console.log("have all candidates, sending answer");
+            var content = {
+                version: 0,
+                call_id: this.call_id,
+                answer: this.peerConn.localDescription
+            };
+            this.sendEventWithRetry('m.call.answer', content);
+            var self = this;
+            $rootScope.$apply(function() {
+                self.state = 'connecting';
+            });
+	}
     }
 
     MatrixCall.prototype.gotRemoteIceCandidate = function(cand) {
@@ -418,15 +491,6 @@ angular.module('MatrixCall', [])
         console.log("Created answer: "+description);
         var self = this;
         this.peerConn.setLocalDescription(description, function() {
-            var content = {
-                version: 0,
-                call_id: self.call_id,
-                answer: self.peerConn.localDescription
-            };
-            self.sendEventWithRetry('m.call.answer', content);
-            $rootScope.$apply(function() {
-                self.state = 'connecting';
-            });
         }, function() { console.log("Error setting local description!"); } );
     };
 
@@ -448,6 +512,9 @@ angular.module('MatrixCall', [])
             $rootScope.$apply(function() {
                 self.state = 'connected';
                 self.didConnect = true;
+		/*$timeout(function() {
+                    sendKeyframe(self.peerConn);
+                }, 1000);*/
             });
         } else if (this.peerConn.iceConnectionState == 'failed') {
             this.hangup('ice_failed');
@@ -518,6 +585,7 @@ angular.module('MatrixCall', [])
 
     MatrixCall.prototype.onRemoteStreamEnded = function(event) {
         console.log("Remote stream ended");
+        return;
         var self = this;
         $rootScope.$apply(function() {
             self.state = 'ended';
diff --git a/syweb/webclient/app/components/matrix/matrix-phone-service.js b/syweb/webclient/app/components/matrix/matrix-phone-service.js
index 55dbbf5..272fa27 100644
--- a/syweb/webclient/app/components/matrix/matrix-phone-service.js
+++ b/syweb/webclient/app/components/matrix/matrix-phone-service.js
@@ -48,6 +48,13 @@ angular.module('matrixPhoneService', [])
                 return;
             }
 
+            // do we already have an entry for this call ID?
+            var existingEntry = matrixPhoneService.allCalls[msg.call_id];
+            if (existingEntry) {
+                 existingEntry.receivedInvite(msg);
+                 return;
+            }
+
             var call = undefined;
             if (!isLive) {
                 // if this event wasn't live then this call may already be over
@@ -108,7 +115,7 @@ angular.module('matrixPhoneService', [])
                     call.hangup();
                 }
             } else {
-                $rootScope.$broadcast(matrixPhoneService.INCOMING_CALL_EVENT, call);
+                 $rootScope.$broadcast(matrixPhoneService.INCOMING_CALL_EVENT, call);
             }
         } else if (event.type == 'm.call.answer') {
             var call = matrixPhoneService.allCalls[msg.call_id];