endCall method

void endCall()

Attempts to end the call identified via the callID

This method handles the complete call termination process and uses the CallHandler to ensure proper state management during call end.

State Management:

  • Uses callHandler.changeState(CallState.done) as the single source of truth
  • Ensures state transition callbacks are triggered
  • Maintains consistency with the rest of the SDK

Implementation

void endCall() {
  final uuid = const Uuid().v4();
  final byeDialogParams = ByeDialogParams(callId: callId);

  // Determine the appropriate cause code based on current call state
  final (causeCode, causeName) = switch (callState) {
    // When Active or Connecting, use NORMAL_CLEARING
    CallState.active => (
      CauseCode.NORMAL_CLEARING.value,
      CauseCode.NORMAL_CLEARING.name,
    ),
    CallState.connecting => (
      CauseCode.NORMAL_CLEARING.value,
      CauseCode.NORMAL_CLEARING.name,
    ),
    // When Ringing (i.e. Rejecting an incoming call), use USER_BUSY
    CallState.ringing => (
      CauseCode.USER_BUSY.value,
      CauseCode.USER_BUSY.name,
    ),
    // Default to NORMAL_CLEARING for other states
    _ => (CauseCode.NORMAL_CLEARING.value, CauseCode.NORMAL_CLEARING.name),
  };

  final byeParams = SendByeParams(
    cause: causeName,
    causeCode: causeCode,
    dialogParams: byeDialogParams,
    sessid: sessid,
  );

  final byeMessage = SendByeMessage(
    id: uuid,
    jsonrpc: JsonRPCConstant.jsonrpc,
    method: SocketMethod.bye,
    params: byeParams,
  );

  final String jsonByeMessage = jsonEncode(byeMessage);

  if (_txClient.gatewayState != GatewayState.reged &&
      _txClient.gatewayState != GatewayState.idle &&
      _txClient.gatewayState != GatewayState.attached) {
    GlobalLogger().d(
      'Session end gateway not registered ${_txClient.gatewayState}',
    );
    return;
  } else {
    GlobalLogger().d('Session end peer connection null');
  }

  txSocket.send(jsonByeMessage);
  if (peerConnection != null) {
    peerConnection?.closeSession();
  } else {
    GlobalLogger().d('Session end peer connection null');
  }
  stopAudio();
  callHandler.changeState(CallState.done);
  callEnded();

  // Cancel any reconnection timer for this call
  _txClient.onCallStateChangedToActive(callId);

  _txClient.calls.remove(callId);
  final message = TelnyxMessage(
    socketMethod: SocketMethod.bye,
    message: ReceivedMessage(method: 'telnyx_rtc.bye'),
  );
  _txClient.onSocketMessageReceived.call(message);
}