Implemented t_uac_dlg and build_uac_request_dlg. These functions are more
[sip-router] / modules / tm / t_msgbuilder.c
index 03f3bb0..e50f643 100644 (file)
@@ -317,6 +317,174 @@ error:
 }
 
 
+char *build_uac_request_dlg(str* msg,           /* Method */
+                           str* ruri,          /* Request-URI */
+                           str* to,            /* To */
+                           str* from,          /* From */
+                           str* totag,         /* To header tag */
+                           str* fromtag,       /* From header tag */
+                           unsigned int cseq,  /* CSeq number */
+                           str* callid,        /* Call-ID */
+                           str* headers,       /* Headers to be appended */
+                           str* body,          /* Body of the message */
+                           int branch,         /* Branch */
+                           struct cell *t,     
+                           unsigned int *len)
+{
+       char *via, *buf, *w, content_len[10], cseq_str[10], branch_buf[MAX_BRANCH_PARAM_LEN];
+       int content_len_len, cseq_str_len, branch_len;
+       unsigned int via_len;
+
+       buf=0;
+       content_len_len = 0; /* Makes gcc happy */
+
+            /* 
+             * Print Content-Length
+             */
+       if (body) {
+               content_len_len = snprintf(content_len, sizeof(content_len), "%d", body->len);
+               if (content_len_len == -1) {
+                       LOG(L_ERR, "ERROR: build_uac_request_dlg: content_len too big\n");
+                       return 0;
+               }
+       }
+       
+            /* 
+             * Print CSeq 
+             */
+       cseq_str_len = snprintf(cseq_str, sizeof(cseq_str), "%d", cseq);
+       if (cseq_str_len == -1) {
+               LOG(L_ERR, "ERROR: build_uac_request_dlg: cseq too big\n");
+               return 0;
+       }
+       
+       *len = msg->len + 1 + ruri->len + 1 + SIP_VERSION_LEN + CRLF_LEN;
+
+       if (!t_calc_branch(t, branch, branch_buf, &branch_len)) {
+               LOG(L_ERR, "ERROR: build_uac_request_dlg: branch calculation failed\n");
+               goto error;
+       }
+
+       via = via_builder(&via_len, t->uac[branch].request.send_sock, branch_buf, branch_len);
+       if (!via) {
+               LOG(L_ERR, "ERROR: build_uac_request_dlg: via building failed\n");
+               goto error;
+       }
+       
+       *len += via_len;
+       
+       /* header names and separators */
+       *len +=   TO_LEN + CRLF_LEN
+               + FROM_LEN + CRLF_LEN
+               + CSEQ_LEN + CRLF_LEN
+               + CALLID_LEN + CRLF_LEN
+               + ((body) ? (CONTENT_LENGTH_LEN + CRLF_LEN) : 0)
+               + (server_signature ? USER_AGENT_LEN + CRLF_LEN : 0)
+               + CRLF_LEN; /* EoM */
+       
+            /* header field value and body length */
+       *len +=   to->len + ((totag) ? (TOTAG_LEN + totag->len) : 0) /* To */
+               + from->len + FROMTAG_LEN + fromtag->len             /* From */
+               + cseq_str_len + 1 + msg->len                        /* CSeq */
+               + callid->len                                        /* Call-ID */
+               + ((body) ? (content_len_len) : 0)                   /* Content-Length */
+               + ((headers) ? (headers->len) : 0)                   /* Headers */
+               + ((body) ? (body->len) : 0);                        /* Body */
+       
+       buf = shm_malloc(*len + 1);
+       if (!buf) {
+               LOG(L_ERR, "ERROR: build_uac_request_dlg: no shmem\n");
+               goto error1;
+       }
+       
+       w = buf;
+
+            /* First line */
+       memapp(w, msg->s, msg->len); 
+       memapp(w, " ", 1); 
+
+       t->uac[branch].uri.s = w; 
+       t->uac[branch].uri.len = ruri->len;
+
+       memapp(w, ruri->s, ruri->len); 
+       memapp(w, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
+
+            /* First Via */
+       memapp(w, via, via_len);
+
+            /* To */
+       t->to.s = w;
+       t->to.len = TO_LEN + to->len + ((totag) ? (TOTAG_LEN + totag->len) : 0);
+
+       memapp(w, TO, TO_LEN);
+       memapp(w, to->s, to->len);
+       if (totag) {
+               memapp(w, TOTAG, TOTAG_LEN);
+               memapp(w, totag->s, totag->len);
+       }
+       memapp(w, CRLF, CRLF_LEN);
+
+            /* From */
+       t->from.s = w;
+       t->from.len = FROM_LEN + from->len + FROMTAG_LEN + fromtag->len;
+
+       memapp(w, FROM, FROM_LEN);
+       memapp(w, from->s, from->len);
+       memapp(w, FROMTAG, FROMTAG_LEN);
+       memapp(w, fromtag->s, fromtag->len);
+       memapp(w, CRLF, CRLF_LEN);
+       
+            /* CSeq */
+       t->cseq_n.s = w; 
+       t->cseq_n.len = CSEQ_LEN + cseq_str_len;
+
+       memapp(w, CSEQ, CSEQ_LEN);
+       memapp(w, cseq_str, cseq_str_len);
+       memapp(w, " ", 1);
+       memapp(w, msg->s, msg->len);
+
+            /* Call-ID */
+       t->callid.s = w + CRLF_LEN; 
+       t->callid.len = callid->len;
+       memapp(w, CRLF CALLID, CRLF_LEN + CALLID_LEN);
+       memapp(w, callid->s, callid->len);
+
+            /* Content-Length */
+       if (body) {
+               memapp(w, CRLF CONTENT_LENGTH, CRLF_LEN + CONTENT_LENGTH_LEN);
+               memapp(w, content_len, content_len_len);
+               memapp(w, CRLF, CRLF_LEN);
+       }
+       
+            /* Server signature */
+       if (server_signature) {
+               memapp(w, USER_AGENT CRLF, USER_AGENT_LEN + CRLF_LEN);
+       }
+
+            /* Headers */
+       if (headers) {
+               memapp(w, headers->s, headers->len);
+       }
+
+            /* EoH */
+       memapp(w, CRLF, CRLF_LEN);
+       
+            /* Body */
+       if (body) {
+               memapp(w, body->s, body->len);
+       }
+
+#ifdef EXTRA_DEBUG
+       if (w-buf != *len ) abort();
+#endif
+       
+ error1:
+       pkg_free(via);  
+ error:
+       return buf;
+}
+
+
 int t_calc_branch(struct cell *t, 
        int b, char *branch, int *branch_len)
 {