Skip to content

Commit

Permalink
SimpleUser and SessionManager optionally send DTMF via SDH.
Browse files Browse the repository at this point in the history
  • Loading branch information
seanbright authored and john-e-riordan committed Oct 25, 2022
1 parent 70b6b66 commit 48cb9b5
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 29 deletions.
6 changes: 6 additions & 0 deletions src/platform/web/session-manager/session-manager-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ export interface SessionManagerOptions {
*/
registererRegisterOptions?: RegistererRegisterOptions;

/**
* Send DTMF using the session description handler (uses RFC 2833 DTMF).
* @defaultValue `false`
*/
sendDTMFUsingSessionDescriptionHandler?: boolean;

/**
* Options for UserAgent.
*/
Expand Down
72 changes: 43 additions & 29 deletions src/platform/web/session-manager/session-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export class SessionManager {
registerGuard: null,
registererOptions: {},
registererRegisterOptions: {},
sendDTMFUsingSessionDescriptionHandler: false,
userAgentOptions: {}
},
...SessionManager.stripUndefinedProperties(options)
Expand Down Expand Up @@ -715,16 +716,6 @@ export class SessionManager {
public async sendDTMF(session: Session, tone: string): Promise<void> {
this.logger.log(`[${session.id}] Sending DTMF...`);

// As RFC 6086 states, sending DTMF via INFO is not standardized...
//
// Companies have been using INFO messages in order to transport
// Dual-Tone Multi-Frequency (DTMF) tones. All mechanisms are
// proprietary and have not been standardized.
// https://tools.ietf.org/html/rfc6086#section-2
//
// It is however widely supported based on this draft:
// https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00

// Validate tone
if (!/^[0-9A-D#*,]$/.exec(tone)) {
return Promise.reject(new Error("Invalid DTMF tone."));
Expand All @@ -734,27 +725,50 @@ export class SessionManager {
return Promise.reject(new Error("Session does not exist."));
}

// The UA MUST populate the "application/dtmf-relay" body, as defined
// earlier, with the button pressed and the duration it was pressed
// for. Technically, this actually requires the INFO to be generated
// when the user *releases* the button, however if the user has still
// not released a button after 5 seconds, which is the maximum duration
// supported by this mechanism, the UA should generate the INFO at that
// time.
// https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00#section-5.3
this.logger.log(`[${session.id}] Sending DTMF tone: ${tone}`);
const dtmf = tone;
const duration = 2000;
const body = {
contentDisposition: "render",
contentType: "application/dtmf-relay",
content: "Signal=" + dtmf + "\r\nDuration=" + duration
};
const requestOptions = { body };

return session.info({ requestOptions }).then(() => {
return;
});
if (this.options.sendDTMFUsingSessionDescriptionHandler) {
if (!session.sessionDescriptionHandler) {
return Promise.reject(new Error("Session desciption handler undefined."));
}

if (!session.sessionDescriptionHandler.sendDtmf(tone)) {
return Promise.reject(new Error("Failed to send DTMF"));
}

return Promise.resolve();
} else {
// As RFC 6086 states, sending DTMF via INFO is not standardized...
//
// Companies have been using INFO messages in order to transport
// Dual-Tone Multi-Frequency (DTMF) tones. All mechanisms are
// proprietary and have not been standardized.
// https://tools.ietf.org/html/rfc6086#section-2
//
// It is however widely supported based on this draft:
// https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00

// The UA MUST populate the "application/dtmf-relay" body, as defined
// earlier, with the button pressed and the duration it was pressed
// for. Technically, this actually requires the INFO to be generated
// when the user *releases* the button, however if the user has still
// not released a button after 5 seconds, which is the maximum duration
// supported by this mechanism, the UA should generate the INFO at that
// time.
// https://tools.ietf.org/html/draft-kaplan-dispatch-info-dtmf-package-00#section-5.3
const dtmf = tone;
const duration = 2000;
const body = {
contentDisposition: "render",
contentType: "application/dtmf-relay",
content: "Signal=" + dtmf + "\r\nDuration=" + duration
};
const requestOptions = { body };

return session.info({ requestOptions }).then(() => {
return;
});
}
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/platform/web/simple-user/simple-user-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ export interface SimpleUserOptions {
*/
registererOptions?: RegistererOptions;

/**
* Send DTMF using the session description handler (uses RFC 2833 DTMF).
* @defaultValue `false`
*/
sendDTMFUsingSessionDescriptionHandler?: boolean;

/**
* Options for UserAgent.
*/
Expand Down
1 change: 1 addition & 0 deletions src/platform/web/simple-user/simple-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export class SimpleUser {
reconnectionAttempts: this.options.reconnectionAttempts,
reconnectionDelay: this.options.reconnectionDelay,
registererOptions: this.options.registererOptions,
sendDTMFUsingSessionDescriptionHandler: this.options.sendDTMFUsingSessionDescriptionHandler,
userAgentOptions: this.options.userAgentOptions
};

Expand Down

0 comments on commit 48cb9b5

Please sign in to comment.