receiveRequest method
Request reception
Implementation
void receiveRequest(IncomingRequest request) {
DartSIP_C.SipMethod? method = request.method;
// Check that request URI points to us.
if (request.ruri!.user != _configuration!.uri.user &&
request.ruri!.user != _contact!.uri!.user) {
logger.debug('Request-URI does not point to us');
if (request.method != SipMethod.ACK) {
request.reply_sl(404);
}
return;
}
// Check request URI scheme.
if (request.ruri!.scheme == DartSIP_C.SIPS) {
request.reply_sl(416);
return;
}
// Check transaction.
if (checkTransaction(_transactions, request)) {
return;
}
// Create the server transaction.
if (method == SipMethod.INVITE) {
/* eslint-disable no-*/
InviteServerTransaction(this, _transport, request);
/* eslint-enable no-*/
} else if (method != SipMethod.ACK && method != SipMethod.CANCEL) {
/* eslint-disable no-*/
NonInviteServerTransaction(this, _transport, request);
/* eslint-enable no-*/
}
/* RFC3261 12.2.2
* Requests that do not change in any way the state of a dialog may be
* received within a dialog (for example, an OPTIONS request).
* They are processed as if they had been received outside the dialog.
*/
if (method == SipMethod.OPTIONS) {
request.reply(200);
} else if (method == SipMethod.MESSAGE) {
if (!hasListeners(EventNewMessage())) {
request.reply(405);
return;
}
Message message = Message(this);
message.init_incoming(request);
return;
} else if (method == SipMethod.INVITE) {
// Initial INVITE.
if (request.to_tag != null && !hasListeners(EventNewRTCSession())) {
request.reply(405);
return;
}
}
Dialog? dialog;
RTCSession? session;
// Initial Request.
if (request.to_tag == null) {
switch (method) {
case SipMethod.INVITE:
if (hasRTCPeerConnection) {
if (request.hasHeader('replaces')) {
ParsedData replaces = request.replaces;
dialog = _findDialog(
replaces.call_id, replaces.from_tag!, replaces.to_tag!);
if (dialog != null) {
session = dialog.owner;
if (!session!.isEnded()) {
session.receiveRequest(request);
} else {
request.reply(603);
}
} else {
request.reply(481);
}
} else {
session = RTCSession(this);
session.init_incoming(request);
}
} else {
logger.error('INVITE received but WebRTC is not supported');
request.reply(488);
}
break;
case SipMethod.BYE:
// Out of dialog BYE received.
request.reply(481);
break;
case SipMethod.CANCEL:
session =
_findSession(request.call_id!, request.from_tag, request.to_tag);
if (session != null) {
session.receiveRequest(request);
} else {
logger.debug('received CANCEL request for a non existent session');
}
break;
case SipMethod.ACK:
/* Absorb it.
* ACK request without a corresponding Invite Transaction
* and without To tag.
*/
break;
case SipMethod.NOTIFY:
// Receive sip event.
emit(EventSipEvent(request: request));
request.reply(200);
break;
default:
request.reply(405);
break;
}
}
// In-dialog request.
else {
dialog =
_findDialog(request.call_id!, request.from_tag!, request.to_tag!);
if (dialog != null) {
dialog.receiveRequest(request);
} else if (method == SipMethod.NOTIFY) {
session =
_findSession(request.call_id!, request.from_tag, request.to_tag);
if (session != null) {
session.receiveRequest(request);
} else {
logger
.debug('received NOTIFY request for a non existent subscription');
request.reply(481, 'Subscription does not exist');
}
}
/* RFC3261 12.2.2
* Request with to tag, but no matching dialog found.
* Exception: ACK for an Invite request for which a dialog has not
* been created.
*/
else if (method != SipMethod.ACK) {
request.reply(481);
}
}
}