SIP_Templates: Always set Content-Length

According to RFC3261 7.4.2, 7.5, 20.14 Content-Length SHOULD be set over
any transport, and MUST be set over TCP.
Hence, make sure we set it in all cases.
This allows Asterisk being able to decode SIP messages sent to it over a
TCP connection, since it uses the Content-Length field to look up for
message boundaries over the TCP stream.

Change-Id: I26e444fe466b4742d74ef5a6e371ce8488a5afcf
diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn
index 65f9d22..e2be94b 100644
--- a/library/SIP_Templates.ttcn
+++ b/library/SIP_Templates.ttcn
@@ -201,6 +201,16 @@
 }
 
 
+// [20.14]
+template (value) ContentLength ts_ContentLength(template (value) integer len := 0) := {
+	fieldName := CONTENT_LENGTH_E,
+	len := len
+}
+template (present) ContentLength tr_ContentLength(template (present) integer len := ?) := {
+	fieldName := CONTENT_LENGTH_E,
+	len := len
+}
+
 // [20.19]
 template (value) Expires ts_Expires(template (value) DeltaSec deltaSec := "7200") := {
 	fieldName := EXPIRES_E,
@@ -419,6 +429,16 @@
 	return ct;
 }
 
+private function f_ContentLength(template (omit) charstring body)
+return template (value) ContentLength {
+	/* rfc3261 20.14: "If no body is present in a message, then the
+	 * Content-Length header field value MUST be set to zero." */
+	if (istemplatekind(body, "omit")) {
+		return ts_ContentLength(0);
+	}
+	return ts_ContentLength(lengthof(body));
+}
+
 template (value) ContentType ts_CT_SDP := {
 	fieldName := CONTENT_TYPE_E,
 	mediaType := "application/sdp"
@@ -539,6 +559,7 @@
 		template (value) charstring method,
 		template (value) integer seq_nr,
 		template (value) Via via,
+		template (omit) ContentLength content_length := ts_ContentLength(0),
 		template (omit) ContentType content_type := omit,
 		template (omit)Authorization authorization := omit,
 		template (omit) Allow allow := ts_Allow(c_SIP_defaultMethods),
@@ -558,6 +579,7 @@
 		callid := call_id
 	},
 	contact := contact,
+	contentLength := content_length,
 	contentType := content_type,
 	cSeq := {
 		fieldName := CSEQ_E,
@@ -592,8 +614,9 @@
 		template Contact contact,
 		template (present) Via via := tr_Via_from(?),
 		template charstring method,
-		template ContentType content_type := *,
 		template integer seq_nr := ?,
+		template ContentLength content_length := *,
+		template ContentType content_type := *,
 		template Allow allow := *,
 		template Expires expires := *,
 		template Require require := *,
@@ -610,6 +633,7 @@
 		callid := call_id
 	},
 	contact := contact,
+	contentLength := content_length,
 	contentType := content_type,
 	cSeq := {
 		fieldName := CSEQ_E,
@@ -655,7 +679,8 @@
 	requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
 				     "REGISTER", seq_nr, via,
-				     f_ContentTypeOrOmit(ts_CT_SDP, body),
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body),
 				     authorization := authorization,
 				     expires := expires,
 				     require := require,
@@ -679,7 +704,7 @@
 		template charstring body := *) := {
 	requestLine := tr_SIP_ReqLine(REGISTER_E, sip_url_host_port),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
-				     via, "REGISTER", *, seq_nr,
+				     via, "REGISTER", seq_nr,
 				     expires := expires,
 				     require := require,
 				     security_client := security_client,
@@ -700,7 +725,8 @@
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
 				     "INVITE", seq_nr,
 				     via,
-				     f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -714,7 +740,7 @@
 	      template charstring body) := {
 	requestLine := tr_SIP_ReqLine(INVITE_E, uri),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, ?,
-				     via, "INVITE", *, seq_nr),
+				     via, "INVITE", seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -728,7 +754,9 @@
 	   template (omit) charstring body) := {
 	requestLine := ts_SIP_ReqLine(BYE_E, to_addr.addr.nameAddr.addrSpec),
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, "BYE", seq_nr,
-				     via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     via,
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -743,7 +771,7 @@
 	   template charstring body := *) := {
 	requestLine := tr_SIP_ReqLine(BYE_E, uri),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
-				     via, "BYE", *, seq_nr),
+				     via, "BYE", seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -761,7 +789,8 @@
 				     ts_Contact_SipAddr(from_addr),
 				     "ACK", seq_nr,
 				     via,
-				     f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -776,7 +805,7 @@
 	requestLine := tr_SIP_ReqLine(ACK_E, uri),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
 				     via,
-				     "ACK", *, seq_nr),
+				     "ACK", seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -792,7 +821,7 @@
 	requestLine := tr_SIP_ReqLine(CANCEL_E, uri),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
 				     via,
-				     "CANCEL", *, seq_nr),
+				     "CANCEL", seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -809,7 +838,9 @@
 		template (omit) charstring body := omit) := {
 	statusLine := ts_SIP_StatusLine(status_code, reason),
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
-				     via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     via,
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -825,7 +856,9 @@
 	template (omit) charstring body := omit) := {
 	statusLine := ts_SIP_StatusLine(100, "Trying"),
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
-				     via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     via,
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -841,7 +874,9 @@
 	template (omit) charstring body := omit) := {
 	statusLine := ts_SIP_StatusLine(180, "Ringing"),
 	msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, omit, method, seq_nr,
-				     via, f_ContentTypeOrOmit(ts_CT_SDP, body)),
+				     via,
+				     content_length := f_ContentLength(body),
+				     content_type := f_ContentTypeOrOmit(ts_CT_SDP, body)),
 	messageBody := body,
 	payload := omit
 }
@@ -860,7 +895,7 @@
 	statusLine := tr_SIP_StatusLine(status_code, reason),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
 				     via,
-				     method, *, seq_nr),
+				     method, seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -882,7 +917,7 @@
 	statusLine := tr_SIP_StatusLine(status_code, reason),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
 				     via,
-				     method, *, seq_nr,
+				     method, seq_nr,
 				     wwwAuthenticate := wwwAuthenticate),
 	messageBody := body,
 	payload := omit
@@ -903,7 +938,7 @@
 	statusLine := tr_SIP_StatusLine(status_code, reason),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, omit,
 				     via,
-				     method, *, seq_nr),
+				     method, seq_nr),
 	messageBody := body,
 	payload := omit
 }
@@ -923,7 +958,7 @@
 	statusLine := tr_SIP_StatusLine(status_code, reason),
 	msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
 				     via,
-				     method, *, seq_nr),
+				     method, seq_nr),
 	messageBody := body,
 	payload := omit
 }