mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-25 04:15:31 +00:00
mobile: webrtc calls (#661)
* mobile: webrtc calls work on Android and iOS separately * core: only send public key with offer if invitation/current call supports e2ee * update npm module
This commit is contained in:
committed by
GitHub
parent
106dceabfc
commit
dc418923ac
+7
-8
@@ -430,13 +430,13 @@ processChatCommand = \case
|
||||
`E.finally` deleteContactRequest st userId connReqId
|
||||
withAgent $ \a -> rejectContact a connId invId
|
||||
pure $ CRContactRequestRejected cReq
|
||||
APISendCallInvitation contactId callType@CallType {capabilities = CallCapabilities {encryption}} -> withUser $ \user@User {userId} -> do
|
||||
APISendCallInvitation contactId callType -> withUser $ \user@User {userId} -> do
|
||||
-- party initiating call
|
||||
ct <- withStore $ \st -> getContact st userId contactId
|
||||
calls <- asks currentCalls
|
||||
withChatLock $ do
|
||||
callId <- CallId <$> (asks idsDrg >>= liftIO . (`randomBytes` 16))
|
||||
dhKeyPair <- if encryption then Just <$> liftIO C.generateKeyPair' else pure Nothing
|
||||
dhKeyPair <- if encryptedCall callType then Just <$> liftIO C.generateKeyPair' else pure Nothing
|
||||
let invitation = CallInvitation {callType, callDhPubKey = fst <$> dhKeyPair}
|
||||
callState = CallInvitationSent {localCallType = callType, localDhPrivKey = snd <$> dhKeyPair}
|
||||
msg@SndMessage {msgId} <- sendDirectContactMessage ct (XCallInv callId invitation)
|
||||
@@ -460,8 +460,8 @@ processChatCommand = \case
|
||||
-- party accepting call
|
||||
withCurrentCall contactId $ \userId ct call@Call {callId, chatItemId, callState} -> case callState of
|
||||
CallInvitationReceived {peerCallType, localDhPubKey, sharedKey} -> do
|
||||
-- TODO check that call type matches peerCallType
|
||||
let offer = CallOffer {callType, rtcSession, callDhPubKey = localDhPubKey}
|
||||
let callDhPubKey = if encryptedCall callType then localDhPubKey else Nothing
|
||||
offer = CallOffer {callType, rtcSession, callDhPubKey}
|
||||
callState' = CallOfferSent {localCallType = callType, peerCallType, localCallSession = rtcSession, sharedKey}
|
||||
aciContent = ACIContent SMDRcv $ CIRcvCall CISCallAccepted 0
|
||||
SndMessage {msgId} <- sendDirectContactMessage ct (XCallOffer callId offer)
|
||||
@@ -1630,8 +1630,7 @@ processAgentMessage (Just user@User {userId, profile}) agentConnId agentMessage
|
||||
xCallInv :: Contact -> CallId -> CallInvitation -> RcvMessage -> MsgMeta -> m ()
|
||||
xCallInv ct@Contact {contactId} callId CallInvitation {callType, callDhPubKey} msg@RcvMessage {msgId} msgMeta = do
|
||||
checkIntegrity msgMeta $ toView . CRMsgIntegrityError
|
||||
let CallType {capabilities = CallCapabilities {encryption}} = callType
|
||||
dhKeyPair <- if encryption then Just <$> liftIO C.generateKeyPair' else pure Nothing
|
||||
dhKeyPair <- if encryptedCall callType then Just <$> liftIO C.generateKeyPair' else pure Nothing
|
||||
ci <- saveCallItem CISCallPending
|
||||
let sharedKey = C.Key . C.dhBytes' <$> (C.dh' <$> callDhPubKey <*> (snd <$> dhKeyPair))
|
||||
callState = CallInvitationReceived {peerCallType = callType, localDhPubKey = fst <$> dhKeyPair, sharedKey}
|
||||
@@ -1655,8 +1654,8 @@ processAgentMessage (Just user@User {userId, profile}) agentConnId agentMessage
|
||||
CallInvitationSent {localCallType, localDhPrivKey} -> do
|
||||
let sharedKey = C.Key . C.dhBytes' <$> (C.dh' <$> callDhPubKey <*> localDhPrivKey)
|
||||
callState' = CallOfferReceived {localCallType, peerCallType = callType, peerCallSession = rtcSession, sharedKey}
|
||||
-- TODO decide if should askConfirmation
|
||||
toView CRCallOffer {contact = ct, callType, offer = rtcSession, sharedKey, askConfirmation = False}
|
||||
askConfirmation = encryptedCall localCallType && not (encryptedCall callType)
|
||||
toView CRCallOffer {contact = ct, callType, offer = rtcSession, sharedKey, askConfirmation}
|
||||
pure (Just call {callState = callState'}, Just . ACIContent SMDSnd $ CISndCall CISCallAccepted 0)
|
||||
_ -> do
|
||||
msgCallStateError "x.call.offer" call
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Simplex.Chat.Call where
|
||||
@@ -99,6 +100,9 @@ data CallType = CallType
|
||||
defaultCallType :: CallType
|
||||
defaultCallType = CallType CMVideo $ CallCapabilities {encryption = True}
|
||||
|
||||
encryptedCall :: CallType -> Bool
|
||||
encryptedCall CallType {capabilities = CallCapabilities {encryption}} = encryption
|
||||
|
||||
instance ToJSON CallType where toEncoding = J.genericToEncoding J.defaultOptions
|
||||
|
||||
-- | * Types for chat protocol
|
||||
|
||||
@@ -646,7 +646,7 @@ fileProgress chunksNum chunkSize fileSize =
|
||||
|
||||
viewCallInvitation :: Contact -> CallType -> Maybe C.Key -> [StyledString]
|
||||
viewCallInvitation ct@Contact {contactId} callType@CallType {media} sharedKey =
|
||||
[ ttyContact' ct <> " wants to connect with you via WebRTC " <> callMediaStr callType <> " call " <> encryptedCall callType,
|
||||
[ ttyContact' ct <> " wants to connect with you via WebRTC " <> callMediaStr callType <> " call " <> encryptedCallText callType,
|
||||
"To accept the call, please open the link below in your browser" <> supporedBrowsers callType,
|
||||
"",
|
||||
"https://simplex.chat/call#" <> plain queryString
|
||||
@@ -662,7 +662,7 @@ viewCallInvitation ct@Contact {contactId} callType@CallType {media} sharedKey =
|
||||
|
||||
viewCallOffer :: Contact -> CallType -> WebRTCSession -> Maybe C.Key -> [StyledString]
|
||||
viewCallOffer ct@Contact {contactId} callType@CallType {media} WebRTCSession {rtcSession = offer, rtcIceCandidates = iceCandidates} sharedKey =
|
||||
[ ttyContact' ct <> " accepted your WebRTC " <> callMediaStr callType <> " call " <> encryptedCall callType,
|
||||
[ ttyContact' ct <> " accepted your WebRTC " <> callMediaStr callType <> " call " <> encryptedCallText callType,
|
||||
"To connect, please open the link below in your browser" <> supporedBrowsers callType,
|
||||
"",
|
||||
"https://simplex.chat/call#" <> plain queryString
|
||||
@@ -689,13 +689,14 @@ callMediaStr CallType {media} = case media of
|
||||
CMVideo -> "video"
|
||||
CMAudio -> "audio"
|
||||
|
||||
encryptedCall :: CallType -> StyledString
|
||||
encryptedCall CallType {capabilities = CallCapabilities {encryption}} =
|
||||
if encryption then "(e2e encrypted)" else "(not e2e encrypted)"
|
||||
encryptedCallText :: CallType -> StyledString
|
||||
encryptedCallText callType
|
||||
| encryptedCall callType = "(e2e encrypted)"
|
||||
| otherwise = "(not e2e encrypted)"
|
||||
|
||||
supporedBrowsers :: CallType -> StyledString
|
||||
supporedBrowsers CallType {capabilities = CallCapabilities {encryption}}
|
||||
| encryption = " (only Chrome and Safari support e2e encryption for WebRTC, Safari requires enabling WebRTC insertable streams)"
|
||||
supporedBrowsers callType
|
||||
| encryptedCall callType = " (only Chrome and Safari support e2e encryption for WebRTC, Safari may require enabling WebRTC insertable streams)"
|
||||
| otherwise = ""
|
||||
|
||||
data WCallCommand
|
||||
|
||||
Reference in New Issue
Block a user