Browse code

voicemail specific code added (see #define VOICE_MAIL and module vm)

Raphael Coeffic authored on 31/01/2003 13:54:59
Showing 10 changed files
... ...
@@ -141,6 +141,10 @@ YACC := $(shell echo "$${YACC}")
141 141
 # -DUSE_TCP
142 142
 #		compiles in tcp support (highly experimental for now, it will probably
143 143
 #		not work, use it only if you really now what you are doing)
144
+# -DVOICE_MAIL
145
+#               enables voicemail support in ser core and in tm module
146
+#               voicemail needs also -D_TOTAG
147
+
144 148
 DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
145 149
 	 -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"' -D__CPU_$(ARCH)\
146 150
 	 -DCFG_DIR='"$(cfg-target)"'\
... ...
@@ -149,7 +153,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
149 149
 	 -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
150 150
 	 -DDNS_IP_HACK \
151 151
 	 -DUSE_IPV6 \
152
-	 -DDBG_QM_MALLOC \
152
+	 -DVOICE_MAIL \
153
+	 -D_TOTAG \
153 154
 	 -DUSE_TCP \
154 155
 	 #-DF_MALLOC \
155 156
 	 #-DNO_DEBUG \
... ...
@@ -930,3 +930,76 @@ int t_unref( struct sip_msg* p_msg  )
930 930
 	return 1;
931 931
 }
932 932
 
933
+#ifdef VOICE_MAIL
934
+int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index, unsigned int* label)
935
+{
936
+    struct cell* t;
937
+    if(t_check(p_msg,0) != 1){
938
+	LOG(L_ERR,"ERROR: t_get_trans_ident: no transaction found\n");
939
+	return -1;
940
+    }
941
+    t = get_t();
942
+    if(!t){
943
+	LOG(L_ERR,"ERROR: t_get_trans_ident: transaction found is NULL\n");
944
+	return -1;
945
+    }
946
+    
947
+    *hash_index = t->hash_index;
948
+    *label = t->label;
949
+
950
+    return 1;
951
+}
952
+
953
+int t_lookup_ident(struct sip_msg** p_msg, unsigned int hash_index, unsigned int label)
954
+{
955
+    int ret = 0;
956
+    struct cell* p_cell;
957
+
958
+    if(hash_index >= TABLE_ENTRIES){
959
+	LOG(L_ERR,"ERROR: t_lookup_ident: invalid hash_index=%u\n",hash_index);
960
+	return -1;
961
+    }
962
+
963
+    LOCK_HASH(hash_index);
964
+
965
+    /* all the transactions from the entry are compared */
966
+    for ( p_cell = get_tm_table()->entrys[hash_index].first_cell;
967
+	  p_cell; p_cell = p_cell->next_cell ) 
968
+    {
969
+	if(p_cell->label == label){
970
+	    ret = 1;
971
+	    break;
972
+	}
973
+    }
974
+
975
+    if(ret==1){
976
+	DBG("DEBUG: t_lookup_ident: transaction found\n");
977
+	*p_msg = p_cell->uas.request;
978
+    }
979
+    else
980
+	DBG("DEBUG: t_lookup_ident: transaction not found\n");
981
+    
982
+    UNLOCK_HASH(hash_index);
983
+    return ret;
984
+}
985
+
986
+int t_is_local(struct sip_msg* p_msg)
987
+{
988
+    struct cell* t;
989
+    if(t_check(p_msg,0) != 1){
990
+	LOG(L_ERR,"ERROR: t_is_local: no transaction found\n");
991
+	return -1;
992
+    }
993
+    t = get_t();
994
+    if(!t){
995
+	LOG(L_ERR,"ERROR: t_is_local: transaction found is NULL\n");
996
+	return -1;
997
+    }
998
+    
999
+    return t->local;
1000
+}
1001
+
1002
+#endif
1003
+
1004
+
1005
+
... ...
@@ -73,6 +73,20 @@ struct cell *get_t();
73 73
  * primarily set by lookup functions */
74 74
 void set_t(struct cell *t);
75 75
 
76
+#ifdef VOICE_MAIL
77
+
78
+#define T_GET_TI       "t_get_trans_ident"
79
+#define T_LOOKUP_IDENT "t_lookup_ident"
80
+#define T_IS_LOCAL     "t_is_local"
81
+
82
+typedef int (*tislocal_f)(struct sip_msg*);
83
+typedef int (*tget_ti_f)(struct sip_msg*, unsigned int*, unsigned int*);
84
+typedef int (*tlookup_ident_f)(struct sip_msg**, unsigned int, unsigned int);
85
+
86
+int t_is_local(struct sip_msg*);
87
+int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index, unsigned int* label);
88
+int t_lookup_ident(struct sip_msg** p_msg, unsigned int hash_index, unsigned int label);
89
+#endif
76 90
 
77 91
 #endif
78 92
 
... ...
@@ -491,6 +491,18 @@ error:
491 491
 }
492 492
 
493 493
 
494
+#ifdef VOICE_MAIL
495
+static int _reply_light( struct cell *trans, char* buf, unsigned int len,
496
+			 unsigned int code, char * text, 
497
+			 char *to_tag, unsigned int to_tag_len, int lock );
498
+
499
+int t_reply_light( struct cell *t, char* buf, unsigned int len,
500
+		   unsigned int code, char * text,
501
+		   char *to_tag, unsigned int to_tag_len )
502
+{
503
+    return _reply_light( t, buf, len, code, text, to_tag, to_tag_len, 1 /* lock replies */ );
504
+}
505
+#endif
494 506
 
495 507
 int t_reply( struct cell *t, struct sip_msg* p_msg, unsigned int code, 
496 508
 	char * text )
... ...
@@ -512,18 +524,25 @@ int t_reply_unsafe( struct cell *t, struct sip_msg* p_msg, unsigned int code,
512 512
 static int _reply( struct cell *trans, struct sip_msg* p_msg, 
513 513
 	unsigned int code, char * text, int lock )
514 514
 {
515
+#ifndef VOICE_MAIL
515 516
 	unsigned int len, buf_len=0;
516 517
 	char * buf;
517 518
 	struct retr_buf *rb;
518 519
 
519 520
 	branch_bm_t cancel_bitmap;
521
+#else
522
+	unsigned int len;
523
+	char * buf;
524
+#endif
520 525
 
521 526
 	if (code>=200) trans->kr|=REQ_RPLD;
522 527
 	/*
523 528
 	buf = build_res_buf_from_sip_req(code,text,trans->uas.tag->s,
524 529
 		trans->uas.tag->len, trans->uas.request,&len);
525 530
 	*/
531
+#ifndef VOICE_MAIL
526 532
 	cancel_bitmap=0;
533
+#endif
527 534
 	/* compute the buffer in private memory prior to entering lock;
528 535
 	 * create to-tag if needed */
529 536
 	if (code>=180 && p_msg->to 
... ...
@@ -533,11 +552,34 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
533 533
 		buf = build_res_buf_from_sip_req(code,text, 
534 534
 				tm_tags, TOTAG_LEN, 
535 535
 				p_msg,&len);
536
+#ifdef VOICE_MAIL
537
+
538
+		return _reply_light(trans,buf,len,code,text,
539
+				    tm_tags, TOTAG_LEN,
540
+				    lock);
541
+#endif
536 542
 	} else {
537 543
 		buf = build_res_buf_from_sip_req(code,text, 0,0, /* no to-tag */
538 544
 			p_msg,&len);
545
+#ifdef VOICE_MAIL
546
+
547
+		return _reply_light(trans,buf,len,code,text,
548
+				    0,0, /* no to-tag */
549
+				    lock);
550
+#endif
539 551
 	}
540 552
 	DBG("DEBUG: t_reply: buffer computed\n");
553
+#ifdef VOICE_MAIL
554
+}
555
+
556
+static int _reply_light( struct cell *trans, char* buf, unsigned int len,
557
+			 unsigned int code, char * text, 
558
+			 char *to_tag, unsigned int to_tag_len, int lock )
559
+{
560
+	struct retr_buf *rb;
561
+	unsigned int buf_len=0;
562
+	branch_bm_t cancel_bitmap=0;
563
+#endif
541 564
 	if (!buf)
542 565
 	{
543 566
 		DBG("DEBUG: t_reply: response building failed\n");
... ...
@@ -571,6 +613,19 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
571 571
 	}
572 572
 	rb->buffer_len = len ;
573 573
 	memcpy( rb->buffer , buf , len );
574
+#ifdef VOICE_MAIL
575
+	if(to_tag){
576
+	    trans->uas.to_tag.s = (char*)shm_resize( trans->uas.to_tag.s, to_tag_len );
577
+	    if(! trans->uas.to_tag.s ){
578
+			LOG(L_ERR, "ERROR: t_reply: cannot allocate shmem buffer\n");
579
+			// Is it ok? or should i free rb->buffer also, 
580
+			// or will it be freed in free_cell() ?
581
+			goto error2; 
582
+	    }
583
+	    trans->uas.to_tag.len = to_tag_len;
584
+	    memcpy( trans->uas.to_tag.s, to_tag, to_tag_len );
585
+	}
586
+#endif
574 587
 	/* needs to be protected too because what timers are set depends
575 588
 	   on current transactions status */
576 589
 	/* t_update_timers_after_sending_reply( rb ); */
... ...
@@ -1027,3 +1082,55 @@ done:
1027 1027
 	return 0;
1028 1028
 }
1029 1029
 
1030
+#ifdef VOICE_MAIL
1031
+
1032
+#include <assert.h>
1033
+
1034
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, char * text, char * body, char * new_header, char * to_tag )
1035
+{
1036
+    struct cell * t;
1037
+    //char to_tag[64];
1038
+    str  s_to_tag,sb,snh;
1039
+    char* res_buf;
1040
+    int res_len,ret;
1041
+
1042
+    /*  check if we have a transaction */
1043
+    if (t_check(p_msg, 0)==-1) {
1044
+	LOG(L_ERR,"ERROR: t_reply_with_body: no transaction found.\n");
1045
+	return -1;
1046
+    }
1047
+
1048
+    t=get_t();
1049
+    assert(t);
1050
+
1051
+    s_to_tag.s = to_tag;
1052
+    if(to_tag)
1053
+	s_to_tag.len = strlen(to_tag);
1054
+
1055
+    // mark the transaction as replied
1056
+    t->kr|=REQ_RPLD;
1057
+
1058
+    /* compute the response */
1059
+    sb.s = body;
1060
+    sb.len = strlen(body);
1061
+    snh.s = new_header;
1062
+    snh.len = strlen(new_header);
1063
+
1064
+    res_buf = build_res_buf_with_body_from_sip_req(code,text, s_to_tag.s, s_to_tag.len,
1065
+						   sb.s,sb.len,
1066
+						   snh.s,snh.len,
1067
+						   p_msg,&res_len);
1068
+    
1069
+    DBG("t_reply_with_body: buffer computed\n");
1070
+    // frees 'res_buf' ... no panic !
1071
+    ret = t_reply_light(t, res_buf, res_len, code, text,
1072
+			s_to_tag.s, s_to_tag.len);
1073
+
1074
+    // TODO: i'm not sure i should do this here ...
1075
+    if(t_unref(p_msg) == -1)
1076
+	LOG(L_WARN,"WARNING: fifo_t_reply: could not unref transaction %p\n",t);
1077
+
1078
+    return ret;
1079
+}
1080
+
1081
+#endif
... ...
@@ -60,6 +60,11 @@ typedef unsigned int branch_bm_t;
60 60
 /* reply export types */
61 61
 typedef int (*treply_f)( struct sip_msg* p_msg,
62 62
 	unsigned int code, char * text );
63
+#ifdef VOICE_MAIL
64
+typedef int (*treply_wb_f)( struct sip_msg* p_msg,
65
+	unsigned int code, char * text, char * body, 
66
+	char * new_header, char * to_tag);
67
+#endif
63 68
 
64 69
 #define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex )
65 70
 #define UNLOCK_REPLIES(_t) unlock(&(_t)->reply_mutex )
... ...
@@ -80,6 +85,21 @@ int t_retransmit_reply( /* struct sip_msg * */  );
80 80
 
81 81
 
82 82
 /* send a UAS reply
83
+ * Warning: 'buf' and 'len' should already have been build.
84
+ * returns 1 if everything was OK or -1 for erro
85
+ */
86
+#ifdef VOICE_MAIL
87
+
88
+int t_reply_light( struct cell *trans, char* buf, unsigned int len,
89
+		   unsigned int code, char * text,
90
+		   char *to_tag, unsigned int to_tag_len);
91
+
92
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, 
93
+		       char * text, char * body, char * new_header, char * to_tag );
94
+
95
+#endif
96
+
97
+/* send a UAS reply
83 98
  * returns 1 if everything was OK or -1 for erro
84 99
  */
85 100
 int t_reply( struct cell *t, struct sip_msg * , unsigned int , char * );
... ...
@@ -137,6 +137,12 @@ struct module_exports exports= {
137 137
 #endif
138 138
 				T_UAC_DLG,
139 139
 				"load_tm",
140
+#ifdef VOICE_MAIL
141
+				T_REPLY_WB,
142
+				T_IS_LOCAL,
143
+				T_GET_TI,
144
+				T_LOOKUP_IDENT,
145
+#endif
140 146
 				"t_newdlg"
141 147
 			},
142 148
 	(cmd_function[]){
... ...
@@ -160,6 +166,12 @@ struct module_exports exports= {
160 160
 #endif
161 161
 					(cmd_function) t_uac_dlg,
162 162
 					(cmd_function) load_tm,
163
+#ifdef VOICE_MAIL
164
+					(cmd_function) t_reply_with_body,
165
+					(cmd_function) t_is_local,
166
+					(cmd_function) t_get_trans_ident,
167
+					(cmd_function) t_lookup_ident,
168
+#endif
163 169
 					w_t_newdlg,
164 170
 					},
165 171
 	(int[]){
... ...
@@ -182,6 +194,12 @@ struct module_exports exports= {
182 182
 #endif
183 183
 				NO_SCRIPT /* t_uac_dlg */,
184 184
 				NO_SCRIPT /* load_tm */,
185
+#ifdef VOICE_MAIL
186
+				NO_SCRIPT /* t_reply_with_body */,
187
+				NO_SCRIPT /* t_is_local */,
188
+				NO_SCRIPT /* t_get_trans_ident */,
189
+				NO_SCRIPT /* t_lookup_ident */,
190
+#endif
185 191
 				0 /* t_newdlg */
186 192
 			},
187 193
 	(fixup_function[]){
... ...
@@ -204,6 +222,12 @@ struct module_exports exports= {
204 204
 #endif
205 205
 				0,                                              /* t_uac_dlg */
206 206
 				0,						/* load_tm */
207
+#ifdef VOICE_MAIL
208
+				0, /* t_reply_with_body */
209
+				0, /* t_is_local */
210
+				0, /* t_get_trans_ident */
211
+				0, /* t_lookup_ident */
212
+#endif
207 213
 				0						/* t_newdlg */
208 214
 	
209 215
 		},
... ...
@@ -211,10 +235,12 @@ struct module_exports exports= {
211 211
 	1+
212 212
 #endif
213 213
 #ifdef _OBSO
214
-	15,
215
-#else
216
-	14,
214
+	1+
217 215
 #endif
216
+#ifdef VOICE_MAIL
217
+	4+
218
+#endif
219
+	14,
218 220
 
219 221
 	/* ------------ exported variables ---------- */
220 222
 	(char *[]) { /* Module parameter names */
... ...
@@ -63,6 +63,24 @@ int load_tm( struct tm_binds *tmb)
63 63
 		LOG( L_ERR, LOAD_ERROR "'t_reply' not found\n");
64 64
 		return -1;
65 65
 	}
66
+#ifdef VOICE_MAIL
67
+	if (!(tmb->t_reply_with_body=(treply_wb_f)find_export(T_REPLY_WB, NO_SCRIPT)) ) {
68
+	        LOG( L_ERR, LOAD_ERROR "'t_reply' not found\n");
69
+		return -1;
70
+	}
71
+	if (!(tmb->t_is_local=(tget_ti_f)find_export(T_IS_LOCAL, NO_SCRIPT)) ) {
72
+	        LOG( L_ERR, LOAD_ERROR "'t_get_trans_ident' not found\n");
73
+		return -1;
74
+	}
75
+	if (!(tmb->t_get_trans_ident=(tget_ti_f)find_export(T_GET_TI, NO_SCRIPT)) ) {
76
+	        LOG( L_ERR, LOAD_ERROR "'t_get_trans_ident' not found\n");
77
+		return -1;
78
+	}
79
+	if (!(tmb->t_lookup_ident=(tlookup_ident_f)find_export(T_LOOKUP_IDENT, NO_SCRIPT)) ) {
80
+	        LOG( L_ERR, LOAD_ERROR "'t_lookup_ident' not found\n");
81
+		return -1;
82
+	}
83
+#endif
66 84
 #ifdef _OBSO
67 85
 	if (!(tmb->t_reply_unsafe=(treply_f)find_export(T_REPLY_UNSAFE, 2)) ) {
68 86
 		LOG( L_ERR, LOAD_ERROR "'t_reply_unsafe' not found\n");
... ...
@@ -37,6 +37,9 @@
37 37
 #include "uac.h"
38 38
 #include "t_fwd.h"
39 39
 #include "t_reply.h"
40
+#ifdef VOICE_MAIL
41
+#    include "t_lookup.h"
42
+#endif
40 43
 
41 44
 /* export not usable from scripts */
42 45
 #define NO_SCRIPT	-1
... ...
@@ -48,6 +51,9 @@
48 48
 #endif
49 49
 #define T_UAC_DLG "t_uac_dlg"
50 50
 #define T_REPLY "t_reply"
51
+#ifdef VOICE_MAIL
52
+#define T_REPLY_WB "t_reply_with_body"
53
+#endif
51 54
 #define T_REPLY_UNSAFE "t_reply_unsafe"
52 55
 #define T_FORWARD_NONACK "t_forward_nonack"
53 56
 
... ...
@@ -62,6 +68,12 @@ struct tm_binds {
62 62
 #endif
63 63
 	tuacdlg_f               t_uac_dlg;
64 64
 	treply_f		t_reply;
65
+#ifdef VOICE_MAIL
66
+        treply_wb_f             t_reply_with_body;
67
+        tislocal_f              t_is_local;
68
+        tget_ti_f               t_get_trans_ident;
69
+        tlookup_ident_f         t_lookup_ident;
70
+#endif
65 71
 	treply_f		t_reply_unsafe;
66 72
 	tfwd_f			t_forward_nonack;
67 73
 };
... ...
@@ -814,6 +814,20 @@ error:
814 814
 char * build_res_buf_from_sip_req( unsigned int code, char *text,
815 815
 					char *new_tag, unsigned int new_tag_len,
816 816
 					struct sip_msg* msg, unsigned int *returned_len)
817
+#ifdef VOICE_MAIL
818
+{
819
+    return build_res_buf_with_body_from_sip_req(code,text,new_tag,new_tag_len,
820
+						0,0, /* no body */
821
+						0,0, /* no content type */
822
+						msg,returned_len);
823
+}
824
+
825
+char * build_res_buf_with_body_from_sip_req( unsigned int code, char *text ,
826
+					     char *new_tag, unsigned int new_tag_len ,
827
+					     char *body, unsigned int body_len,
828
+					     char *content_type, unsigned int content_type_len,
829
+					     struct sip_msg* msg, unsigned int *returned_len)
830
+#endif
817 831
 {
818 832
 	char              *buf, *p;
819 833
 	unsigned int      len,foo;
... ...
@@ -830,6 +844,10 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
830 830
 	unsigned int      warning_len;
831 831
 	unsigned int	  text_len;
832 832
 	int r;
833
+#ifdef VOICE_MAIL
834
+	char content_len[27];
835
+	int content_len_len;
836
+#endif
833 837
 #ifndef PRESERVE_ZT
834 838
 	char *after_body;
835 839
 #endif
... ...
@@ -928,9 +946,17 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
928 928
 	if (server_signature) {
929 929
 		/*server header*/
930 930
 		len += SERVER_HDR_LEN + CRLF_LEN;
931
+#ifndef VOICE_MAIL
931 932
 		/*content length header*/
932 933
 		len +=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
934
+#endif
933 935
 	}
936
+#ifdef VOICE_MAIL
937
+	content_len_len=snprintf(content_len, sizeof(content_len), "Content-Length: %d", body_len);
938
+	len += content_len_len + CRLF_LEN;
939
+	if(content_type_len)
940
+	    len += content_type_len + CRLF_LEN;
941
+#endif
934 942
 	if (sip_warning) {
935 943
 		warning = warning_builder(msg,&warning_len);
936 944
 		if (warning) len += warning_len + CRLF_LEN;
... ...
@@ -938,6 +964,11 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
938 938
 	}
939 939
 	/* end of message */
940 940
 	len += CRLF_LEN; /*new line*/
941
+
942
+#ifdef VOICE_MAIL
943
+	if(body_len)
944
+	    len += body_len;
945
+#endif
941 946
 	/*allocating mem*/
942 947
 	buf = (char*) pkg_malloc( len+1 );
943 948
 	if (!buf)
... ...
@@ -1062,12 +1093,27 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
1062 1062
 		p+=SERVER_HDR_LEN;
1063 1063
 		memcpy( p, CRLF, CRLF_LEN );
1064 1064
 		p+=CRLF_LEN;
1065
+#ifndef VOICE_MAIL
1065 1066
 		/* content length header*/
1066 1067
 		memcpy( p, CONTENT_LENGTH "0" , CONTENT_LENGTH_LEN+1 );
1067 1068
 		p+=CONTENT_LENGTH_LEN+1;
1068 1069
 		memcpy( p, CRLF, CRLF_LEN );
1069 1070
 		p+=CRLF_LEN;
1071
+#endif
1072
+	}
1073
+
1074
+#ifdef VOICE_MAIL
1075
+	memcpy( p, content_len, content_len_len );
1076
+	p+=content_len_len;
1077
+	memcpy( p, CRLF, CRLF_LEN );
1078
+	p+=CRLF_LEN;
1079
+	if(content_type_len){
1080
+	    memcpy( p, content_type, content_type_len );
1081
+	    p+=content_type_len;
1082
+	    memcpy( p, CRLF, CRLF_LEN );
1083
+	    p+=CRLF_LEN;
1070 1084
 	}
1085
+#endif
1071 1086
 	if (sip_warning && warning) {
1072 1087
 		memcpy( p, warning, warning_len);
1073 1088
 		p+=warning_len;
... ...
@@ -1077,6 +1123,12 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
1077 1077
 	/*end of message*/
1078 1078
 	memcpy( p, CRLF, CRLF_LEN );
1079 1079
 	p+=CRLF_LEN;
1080
+#ifdef VOICE_MAIL
1081
+	if(body_len){
1082
+	    memcpy ( p, body, body_len );
1083
+	    p+=body_len;
1084
+	}
1085
+#endif
1080 1086
 	*(p) = 0;
1081 1087
 	*returned_len = len;
1082 1088
 	/* in req2reply, received_buf is not introduced to lumps and
... ...
@@ -54,6 +54,18 @@ char * build_res_buf_from_sip_req(	unsigned int code ,
54 54
 				unsigned int new_tag_len ,
55 55
 				struct sip_msg* msg,
56 56
 				unsigned int *returned_len);
57
+#ifdef VOICE_MAIL
58
+char * build_res_buf_with_body_from_sip_req(	unsigned int code ,
59
+				char *text ,
60
+				char *new_tag ,
61
+				unsigned int new_tag_len ,
62
+				char *body ,
63
+				unsigned int body_len,
64
+				char *content_type,
65
+				unsigned int content_type_len,
66
+				struct sip_msg* msg,
67
+				unsigned int *returned_len);
68
+#endif
57 69
 
58 70
 char* via_builder( unsigned int *len,
59 71
 	struct socket_info* send_sock,