reply method
      
void
reply(])
      
     
    
Stateful reply.
-param {Number} code status code
-param {String} reason reason phrase
-param {Object} headers extra headers
-param {String} body body
-param {Function} onSuccess onSuccess callback
-param {Function} onFailure onFailure callback
Implementation
void reply(int code,
    [String? reason,
    List<dynamic>? extraHeaders,
    String? body,
    Function? onSuccess,
    Function? onFailure]) {
  List<dynamic> supported = <dynamic>[];
  dynamic to = getHeader('To');
  reason = reason ?? null;
  // Validate code and reason values.
  if (code < 100 || code > 699) {
    throw Exceptions.TypeError('Invalid status_code: $code');
  } else if (reason != null) {
    throw Exceptions.TypeError('Invalid reason_phrase: $reason');
  }
  reason = reason ?? DartSIP_C.REASON_PHRASE[code] ?? '';
  if (extraHeaders != null) extraHeaders = utils.cloneArray(extraHeaders);
  String response = 'SIP/2.0 $code $reason\r\n';
  if (method == SipMethod.INVITE && code > 100 && code <= 200) {
    List<dynamic> headers = getHeaders('record-route');
    for (dynamic header in headers) {
      response += 'Record-Route: $header\r\n';
    }
  }
  List<dynamic> vias = getHeaders('via');
  for (dynamic via in vias) {
    response += 'Via: $via\r\n';
  }
  if (to_tag == null && code > 100) {
    to += ';tag=${utils.newTag()}';
  } else if (to_tag != null && !s('to').hasParam('tag')) {
    to += ';tag=$to_tag';
  }
  response += 'To: $to\r\n';
  response += 'From: ${getHeader('From')}\r\n';
  response += 'Call-ID: $call_id\r\n';
  response += 'CSeq: $cseq ${SipMethodHelper.getName(method)}\r\n';
  if (extraHeaders != null)
    for (dynamic header in extraHeaders) {
      response += '${header.trim()}\r\n';
    }
  // Supported.
  switch (method) {
    case SipMethod.INVITE:
      if (ua!.configuration!.sessionTimers) {
        supported.add('timer');
      }
      if (ua!.contact!.pub_gruu != null || ua!.contact!.temp_gruu != null) {
        supported.add('gruu');
      }
      supported.add('ice');
      supported.add('replaces');
      break;
    case SipMethod.UPDATE:
      if (ua!.configuration!.sessionTimers) {
        supported.add('timer');
      }
      if (body != null) {
        supported.add('ice');
      }
      supported.add('replaces');
      break;
    default:
      break;
  }
  supported.add('outbound');
  // Allow and Accept.
  if (method == SipMethod.OPTIONS) {
    response += 'Allow: ${DartSIP_C.ALLOWED_METHODS}\r\n';
    response += 'Accept: ${DartSIP_C.ACCEPTED_BODY_TYPES}\r\n';
  } else if (code == 405) {
    response += 'Allow: ${DartSIP_C.ALLOWED_METHODS}\r\n';
  } else if (code == 415) {
    response += 'Accept: ${DartSIP_C.ACCEPTED_BODY_TYPES}\r\n';
  }
  response += 'Supported: ${supported.join(',')}\r\n';
  if (body != null) {
    int length = body.length;
    response += 'Content-Type: application/sdp\r\n';
    response += 'Content-Length: $length\r\n\r\n';
    response += body;
  } else {
    response += 'Content-Length: ${0}\r\n\r\n';
  }
  IncomingMessage message = IncomingMessage();
  message.data = response;
  server_transaction!.receiveResponse(code, message,
      onSuccess as void Function()?, onFailure as void Function()?);
}