parseMessage function
Parse SIP Message
Implementation
IncomingMessage? parseMessage(String data, PitelUA? ua) {
IncomingMessage message;
int bodyStart;
int headerEnd = data.indexOf('\r\n');
if (headerEnd == -1) {
logger.error('parseMessage() | no CRLF found, not a SIP message');
return null;
}
// Parse first line. Check if it is a Request or a Reply.
String firstLine = data.substring(0, headerEnd);
dynamic parsed;
try {
parsed = Grammar.parse(firstLine, 'Request_Response');
} catch (FormatException) {
// Catch exception and fake the expected -1 result
parsed = -1;
}
if (parsed == -1) {
logger.error(
'parseMessage() | error parsing first line of SIP message: "$firstLine"');
return null;
} else if (parsed.status_code == null) {
IncomingRequest incomingRequest = IncomingRequest(ua);
incomingRequest.method = parsed.method;
incomingRequest.ruri = parsed.uri;
message = incomingRequest;
} else {
message = IncomingResponse();
message.status_code = parsed.status_code;
message.reason_phrase = parsed.reason_phrase;
}
message.data = data;
int headerStart = headerEnd + 2;
/* Loop over every line in data. Detect the end of each header and parse
* it or simply add to the headers collection.
*/
while (true) {
headerEnd = getHeader(data, headerStart);
// The SIP message has normally finished.
if (headerEnd == -2) {
bodyStart = headerStart + 2;
break;
}
// Data.indexOf returned -1 due to a malformed message.
else if (headerEnd == -1) {
logger.error('parseMessage() | malformed message');
return null;
}
parsed = parseHeader(message, data, headerStart, headerEnd);
if (parsed != true) {
logger.error('parseMessage() |' + parsed['error']);
return null;
}
headerStart = headerEnd + 2;
}
/* RFC3261 18.3.
* If there are additional bytes in the transport packet
* beyond the end of the body, they MUST be discarded.
*/
if (message.hasHeader('content-length')) {
dynamic contentLength = message.getHeader('content-length');
if (contentLength is String) {
contentLength = int.tryParse(contentLength) ?? 0;
}
contentLength ??= 0;
if (contentLength > 0) {
List<int> encoded = utf8.encode(data);
List<int> content =
encoded.sublist(bodyStart, bodyStart + contentLength as int);
message.body = utf8.decode(content);
}
} else {
message.body = data.substring(bodyStart);
}
return message;
}