1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Support m.call.reject

Start the migration to v1 VoIP by supporting m.call.reject, which
we'll send if the caller says they're v1. Our version stays as v0
for now, until we speak the rest of v1.

Honour the default reaosn in a hangup being user_hangup.
This commit is contained in:
David Baker
2020-10-15 14:51:05 +01:00
parent 4cc4b28c47
commit 7c3af91b42
3 changed files with 62 additions and 8 deletions

View File

@@ -45,6 +45,7 @@ export enum EventType {
CallCandidates = "m.call.candidates", CallCandidates = "m.call.candidates",
CallAnswer = "m.call.answer", CallAnswer = "m.call.answer",
CallHangup = "m.call.hangup", CallHangup = "m.call.hangup",
CallReject = "m.call.reject",
KeyVerificationRequest = "m.key.verification.request", KeyVerificationRequest = "m.key.verification.request",
KeyVerificationStart = "m.key.verification.start", KeyVerificationStart = "m.key.verification.start",
KeyVerificationCancel = "m.key.verification.cancel", KeyVerificationCancel = "m.key.verification.cancel",

View File

@@ -164,6 +164,14 @@ export enum CallErrorCode {
Replaced = 'replaced', Replaced = 'replaced',
} }
/**
* The version field that we set in m.call.* events
* Once we are able to speak v1 VoIP sufficiently, this
* bumped to 1. While we partially speak v1 VoIP, it remains
* as 0.
*/
const VOIP_PROTO_VERSION = 0;
/** The fallback ICE server to use for STUN or TURN protocols. */ /** The fallback ICE server to use for STUN or TURN protocols. */
const FALLBACK_ICE_SERVER = 'stun:turn.matrix.org'; const FALLBACK_ICE_SERVER = 'stun:turn.matrix.org';
@@ -222,6 +230,7 @@ export class MatrixCall extends EventEmitter {
// XXX: I don't know why this is called 'config'. // XXX: I don't know why this is called 'config'.
private config: MediaStreamConstraints; private config: MediaStreamConstraints;
private successor: MatrixCall; private successor: MatrixCall;
private opponentVersion: number;
constructor(opts: CallOpts) { constructor(opts: CallOpts) {
super(); super();
@@ -439,6 +448,7 @@ export class MatrixCall extends EventEmitter {
this.setState(CallState.Ringing); this.setState(CallState.Ringing);
this.direction = CallDirection.Inbound; this.direction = CallDirection.Inbound;
this.opponentVersion = this.msg.version;
if (event.getLocalAge()) { if (event.getLocalAge()) {
setTimeout(() => { setTimeout(() => {
@@ -457,7 +467,7 @@ export class MatrixCall extends EventEmitter {
} }
/** /**
* Configure this call from a hangup event. Used by MatrixClient. * Configure this call from a hangup or reject event. Used by MatrixClient.
* @param {MatrixEvent} event The m.call.hangup event * @param {MatrixEvent} event The m.call.hangup event
*/ */
initWithHangup(event: MatrixEvent) { initWithHangup(event: MatrixEvent) {
@@ -536,7 +546,7 @@ export class MatrixCall extends EventEmitter {
logger.debug("Ending call " + this.callId); logger.debug("Ending call " + this.callId);
this.terminate(CallParty.Local, reason, !suppressEvent); this.terminate(CallParty.Local, reason, !suppressEvent);
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
}; };
// Continue to send no reason for user hangups temporarily, until // Continue to send no reason for user hangups temporarily, until
@@ -545,6 +555,33 @@ export class MatrixCall extends EventEmitter {
this.sendEvent('m.call.hangup', content); this.sendEvent('m.call.hangup', content);
} }
/**
* Reject a call
* This used to be done by calling hangup, but is a separate method and protocol
* event as of MSC2746.
*/
reject() {
if (this.state !== CallState.Ringing) {
throw Error("Call must be in 'ringing' state to reject!");
}
if (this.opponentVersion < 1) {
logger.info(
`Opponent version is less than 1 (${this.opponentVersion}): sending hangup instead of reject`,
);
this.hangup(CallErrorCode.UserHangup, true);
return;
}
logger.debug("Rejecting call: " + this.callId);
this.terminate(CallParty.Local, CallErrorCode.UserHangup, true);
const content = {
version: VOIP_PROTO_VERSION,
call_id: this.callId,
};
this.sendEvent('m.call.reject', content);
}
/** /**
* Set whether the local video preview should be muted or not. * Set whether the local video preview should be muted or not.
* @param {boolean} muted True to mute the local video. * @param {boolean} muted True to mute the local video.
@@ -713,7 +750,7 @@ export class MatrixCall extends EventEmitter {
await this.peerConn.setLocalDescription(myAnswer); await this.peerConn.setLocalDescription(myAnswer);
this.answerContent = { this.answerContent = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
answer: { answer: {
sdp: this.peerConn.localDescription.sdp, sdp: this.peerConn.localDescription.sdp,
@@ -800,6 +837,8 @@ export class MatrixCall extends EventEmitter {
return; return;
} }
this.opponentVersion = msg.version;
try { try {
this.peerConn.setRemoteDescription(msg.answer); this.peerConn.setRemoteDescription(msg.answer);
} catch (e) { } catch (e) {
@@ -829,7 +868,7 @@ export class MatrixCall extends EventEmitter {
} }
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
// OpenWebRTC appears to add extra stuff (like the DTLS fingerprint) // OpenWebRTC appears to add extra stuff (like the DTLS fingerprint)
// to the description when setting it on the peerconnection. // to the description when setting it on the peerconnection.
@@ -1004,7 +1043,17 @@ export class MatrixCall extends EventEmitter {
onHangupReceived = (msg) => { onHangupReceived = (msg) => {
logger.debug("Hangup received"); logger.debug("Hangup received");
this.terminate(CallParty.Remote, msg.reason, true); // default reason is user_hangup
this.terminate(CallParty.Remote, msg.reason || CallErrorCode.UserHangup, true);
};
onRejectReceived = (msg) => {
logger.debug("Reject received");
if (this.state === CallState.InviteSent) {
this.terminate(CallParty.Remote, CallErrorCode.UserHangup, true);
} else {
logger.debug(`Call is in state: ${this.state}: ignoring reject`);
}
}; };
onAnsweredElsewhere = (msg) => { onAnsweredElsewhere = (msg) => {
@@ -1127,7 +1176,7 @@ export class MatrixCall extends EventEmitter {
this.candidateSendQueue = []; this.candidateSendQueue = [];
++this.candidateSendTries; ++this.candidateSendTries;
const content = { const content = {
version: 0, version: VOIP_PROTO_VERSION,
call_id: this.callId, call_id: this.callId,
candidates: cands, candidates: cands,
}; };

View File

@@ -232,7 +232,7 @@ export class CallEventHandler {
call.gotRemoteIceCandidate(cand); call.gotRemoteIceCandidate(cand);
} }
} }
} else if (event.getType() === EventType.CallHangup) { } else if ([EventType.CallHangup, EventType.CallReject].includes(event.getType())) {
// Note that we also observe our own hangups here so we can see // Note that we also observe our own hangups here so we can see
// if we've already rejected a call that would otherwise be valid // if we've already rejected a call that would otherwise be valid
if (!call) { if (!call) {
@@ -247,7 +247,11 @@ export class CallEventHandler {
} }
} else { } else {
if (call.state !== CallState.Ended) { if (call.state !== CallState.Ended) {
if (event.getType() === EventType.CallHangup) {
call.onHangupReceived(content); call.onHangupReceived(content);
} else {
call.onRejectReceived(content);
}
this.calls.delete(content.call_id); this.calls.delete(content.call_id);
} }
} }