From 0d315f563ed0aac5a040f53c3a5a6cb4b3e59b24 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Mon, 16 Feb 2026 17:37:28 +0100 Subject: [PATCH 1/2] sip: add a few missing features --- src/plugins/sip-plugin.js | 488 +++++++++++++++++++++++++++++++++++++- 1 file changed, 475 insertions(+), 13 deletions(-) diff --git a/src/plugins/sip-plugin.js b/src/plugins/sip-plugin.js index 2641a21..ba1886c 100644 --- a/src/plugins/sip-plugin.js +++ b/src/plugins/sip-plugin.js @@ -13,27 +13,46 @@ const PLUGIN_ID = 'janus.plugin.sip'; /* These are the requests defined for the Janus SIP plugin API */ const REQUEST_REGISTER = 'register'; +const REQUEST_UNREGISTER = 'unregister'; const REQUEST_CALL = 'call'; const REQUEST_ACCEPT = 'accept'; +const REQUEST_PROGRESS = 'progress'; +const REQUEST_INFO = 'info'; +const REQUEST_MESSAGE = 'message'; +const REQUEST_KEYFRAME = 'keyframe'; +const REQUEST_RECORDING = 'recording'; +const REQUEST_RTP_FWD_START = 'rtp_forward'; +const REQUEST_RTP_FWD_STOP = 'stop_rtp_forward'; +const REQUEST_RTP_FWD_LIST = 'listforwarders'; const REQUEST_HANGUP = 'hangup'; const REQUEST_DECLINE = 'decline'; /* These are the events/responses that the Janode plugin will manage */ /* Some of them will be exported in the plugin descriptor */ const PLUGIN_EVENT = { - REGISTERED: 'sip_registered', REGISTERING: 'sip_registering', + REGISTERED: 'sip_registered', + UNREGISTERING: 'sip_unregistering', + UNREGISTERED: 'sip_unregistered', CALLING: 'sip_calling', RINGING: 'sip_ringing', PROCEEDING: 'sip_proceeding', INCOMING: 'sip_incoming', HANGUP: 'sip_hangup', HANGINGUP: 'sip_hangingup', - DECLINING: 'declining', + DECLINING: 'sip_declining', + PROGRESSING: 'sip_progressing', ACCEPTED: 'sip_accepted', MISSED: 'sip_missed', INFO: 'sip_info', + INFO_SENT: 'sip_info_sent', + MESSAGE: 'sip_message', + MESSAGE_SENT: 'sip_message_sent', DTMF: 'sip_dtmf', + KEYFRAME_SENT: 'sip_keyframe_sent', + RECORDING_UPDATED: 'sip_recording_updated', + RTP_FWD: 'sip_rtp_fwd', + FWD_LIST: 'sip_rtp_list', ERROR: 'sip_error', ERROR_EVENT: 'sip_error_event', }; @@ -58,14 +77,17 @@ class SipHandle extends Handle { constructor(session, id) { super(session, id); this._pendingRegister = null; + this._pendingUnregister = null; this._pendingCalls = {}; this.on(JANODE.EVENT.HANDLE_HANGUP, _ => { this._pendingRegister = null; + this._pendingUnregister = null; this._pendingCalls = {}; }); this.on(JANODE.EVENT.HANDLE_DETACHED, _ => { this._pendingRegister = null; + this._pendingUnregister = null; this._pendingCalls = {}; }); } @@ -120,9 +142,10 @@ class SipHandle extends Handle { switch (result.event) { - /* Registering event */ + /* Registration events */ case 'registering': janode_event.event = PLUGIN_EVENT.REGISTERING; + janode_event.data.unique_id = result.unique_id; closeTx = CLOSE_TX_NO; emit = true; break; @@ -139,11 +162,39 @@ class SipHandle extends Handle { janode_event.event = PLUGIN_EVENT.REGISTERED; janode_event.data.username = result.username; janode_event.data.register_sent = result.register_sent; + janode_event.data.helper = result.helper; + janode_event.data.master_id = result.master_id; + janode_event.data.unique_id = result.unique_id; + if (result.headers) { + janode_event.data.headers = result.headers; + } closeTx = CLOSE_TX_SUCCESS; txId = transaction || this._pendingRegister; emit = false; break; + case 'unregistering': + janode_event.event = PLUGIN_EVENT.UNREGISTERING; + closeTx = CLOSE_TX_NO; + emit = true; + break; + + case 'unregistered': + janode_event.event = PLUGIN_EVENT.UNREGISTERED; + janode_event.data.username = result.username; + janode_event.data.register_sent = result.register_sent; + janode_event.data.helper = result.helper; + janode_event.data.master_id = result.master_id; + janode_event.data.unique_id = result.unique_id; + if (result.headers) { + janode_event.data.headers = result.headers; + } + closeTx = CLOSE_TX_SUCCESS; + txId = transaction || this._pendingUnregister; + emit = false; + break; + + /* Call events */ case 'calling': janode_event.event = PLUGIN_EVENT.CALLING; closeTx = CLOSE_TX_NO; @@ -173,6 +224,9 @@ class SipHandle extends Handle { janode_event.data.username = result.username; janode_event.data.callee = result.callee; janode_event.data.display_name = result.displayname || undefined; + if (result.headers) { + janode_event.data.headers = result.headers; + } closeTx = CLOSE_TX_NO; emit = true; break; @@ -189,6 +243,9 @@ class SipHandle extends Handle { /* Async hangup */ else { janode_event.event = PLUGIN_EVENT.HANGUP; + if (result.headers) { + janode_event.data.headers = result.headers; + } closeTx = CLOSE_TX_NO; emit = true; } @@ -213,10 +270,24 @@ class SipHandle extends Handle { break; } + case 'progressing': { + janode_event.event = PLUGIN_EVENT.PROGRESSING; + const call = this._pendingCalls[call_id]; + if (call) { + call.earlyMedia = true; + } + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + /* A call has been accepted */ case 'accepted': { janode_event.event = PLUGIN_EVENT.ACCEPTED; janode_event.data.username = result.username || this._pendingCalls[call_id].incoming; + if (result.headers) { + janode_event.data.headers = result.headers; + } const call = this._pendingCalls[call_id]; if (call) { call.accepted = true; @@ -253,6 +324,36 @@ class SipHandle extends Handle { break; } + case 'infosent': { + janode_event.event = PLUGIN_EVENT.INFO_SENT; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + + /* SIP MESSAGE */ + case 'message': { + janode_event.event = PLUGIN_EVENT.MESSAGE; + janode_event.data.sender = result.sender; + if (result.displayname) { + janode_event.data.displayname = result.displayname; + } + janode_event.data.type = result.content_type; + janode_event.data.content = result.content; + if (result.headers) { + janode_event.data.headers = result.headers; + } + emit = true; + break; + } + + case 'messagesent': { + janode_event.event = PLUGIN_EVENT.MESSAGE_SENT; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + /* RFC2833 DTMF */ case 'dtmf': { janode_event.event = PLUGIN_EVENT.DTMF; @@ -262,6 +363,47 @@ class SipHandle extends Handle { emit = true; break; } + + /* Keyframe request */ + case 'keyframesent': { + janode_event.event = PLUGIN_EVENT.KEYFRAME_SENT; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + + /* Recordings */ + case 'recordingupdated': { + janode_event.event = PLUGIN_EVENT.RECORDING_UPDATED; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + + /* RTP forwarders */ + case 'rtp_forward': { + janode_event.event = PLUGIN_EVENT.RTP_FWD; + janode_event.data.forwarders = result.forwarders; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + + case 'stop_rtp_forward': { + janode_event.event = PLUGIN_EVENT.RTP_FWD; + janode_event.data.stream_id = result.stream_id; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } + + case 'forwarders': { + janode_event.event = PLUGIN_EVENT.FWD_LIST; + janode_event.data.forwarders = result.rtp_forwarders; + closeTx = CLOSE_TX_SUCCESS; + emit = false; + break; + } } /* The event has been handled */ @@ -297,10 +439,11 @@ class SipHandle extends Handle { * @param {string} [params.proxy] - The server to register at (not needed for guests) * @param {string} [params.outbound_proxy] - The server to register at (not needed for guests) * @param {number} [params.register_ttl] - The number of seconds after which the registration should expire + * @param {number} [params.master_id] - In case this is for a helper session (additional line), the ID of the master session holding the actual registration * * @returns {Promise} */ - async register({ type, send_register, force_udp, force_tcp, sips, rfc2543_cancel, username, secret, ha1_secret, display_name, proxy, outbound_proxy, register_ttl }) { + async register({ type, send_register, force_udp, force_tcp, sips, rfc2543_cancel, username, secret, ha1_secret, display_name, proxy, outbound_proxy, register_ttl, master_id }) { const body = { request: REQUEST_REGISTER, username, @@ -318,6 +461,7 @@ class SipHandle extends Handle { if (typeof proxy === 'string') body.proxy = proxy; if (typeof outbound_proxy === 'string') body.outbound_proxy = outbound_proxy; if (typeof register_ttl === 'number') body.register_ttl = register_ttl; + if (typeof master_id === 'number') body.master_id = master_id; const request = { janus: 'message', @@ -336,6 +480,33 @@ class SipHandle extends Handle { throw (error); } + /** + * Unregister on the SIP plugin (sending of a SIP REGISTER is conditional to the type of the original registration). + * + * @returns {Promise} + */ + async unregister() { + const body = { + request: REQUEST_UNREGISTER, + username, + }; + + const request = { + janus: 'message', + body, + }; + this.decorateRequest(request); + this._pendingUnregister = request.transaction; + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.UNREGISTERED) { + return evtdata; + } + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + /** * Start a SIP call. * @@ -345,10 +516,13 @@ class SipHandle extends Handle { * @param {string} [params.authuser] - The username to use to authenticate as to call, only needed in case authentication is needed and no REGISTER was sent * @param {string} [params.secret] - The password to use for authentication, if any * @param {string} [params.ha1_secret] - The prehashed password to use for authentication, if any + * @param {string} [params.srtp] - Whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support + * @param {string} [params.srtp_profile] - SRTP profile to negotiate, in case SRTP is offered + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) * @param {RTCSessionDescription} params.jsep - JSEP offer * @returns {Promise} */ - async call({ uri, call_id, authuser, secret, ha1_secret, jsep }) { + async call({ uri, call_id, authuser, secret, ha1_secret, srtp, srtp_profile, headers, jsep } = {}) { if (typeof jsep === 'object' && jsep && jsep.type !== 'offer') { const error = new Error('jsep must be an offer'); return Promise.reject(error); @@ -363,6 +537,11 @@ class SipHandle extends Handle { if (typeof authuser === 'string') body.authuser = authuser; if (typeof secret === 'string') body.secret = secret; if (typeof ha1_secret === 'string') body.ha1_secret = ha1_secret; + if (typeof srtp === 'string') body.srtp = srtp; + if (typeof srtp_profile === 'string') body.srtp_profile = srtp_profile; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } const request = { janus: 'message', @@ -383,17 +562,21 @@ class SipHandle extends Handle { * Accept an incoming SIP call. * * @param {Object} params + * @param {string} [params.srtp] - Whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support + * @param {string} [params.srtp_profile] - SRTP profile to negotiate, in case SRTP is offered + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) * @param {RTCSessionDescription} params.jsep - JSEP answer * @returns {Promise} */ - async accept({ jsep }) { - if (typeof jsep === 'object' && jsep && jsep.type !== 'answer') { - const error = new Error('jsep must be an answer'); - return Promise.reject(error); - } + async accept({ srtp, srtp_profile, headers, jsep } = {}) { const body = { request: REQUEST_ACCEPT, }; + if (typeof srtp === 'string') body.srtp = srtp; + if (typeof srtp_profile === 'string') body.srtp_profile = srtp_profile; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } const request = { janus: 'message', @@ -410,15 +593,55 @@ class SipHandle extends Handle { throw (error); } + /** + * Progress an incoming SIP call (early media). + * + * @param {Object} params + * @param {string} [params.srtp] - Whether to mandate (sdes_mandatory) or offer (sdes_optional) SRTP support + * @param {string} [params.srtp_profile] - SRTP profile to negotiate, in case SRTP is offered + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) + * @param {RTCSessionDescription} params.jsep - JSEP answer + * @returns {Promise} + */ + async progress({ srtp, srtp_profile, headers, jsep } = {}) { + const body = { + request: REQUEST_PROGRESS, + }; + if (typeof srtp === 'string') body.srtp = srtp; + if (typeof srtp_profile === 'string') body.srtp_profile = srtp_profile; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } + + const request = { + janus: 'message', + body, + jsep, + }; + this.decorateRequest(request); + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.PROGRESSING) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + /** * Hangup a SIP call. * + * @param {Object} params + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) * @returns {Promise} */ - async sip_hangup() { + async sip_hangup({ headers } = {}) { const body = { request: REQUEST_HANGUP, }; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } const request = { janus: 'message', @@ -437,12 +660,19 @@ class SipHandle extends Handle { /** * Decline an incoming SIP call. * + * @param {Object} params + * @param {number} [params.code] - SIP code to send back (default depends on current call context) + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) * @returns {Promise} */ - async decline() { + async decline({ code, headers } = {}) { const body = { request: REQUEST_DECLINE, + code }; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } const request = { janus: 'message', @@ -457,6 +687,208 @@ class SipHandle extends Handle { const error = new Error(`unexpected response to ${body.request} request`); throw (error); } + + /** + * Send a SIP INFO within the context of a call. + * + * @param {Object} params + * @param {string} params.type - The content type + * @param {string} params.content - The content as a string + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) + * @returns {Promise} + */ + async sipInfo({ type, content, headers } = {}) { + const body = { + request: REQUEST_INFO, + type, + content + }; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } + + const request = { + janus: 'message', + body + }; + this.decorateRequest(request); + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.INFO_SENT) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * Send a SIP MESSAGE, in-dialog or not. + * + * @param {Object} params + * @param {string} params.uri - If not in-dialog, the SIP URI to send the MESSAGE to + * @param {string} params.call_id - If not in-dialog, the call-ID to use (optional) + * @param {string} params.content_type - The content type + * @param {string} params.content - The content as a string + * @param {object[]} [params.headers] - Custom headers to add to the request, if any (array of key/value mappings, header name/value) + * @returns {Promise} + */ + async sipMessage({ uri, call_id, content_type, content, headers } = {}) { + const body = { + request: REQUEST_MESSAGE, + uri, + call_id, + content_type, + content + }; + if (headers && Array.isArray(headers)) { + body.headers = headers; + } + + const request = { + janus: 'message', + body + }; + this.decorateRequest(request); + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.MESSAGE_SENT) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * Send a keyframe request within the context of a call. + * + * @param {Object} params + * @param {boolean} params.user - Whether to send a keyframe request to the WebRTC user + * @param {boolean} params.peer - Whether to send a keyframe request to the SIP peer + * @returns {Promise} + */ + async keyframe({ user, peer } = {}) { + const body = { + request: REQUEST_KEYFRAME, + user, + peer + }; + + const request = { + janus: 'message', + body + }; + this.decorateRequest(request); + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.KEYFRAME_SENT) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * Send Update the recording status of a call. + * + * @param {Object} params + * @param {boolean} params.stop - Whether the recording must be stopped (if missing or false, it will be started) + * @param {boolean} params.audio - Whether the recording request impacts the WebRTC user audio + * @param {boolean} params.video - Whether the recording request impacts the WebRTC user video + * @param {boolean} params.peer_audio - Whether the recording request impacts the SIP peer audio + * @param {boolean} params.peer_video - Whether the recording request impacts the SIP peer video + * @param {boolean} params.send_peer_pli - Whether a keyframe request should be sent to the SIP peer + * @param {string} params.filename - Base path/filename to use for all the recordings + * @returns {Promise} + */ + async recording({ stop, audio, video, peer_audio, peer_video, send_peer_pli, filename } = {}) { + const body = { + request: REQUEST_RECORDING, + action: (stop ? 'stop' : 'start'), + audio, + video, + peer_audio, + peer_video, + send_peer_pli, + filename + }; + + const request = { + janus: 'message', + body + }; + this.decorateRequest(request); + + const response = await this.sendRequest(request, 10000); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.RECORDING_UPDATED) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * Start a RTP forwarder within the context of a call. + * + * @param {Object} params + * @param {object[]} [params.streams] - Properties of each individual forwarder, each stream includes type, host, host_family, port, ssrc, pt, etc. + * @returns {Promise} + */ + async startForward({ streams } = {}) { + const body = { + request: REQUEST_RTP_FWD_START, + }; + if (streams && Array.isArray(streams)) { + body.streams = streams; + } + + const response = await this.message(body); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.RTP_FWD) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * Stop a RTP forwarder within the context of a call. + * + * @param {Object} params + * @param {number} params.stream - The forwarder identifier to stop + * @returns {Promise} + */ + async stopForward({ stream }) { + const body = { + request: REQUEST_RTP_FWD_STOP, + stream_id: stream, + }; + if (typeof secret === 'string') body.secret = secret; + if (typeof admin_key === 'string') body.admin_key = admin_key; + + const response = await this.message(body); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.RTP_FWD) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } + + /** + * List active forwarders within the context of a call. + * + * @returns {Promise} + */ + async listForward() { + const body = { + request: REQUEST_RTP_FWD_LIST + }; + + const response = await this.message(body); + const { event, data: evtdata } = this._getPluginEvent(response); + if (event === PLUGIN_EVENT.FWD_LIST) + return evtdata; + const error = new Error(`unexpected response to ${body.request} request`); + throw (error); + } } /** @@ -475,6 +907,14 @@ class SipHandle extends Handle { * @property {boolean} register_sent - True is a REGISTER has been sent */ +/** + * The success event for an unregister request + * + * @typedef {Object} SIP_EVENT_UNREGISTERED + * @property {string} username - The URI that has been unregistered + * @property {boolean} register_sent - True is a REGISTER has been sent + */ + /** * The success event for an accept request * @@ -506,6 +946,7 @@ class SipHandle extends Handle { * @property {module:sip-plugin~SipHandle} Handle - The custom class implementing the plugin * @property {Object} EVENT - The events emitted by the plugin * @property {string} EVENT.SIP_REGISTERING {@link module:sip-plugin~SipHandle#event:SIP_REGISTERING SIP_REGISTERING} + * @property {string} EVENT.SIP_UNREGISTERING {@link module:sip-plugin~SipHandle#event:SIP_UNREGISTERING SIP_UNREGISTERING} * @property {string} EVENT.SIP_CALLING {@link module:sip-plugin~SipHandle#event:SIP_CALLING SIP_CALLING} * @property {string} EVENT.SIP_RINGING {@link module:sip-plugin~SipHandle#event:SIP_RINGING SIP_RINGING} * @property {string} EVENT.SIP_PROCEEDING {@link module:sip-plugin~SipHandle#event:SIP_PROCEEDING SIP_PROCEEDING} @@ -513,6 +954,7 @@ class SipHandle extends Handle { * @property {string} EVENT.SIP_HANGUP {@link module:sip-plugin~SipHandle#event:SIP_HANGUP SIP_HANGUP} * @property {string} EVENT.SIP_MISSED {@link module:sip-plugin~SipHandle#event:SIP_MISSED SIP_MISSED} * @property {string} EVENT.SIP_INFO {@link module:sip-plugin~SipHandle#event:SIP_INFO SIP_INFO} + * @property {string} EVENT.SIP_MESSAGE {@link module:sip-plugin~SipHandle#event:SIP_MESSAGE SIP_MESSAGE} * @property {string} EVENT.SIP_DTMF {@link module:sip-plugin~SipHandle#event:SIP_DTMF SIP_DTMF} */ export default { @@ -527,6 +969,14 @@ export default { */ SIP_REGISTERING: PLUGIN_EVENT.REGISTERING, + /** + * The event notifying an unregister is in progress + * + * @event module:sip-plugin~SipHandle#event:SIP_UNREGISTERING + * @type {Object} + */ + SIP_REGISTERING: PLUGIN_EVENT.UNREGISTERING, + /** * Event for a SIP call in progress * @@ -599,6 +1049,18 @@ export default { */ SIP_INFO: PLUGIN_EVENT.INFO, + /** + * @event module:sip-plugin~SipHandle#event:SIP_MESSAGE + * @type {Object} + * @property {string} sender - SIP URI of the message sender + * @property {string} [call_id] - SIP Call-ID header for related call + * @property {string} [displayname] - Display name of the sender + * @property {string} type - Content type of the message + * @property {string} content - Content of the message + * @property {Object} [headers] - Custom headers extracted from SIP event + */ + SIP_MESSAGE: PLUGIN_EVENT.MESSAGE, + /** * @event module:sip-plugin~SipHandle#event:SIP_DTMF * @type {Object} @@ -609,4 +1071,4 @@ export default { */ SIP_DTMF: PLUGIN_EVENT.DTMF, }, -}; \ No newline at end of file +}; From 26c2f13e04df6e57523c6bc8ab31e0f64d9d2116 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Mon, 16 Feb 2026 17:46:26 +0100 Subject: [PATCH 2/2] Fixed linting errors --- src/plugins/sip-plugin.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/sip-plugin.js b/src/plugins/sip-plugin.js index ba1886c..2a7b10f 100644 --- a/src/plugins/sip-plugin.js +++ b/src/plugins/sip-plugin.js @@ -488,7 +488,6 @@ class SipHandle extends Handle { async unregister() { const body = { request: REQUEST_UNREGISTER, - username, }; const request = { @@ -861,8 +860,6 @@ class SipHandle extends Handle { request: REQUEST_RTP_FWD_STOP, stream_id: stream, }; - if (typeof secret === 'string') body.secret = secret; - if (typeof admin_key === 'string') body.admin_key = admin_key; const response = await this.message(body); const { event, data: evtdata } = this._getPluginEvent(response); @@ -975,7 +972,7 @@ export default { * @event module:sip-plugin~SipHandle#event:SIP_UNREGISTERING * @type {Object} */ - SIP_REGISTERING: PLUGIN_EVENT.UNREGISTERING, + SIP_UNREGISTERING: PLUGIN_EVENT.UNREGISTERING, /** * Event for a SIP call in progress