浏览代码

preliminary support for FIFO/t_uac added -- compiles, but not completed yet

Jiri Kuthan 22 年之前
父节点
当前提交
ff9799524a

+ 2 - 0
error.h

@@ -47,6 +47,8 @@
 /* too many branches demanded */
 #define E_TOO_MANY_BRANCHES -12
 #define E_BAD_TO	-13
+/* invalid params */
+#define E_INVALID_PARAMS -14
 
 #define E_SEND		  -477
 /* unresolveable next-hop address */

+ 2 - 1
fifo_server.c

@@ -217,7 +217,7 @@ int read_line_set(char *buf, int max_len, FILE *fifo, int *len)
 			return 0;
 		}
 		/* end encountered ... return */
-		if (line_len==0) {
+		if (line_len==0 || (line_len==1 && c[0]=='.' )) {
 			*len=set_len;
 			return 1;
 		}
@@ -231,6 +231,7 @@ int read_line_set(char *buf, int max_len, FILE *fifo, int *len)
 	}
 }
 
+
 /* read from input until line with only dot in it is encountered */
 int read_body(char *buf, int max_len, FILE *fifo, int *len)
 {

+ 10 - 0
modules/tm/README

@@ -322,3 +322,13 @@ Known Issues
   for keeing SUB-NOT dialog state, etc. Currently, there are only
   place-holders for in in TM.
 - places labeled with "HACK" strongly deserve beautification
+
+
+ * ***************************************************
+ *             IMPORTANT NOTE
+ *
+ *    All UACs but t_uac_dlg are being deprecated now
+ *    and will be removed from future versions of TM
+ *    module. Eliminate all dependancies on them asap.
+ *
+ * ****************************************************

+ 2 - 0
modules/tm/config.h

@@ -30,6 +30,8 @@
 #ifndef _TM_CONFIG_H
 #define _TM_CONFIG_H
 
+#include "defs.h"
+
 #ifdef _OBSOLETED
 /* moved to hash.h */
 /* always use a power of 2 for hash table size */

+ 35 - 0
modules/tm/defs.h

@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _TM_DEFS_H
+#define _TM_DEFS_H
+
+#undef DEPRECATE_OLD_STUFF
+
+#endif

+ 3 - 0
modules/tm/fix_lumps.h

@@ -35,6 +35,9 @@
 #ifndef _FIX_LUMPS_H
 #define _FIX_LUMPS_H
 
+#include "defs.h"
+
+
 /* used to delete attached via lumps from msg; msg can
    be either an original pkg msg, whose Via lump I want
    to delete before generating next branch, or a shmem-stored

+ 3 - 0
modules/tm/h_table.c

@@ -25,6 +25,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
+
 #include <stdlib.h>
 #include "../../mem/shm_mem.h"
 #include "../../hash_func.h"

+ 1 - 0
modules/tm/h_table.h

@@ -25,6 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
 
 
 #ifndef _H_TABLE_H

+ 2 - 0
modules/tm/lock.c

@@ -26,6 +26,8 @@
  */
 
 
+#include "defs.h"
+
 
 #include <errno.h>
 

+ 1 - 0
modules/tm/lock.h

@@ -25,6 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
 
 
 #ifndef __lock_h

+ 2 - 0
modules/tm/sip_msg.c

@@ -36,6 +36,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
 
 #include <stdio.h>
 #include "sip_msg.h"

+ 3 - 0
modules/tm/sip_msg.h

@@ -30,6 +30,9 @@
 #ifndef _SIP_MSG_H
 #define _SIP_MSG_H
 
+#include "defs.h"
+
+
 #include "../../parser/msg_parser.h"
 #include "../../mem/shm_mem.h"
 

+ 2 - 0
modules/tm/t_cancel.c

@@ -27,6 +27,8 @@
  */
 
 
+#include "defs.h"
+
 
 #include "t_funcs.h"
 #include "../../dprint.h"

+ 3 - 0
modules/tm/t_cancel.h

@@ -30,6 +30,9 @@
 #ifndef _CANCEL_H
 #define _CANCEL_H
 
+#include "defs.h"
+
+
 /* a buffer is empty but cannot be used by anyone else;
    particularly, we use this value in the buffer pointer
    in local_buffer to tell "a process is already scheduled

+ 2 - 0
modules/tm/t_dlg.c

@@ -27,6 +27,8 @@
  */
 
 
+#include "defs.h"
+
 #include "t_dlg.h"
 
 dlg_t dlg=0;

+ 3 - 0
modules/tm/t_dlg.h

@@ -30,6 +30,9 @@
 #ifndef _T_DLG_H
 #define _T_DLG_H
 
+#include "defs.h"
+
+
 #include "../../parser/msg_parser.h"
 
 struct dialog {

+ 3 - 0
modules/tm/t_funcs.c

@@ -28,6 +28,9 @@
  */
 
 
+#include "defs.h"
+
+
 #include <limits.h>
 #include "../../dprint.h"
 #include "../../config.h"

+ 3 - 0
modules/tm/t_funcs.h

@@ -30,6 +30,9 @@
 #ifndef _T_FUNCS_H
 #define _T_FUNCS_H
 
+#include "defs.h"
+
+
 #include <errno.h>
 #include <netdb.h>
 

+ 2 - 0
modules/tm/t_fwd.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
 
 #include "../../dprint.h"
 #include "../../config.h"

+ 2 - 0
modules/tm/t_fwd.h

@@ -30,6 +30,8 @@
 #ifndef _T_FWD_H
 #define _T_FWD_H
 
+#include "defs.h"
+
 #include "../../proxy.h"
 
 typedef int (*tfwd_f)(struct sip_msg* p_msg , struct proxy_l * proxy );

+ 2 - 0
modules/tm/t_hooks.c

@@ -25,6 +25,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
 
 #include "stdlib.h"
 #include "../../dprint.h"

+ 3 - 0
modules/tm/t_hooks.h

@@ -29,6 +29,9 @@
 #ifndef _HOOKS_H
 #define _HOOKS_H
 
+#include "defs.h"
+
+
 struct sip_msg;
 struct cell;
 

+ 3 - 0
modules/tm/t_lookup.c

@@ -51,6 +51,9 @@
  */
 
 
+#include "defs.h"
+
+
 #include <assert.h>
 #include "../../dprint.h"
 #include "../../config.h"

+ 3 - 0
modules/tm/t_lookup.h

@@ -30,6 +30,9 @@
 #ifndef _T_LOOKUP_H
 #define _T_LOOKUP_H
 
+#include "defs.h"
+
+
 #include "config.h"
 #include "t_funcs.h"
 

+ 4 - 1
modules/tm/t_msgbuilder.c

@@ -27,6 +27,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
 
 #include "../../hash_func.h"
 #include "../../globals.h"
@@ -166,7 +168,7 @@ error:
 }
 
 
-
+#ifndef DEPRECATE_OLD_STUFF
 char *build_uac_request(  str msg_type, str dst, str from,
 	str fromtag, int cseq, str callid, str headers, 
 	str body, int branch, 
@@ -315,6 +317,7 @@ error:
 	return buf;
 	
 }
+#endif
 
 
 char *build_uac_request_dlg(str* msg,           /* Method */

+ 3 - 0
modules/tm/t_msgbuilder.h

@@ -30,6 +30,9 @@
 #ifndef _MSGBUILDER_H
 #define _MSGBUILDER_H
 
+#include "defs.h"
+
+
 #define CSEQ "CSeq: "
 #define CSEQ_LEN (sizeof(CSEQ)-1)
 #define TO "To: "

+ 1 - 0
modules/tm/t_reply.c

@@ -30,6 +30,7 @@
  * 2003-01-19 faked lump list created in on_reply handlers
  */
 
+#include "defs.h"
 
 
 #include "../../hash_func.h"

+ 3 - 0
modules/tm/t_reply.h

@@ -30,6 +30,9 @@
 #ifndef _T_REPLY_H
 #define _T_REPLY_H
 
+#include "defs.h"
+
+
 #include "h_table.h"
 
 /* reply processing status */

+ 2 - 0
modules/tm/t_stats.c

@@ -28,6 +28,8 @@
  */
 
 
+#include "defs.h"
+
 
 #include <stdio.h>
 #include "t_stats.h"

+ 3 - 0
modules/tm/t_stats.h

@@ -31,6 +31,9 @@
 #ifndef _T_STATS_H
 #define _T_STATS_H
 
+#include "defs.h"
+
+
 #include "../../pt.h"
 
 

+ 1 - 0
modules/tm/test.c

@@ -26,6 +26,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
 
 
 #include "../../hash_func.h"

+ 3 - 0
modules/tm/timer.c

@@ -93,6 +93,9 @@
 
 */
 
+#include "defs.h"
+
+
 
 #include "config.h"
 #include "h_table.h"

+ 2 - 0
modules/tm/timer.h

@@ -29,6 +29,8 @@
 #ifndef _TIMER_H
 #define _TIMER_H
 
+#include "defs.h"
+
 #include "lock.h"
 #include "t_funcs.h"
 

+ 38 - 9
modules/tm/tm.c

@@ -53,6 +53,9 @@
  */
 
 
+#include "defs.h"
+
+
 #include <stdio.h>
 #include <string.h>
 #include <netdb.h>
@@ -129,7 +132,9 @@ struct module_exports exports= {
 				/* not applicable from script ... */
 
 				"register_tmcb",
+#ifndef DEPRECATE_OLD_STUFF
 				T_UAC,
+#endif
 				T_UAC_DLG,
 				"load_tm",
 				"t_newdlg"
@@ -150,7 +155,9 @@ struct module_exports exports= {
 					w_t_on_negative,
 
 					(cmd_function) register_tmcb,
+#ifndef DEPRECATE_OLD_STUFF
 					(cmd_function) t_uac,
+#endif
 					(cmd_function) t_uac_dlg,
 					(cmd_function) load_tm,
 					w_t_newdlg,
@@ -170,7 +177,9 @@ struct module_exports exports= {
 				2, /* t_forward_nonack */
 				1, /* t_on_negative */
 				NO_SCRIPT /* register_tmcb */,
+#ifndef DEPRECATE_OLD_STUFF
 				NO_SCRIPT /* t_uac */,
+#endif
 				NO_SCRIPT /* t_uac_dlg */,
 				NO_SCRIPT /* load_tm */,
 				0 /* t_newdlg */
@@ -190,16 +199,21 @@ struct module_exports exports= {
 				fixup_hostport2proxy,	/* t_forward_nonack */
 				fixup_str2int,			/* t_on_negative */
 				0,						/* register_tmcb */
+#ifndef DEPRECATE_OLD_STUFF
 				0,						/* t_uac */
+#endif
 				0,                                              /* t_uac_dlg */
 				0,						/* load_tm */
 				0						/* t_newdlg */
 	
 		},
+#ifndef DEPRECATE_OLD_STUFF
+	1+
+#endif
 #ifdef _OBSO
-	16,
-#else
 	15,
+#else
+	14,
 #endif
 
 	/* ------------ exported variables ---------- */
@@ -212,8 +226,10 @@ struct module_exports exports= {
 		"retr_timer1p2",
 		"retr_timer1p3",
 		"retr_timer2",
-		"noisy_ctimer",
-		"uac_from"
+		"noisy_ctimer"
+#ifndef DEPRECATE_OLD_STUFF
+		,"uac_from"
+#endif
 	},
 	(modparam_t[]) { /* variable types */
 		INT_PARAM, /* fr_timer */
@@ -224,8 +240,10 @@ struct module_exports exports= {
 		INT_PARAM, /* retr_timer1p2 */
 		INT_PARAM, /* retr_timer1p3 */
 		INT_PARAM, /* retr_timer2 */
-		INT_PARAM, /* noisy_ctimer */
-		STR_PARAM, /* uac_from */
+		INT_PARAM /* noisy_ctimer */
+#ifndef DEPRECATE_OLD_STUFF
+		,STR_PARAM /* uac_from */
+#endif
 	},
 	(void *[]) { /* variable pointers */
 		&(timer_id2timeout[FR_TIMER_LIST]),
@@ -236,10 +254,15 @@ struct module_exports exports= {
 		&(timer_id2timeout[RT_T1_TO_2]),
 		&(timer_id2timeout[RT_T1_TO_3]),
 		&(timer_id2timeout[RT_T2]),
-		&noisy_ctimer,
-		&uac_from
+		&noisy_ctimer
+#ifndef DEPRECATE_OLD_STUFF
+		,&uac_from
+#endif
 	},
-	11,      /* Number of module paramers */
+#ifndef DEPRECATE_OLD_STUFF
+	1+
+#endif
+	10,      /* Number of module paramers */
 
 	mod_init, /* module initialization function */
 	(response_function) t_on_reply,
@@ -301,6 +324,7 @@ static int mod_init(void)
 	}
 
 
+#ifndef DEPRECATE_OLD_STUFF
 	if (register_fifo_cmd(fifo_uac, "t_uac", 0)<0) {
 		LOG(L_CRIT, "cannot register fifo uac\n");
 		return -1;
@@ -309,6 +333,11 @@ static int mod_init(void)
 		LOG(L_CRIT, "cannot register fifo uac\n");
 		return -1;
 	}
+#endif
+	if (register_fifo_cmd(fifo_uac_dlg, "t_uac_dlg", 0)<0) {
+		LOG(L_CRIT, "cannot register fifo uac\n");
+		return -1;
+	}
 	if (register_fifo_cmd(fifo_hash, "t_hash", 0)<0) {
 		LOG(L_CRIT, "cannot register hash\n");
 		return -1;

+ 4 - 0
modules/tm/tm_load.c

@@ -25,6 +25,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "defs.h"
+
 
 #include "tm_load.h"
 #include "uac.h"
@@ -47,10 +49,12 @@ int load_tm( struct tm_binds *tmb)
 		LOG(L_ERR, LOAD_ERROR "'t_relay' not found\n");
 		return -1;
 	}
+#ifndef DEPRECATE_OLD_STUFF
 	if (!(tmb->t_uac=(tuac_f)find_export(T_UAC, NO_SCRIPT)) ) {
 		LOG( L_ERR, LOAD_ERROR "'t_uac' not found\n");
 		return -1;
 	}
+#endif
 	if (!(tmb->t_uac_dlg=(tuacdlg_f)find_export(T_UAC_DLG, NO_SCRIPT)) ) {
 		LOG( L_ERR, LOAD_ERROR "'t_uac_dlg' not found\n");
 		return -1;

+ 8 - 1
modules/tm/tm_load.h

@@ -29,6 +29,9 @@
 #ifndef _TM_BIND_H
 #define _TM_BIND_H
 
+#include "defs.h"
+
+
 #include "../../sr_module.h"
 #include "t_hooks.h"
 #include "uac.h"
@@ -40,7 +43,9 @@
 
 #define T_RELAY_TO "t_relay_to"
 #define T_RELAY "t_relay"
-#define T_UAC "t_uac"
+#ifndef DEPRECATE_OLD_STUFF
+#	define T_UAC "t_uac"
+#endif
 #define T_UAC_DLG "t_uac_dlg"
 #define T_REPLY "t_reply"
 #define T_REPLY_UNSAFE "t_reply_unsafe"
@@ -52,7 +57,9 @@ struct tm_binds {
 	register_tmcb_f	register_tmcb;
 	cmd_function	t_relay_to;
 	cmd_function 	t_relay;
+#ifndef DEPRECATE_OLD_STUFF
 	tuac_f			t_uac;
+#endif
 	tuacdlg_f               t_uac_dlg;
 	treply_f		t_reply;
 	treply_f		t_reply_unsafe;

+ 308 - 7
modules/tm/uac.c

@@ -29,9 +29,24 @@
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ***************************************************
+ *             IMPORTANT NOTE
+ *
+ *    All UACs but t_uac_dlg are being deprecated now
+ *    and will be removed from future versions of TM
+ *    module. Eliminate all dependancies on them asap.
+ *    For backwards compatibility (NOT RECOMMENDED)
+ *    turn off DEPRECATE_OLD_STUFF in defs.h. Similarly,
+ *    there is a new FIFO UAC.
+ *
+ * ****************************************************
  */
 
 
+#include "defs.h"
+
+
 #include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -82,9 +97,10 @@ static int callid_suffix_len;
 static int rand_len;	/* number of chars to display max rand */
 static char callid[CALLID_NR_LEN+CALLID_SUFFIX_LEN];
 
+#ifndef DEPRECATE_OLD_STUFF
 char *uac_from="\"UAC Account\" <sip:[email protected]:9>";
-
 str uac_from_str;
+#endif
 
 static char from_tag[ FROM_TAG_LEN+1 ];
 
@@ -147,8 +163,10 @@ int uac_init() {
 	MDStringArray( from_tag, src, 3 );
 	from_tag[MD5_LEN]=CID_SEP;
 
+#ifndef DEPRECATE_OLD_STUFF
 	uac_from_str.s = uac_from;
 	uac_from_str.len = strlen(uac_from);
+#endif
 
 	return 1;
 }
@@ -168,6 +186,7 @@ int uac_child_init( int rank )
 	return 1;
 }
 
+#ifndef DEPRECATE_OLD_STUFF
 int t_uac( str *msg_type, str *dst, 
 	str *headers, str *body, str *from, 
 	transaction_cb completion_cb, void *cbp, 
@@ -302,10 +321,59 @@ done:
 	if (cbp) shm_free(cbp);
 	return ser_error=ret;
 }
+#endif
 
 
 /*
  * Send a request within a dialog
+ * 
+ * Some parameters are required, some are optional (i.e., ephemeral
+ * or default values are created if 0 is passed as parameter). The
+ * optional parameters are typically used to set some header fields
+ * to dialog-related values (as opposed to having them set to
+ * ephemeral values).
+ *
+ * Required:
+ * - msg ..   specifies type of message, such as "OPTIONS"
+ * - ruri ..  specifies request URI; 
+ * - from ..  value of From header field (if it already includes from tag, 
+ *            the fromtag parameter MUST point to en empty string)
+ * - to ...   value of To header field (if it already includes to tag,
+ *            the totag parameter MUST point to an empty string)
+ * - totag .. to tag
+ * 
+ * Optional:
+ * - dst     transport destination (expressed as URI) -- if present,
+ *           request is physically forwarded to address indicated in it,
+ *           overriding the transport address in ruri; useful for use with 
+ *           outbound proxies or loose routers (that is where the first 
+ *           element of route set comes in)
+ * - fromtag from HF tag -- dialog-less applications do not to set it (==0),
+ *           in which case an ephemeral value is created; if fromtag present,
+ *           its appended to the From header field; it may be also present 
+ *           and point to an empty string -- that only makes sense if
+ *           application includes the tag in From and does not care to
+ *           separate the tag from the rest of header field
+ * - cid ..  callid; if 0, ephemeral value is created; transactions
+ *           within a dialog need to set this value to dialog's callid
+ * - cseq .. CSeq; if 0, default value (DEFAULT_CSEQ) is used; transactions
+ *           within a dialog need to set this value to current local cseq,
+ *           which grows continously with transactions sent
+ * - headers .. block of header fields that will be included in the
+ *           message. It MAY NOT include header fields already described
+ *           in other parameters (From, to, cid, cseq) or created 
+ *           automatically   (Content_length)   otherwise the parameter
+ *           would appear multiple times. It MUST include all additional
+ *           header fields required for a given SIP message, like Content-Type 
+ *           for any messages including a body or Contact for INVITEs.
+ * - body .. if present, body and Content-Length is appended to the 
+ *           SIP message; Content-Type then needs to be present inside
+ *           'headers' parameter
+ * - cb ..   callback to be called when transaction completes; if none
+ *           present, no callback will be called
+ * - cbp ..  callback parameter -- value passed to callback function
+ *           when called
+ *
  */
 int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OPTIONS etc. */
 	      str* dst,                     /* Real destination (can be different than R-URI) */
@@ -336,7 +404,18 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	/* make -Wall shut up */
 	ret=0;
 
-	proxy = uri2proxy((dst) ? (dst) : ((ruri) ? (ruri) : (to)));
+	/* check for invalid parameter */
+	if (!msg || !msg->s
+				|| !ruri || !ruri->s
+				|| !from || !from->s
+				|| !to || !to->s
+				|| !totag || !totag->s ) {
+		LOG(L_ERR, "ERROR: t_uac_dlg: invalud parameters\n");
+		ser_error = ret = E_INVALID_PARAMS;
+		goto done;
+	}
+
+	proxy = uri2proxy((dst) ? (dst) : ruri);
 	if (proxy == 0) {
 		ser_error = ret = E_BAD_ADDRESS;
 		LOG(L_ERR, "ERROR: t_uac_dlg: Can't create a dst proxy\n");
@@ -401,9 +480,9 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	}
 
 	buf = build_uac_request_dlg(msg, 
-				    (ruri) ? (ruri) : (to),
+				    ruri,
 				    to, 
-				    (from) ? (from) : (&uac_from_str), 
+				    from,
 				    totag,
 				    (fromtag) ? (fromtag) : (&ftag), 
 				    (cseq) ? (*cseq) : DEFAULT_CSEQ, 
@@ -431,10 +510,8 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	if (SEND_BUFFER(request) == -1) {
 		if (dst) {
 			tmp = *dst;
-		} else if (ruri) {
-			tmp = *ruri;
 		} else {
-			tmp = *to;
+			tmp = *ruri;
 		}
 		LOG(L_ERR, "ERROR: t_uac: UAC sending to \'%.*s\' failed\n", tmp.len, tmp.s);
 		proxy->errors++;
@@ -566,6 +643,8 @@ int fifo_uac( FILE *stream, char *response_file )
 	return 1;
 }
 
+#ifndef DEPRECATE_OLD_STUFF
+
 /* syntax:
 
 	:t_uac_from:[file] EOL
@@ -671,3 +750,225 @@ int fifo_uac_from( FILE *stream, char *response_file )
 	return 1;
 
 }
+
+#endif
+
+
+static void fifo_uac_error(char *reply_fifo, int code, char *msg)
+{
+	LOG(L_ERR, "ERROR: fifo_uac: %s\n", msg ); 
+	fifo_reply(reply_fifo, "%d fifo_uac: %s", code, msg);
+}
+
+/* syntax:
+
+	:t_uac_dlg:[file] EOL
+	method EOL
+	r-uri EOL 
+	dst EOL 				// ("." if no outbound server used)
+							// must be used with dialogs/lr
+	<EOL separated HFs>+	// From and To must be present at least;
+							// dialog-apps must include tag in From
+ 							// (an ephemeral is appended otherwise)
+							// and supply CSeq/CallId
+	.[EOL]
+	[body] 
+	.EOL
+
+*/
+
+int fifo_uac_dlg( FILE *stream, char *response_file ) 
+{
+	char method_buf[MAX_METHOD];
+	char ruri_buf[MAX_URI_SIZE];
+	char outbound_buf[MAX_URI_SIZE];
+	char header_buf[MAX_HEADER]; 
+	char body_buf[MAX_BODY]; 
+	str method, ruri, outbound, header, body;
+	struct sip_uri parsed_ruri, parsed_outbound;
+	str dummy_empty;
+	int fromtag;
+	int cseq;
+	struct cseq_body *parsed_cseq;
+	int i;
+	char c;
+	struct to_body *parsed_from;
+
+
+	char *shmem_file;
+	int fn_len;
+	int ret;
+	int sip_error;
+	char err_buf[MAX_REASON_LEN];
+	int err_ret;
+	struct sip_msg faked_msg;
+
+
+	if (!read_line(method_buf, MAX_METHOD, stream,&method.len)
+					||method.len==0) {
+		/* line breaking must have failed -- consume the rest
+		   and proceed to a new request
+		*/
+		fifo_uac_error(response_file, 400, "method expected");
+		return 1;
+	}
+	method.s=method_buf;
+	DBG("DEBUG: fifo_uac: method: %.*s\n", method.len, method.s );
+
+	if (!read_line(ruri_buf, MAX_URI_SIZE, stream, &ruri.len)
+					|| ruri.len==0) {
+		fifo_uac_error(response_file, 400, "ruri expected");
+		return 1;
+	}
+	if (!parse_uri(ruri_buf, ruri.len, &parsed_ruri) < 0 ) {
+		fifo_uac_error(response_file, 400, "ruri invalid\n");
+		return 1;
+	}
+	ruri.s=ruri_buf;
+	DBG("DEBUG: fifo_uac:  ruri: %.*s\n", ruri.len, ruri.s);
+
+	if (!read_line(outbound_buf, MAX_URI_SIZE, stream, &outbound.len)
+					||outbound.len==0) {
+		fifo_uac_error(response_file, 400, "outbound address expected");
+		return 1;
+	}
+	if (outbound.len==1 && outbound_buf[0]=='.' ) {
+		DBG("DEBUG: fifo_uac: outbound empty");
+		outbound.s=0; outbound.len=0;
+	} else if (!parse_uri(outbound_buf, outbound.len, 
+							&parsed_outbound) < 0 ) {
+		fifo_uac_error(response_file, 400, "outbound uri invalid\n");
+		return 1;
+	} else {
+		outbound.s=outbound_buf;
+		DBG("DEBUG: fifo_uac:  dst: %.*s\n", outbound.len, outbound.s);
+	}
+
+
+	/* now read and parse header fields */
+	if (!read_line_set(header_buf, MAX_HEADER, stream, &header.len)
+					|| header.len==0 ) {
+		fifo_uac_error(response_file, 400, "HFs expected");
+		return 1;
+	}
+	header.s=header_buf;
+	DBG("DEBUG: fifo_uac: header: %.*s\n", header.len, header.s );
+	/* use SIP parser to look at what is in the FIFO request */
+	memset(&faked_msg, 0, sizeof(struct sip_msg));
+	faked_msg.len=header.len; faked_msg.unparsed=header_buf;
+	if (parse_headers(&faked_msg, HDR_EOH, 0)==-1 ) {
+			fifo_uac_error(response_file, 400, "HFs unparseable");
+			goto error;
+	}
+
+	/* and eventually body */
+	if (!read_body(body_buf, MAX_BODY, stream, &body.len)) {
+		fifo_uac_error(response_file, 400, "body expected");
+		goto error;
+	}
+	body.s=body_buf;
+	DBG("DEBUG: fifo_uac: body: %.*s\n", body.len, body.s );
+
+
+	/* at this moment, we collected all the things we got, let's
+	 * verify user has not forgotten something */
+	if (body.len && !faked_msg.content_type) {
+		fifo_uac_error(response_file, 400, "Content_type missing");
+		goto error;
+	}
+	if (body.len && faked_msg.content_length) {
+		fifo_uac_error(response_file, 400, "Content_length disallowed");
+		goto error;
+	}
+	if (!faked_msg.to) {
+		fifo_uac_error(response_file, 400, "To missing");
+		goto error;
+	}
+	if (!faked_msg.from) {
+		fifo_uac_error(response_file, 400, "From missing");
+		goto error;
+	}
+	/* we also need to know if there is from-tag and add it otherwise */
+	if (parse_from_header(&faked_msg)<0) {
+		fifo_uac_error(response_file, 400, "Error in From");
+		goto error;
+	}
+	parsed_from=(struct to_body*)faked_msg.from->parsed;
+	fromtag=parsed_from->tag_value.s &&
+			parsed_from->tag_value.len;
+	cseq=0;
+	if (faked_msg.cseq && (parsed_cseq=get_cseq(&faked_msg))) {
+		for (i=0; i<parsed_cseq->number.len; i++ ) {
+			c=parsed_cseq->number.s[i];
+			if (c>='0' && c<'9' ) cseq=cseq*10+c-'0';
+			else {
+				fifo_uac_error(response_file, 400, "non-nummerical CSeq");
+				goto error;
+			}
+		}
+		if (parsed_cseq->method.len!=method.len 
+				|| memcmp(parsed_cseq->method.s, method.s, method.len)!=0) {
+			fifo_uac_error(response_file, 400, "CSeq method mismatch");
+			goto error;
+		}
+	}
+
+
+
+
+	DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
+	/* we got it all, initiate transaction now! */
+	if (response_file) {
+		fn_len=strlen(response_file)+1;
+		shmem_file=shm_malloc(fn_len);
+		if (shmem_file==0) {
+			fifo_uac_error(response_file, 500, "no shmem");
+			goto error;
+		}
+		memcpy(shmem_file, response_file, fn_len );
+	} else {
+		shmem_file=0;
+	}
+	/* HACK: there is yet a shortcoming -- if t_uac fails, callback
+	   will not be triggered and no feedback will be printed
+	   to shmem_file
+	*/
+	dummy_empty.s=0; dummy_empty.len=0;
+	ret=t_uac_dlg( &method, 
+		outbound.len ? &outbound: 0,
+		&ruri, 
+		&faked_msg.to->body,	/* possibly w/to-tag in it */
+		&faked_msg.from->body,
+		&dummy_empty,			/* if present, to-tag passed in to */
+		fromtag ? 				/* if fromtag present, ... */
+			&dummy_empty: 		/* ... pass it in from ... */
+			0,					/* use ephemeral otherwise */
+		cseq ? &cseq : 0,
+		faked_msg.callid ?
+			&faked_msg.callid->body:
+			0,
+		0, 						/* headers -- TBD */
+		&body,
+		fifo_callback, shmem_file );
+
+
+	if (ret<=0) {
+		err_ret=err2reason_phrase(ret, &sip_error, err_buf,
+				sizeof(err_buf), "FIFO/UAC" ) ;
+		if (err_ret > 0 )
+		{
+
+			fifo_uac_error(response_file, sip_error, err_buf);
+		} else {
+			fifo_uac_error(response_file, 500, "FIFO/UAC error" );
+#ifdef _OBSO
+			fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
+				ret );
+#endif
+		}
+	}
+
+error:
+	free_sip_msg(&faked_msg);
+	return 1;
+}

+ 9 - 1
modules/tm/uac.h

@@ -30,6 +30,9 @@
 #ifndef _UAC_H
 #define _UAC_H
 
+#include "defs.h"
+
+
 #include <stdio.h>
 #include "config.h"
 #include "t_dlg.h"
@@ -111,7 +114,12 @@ int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OP
 	      void* cbp                     /* Callback pointer */
 	      );
 
-
+#ifndef DEPRECATE_OLD_STUFF
 int fifo_uac( FILE *stream, char *response_file );
 int fifo_uac_from( FILE *stream, char *response_file );
 #endif
+
+int fifo_uac_dlg( FILE *stream, char *response_file );
+
+
+#endif

+ 3 - 0
modules/tm/ut.h

@@ -32,6 +32,9 @@
 #ifndef _TM_UT_H
 #define _TM_UT_H
 
+#include "defs.h"
+
+
 #include "../../dprint.h"
 #include "../../error.h"
 #include "../../ut.h"