diff --git a/linphone-desktop/assets/images/call_chat_secure_hovered.svg b/linphone-desktop/assets/images/call_chat_secure_hovered.svg
new file mode 100644
index 000000000..06d11d7aa
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_secure_hovered.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/images/call_chat_secure_normal.svg b/linphone-desktop/assets/images/call_chat_secure_normal.svg
new file mode 100644
index 000000000..06d11d7aa
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_secure_normal.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/images/call_chat_secure_pressed.svg b/linphone-desktop/assets/images/call_chat_secure_pressed.svg
new file mode 100644
index 000000000..06d11d7aa
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_secure_pressed.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/images/call_chat_unsecure_hovered.svg b/linphone-desktop/assets/images/call_chat_unsecure_hovered.svg
new file mode 100644
index 000000000..414fe3d76
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_unsecure_hovered.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/images/call_chat_unsecure_normal.svg b/linphone-desktop/assets/images/call_chat_unsecure_normal.svg
new file mode 100644
index 000000000..414fe3d76
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_unsecure_normal.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/images/call_chat_unsecure_pressed.svg b/linphone-desktop/assets/images/call_chat_unsecure_pressed.svg
new file mode 100644
index 000000000..414fe3d76
--- /dev/null
+++ b/linphone-desktop/assets/images/call_chat_unsecure_pressed.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/linphone-desktop/assets/languages/en.ts b/linphone-desktop/assets/languages/en.ts
index 5d14a2aa3..3518c737f 100644
--- a/linphone-desktop/assets/languages/en.ts
+++ b/linphone-desktop/assets/languages/en.ts
@@ -731,6 +731,26 @@ Server url not configured.
pendingRequestLabel
Please to wait, a request is pending.
+
+ Say:
+ Say:
+
+
+ Your correspondent should say:
+ Your correspondent should say:
+
+
+ Deny
+ DENY
+
+
+ Accept
+ ACCEPT
+
+
+ Confirm the following SAS with peer:
+ Confirm the following SAS with peer:
+
InviteFriends
diff --git a/linphone-desktop/assets/languages/fr.ts b/linphone-desktop/assets/languages/fr.ts
index 228ac12fe..23c45e1d1 100644
--- a/linphone-desktop/assets/languages/fr.ts
+++ b/linphone-desktop/assets/languages/fr.ts
@@ -731,6 +731,26 @@ Url du serveur non configurée.
pendingRequestLabel
Merci de patienter, une requête est en attente.
+
+ Say:
+ Dites :
+
+
+ Your correspondent should say:
+ Votre interlocuteur devrait dire :
+
+
+ Deny
+ REJETER
+
+
+ Accept
+ VALIDER
+
+
+ Confirm the following SAS with peer:
+ Confirmez le SAS suivant avec votre interlocuteur :
+
InviteFriends
diff --git a/linphone-desktop/resources.qrc b/linphone-desktop/resources.qrc
index 6b590b9a1..bc822f0d9 100644
--- a/linphone-desktop/resources.qrc
+++ b/linphone-desktop/resources.qrc
@@ -26,6 +26,12 @@
assets/images/call_accept_hovered.svg
assets/images/call_accept_normal.svg
assets/images/call_accept_pressed.svg
+ assets/images/call_chat_secure_hovered.svg
+ assets/images/call_chat_secure_normal.svg
+ assets/images/call_chat_secure_pressed.svg
+ assets/images/call_chat_unsecure_hovered.svg
+ assets/images/call_chat_unsecure_normal.svg
+ assets/images/call_chat_unsecure_pressed.svg
assets/images/call_hovered.svg
assets/images/call_normal.svg
assets/images/call_pressed.svg
diff --git a/linphone-desktop/src/components/call/CallModel.cpp b/linphone-desktop/src/components/call/CallModel.cpp
index 792bc67ec..9dcf31452 100644
--- a/linphone-desktop/src/components/call/CallModel.cpp
+++ b/linphone-desktop/src/components/call/CallModel.cpp
@@ -263,6 +263,7 @@ void CallModel::handleCallStateChanged (const shared_ptr &call,
break;
}
+ emit securityUpdated();
emit statusChanged(getStatus());
}
@@ -495,6 +496,56 @@ void CallModel::sendDtmf (const QString &dtmf) {
// -----------------------------------------------------------------------------
+CallModel::CallEncryption CallModel::getEncryption () const {
+ shared_ptr params = mCall->getCurrentParams();
+ linphone::MediaEncryption encryption = params->getMediaEncryption();
+ switch (encryption) {
+ case linphone::MediaEncryptionSRTP:
+ return CallEncryptionSRTP;
+ case linphone::MediaEncryptionZRTP:
+ return CallEncryptionZRTP;
+ case linphone::MediaEncryptionDTLS:
+ return CallEncryptionDTLS;
+ case linphone::MediaEncryptionNone:
+ default:
+ return CallEncryptionNone;
+ }
+}
+
+bool CallModel::isSecured () const {
+ shared_ptr params = mCall->getCurrentParams();
+ linphone::MediaEncryption encryption = params->getMediaEncryption();
+ return (encryption == linphone::MediaEncryptionZRTP && mCall->getAuthenticationTokenVerified())
+ || encryption == linphone::MediaEncryptionSRTP || encryption == linphone::MediaEncryptionDTLS;
+}
+
+QString CallModel::getLocalSAS() const {
+ QString token = mCall->getAuthenticationToken().c_str();
+ linphone::CallDir direction = mCall->getDir();
+ if (direction == linphone::CallDirIncoming) {
+ return token.left(2).toUpper();
+ } else {
+ return token.right(2).toUpper();
+ }
+}
+
+QString CallModel::getRemoteSAS() const {
+ QString token = mCall->getAuthenticationToken().c_str();
+ linphone::CallDir direction = mCall->getDir();
+ if (direction == linphone::CallDirIncoming) {
+ return token.right(2).toUpper();
+ } else {
+ return token.left(2).toUpper();
+ }
+}
+
+void CallModel::verifyAuthenticationToken(bool verify) {
+ mCall->setAuthenticationTokenVerified(verify);
+ emit securityUpdated();
+}
+
+// -----------------------------------------------------------------------------
+
QVariantList CallModel::getAudioStats () const {
return mAudioStats;
}
diff --git a/linphone-desktop/src/components/call/CallModel.hpp b/linphone-desktop/src/components/call/CallModel.hpp
index e1a9f30b2..bd9e40762 100644
--- a/linphone-desktop/src/components/call/CallModel.hpp
+++ b/linphone-desktop/src/components/call/CallModel.hpp
@@ -55,6 +55,11 @@ class CallModel : public QObject {
Q_PROPERTY(QVariantList audioStats READ getAudioStats NOTIFY statsUpdated);
Q_PROPERTY(QVariantList videoStats READ getVideoStats NOTIFY statsUpdated);
+ Q_PROPERTY(CallEncryption encryption READ getEncryption NOTIFY securityUpdated);
+ Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated);
+ Q_PROPERTY(QString localSAS READ getLocalSAS NOTIFY securityUpdated);
+ Q_PROPERTY(QString remoteSAS READ getRemoteSAS NOTIFY securityUpdated);
+
public:
enum CallStatus {
CallStatusConnected,
@@ -67,6 +72,15 @@ public:
Q_ENUM(CallStatus);
+ enum CallEncryption {
+ CallEncryptionNone,
+ CallEncryptionSRTP,
+ CallEncryptionZRTP,
+ CallEncryptionDTLS
+ };
+
+ Q_ENUM(CallEncryption);
+
CallModel (std::shared_ptr linphoneCall);
~CallModel ();
@@ -100,6 +114,8 @@ public:
Q_INVOKABLE void sendDtmf (const QString &dtmf);
+ Q_INVOKABLE void verifyAuthenticationToken(bool verify);
+
signals:
void callErrorChanged (const QString &callError);
void isInConferenceChanged (bool status);
@@ -108,6 +124,7 @@ signals:
void statsUpdated ();
void statusChanged (CallStatus status);
void videoRequested ();
+ void securityUpdated ();
private:
void handleCallStateChanged (const std::shared_ptr &call, linphone::CallState state);
@@ -145,10 +162,16 @@ private:
bool getRecording () const;
+ CallEncryption getEncryption () const;
+ bool isSecured () const;
+ QString getLocalSAS () const;
+ QString getRemoteSAS () const;
+
QVariantList getAudioStats () const;
QVariantList getVideoStats () const;
void updateStats (const std::shared_ptr &callStats, QVariantList &statsList);
+
QString iceStateToString (linphone::IceState state) const;
bool mIsInConference = false;
diff --git a/linphone-desktop/ui/views/App/Calls/Incall.js b/linphone-desktop/ui/views/App/Calls/Incall.js
index 2f3f291ed..afcf0be91 100644
--- a/linphone-desktop/ui/views/App/Calls/Incall.js
+++ b/linphone-desktop/ui/views/App/Calls/Incall.js
@@ -9,7 +9,7 @@
// =============================================================================
function computeAvatarSize (maxSize) {
- var height = container.height
+ var height = zrtp.visible ? container.height - zrtp.height : container.height
var width = container.width
var size = height < maxSize && height > 0 ? height : maxSize
diff --git a/linphone-desktop/ui/views/App/Calls/Incall.qml b/linphone-desktop/ui/views/App/Calls/Incall.qml
index 31fa54faa..1fd01ac0e 100644
--- a/linphone-desktop/ui/views/App/Calls/Incall.qml
+++ b/linphone-desktop/ui/views/App/Calls/Incall.qml
@@ -102,6 +102,13 @@ Rectangle {
onClicked: telKeypad.visible = !telKeypad.visible
}
+
+ ActionButton {
+ id: callSecure
+
+ icon: incall.call.isSecured ? 'call_chat_secure' : 'call_chat_unsecure'
+ onClicked: incall.call.encryption === CallModel.CallEncryptionZRTP ? zrtp.visible = true : zrtp.visible = false
+ }
}
ContactDescription {
@@ -228,7 +235,7 @@ Rectangle {
Camera {
call: incall.call
- height: container.height
+ height: zrtp.visible ? container.height - zrtp.height : container.height
width: container.width
}
}
@@ -242,6 +249,92 @@ Rectangle {
}
}
+ Item {
+ id: zrtp
+ height: CallStyle.zrtpArea.height
+ visible: false
+ Layout.fillWidth: true
+ anchors.top: container.bottom
+ Layout.margins: CallStyle.container.margins
+
+ GridLayout {
+ anchors.centerIn: parent
+ columns: 1
+
+ Text {
+ Layout.fillWidth: true
+ anchors.horizontalCenter: parent.horizontalCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ text: qsTr("Confirm the following SAS with peer:")
+ elide: Text.ElideRight
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ font.bold: true
+ color: Colors.j
+ }
+
+ RowLayout {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: CallStyle.zrtpArea.vu.spacing
+ Layout.fillWidth: true
+
+ Text {
+ text: qsTr("Say:")
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ color: Colors.j
+ }
+
+ Text {
+ text: incall.call.localSAS
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ font.bold: true
+ color: Colors.i
+ }
+
+ Text {
+ text: "-"
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ color: Colors.j
+ }
+
+ Text {
+ text: qsTr("Your correspondent should say:")
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ color: Colors.j
+ }
+
+ Text {
+ text: incall.call.remoteSAS
+ font.pointSize: CallStyle.zrtpArea.fontSize
+ font.bold: true
+ color: Colors.i
+ }
+ }
+
+ RowLayout {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: CallStyle.zrtpArea.vu.spacing
+ Layout.fillWidth: true
+
+ TextButtonA {
+ text: qsTr('Deny')
+ onClicked: {
+ zrtp.visible = false
+ incall.call.verifyAuthenticationToken(false)
+ }
+ }
+
+ TextButtonB {
+ text: qsTr('Accept')
+ onClicked: {
+ zrtp.visible = false
+ incall.call.verifyAuthenticationToken(true)
+ }
+ }
+ }
+ }
+ }
+
// -------------------------------------------------------------------------
// Action Buttons.
// -------------------------------------------------------------------------
diff --git a/linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml b/linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
index 8b762f51d..2b837dcdf 100644
--- a/linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
+++ b/linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
@@ -76,4 +76,13 @@ QtObject {
property int relativeY: 90
}
}
+
+ property QtObject zrtpArea: QtObject {
+ property int height: 50
+ property int fontSize: 12
+
+ property QtObject vu: QtObject {
+ property int spacing: 5
+ }
+ }
}
diff --git a/submodules/linphone b/submodules/linphone
index 87ca1adf5..19a0bf173 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 87ca1adf5ef967bb3876ea0c060cb9135f36718d
+Subproject commit 19a0bf173f7060dec5023292239a715ed807e327