Commit db132dd for jssip.net
commit db132ddcf6f05bea4fc10388c0a6bff285ab17aa
Author: Filippo Giacchè <filippo.giacche@gmail.com>
Date: Fri Dec 19 13:12:57 2025 +0100
Allow sending DTMF during early dialog #689 (#925)
diff --git a/lib/Dialog.js b/lib/Dialog.js
index 18d0dd7..baa5ed6 100644
--- a/lib/Dialog.js
+++ b/lib/Dialog.js
@@ -83,7 +83,7 @@ module.exports = class Dialog
this._remote_uri = message.parseHeader('to').uri;
this._remote_target = contact.uri;
this._route_set = message.getHeaders('record-route').reverse();
- this._ack_seqnum = null;
+ this._ack_seqnum = this._local_seqnum;
}
@@ -202,8 +202,9 @@ module.exports = class Dialog
if (!this._local_seqnum) { this._local_seqnum = Math.floor(Math.random() * 10000); }
+ // CANCEL and ACK must use the same sequence number as the INVITE.
const cseq = (method === JsSIP_C.CANCEL || method === JsSIP_C.ACK) ?
- this._local_seqnum :
+ this._ack_seqnum :
this._local_seqnum += 1;
const request = new SIPMessage.OutgoingRequest(
diff --git a/lib/RTCSession.js b/lib/RTCSession.js
index 617ef61..7f623c9 100644
--- a/lib/RTCSession.js
+++ b/lib/RTCSession.js
@@ -1420,7 +1420,23 @@ module.exports = class RTCSession extends EventEmitter
{
logger.debug('sendRequest()');
- return this._dialog.sendRequest(method, options);
+ if (this._dialog)
+ {
+ return this._dialog.sendRequest(method, options);
+ }
+ else
+ {
+ const dialogsArray = Object.values(this._earlyDialogs);
+
+ if (dialogsArray.length > 0)
+ {
+ return dialogsArray[0].sendRequest(method, options);
+ }
+
+ logger.warn('No valid early dialog found to send request');
+
+ return;
+ }
}
/**
diff --git a/lib/RTCSession/DTMF.js b/lib/RTCSession/DTMF.js
index e86bb93..b296bae 100644
--- a/lib/RTCSession/DTMF.js
+++ b/lib/RTCSession/DTMF.js
@@ -47,8 +47,11 @@ module.exports = class DTMF extends EventEmitter
this._direction = 'outgoing';
// Check RTCSession Status.
- if (this._session.status !== this._session.C.STATUS_CONFIRMED &&
- this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK)
+ if (
+ this._session.status !== this._session.C.STATUS_CONFIRMED &&
+ this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK &&
+ this._session.status !== this._session.C.STATUS_1XX_RECEIVED
+ )
{
throw new Exceptions.InvalidStateError(this._session.status);
}