diff --git a/lib/session/call-session.js b/lib/session/call-session.js index 752f9d42..400d2bc4 100644 --- a/lib/session/call-session.js +++ b/lib/session/call-session.js @@ -106,6 +106,16 @@ class CallSession extends Emitter { assert(rootSpan); this._recordState = RecordState.RecordingOff; + + /* A call transferred from another feature server is still being recorded by the SBC, so + this session inherits that state - and takes it off the application, which is handed + on to child legs (dial confirm, adulting) and to any later transfer. */ + const inheritedRecording = application?.siprecRecording; + if (inheritedRecording) { + delete application.siprecRecording; + this._recordState = inheritedRecording.state || RecordState.RecordingOff; + if (inheritedRecording.options) this.recordOptions = inheritedRecording.options; + } this._notifyEvents = false; this.tmpFiles = new Set(); diff --git a/lib/tasks/task.js b/lib/tasks/task.js index 9de60b89..5bb15051 100644 --- a/lib/tasks/task.js +++ b/lib/tasks/task.js @@ -3,7 +3,7 @@ const crypto = require('crypto'); const {TaskPreconditions} = require('../utils/constants'); const { normalizeJambones } = require('@jambonz/verb-specifications'); const WsRequestor = require('../utils/ws-requestor'); -const {TaskName} = require('../utils/constants'); +const {TaskName, RecordState} = require('../utils/constants'); const {trace} = require('@opentelemetry/api'); /** @@ -345,6 +345,12 @@ class Task extends Emitter { delete obj.notifier; obj.tasks = cs.getRemainingTaskData(); obj.callInfo = cs.callInfo.toJSON(); + + /* the SBC keeps the siprec session across the REFER, so the receiving session must + inherit the state or pause/resume/stop there will be rejected as out of sync */ + if (cs.recordState !== RecordState.RecordingOff) { + obj.siprecRecording = {state: cs.recordState, options: cs.recordOptions}; + } if (opts && obj.tasks.length > 0) { const key = Object.keys(obj.tasks[0])[0]; Object.assign(obj.tasks[0][key], {_: opts});