sendDTMF method
tones may be a single character or a string of dtmf digits
Implementation
void sendDTMF(dynamic tones, [Map<String, dynamic>? options]) {
logger.debug('sendDTMF() | tones: ${tones.toString()}');
options = options ?? <String, dynamic>{};
DtmfMode mode = _ua!.configuration!.dtmfMode;
// sensible defaults
int duration = options['duration'] ?? rtc_session_dtfm.C.DEFAULT_DURATION;
int interToneGap =
options['interToneGap'] ?? rtc_session_dtfm.C.DEFAULT_INTER_TONE_GAP;
if (tones == null) {
throw exceptions.TypeError('Not enough arguments');
}
// Check Session Status.
if (_status != C.statusConfirmed && _status != C.statusWaitingForAck) {
throw exceptions.InvalidStateError(_status);
}
// Convert to string.
if (tones is num) {
tones = tones.toString();
}
// Check tones.
if (tones == null ||
tones is! String ||
!tones.contains(RegExp(r'^[0-9A-DR#*,]+$', caseSensitive: false))) {
throw exceptions.TypeError('Invalid tones: ${tones.toString()}');
}
// Check duration.
if (duration != null && !utils.isDecimal(duration)) {
throw exceptions.TypeError(
'Invalid tone duration: ${duration.toString()}');
} else if (duration == null) {
duration = rtc_session_dtfm.C.DEFAULT_DURATION;
} else if (duration < rtc_session_dtfm.C.MIN_DURATION) {
logger.debug(
'"duration" value is lower than the minimum allowed, setting it to ${rtc_session_dtfm.C.MIN_DURATION} milliseconds');
duration = rtc_session_dtfm.C.MIN_DURATION;
} else if (duration > rtc_session_dtfm.C.MAX_DURATION) {
logger.debug(
'"duration" value is greater than the maximum allowed, setting it to ${rtc_session_dtfm.C.MAX_DURATION} milliseconds');
duration = rtc_session_dtfm.C.MAX_DURATION;
} else {
duration = utils.Math.abs(duration) as int;
}
options['duration'] = duration;
// Check interToneGap.
if (interToneGap != null && !utils.isDecimal(interToneGap)) {
throw exceptions.TypeError(
'Invalid interToneGap: ${interToneGap.toString()}');
} else if (interToneGap == null) {
interToneGap = rtc_session_dtfm.C.DEFAULT_INTER_TONE_GAP;
} else if (interToneGap < rtc_session_dtfm.C.MIN_INTER_TONE_GAP) {
logger.debug(
'"interToneGap" value is lower than the minimum allowed, setting it to ${rtc_session_dtfm.C.MIN_INTER_TONE_GAP} milliseconds');
interToneGap = rtc_session_dtfm.C.MIN_INTER_TONE_GAP;
} else {
interToneGap = utils.Math.abs(interToneGap) as int;
}
options['interToneGap'] = interToneGap;
//// ***************** and follows the actual code to queue DTMF tone(s) **********************
///using dtmfFuture to queue the playing of the tones
for (int i = 0; i < tones.length; i++) {
String tone = tones[i];
if (tone == ',') {
// queue the delay
dtmfFuture = dtmfFuture.then((_) async {
if (_status == C.statusTerminated) {
return;
}
await Future<void>.delayed(Duration(milliseconds: 2000), () {});
});
} else {
// queue playing the tone
dtmfFuture = dtmfFuture.then((_) async {
if (_status == C.statusTerminated) {
return;
}
rtc_session_dtfm.DTMF dtmf = rtc_session_dtfm.DTMF(this, mode: mode);
EventManager handlers = EventManager();
handlers.on(EventCallFailed(), (EventCallFailed event) {
logger.error('Failed to send DTMF ${event.cause}');
});
options!['eventHandlers'] = handlers;
dtmf.send(tone, options);
await Future<void>.delayed(
Duration(milliseconds: duration + interToneGap), () {});
});
}
}
}