Browse code

click-to-dial completed

Jiri Kuthan authored on 27/02/2003 20:29:25
Showing 5 changed files
... ...
@@ -19,6 +19,7 @@
19 19
 <!ENTITY execstep5 SYSTEM "../../examples/exec_s5.cfg">
20 20
 <!ENTITY execstep5b SYSTEM "../../examples/exec_s5b.cfg">
21 21
 <!ENTITY ccdiversion SYSTEM "../../examples/ccdiversion.cfg">
22
+<!ENTITY logging SYSTEM "../../examples/logging.cfg">
22 23
 <!ENTITY releasenotes SYSTEM "../../NEWS">
23 24
 <!ENTITY install SYSTEM "../../INSTALL">
24 25
 <!ENTITY voicemail SYSTEM "voicemail.sgml">
... ...
@@ -1957,7 +1958,7 @@ route{
1957 1957
 	    </section> <!-- exec example -->
1958 1958
 	    
1959 1959
 	    <section id="replyprocessingsection">
1960
-		<title>Reply Processing (Forward on Unavailable)</title>
1960
+		<title>On-Reply Processing (Forward on Unavailable)</title>
1961 1961
 		<para>
1962 1962
 		    Many services depend on status of messages relayed
1963 1963
 		    downstream: <emphasis>forward on busy</emphasis> and 
... ...
@@ -1981,6 +1982,18 @@ route{
1981 1981
 		    any final reply within final response period.
1982 1982
 		</para>
1983 1983
 		<para>
1984
+		    The length of the timer is governed by parameters of the
1985
+		    tm module. <varname>fr_timer</varname> is the length of
1986
+		    timer set for non-INVITE transactions and INVITE transactions
1987
+		    for which no provisional response is received. If a timer
1988
+		    hits, it indicates that a downstream server is unresponsive.
1989
+		    <varname>fr_inv_timer</varname> governs time to wait for 
1990
+		    a final reply for an INVITE. It is typically longer than
1991
+		    <varname>fr_timer</varname> because final reply may take
1992
+		    long time until callee (finds a mobile phone in a pocket and)
1993
+		    answers the call.
1994
+		</para>
1995
+		<para>
1984 1996
 		    In <xref linkend="replyprocessing">, <command moreinfo="none">reply_route[1]</command>
1985 1997
 		    is set to be entered on error using the <command moreinfo="none">t_on_negative(1)</command>
1986 1998
 		    action. Within this reply block, <application moreinfo="none">ser</application>
... ...
@@ -1991,7 +2004,7 @@ route{
1991 1991
 		    is entered and a last resort destination (sip:foo@iptel.org) is tried.
1992 1992
 		</para>
1993 1993
 		<example id="replyprocessing">
1994
-		    <title>Reply Processing</title>
1994
+		    <title>On-Reply Processing</title>
1995 1995
 		    <programlisting format="linespecific">
1996 1996
 			<!-- ../../examples/onr.cfg -->
1997 1997
 			&replyexample;
... ...
@@ -2005,7 +2018,7 @@ route{
2005 2005
 
2006 2006
     <chapter>
2007 2007
 	<title>Server Operation</title>
2008
-	<section>
2008
+	<section id="operationalpractices">
2009 2009
 	    <title>Recommended Operational Practices</title>
2010 2010
 
2011 2011
 	    <para>
... ...
@@ -2296,23 +2309,6 @@ warning: IP extract from warning activated to be more informational
2296 2296
 		    </para>
2297 2297
 		</answer>
2298 2298
 	    </qandaentry>
2299
-		<qandaentry>
2300
-		    <question>
2301
-			<para>
2302
-			    Setting Proper Log Level
2303
-			</para>
2304
-		    </question>
2305
-		    <answer>
2306
-			<para>
2307
-			    If something is going wrong and you are in doubts what causes the
2308
-			    error, increase log level. Additional log messages may help you
2309
-			    to trace the error reason. Be careful though: <application moreinfo="none">
2310
-			    ser</application> is very talkative in higher debugging levels.
2311
-			    Too noisy log files are difficult to read too and server's
2312
-			    operation slows down noticeably.
2313
-			</para>
2314
-		    </answer>
2315
-		</qandaentry>
2316 2299
 	    <qandaentry>
2317 2300
 		<question>
2318 2301
 		    <para>
... ...
@@ -2364,25 +2360,103 @@ warning: IP extract from warning activated to be more informational
2364 2364
 				</para>
2365 2365
 			</question>
2366 2366
 			<answer>
2367
-				<para>
2368
-					<application>ser</application> by default logs
2369
-					to <application>syslog</application> facility.
2370
-					It is very useful to watch log messages for
2371
-					abnormal behaviour. Log messages, subject to
2372
-					<application>syslog</application> configuration
2373
-					may be stored at different files, or even at remote
2374
-					systems. A typical location of the log file is
2375
-					<filename>/var/log/messages</filename>.
2376
-				</para>
2377
-				<para>
2378
-					One can also use other <application>syslogd</application>
2379
-					implementation. <application>metalog</application>
2380
-					(<ulink url="http://http://metalog.sourceforge.net//">
2381
-			    	http://metalog.sourceforge.net/
2382
-					</ulink>)
2383
-					features regular expression matching that enables
2384
-					to filter and group log messages.
2385
-				</para>
2367
+			<anchor id="logging">
2368
+			<para>
2369
+			    <application>ser</application> by default logs
2370
+			    to <application>syslog</application> facility.
2371
+			    It is very useful to watch log messages for
2372
+			    abnormal behaviour. Log messages, subject to
2373
+			    <application>syslog</application> configuration
2374
+			    may be stored at different files, or even at remote
2375
+			    systems. A typical location of the log file is
2376
+			    <filename>/var/log/messages</filename>.
2377
+			</para>
2378
+			<note>
2379
+			    <para>
2380
+				One can also use other <application>syslogd</application>
2381
+				implementation. <application>metalog</application>
2382
+				(<ulink url="http://http://metalog.sourceforge.net//">
2383
+				    http://metalog.sourceforge.net/
2384
+				</ulink>)
2385
+				features regular expression matching that enables
2386
+				to filter and group log messages.
2387
+			    </para>
2388
+			</note>
2389
+			<para>
2390
+			    For the purpose of debugging configuration scripts, one may
2391
+			    want to redirect log messages to console not to pollute
2392
+			    syslog files. To do so configure <application moreinfo="none">ser</application>
2393
+			    in the following way:
2394
+			    <itemizedlist>
2395
+				<listitem>
2396
+				    <para>
2397
+					Attach ser to console by setting <varname>fork=no</varname>.
2398
+				    </para>
2399
+				</listitem>
2400
+				<listitem>
2401
+				    <para>
2402
+					Set explicitely at which address 
2403
+					<application moreinfo="none">ser</application>
2404
+					should be listening, e.g., <varname>listen=192.168.2.16</varname>.
2405
+				    </para>
2406
+				</listitem>
2407
+				<listitem>
2408
+				    <para>
2409
+					Redirect log messages to standard error by setting
2410
+					<varname>log_stderror=yes</varname>
2411
+				    </para>
2412
+				</listitem>
2413
+				<listitem>
2414
+				    <para>
2415
+					Set appropriately high log level. (Be sure that you redirected logging
2416
+					to standard output. Flooding system logs with many detailed messages
2417
+					would make the logs difficult to read and use.) You can set the global
2418
+					logging threshold value with the option <varname>debug=nr</varname>,
2419
+					where the higher <varname>nr</varname> the more detailed output.
2420
+					If you wish to set log level only for some script events, include
2421
+					the desired log level as the first parameter of the
2422
+					<command moreinfo="none">log</command> action in your script.
2423
+					The messages will be then printed if <command moreinfo="none">log</command>'s
2424
+					level is lower than the global threshold, i.e., the lower the more
2425
+					noisy output you get.
2426
+					<example>
2427
+					    <title>Logging Script</title>
2428
+					    <programlisting format="linespecific">
2429
+&logging;
2430
+					    </programlisting>
2431
+					    <para>
2432
+						The following SIP message causes then logging output as shown
2433
+						bellow.
2434
+					    </para>
2435
+					    <programlisting format="linespecific">
2436
+REGISTER sip:192.168.2.16 SIP/2.0
2437
+Via: SIP/2.0/UDP 192.168.2.33:5060
2438
+From: sip:113311@192.168.2.16
2439
+To: sip:113311@192.168.2.16
2440
+Call-ID: 00036bb9-0fd305e2-7daec266-212e5ec9@192.168.2.33
2441
+Date: Thu, 27 Feb 2003 15:10:52 GMT
2442
+CSeq: 101 REGISTER
2443
+User-Agent: CSCO/4
2444
+Contact: sip:113311@192.168.2.33:5060
2445
+Content-Length: 0
2446
+Expires: 600                                 
2447
+					    </programlisting>
2448
+					    <programlisting format="linespecific">
2449
+[jiri@cat sip_router]$ ./ser -f examples/logging.cfg 
2450
+Listening on 
2451
+              192.168.2.16 [192.168.2.16]::5060
2452
+Aliases: cat.iptel.org:5060 cat:5060 
2453
+WARNING: no fork mode 
2454
+ 0(0) INFO: udp_init: SO_RCVBUF is initially 65535
2455
+ 0(0) INFO: udp_init: SO_RCVBUF is finally 131070
2456
+ 0(17379) REGISTER received
2457
+ 0(17379) request for other domain received					
2458
+					    </programlisting>
2459
+					</example>
2460
+				    </para>
2461
+				</listitem>
2462
+			    </itemizedlist>
2463
+			</para>
2386 2464
 			</answer>
2387 2465
 		</qandaentry>
2388 2466
 	    <qandaentry>
... ...
@@ -2826,12 +2900,13 @@ MySql Password:
2826 2826
 	    </section> <!-- reliability -->
2827 2827
 	    <section>
2828 2828
 		<title>Stateful versus Stateless Forwarding</title>
2829
-			<para>
2830
-			    <application moreinfo="none">ser</application> allows both stateless
2831
-			    and stateful request processing. This memo explains what are pros and cons of
2832
-			    using each method. The rule of thumb is "stateless for scalability,
2833
-			    stateful for services".
2834
-			</para>
2829
+		<para>
2830
+		    <application moreinfo="none">ser</application> allows both stateless
2831
+		    and stateful request processing. This memo explains what are pros and cons of
2832
+		    using each method. The rule of thumb is "stateless for scalability,
2833
+		    stateful for services". If you are unsure which you need, stateful
2834
+		    is a safer choice which supports more usage scenarios.
2835
+		</para>
2835 2836
 			<para>
2836 2837
 			    Stateless forwarding with the
2837 2838
 			    <command moreinfo="none">forward(uri:host, uri:port)</command> action
... ...
@@ -2881,6 +2956,36 @@ MySql Password:
2881 2881
 					action must be processed statefuly.
2882 2882
 				    </para>
2883 2883
 				</listitem>
2884
+			<listitem>
2885
+			    <para>
2886
+				<emphasis>
2887
+				    Fail-over.
2888
+				</emphasis>
2889
+				If you wish to try out another destination, after a primary destination
2890
+				failed you need to use stateful processing. With stateless processing
2891
+				you never know with what status a forwarded request completed downstream
2892
+				because you immediately release all processing information after the 
2893
+				request is sent out. 
2894
+
2895
+				<note>
2896
+				    <para>
2897
+					Positive return value of stateless
2898
+					<command moreinfo="none">forward</command> action only indicates that
2899
+					a request was successfuly sent out, and does not gain any knowledge
2900
+					about whether it was successfuly received or replied. Neither does
2901
+					the return value of
2902
+					the stateful <command moreinfo="none">t_relay</command> action family
2903
+					gain you this knowledge. However, these actions store transactional
2904
+					context with which includes original request and allows you to
2905
+					take an action when a negative reply comes back or a timer strikes.
2906
+					See <xref linkend="replyprocessingsection"> for an example script 
2907
+					which launches another
2908
+					branch if the first try fails.
2909
+				    </para>
2910
+				</note>
2911
+
2912
+			    </para>
2913
+			</listitem>
2884 2914
 			    </itemizedlist>
2885 2915
 			</para>
2886 2916
 	    </section> <!-- stateful vs. stateless -->
... ...
@@ -3222,7 +3327,9 @@ if (to me):
3222 3222
 	    <title>Troubleshooting</title>
3223 3223
 	    <para>
3224 3224
 		This section gathers practices how to deal with errors
3225
-		known to occur frequently.
3225
+		known to occur frequently. To understand how to watch
3226
+		SIP messages, server logs, and in genereal how to
3227
+		troubleshoot, read also <xref linkend="operationalpractices">. 
3226 3228
 	    </para>
3227 3229
 	    <qandaset>
3228 3230
 		<qandaentry>
... ...
@@ -3324,6 +3431,31 @@ if (to me):
3324 3324
 			</para>
3325 3325
 		    </answer>
3326 3326
 		</qandaentry>
3327
+		<qandaentry>
3328
+		    <question>
3329
+			<para>
3330
+			    I try to add an alias but 
3331
+			    <command moreinfo="none">serctl</command>
3332
+			    complains that table does not exist.
3333
+			</para>
3334
+		    </question>
3335
+		    <answer>
3336
+			<para>
3337
+			    You need to run <application moreinfo="none">ser</application>
3338
+			    and use the command
3339
+			    <command moreinfo="none">lookup("aliases")</command>
3340
+			    in its routing script. That's because the table 
3341
+			    of aliases is
3342
+			    stored in cache memory for high speed. The cache
3343
+			    memory is only set up when the 
3344
+			    <application moreinfo="none">ser</application>
3345
+			    is running and configured to use it. If that is
3346
+			    not the case, 
3347
+			    <application moreinfo="none">serctl</application>
3348
+			    is not able to manipulate the aliases table.
3349
+			</para>
3350
+		    </answer>
3351
+		</qandaentry>
3327 3352
 	    </qandaset>
3328 3353
 	</section> <!-- troubleshooting -->
3329 3354
     </chapter> <!-- operation -->
... ...
@@ -3931,6 +4063,185 @@ function write2fifo($fifo_cmd, &$errors, &$status){
3931 3931
 		<application moreinfo="none">ser</application>
3932 3932
 		distribution.
3933 3933
 	    </para>
3934
+	    <section>
3935
+		<title>Advanced Example: Click-To-Dial</title>
3936
+		<para>
3937
+		    A very useful SIP application is phonebook with
3938
+		    "click-to-dial" feature. It allows users to keep their 
3939
+		    phonebooks on the web and dial by clicking on an entry. 
3940
+		    The great advantage is that you can use the phonebook 
3941
+		    alone with any phone you have. If you temporarily use 
3942
+		    another phone, upgrade it permanently with another make, 
3943
+		    or use multiple phones in parallel, your phonebook will 
3944
+		    stay with you on the web. You just need to click an entry 
3945
+		    to initiate a call. Other scenario using "click-to-dial"
3946
+		    feature includes "click to be connected with our
3947
+		    sales representative".
3948
+		</para>
3949
+		<para>
3950
+		    There are basically two ways how to build such a feature:
3951
+		    distributed and centralized. We prefer the distributed
3952
+		    approach since it is very robust and leight-weighted.
3953
+		    The "click-to-dial" application just needs to instruct
3954
+		    the calling user to call a destination and that's it.
3955
+		    (That's done using "REFER" method.)
3956
+		    Then, the calling user takes over whereas the initating
3957
+		    application disappears from signaling and
3958
+		    is no longer involved in subsequent communication. Which
3959
+		    is good because such a simple design scales well. 
3960
+		</para>
3961
+		<para>
3962
+		    The other design alternative is use of a B2BUA 
3963
+		    <footnote>
3964
+			<para>
3965
+			    See <filename moreinfo="none">
3966
+				draft-ietf-sipping-3pcc-02.txt 
3967
+			    </filename>  for more details.
3968
+			</para>
3969
+		    </footnote>
3970
+		    which acts as a "middleman" involved in signaling during the
3971
+		    whole session. It is complex: ringing needs to be achieved
3972
+		    using a media server, it introduces session state,
3973
+		    mangling of SIP payloads, complexity when QoS reservation
3974
+		    is used and possibly other threats which result from 
3975
+		    e2e-unfriendly design. The only benefit
3976
+		    is it works even for poor phones which do not support
3977
+		    REFER -- which should not matter because you do not wish
3978
+		    to buy such.
3979
+		</para>
3980
+		<para>
3981
+		    So how does "distributed click-to-dial" application
3982
+		    work? It is simple. The core piece is sending a REFER
3983
+		    request to the calling party. REFER method is typically
3984
+		    used for call transfer and it means "set up a call 
3985
+		    to someone else". 
3986
+		    </para>
3987
+		<para>
3988
+		    There is an issue -- most phones
3989
+		    don't accept unsolicited REFER. If a malicious
3990
+		    user made your phone to call thirty destinations without
3991
+		    your agreement, you would certainly not appreciate it.
3992
+		    The workaround is that first of all the click-to-dial
3993
+		    application gives you a "wrapper call". If you accept it, 
3994
+		    the application will send a REFER which will be considered
3995
+		    by the phone as a part of approved communication and
3996
+		    granted. Be aware that without cryptography, 
3997
+		    security is still weak. Anyone who saw an INVITE can 
3998
+		    generate an acceptable REFER.
3999
+		    <example>
4000
+			<title>Call-Flow for Click-To-Dial Using REFER</title>
4001
+
4002
+			<programlisting format="linespecific">
4003
+
4004
+        CTD                  Caller               Callee
4005
+            #1 INVITE
4006
+            ----------------->
4007
+                             ...
4008
+                             caller answers
4009
+            #2 200
4010
+            <-----------------
4011
+            #3 ACK
4012
+            ----------------->
4013
+            #4 REFER
4014
+            ----------------->
4015
+            #5 202
4016
+            <-----------------
4017
+            #6 BYE
4018
+            ----------------->
4019
+            #7 200
4020
+            <-----------------
4021
+                                  #8 INVITE
4022
+                                  ------------------>
4023
+                                  #9 180 ringing
4024
+                                  <------------------
4025
+
4026
+
4027
+#1 click-to-dial (CTD) is started and the "wrapper call" is initiated
4028
+INVITE caller
4029
+From: controller
4030
+To: caller
4031
+SDP: on hold
4032
+
4033
+#2 calling user answes
4034
+200 OK
4035
+From: controller
4036
+To: caller
4037
+
4038
+#3 CTD acknowledges
4039
+ACK caller
4040
+From controller
4041
+To: caller
4042
+
4043
+#4 CTD initiates a transfer
4044
+REFER caller
4045
+From: controller
4046
+To: caller
4047
+Refer-To: callee
4048
+Refered-By: controller
4049
+
4050
+#5 caller confirms delivery of REFER
4051
+202 Accepted
4052
+From: controller
4053
+To: caller
4054
+
4055
+#6 CTD terminates the wrapper call -- it is no longer needed
4056
+BYE caller
4057
+From: controller
4058
+To: caller
4059
+
4060
+#7 BYE is confirmed
4061
+200 Ok
4062
+From: controller
4063
+To: caller
4064
+
4065
+#8 caller initates transaction solicited through REFER
4066
+INVITE callee
4067
+From: caller
4068
+To: callee
4069
+Referred-By: controller
4070
+
4071
+#9 that's it -- it is now up to callee to answer the INVITE
4072
+180 ringing
4073
+From: caller
4074
+To: callee
4075
+			</programlisting>
4076
+
4077
+		    </example>
4078
+		</para>
4079
+		<para>
4080
+		    Implementation of this scenario is quite
4081
+		    straight-forward: you initiate INVITE, BYE and
4082
+		    REFER transaction.
4083
+
4084
+
4085
+
4086
+		    The largest amount of code
4087
+		    is spent with getting dialog processing right.
4088
+		    The subsequent BYE and REFER transactions need to
4089
+		    be build using information learned from the reply
4090
+		    to INVITE: Contact header field, To-tag and Route
4091
+		    set. That's what the function 
4092
+		    <function moreinfo="none">filter_fl</function>
4093
+		    is used for. The "main" part just initiates
4094
+		    each of the transactions, waits for its completion
4095
+		    and proceeds to the next one until BYE is over.
4096
+		    Source code of the example written in Bourne shell
4097
+		    is available in source distrubtion, in 
4098
+		    <filename moreinfo="none">examples/ctd.sh</filename>.
4099
+		    A PHP implementation exists as well.
4100
+		</para>
4101
+		<example>
4102
+		    <title>Running the CTD Example</title>
4103
+		    <programlisting format="linespecific">
4104
+[jiri@cat examples]$ ./ctd.sh 
4105
+destination unspecified -- taking default value sip:23@192.168.2.16
4106
+caller unspecified -- taking default value sip:113311@192.168.2.16
4107
+invitation succeeded
4108
+refer succeeded
4109
+bye succeeded
4110
+		    </programlisting>
4111
+		</example>
4112
+	    </section> <!-- click-to-dial -->
3934 4113
 <!-- for some reason, this does not work :-(
3935 4114
 
3936 4115
 		<example>
... ...
@@ -1,90 +1,283 @@
1
-#!/bin/sh 
1
+#!/bin/sh
2 2
 #
3 3
 # $Id$
4
+#
5
+# Usage: ctd.sh $FROM $TARGET
4 6
 # 
5
-# (currently lame) click-to-dial example using REFER
6
-#----------------------------------------------------
7
+# click-to-dial example using REFER
8
+#----------------------------------
9
+#
10
+# About:
11
+# ------
12
+# this script initiates a call from SIP user $FROM to SIP
13
+# user $TARGET; it works as follows: a dummy user invites
14
+# $FROM to a dummy "call on hold"; as soon as it is set up, the
15
+# dummy user transfers $FROM to $TARGET  (REFER transaction)
16
+# and terminates the dummy session established previously
17
+# (BYE transaction). Note: the "dummy call" is used to
18
+# make $FROM accept $REFER -- most of SIP phones do not
19
+# accept REFER if no call has not been established yet.
20
+#
21
+# Requirements: 
22
+# -------------
23
+# SER with FIFO server turned on and TM module loaded
7 24
 #
8
-# it half-way works using FIFO/uac; I tested it with
9
-# Cisco 7960 reaching Mitel 5055 and vice versa
25
+# Limitations: 
26
+# ------------
27
+# it only works with UACs supporting REFER; it has been tested 
28
+# with Cisco 7960 and Mitel 5055; Windows Messenger does not
29
+# support REFER; dialog parser over-simplified (see inline) but 
30
+# quite functional (if there is something to be fixed, it is
31
+# richness of SIP syntax); an awk-only rewrite would be esthetically
32
+# nicer, imho 
10 33
 #
11
-# bugs: 
12
-# -----
13
-# - to-tag in REFER not ok -- should be gained from initial 
14
-#   conversation (need to take fifo processing from sc) as
15
-#   well as the whole dialog stuff (awk could be a better hit)
16
-# - remove user prompt (act on receipt of a reply)
17
-# - bye is missing after REFER
18
-# - it would be cleaner to send "hold" in initial invite
19
-# - in my test setup, initial ACK is for some bizzar reason
20
-#   not forwarded statelessly by outbound proxy
21
-# - put this example in serdoc
22
-
23
-#URI="sip:113311@192.168.2.16"
34
+# History:
35
+# --------
36
+# 2003-02-27 dialog support completed (jiri)
37
+
38
+#--------------------------------
39
+# config: who with whom
40
+# address of the final destination to which we want to transfer
41
+# initial CSeq and CallId
42
+if [ -z "$2" ]; then
43
+	TARGET="sip:23@192.168.2.16"
44
+	echo "destination unspecified -- taking default value $TARGET"
45
+else
46
+	TARGET="$2"
47
+fi
24 48
 # address of user wishing to initiate conversation
25
-TARGET="sip:23@192.168.2.16"
49
+if [ -z "$1" ] ; then
50
+	URI="sip:113311@192.168.2.16"
51
+	echo "caller unspecified -- taking default value $URI"
52
+else
53
+	URI="$1"
54
+fi
55
+
56
+#---------------------------------
57
+# fixed config data
26 58
 FIFO="/tmp/ser_fifo"
27 59
 # address of controller
28
-FROM="<sip:caller@foo.bar>"
29
-# address of the final destination to which we want to transfer
30
-URI="sip:113311@192.168.2.16"
31
-# initial CSeq and CallId
60
+FROM="<sip:controller@foo.bar>"
32 61
 CSEQ="1"
33 62
 CALLIDNR=`date '+%s'`$$
34
-
63
+CALLID="${CALLIDNR}.fifouacctd"
64
+name="ctd_fifo_$$"
65
+fifo_reply="/tmp/$name"
66
+dlg="/tmp/$CALLID.dlg"
67
+FIXED_DLG=`printf "From: $FROM;tag=$CALLIDNR\nCall-ID: $CALLID\nContact: <sip:caller@!!>"`
35 68
 #----------------------------------
36 69
 
37
-CALLID="${CALLIDNR}.fifouacctd"
70
+# generate parts of FIFO-request essential to forming
71
+# subsequent in-dialog reuqests
72
+# 
73
+# limitations: parsing broken if <> in display names or
74
+# line-folding used
75
+filter_fl()
76
+{
38 77
 
39
-cat > $FIFO <<EOF
78
+awk -F ' ' '
79
+BEGIN { IGNORECASE=1; rri=0; line=0; ret=1;eoh=0 }
80
+END { # print dialog information a la RFC3261, S. 12.2.1.1
81
+	# calculate route set 
82
+	if (rri>0) { # route set not empty
83
+		# next-hop loose router?
84
+		if (match(rr[1], ";lr")) {
85
+			ruri=rcontact
86
+			nexthop=rr[1]
87
+			rrb=1 # begin from first
88
+		} else { # next-hop strict router
89
+			ruri=rr[1]
90
+			rrb=2 # skip first
91
+			rri++
92
+			rr[rri]=rcontact
93
+			nexthop="." # t_uac_dlg value for "use ruri"
94
+		}
95
+	} else { # no record-routing
96
+			ruri=rcontact
97
+			nexthop="."
98
+			rrb=1 # do not enter the loop
99
+	}
100
+	# print the FIFO request header
101
+	print ruri
102
+	print nexthop
103
+	print to
104
+	for(i=rrb; i<=rri; i++ ) {
105
+		if (i==rrb) printf "Route: "; else printf ", "
106
+		printf("%s", rr[i])
107
+		if (i==rri) printf("\n")
108
+		
109
+	}
110
+	exit ret
111
+}
112
+
113
+# set true (0) to return value if transaction completed succesfully
114
+{line++; }
115
+line==1 && /^2[0-9][0-9] / { ret=0; next; }
116
+line==1 && /^[3-6][0-9][0-9] / { print; next; }
117
+line==1 { print "reply error"; print; next; } 
118
+
119
+# skip body
120
+/^$/ { eoh=1 }
121
+eoh==1 { next }
122
+
123
+# collect dialog state: contact, rr, to
124
+/^(Contact|m):/ { 
125
+	# contact is <>-ed; fails if < within quotes
126
+	if (match($0, "^(Contact|m):[^<]*<([^>]*)>", arr)) {
127
+		rcontact=arr[2]
128
+		next
129
+	# contact without any extras and without <>, just uri
130
+	} else if (match($0, "^(Contact|m):[ \t]*([^ ;\t]*)", arr)) {
131
+		rcontact=arr[2]
132
+		next
133
+	} else {
134
+		# contact parsing error
135
+		ret=1
136
+	}
137
+}
138
+
139
+/^Record-Route:/ {
140
+	# rr is always <>-ed; fails if <> within quotes
141
+	srch=$0
142
+	while (match(srch, "[^<]*<([^>]*)>", arr )) {
143
+		rri++
144
+		rr[rri]=arr[1]
145
+		srch=substr(srch,RLENGTH)
146
+	}
147
+}
40 148
 
149
+/^(To|t):/ {
150
+	to=$0;
151
+}
41 152
 
42
-:t_uac_dlg:qqq
153
+{next} # do not print uninteresting header fields
154
+	' # end of awk script
155
+} # end of filter_fl
156
+
157
+#---------------------------
158
+# main
159
+
160
+# set up exit cleaner
161
+trap "rm -f $dlg $fifo_reply; exit" 0
162
+
163
+# set up FIFO communication
164
+
165
+if [ ! -w $FIFO ] ; then # can I write to FIFO server?
166
+	echo "Error opening ser's FIFO $FIFO"
167
+	exit 1
168
+fi
169
+mkfifo $fifo_reply # create a reply FIFO
170
+if [ $? -ne 0 ] ; then
171
+	echo "error opening reply fifo $fifo_reply"
172
+	exit 1
173
+fi
174
+chmod a+w $fifo_reply
175
+# start reader now so that it is ready for replies
176
+# immediately after a request is out
177
+cat < $fifo_reply | filter_fl > $dlg  &
178
+fifo_job="$!"
179
+
180
+# initiate dummy INVITE with pre-3261 "on-hold"
181
+# (note the dots -- they mean in order of appearance:
182
+# outbound uri, end of headers, end of body; eventualy
183
+# the FIFO request must be terminated with an empty line)
184
+cat > $FIFO <<EOF
185
+
186
+:t_uac_dlg:$name
43 187
 INVITE 
44 188
 $URI
45 189
 .
46
-From: $FROM;tag=$CALLIDNR
190
+$FIXED_DLG
47 191
 To: <$URI>
48
-Call-ID: $CALLID
49 192
 CSeq: $CSEQ INVITE
50
-Contact: <sip:caller@!!>
51 193
 Content-Type: application/sdp
52 194
 .
53 195
 v=0
54
-o=jku2 0 0 IN IP4 213.20.128.35
196
+o=click-to-dial 0 0 IN IP4 0.0.0.0
55 197
 s=session
56
-c=IN IP4 213.20.128.35
198
+c=IN IP4 0.0.0.0
57 199
 b=CT:1000
58 200
 t=0 0
59
-m=audio 54742 RTP/AVP 97 111 112 6 0
60
-a=rtpmap:97 red/8000
61
-a=rtpmap:111 SIREN/16000
62
-a=fmtp:111 bitrate=16000
63
-a=rtpmap:112 G7221/16000
64
-a=fmtp:112 bitrate=24000
65
-a=rtpmap:6 DVI4/16000
201
+m=audio 9 RTP/AVP 0
66 202
 a=rtpmap:0 PCMU/8000
67 203
 .
204
+
68 205
 EOF
69 206
 
70
-read -p "press any key to initiate transfer: "
207
+# wait for reply 
208
+wait $fifo_job # returns completion status of filter_fl
209
+if [ "$?" -ne "0" ] ; then
210
+	echo "invitation failed"
211
+	exit 1
212
+fi
213
+
214
+echo "invitation succeeded"
71 215
 
216
+# proceed to REFER now
217
+if [ \! -r $dlg ] ; then
218
+	echo "dialog broken"
219
+	exit 1
220
+fi
72 221
 CSEQ=`expr $CSEQ + 1`
73 222
 
74
-cat > $FIFO <<EOF
223
+# start reader now so that it is ready for replies
224
+# immediately after a request is out
225
+cat < $fifo_reply | filter_fl > /dev/null  &
226
+fifo_job="$!"
75 227
 
228
+# dump the REFER request to FIFO server 
229
+cat > $FIFO <<EOF
76 230
 
77
-:t_uac_dlg:qqq
231
+:t_uac_dlg:$name
78 232
 REFER
79
-$URI
80
-.
81
-From: $FROM;tag=$CALLIDNR
82
-To: <$URI>
83
-Call-ID: $CALLID
233
+`cat $dlg`
234
+$FIXED_DLG
84 235
 CSeq: $CSEQ REFER
85
-Contact: <sip:caller@!!>
86 236
 Referred-By: $FROM
87 237
 Refer-To: $TARGET
88 238
 .
89 239
 .
240
+
241
+EOF
242
+
243
+# report REFER status
244
+wait $fifo_job
245
+ret="$?"
246
+
247
+if [ "$ret" -ne "0" ] ; then
248
+	echo "refer failed"
249
+	exit 1
250
+fi
251
+
252
+echo "refer succeeded"
253
+
254
+# well, URI is trying to call TARGET but still maintains the
255
+# dummy call we established with previous INVITE transaction:
256
+# tear it down
257
+
258
+
259
+# dump the BYE request to FIFO server 
260
+CSEQ=`expr $CSEQ + 1`
261
+cat < $fifo_reply | filter_fl > /dev/null  &
262
+fifo_job="$!"
263
+cat > $FIFO <<EOF
264
+
265
+:t_uac_dlg:$name
266
+BYE
267
+`cat $dlg`
268
+$FIXED_DLG
269
+CSeq: $CSEQ BYE
270
+.
271
+.
272
+
90 273
 EOF
274
+
275
+# report BYE status
276
+wait $fifo_job
277
+ret="$?"
278
+
279
+if [ "$ret" -ne "0" ] ; then
280
+	echo "bye failed"
281
+	exit 1
282
+fi
283
+echo "bye succeeded"
91 284
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+#
1
+# $Id$
2
+#
3
+# logging example
4
+#
5
+
6
+# ------------------ module loading ----------------------------------
7
+
8
+fork=no
9
+listen=192.168.2.16
10
+log_stderror=yes
11
+debug=3
12
+
13
+
14
+# -------------------------  request routing logic -------------------
15
+
16
+# main routing logic
17
+
18
+route{
19
+	# for testing purposes, simply okay all REGISTERs
20
+	if (method=="REGISTER") {
21
+		log(1, "REGISTER received\n");
22
+	} else {
23
+		log(1, "non-REGISTER received\n");
24
+	};
25
+	if (uri=~"sip:.*[@:]iptel.org") {
26
+		log(1, "request for iptel.org received\n");
27
+	} else {
28
+		log(1, "request for other domain received\n");
29
+	};
30
+}
... ...
@@ -51,6 +51,7 @@
51 51
  *
52 52
  * History:
53 53
  * ----------
54
+ * 2003-02-27  3261 ACK/200 consumption bug removed (jiri)
54 55
  * 2003-01-28  scratchpad removed (jiri)
55 56
  * 2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
56 57
  * 2003-01-23  options for disabling r-uri matching introduced (jiri)
... ...
@@ -44,11 +44,12 @@
44 44
  *
45 45
  * History:
46 46
  * --------
47
+ * 2003-02-27 FIFO/UAC now dumps reply -- good for CTD (jiri)
48
+ * 2003-02-13  t_uac, t _uac_dlg, gethfblock, uri2proxy changed to use 
49
+ *              proto & rb->dst (andrei)
47 50
  * 2003-01-29  scratchpad removed (jiri)
48 51
  * 2003-01-27  fifo:t_uac_dlg completed (jiri)
49 52
  * 2003-01-23  t_uac_dlg now uses get_out_socket (jiri)
50
- * 2003-02-13  t_uac, t _uac_dlg, gethfblock, uri2proxy changed to use 
51
- *              proto & rb->dst (andrei)
52 53
  */
53 54
 
54 55
 
... ...
@@ -595,7 +596,7 @@ done:
595 595
 }
596 596
 
597 597
 
598
-static void fifo_callback( struct cell *t, struct sip_msg *msg,
598
+static void fifo_callback( struct cell *t, struct sip_msg *reply,
599 599
 	int code, void *param)
600 600
 {
601 601
 
... ...
@@ -609,14 +610,20 @@ static void fifo_callback( struct cell *t, struct sip_msg *msg,
609 609
 	}
610 610
 
611 611
 	filename=(char *)(t->cbp);
612
-	get_reply_status(&text,msg,code);
613
-	if (text.s==0) {
614
-		LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
615
-		fifo_reply(filename, "500 fifo_callback: get_reply_status failed\n");
616
-		return;
612
+	if (reply==FAKED_REPLY) {
613
+		get_reply_status(&text,reply,code);
614
+		if (text.s==0) {
615
+			LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
616
+			fifo_reply(filename, "500 fifo_callback: get_reply_status failed\n");
617
+			return;
618
+		}
619
+		fifo_reply(filename, "%.*s", text.len, text.s );
620
+		pkg_free(text.s);
621
+	} else {
622
+		text.s=reply->first_line.u.reply.status.s;
623
+		text.len=reply->len-(reply->first_line.u.reply.status.s-reply->buf);
624
+		fifo_reply(filename, "%.*s", text.len, text.s );
617 625
 	}
618
-	fifo_reply(filename, "%.*s", text.len, text.s );
619
-	pkg_free(text.s);
620 626
 	DBG("DEBUG: fifo_callback sucesssfuly completed\n");
621 627
 }	
622 628