sendDTMF method

void sendDTMF(
  1. dynamic tones, [
  2. Map<String, dynamic>? options
])

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), () {});
      });
    }
  }
}