@@ -26,6 +26,10 @@ export interface CallContextValue {
export enum CallState {
export enum CallState {
CONNECTING ,
CONNECTING ,
KEY_EXCHANGE ,
KEY_EXCHANGE ,
/**
* Финальная стадия сигналинга, на которой о б е стороны обменялись ключами и теперь устанавливают защищенный канал связи для звонка,
* через WebRTC, и готовятся к активному звонку.
*/
WEB_RTC_EXCHANGE ,
WEB_RTC_EXCHANGE ,
ACTIVE ,
ACTIVE ,
ENDED ,
ENDED ,
@@ -59,6 +63,7 @@ export function CallProvider(props : CallProviderProps) {
const [ sessionKeys , setSessionKeys ] = useState < nacl.BoxKeyPair | null > ( null ) ;
const [ sessionKeys , setSessionKeys ] = useState < nacl.BoxKeyPair | null > ( null ) ;
const send = useSender ( ) ;
const send = useSender ( ) ;
const publicKey = usePublicKey ( ) ;
const publicKey = usePublicKey ( ) ;
const peerConnectionRef = useRef < RTCPeerConnection | null > ( null ) ;
const roleRef = useRef < CallRole | null > ( null ) ;
const roleRef = useRef < CallRole | null > ( null ) ;
const [ sharedSecret , setSharedSecret ] = useState < string > ( "" ) ;
const [ sharedSecret , setSharedSecret ] = useState < string > ( "" ) ;
@@ -74,10 +79,24 @@ export function CallProvider(props : CallProviderProps) {
* У нас уже есть активный звонок, игнорируем все сигналы, кроме сигналов от текущего звонка
* У нас уже есть активный звонок, игнорируем все сигналы, кроме сигналов от текущего звонка
*/
*/
if ( packet . getSrc ( ) != activeCall ) {
if ( packet . getSrc ( ) != activeCall ) {
console . info ( "Received signal from " + packet . getSrc ( ) + " but active call is with " + activeCall + ", ignoring" ) ;
info ( "Received signal for another call, ignoring" ) ;
info ( "Received signal for another call, ignoring" ) ;
return ;
return ;
}
}
}
}
if ( signalType == SignalType . END_CALL ) {
/**
* Сбросили звонок
*/
setActiveCall ( "" ) ;
setCallState ( CallState . ENDED ) ;
setShowCallView ( false ) ;
setSessionKeys ( null ) ;
setSharedSecret ( "" ) ;
setDuration ( 0 ) ;
roleRef . current = null ;
return ;
}
if ( signalType == SignalType . CALL ) {
if ( signalType == SignalType . CALL ) {
/**
/**
* Нам поступает звонок
* Нам поступает звонок
@@ -87,6 +106,7 @@ export function CallProvider(props : CallProviderProps) {
setShowCallView ( true ) ;
setShowCallView ( true ) ;
}
}
if ( signalType == SignalType . KEY_EXCHANGE && roleRef . current == CallRole . CALLER ) {
if ( signalType == SignalType . KEY_EXCHANGE && roleRef . current == CallRole . CALLER ) {
console . info ( "EXCHANGE SIGNAL RECEIVED, CALLER ROLE" ) ;
/**
/**
* Другая сторона сгенерировала ключи для сессии и отправила нам публичную часть,
* Другая сторона сгенерировала ключи для сессии и отправила нам публичную часть,
* теперь мы можем создать общую секретную сессию для шифрования звонка
* теперь мы можем создать общую секретную сессию для шифрования звонка
@@ -105,12 +125,14 @@ export function CallProvider(props : CallProviderProps) {
*/
*/
const signalPacket = new PacketSignal ( ) ;
const signalPacket = new PacketSignal ( ) ;
signalPacket . setSrc ( publicKey ) ;
signalPacket . setSrc ( publicKey ) ;
signalPacket . setDst ( packet . getDst ( ) ) ;
signalPacket . setDst ( packet . getSrc ( ) ) ;
signalPacket . setSignalType ( SignalType . KEY_EXCHANGE ) ;
signalPacket . setSignalType ( SignalType . KEY_EXCHANGE ) ;
signalPacket . setSharedPublic ( Buffer . from ( sessionKeys . publicKey ) . toString ( 'hex' ) ) ;
signalPacket . setSharedPublic ( Buffer . from ( sessionKeys . publicKey ) . toString ( 'hex' ) ) ;
send ( signalPacket ) ;
send ( signalPacket ) ;
setCallState ( CallState . WEB_RTC_EXCHANGE ) ;
}
}
if ( signalType == SignalType . KEY_EXCHANGE && roleRef . current == CallRole . CALLEE ) {
if ( signalType == SignalType . KEY_EXCHANGE && roleRef . current == CallRole . CALLEE ) {
console . info ( "EXCHANGE SIGNAL RECEIVED, CALLEE ROLE" ) ;
/**
/**
* Мы отправили свою публичную часть ключа другой стороне,
* Мы отправили свою публичную часть ключа другой стороне,
* теперь мы получили е е публичную часть и можем создать общую
* теперь мы получили е е публичную часть и можем создать общую
@@ -128,6 +150,7 @@ export function CallProvider(props : CallProviderProps) {
const computedSharedSecret = nacl . box . before ( Buffer . from ( sharedPublic , 'hex' ) , sessionKeys . secretKey ) ;
const computedSharedSecret = nacl . box . before ( Buffer . from ( sharedPublic , 'hex' ) , sessionKeys . secretKey ) ;
info ( "Generated shared secret for call session: " + Buffer . from ( computedSharedSecret ) . toString ( 'hex' ) ) ;
info ( "Generated shared secret for call session: " + Buffer . from ( computedSharedSecret ) . toString ( 'hex' ) ) ;
setSharedSecret ( Buffer . from ( computedSharedSecret ) . toString ( 'hex' ) ) ;
setSharedSecret ( Buffer . from ( computedSharedSecret ) . toString ( 'hex' ) ) ;
setCallState ( CallState . WEB_RTC_EXCHANGE ) ;
}
}
} , [ activeCall , sessionKeys ] ) ;
} , [ activeCall , sessionKeys ] ) ;
@@ -143,6 +166,7 @@ export function CallProvider(props : CallProviderProps) {
setCallState ( CallState . CONNECTING ) ;
setCallState ( CallState . CONNECTING ) ;
setShowCallView ( true ) ;
setShowCallView ( true ) ;
const signalPacket = new PacketSignal ( ) ;
const signalPacket = new PacketSignal ( ) ;
signalPacket . setSrc ( publicKey ) ;
signalPacket . setDst ( dialog ) ;
signalPacket . setDst ( dialog ) ;
signalPacket . setSignalType ( SignalType . CALL ) ;
signalPacket . setSignalType ( SignalType . CALL ) ;
send ( signalPacket ) ;
send ( signalPacket ) ;
@@ -150,6 +174,12 @@ export function CallProvider(props : CallProviderProps) {
}
}
const close = ( ) = > {
const close = ( ) = > {
const packetSignal = new PacketSignal ( ) ;
packetSignal . setSrc ( publicKey ) ;
packetSignal . setDst ( activeCall ) ;
packetSignal . setSignalType ( SignalType . END_CALL ) ;
send ( packetSignal ) ;
peerConnectionRef . current = null ;
setActiveCall ( "" ) ;
setActiveCall ( "" ) ;
setCallState ( CallState . ENDED ) ;
setCallState ( CallState . ENDED ) ;
setShowCallView ( false ) ;
setShowCallView ( false ) ;
@@ -170,6 +200,7 @@ export function CallProvider(props : CallProviderProps) {
*/
*/
const keys = generateSessionKeys ( ) ;
const keys = generateSessionKeys ( ) ;
const signalPacket = new PacketSignal ( ) ;
const signalPacket = new PacketSignal ( ) ;
signalPacket . setSrc ( publicKey ) ;
signalPacket . setDst ( activeCall ) ;
signalPacket . setDst ( activeCall ) ;
signalPacket . setSignalType ( SignalType . KEY_EXCHANGE ) ;
signalPacket . setSignalType ( SignalType . KEY_EXCHANGE ) ;
signalPacket . setSharedPublic ( Buffer . from ( keys . publicKey ) . toString ( 'hex' ) ) ;
signalPacket . setSharedPublic ( Buffer . from ( keys . publicKey ) . toString ( 'hex' ) ) ;