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 153
 	 -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
150 154
 	 -DDNS_IP_HACK \
151 155
 	 -DUSE_IPV6 \
152
-	 -DDBG_QM_MALLOC \
156
+	 -DVOICE_MAIL \
157
+	 -D_TOTAG \
153 158
 	 -DUSE_TCP \
154 159
 	 #-DF_MALLOC \
155 160
 	 #-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 524
 static int _reply( struct cell *trans, struct sip_msg* p_msg, 
513 525
 	unsigned int code, char * text, int lock )
514 526
 {
527
+#ifndef VOICE_MAIL
515 528
 	unsigned int len, buf_len=0;
516 529
 	char * buf;
517 530
 	struct retr_buf *rb;
518 531
 
519 532
 	branch_bm_t cancel_bitmap;
533
+#else
534
+	unsigned int len;
535
+	char * buf;
536
+#endif
520 537
 
521 538
 	if (code>=200) trans->kr|=REQ_RPLD;
522 539
 	/*
523 540
 	buf = build_res_buf_from_sip_req(code,text,trans->uas.tag->s,
524 541
 		trans->uas.tag->len, trans->uas.request,&len);
525 542
 	*/
543
+#ifndef VOICE_MAIL
526 544
 	cancel_bitmap=0;
545
+#endif
527 546
 	/* compute the buffer in private memory prior to entering lock;
528 547
 	 * create to-tag if needed */
529 548
 	if (code>=180 && p_msg->to 
... ...
@@ -533,11 +552,34 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
533 552
 		buf = build_res_buf_from_sip_req(code,text, 
534 553
 				tm_tags, TOTAG_LEN, 
535 554
 				p_msg,&len);
555
+#ifdef VOICE_MAIL
556
+
557
+		return _reply_light(trans,buf,len,code,text,
558
+				    tm_tags, TOTAG_LEN,
559
+				    lock);
560
+#endif
536 561
 	} else {
537 562
 		buf = build_res_buf_from_sip_req(code,text, 0,0, /* no to-tag */
538 563
 			p_msg,&len);
564
+#ifdef VOICE_MAIL
565
+
566
+		return _reply_light(trans,buf,len,code,text,
567
+				    0,0, /* no to-tag */
568
+				    lock);
569
+#endif
539 570
 	}
540 571
 	DBG("DEBUG: t_reply: buffer computed\n");
572
+#ifdef VOICE_MAIL
573
+}
574
+
575
+static int _reply_light( struct cell *trans, char* buf, unsigned int len,
576
+			 unsigned int code, char * text, 
577
+			 char *to_tag, unsigned int to_tag_len, int lock )
578
+{
579
+	struct retr_buf *rb;
580
+	unsigned int buf_len=0;
581
+	branch_bm_t cancel_bitmap=0;
582
+#endif
541 583
 	if (!buf)
542 584
 	{
543 585
 		DBG("DEBUG: t_reply: response building failed\n");
... ...
@@ -571,6 +613,19 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
571 613
 	}
572 614
 	rb->buffer_len = len ;
573 615
 	memcpy( rb->buffer , buf , len );
616
+#ifdef VOICE_MAIL
617
+	if(to_tag){
618
+	    trans->uas.to_tag.s = (char*)shm_resize( trans->uas.to_tag.s, to_tag_len );
619
+	    if(! trans->uas.to_tag.s ){
620
+			LOG(L_ERR, "ERROR: t_reply: cannot allocate shmem buffer\n");
621
+			// Is it ok? or should i free rb->buffer also, 
622
+			// or will it be freed in free_cell() ?
623
+			goto error2; 
624
+	    }
625
+	    trans->uas.to_tag.len = to_tag_len;
626
+	    memcpy( trans->uas.to_tag.s, to_tag, to_tag_len );
627
+	}
628
+#endif
574 629
 	/* needs to be protected too because what timers are set depends
575 630
 	   on current transactions status */
576 631
 	/* t_update_timers_after_sending_reply( rb ); */
... ...
@@ -1027,3 +1082,55 @@ done:
1027 1082
 	return 0;
1028 1083
 }
1029 1084
 
1085
+#ifdef VOICE_MAIL
1086
+
1087
+#include <assert.h>
1088
+
1089
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, char * text, char * body, char * new_header, char * to_tag )
1090
+{
1091
+    struct cell * t;
1092
+    //char to_tag[64];
1093
+    str  s_to_tag,sb,snh;
1094
+    char* res_buf;
1095
+    int res_len,ret;
1096
+
1097
+    /*  check if we have a transaction */
1098
+    if (t_check(p_msg, 0)==-1) {
1099
+	LOG(L_ERR,"ERROR: t_reply_with_body: no transaction found.\n");
1100
+	return -1;
1101
+    }
1102
+
1103
+    t=get_t();
1104
+    assert(t);
1105
+
1106
+    s_to_tag.s = to_tag;
1107
+    if(to_tag)
1108
+	s_to_tag.len = strlen(to_tag);
1109
+
1110
+    // mark the transaction as replied
1111
+    t->kr|=REQ_RPLD;
1112
+
1113
+    /* compute the response */
1114
+    sb.s = body;
1115
+    sb.len = strlen(body);
1116
+    snh.s = new_header;
1117
+    snh.len = strlen(new_header);
1118
+
1119
+    res_buf = build_res_buf_with_body_from_sip_req(code,text, s_to_tag.s, s_to_tag.len,
1120
+						   sb.s,sb.len,
1121
+						   snh.s,snh.len,
1122
+						   p_msg,&res_len);
1123
+    
1124
+    DBG("t_reply_with_body: buffer computed\n");
1125
+    // frees 'res_buf' ... no panic !
1126
+    ret = t_reply_light(t, res_buf, res_len, code, text,
1127
+			s_to_tag.s, s_to_tag.len);
1128
+
1129
+    // TODO: i'm not sure i should do this here ...
1130
+    if(t_unref(p_msg) == -1)
1131
+	LOG(L_WARN,"WARNING: fifo_t_reply: could not unref transaction %p\n",t);
1132
+
1133
+    return ret;
1134
+}
1135
+
1136
+#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 )
... ...
@@ -79,6 +84,21 @@ int t_on_reply( struct sip_msg  *p_msg ) ;
79 84
 int t_retransmit_reply( /* struct sip_msg * */  );
80 85
 
81 86
 
87
+/* send a UAS reply
88
+ * Warning: 'buf' and 'len' should already have been build.
89
+ * returns 1 if everything was OK or -1 for erro
90
+ */
91
+#ifdef VOICE_MAIL
92
+
93
+int t_reply_light( struct cell *trans, char* buf, unsigned int len,
94
+		   unsigned int code, char * text,
95
+		   char *to_tag, unsigned int to_tag_len);
96
+
97
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, 
98
+		       char * text, char * body, char * new_header, char * to_tag );
99
+
100
+#endif
101
+
82 102
 /* send a UAS reply
83 103
  * returns 1 if everything was OK or -1 for erro
84 104
  */
... ...
@@ -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 166
 #endif
161 167
 					(cmd_function) t_uac_dlg,
162 168
 					(cmd_function) load_tm,
169
+#ifdef VOICE_MAIL
170
+					(cmd_function) t_reply_with_body,
171
+					(cmd_function) t_is_local,
172
+					(cmd_function) t_get_trans_ident,
173
+					(cmd_function) t_lookup_ident,
174
+#endif
163 175
 					w_t_newdlg,
164 176
 					},
165 177
 	(int[]){
... ...
@@ -182,6 +194,12 @@ struct module_exports exports= {
182 194
 #endif
183 195
 				NO_SCRIPT /* t_uac_dlg */,
184 196
 				NO_SCRIPT /* load_tm */,
197
+#ifdef VOICE_MAIL
198
+				NO_SCRIPT /* t_reply_with_body */,
199
+				NO_SCRIPT /* t_is_local */,
200
+				NO_SCRIPT /* t_get_trans_ident */,
201
+				NO_SCRIPT /* t_lookup_ident */,
202
+#endif
185 203
 				0 /* t_newdlg */
186 204
 			},
187 205
 	(fixup_function[]){
... ...
@@ -204,6 +222,12 @@ struct module_exports exports= {
204 222
 #endif
205 223
 				0,                                              /* t_uac_dlg */
206 224
 				0,						/* load_tm */
225
+#ifdef VOICE_MAIL
226
+				0, /* t_reply_with_body */
227
+				0, /* t_is_local */
228
+				0, /* t_get_trans_ident */
229
+				0, /* t_lookup_ident */
230
+#endif
207 231
 				0						/* t_newdlg */
208 232
 	
209 233
 		},
... ...
@@ -211,10 +235,12 @@ struct module_exports exports= {
211 235
 	1+
212 236
 #endif
213 237
 #ifdef _OBSO
214
-	15,
215
-#else
216
-	14,
238
+	1+
217 239
 #endif
240
+#ifdef VOICE_MAIL
241
+	4+
242
+#endif
243
+	14,
218 244
 
219 245
 	/* ------------ exported variables ---------- */
220 246
 	(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 51
 #endif
49 52
 #define T_UAC_DLG "t_uac_dlg"
50 53
 #define T_REPLY "t_reply"
54
+#ifdef VOICE_MAIL
55
+#define T_REPLY_WB "t_reply_with_body"
56
+#endif
51 57
 #define T_REPLY_UNSAFE "t_reply_unsafe"
52 58
 #define T_FORWARD_NONACK "t_forward_nonack"
53 59
 
... ...
@@ -62,6 +68,12 @@ struct tm_binds {
62 68
 #endif
63 69
 	tuacdlg_f               t_uac_dlg;
64 70
 	treply_f		t_reply;
71
+#ifdef VOICE_MAIL
72
+        treply_wb_f             t_reply_with_body;
73
+        tislocal_f              t_is_local;
74
+        tget_ti_f               t_get_trans_ident;
75
+        tlookup_ident_f         t_lookup_ident;
76
+#endif
65 77
 	treply_f		t_reply_unsafe;
66 78
 	tfwd_f			t_forward_nonack;
67 79
 };
... ...
@@ -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 844
 	unsigned int      warning_len;
831 845
 	unsigned int	  text_len;
832 846
 	int r;
847
+#ifdef VOICE_MAIL
848
+	char content_len[27];
849
+	int content_len_len;
850
+#endif
833 851
 #ifndef PRESERVE_ZT
834 852
 	char *after_body;
835 853
 #endif
... ...
@@ -928,9 +946,17 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
928 946
 	if (server_signature) {
929 947
 		/*server header*/
930 948
 		len += SERVER_HDR_LEN + CRLF_LEN;
949
+#ifndef VOICE_MAIL
931 950
 		/*content length header*/
932 951
 		len +=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
952
+#endif
933 953
 	}
954
+#ifdef VOICE_MAIL
955
+	content_len_len=snprintf(content_len, sizeof(content_len), "Content-Length: %d", body_len);
956
+	len += content_len_len + CRLF_LEN;
957
+	if(content_type_len)
958
+	    len += content_type_len + CRLF_LEN;
959
+#endif
934 960
 	if (sip_warning) {
935 961
 		warning = warning_builder(msg,&warning_len);
936 962
 		if (warning) len += warning_len + CRLF_LEN;
... ...
@@ -938,6 +964,11 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
938 964
 	}
939 965
 	/* end of message */
940 966
 	len += CRLF_LEN; /*new line*/
967
+
968
+#ifdef VOICE_MAIL
969
+	if(body_len)
970
+	    len += body_len;
971
+#endif
941 972
 	/*allocating mem*/
942 973
 	buf = (char*) pkg_malloc( len+1 );
943 974
 	if (!buf)
... ...
@@ -1062,12 +1093,27 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
1062 1093
 		p+=SERVER_HDR_LEN;
1063 1094
 		memcpy( p, CRLF, CRLF_LEN );
1064 1095
 		p+=CRLF_LEN;
1096
+#ifndef VOICE_MAIL
1065 1097
 		/* content length header*/
1066 1098
 		memcpy( p, CONTENT_LENGTH "0" , CONTENT_LENGTH_LEN+1 );
1067 1099
 		p+=CONTENT_LENGTH_LEN+1;
1068 1100
 		memcpy( p, CRLF, CRLF_LEN );
1069 1101
 		p+=CRLF_LEN;
1102
+#endif
1103
+	}
1104
+
1105
+#ifdef VOICE_MAIL
1106
+	memcpy( p, content_len, content_len_len );
1107
+	p+=content_len_len;
1108
+	memcpy( p, CRLF, CRLF_LEN );
1109
+	p+=CRLF_LEN;
1110
+	if(content_type_len){
1111
+	    memcpy( p, content_type, content_type_len );
1112
+	    p+=content_type_len;
1113
+	    memcpy( p, CRLF, CRLF_LEN );
1114
+	    p+=CRLF_LEN;
1070 1115
 	}
1116
+#endif
1071 1117
 	if (sip_warning && warning) {
1072 1118
 		memcpy( p, warning, warning_len);
1073 1119
 		p+=warning_len;
... ...
@@ -1077,6 +1123,12 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
1077 1123
 	/*end of message*/
1078 1124
 	memcpy( p, CRLF, CRLF_LEN );
1079 1125
 	p+=CRLF_LEN;
1126
+#ifdef VOICE_MAIL
1127
+	if(body_len){
1128
+	    memcpy ( p, body, body_len );
1129
+	    p+=body_len;
1130
+	}
1131
+#endif
1080 1132
 	*(p) = 0;
1081 1133
 	*returned_len = len;
1082 1134
 	/* 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,