ctd.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/bin/sh
  2. #
  3. # $Id$
  4. #
  5. # Usage: ctd.sh $FROM $TARGET
  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
  24. #
  25. # Limitations:
  26. # ------------
  27. # it only works with UAs supporting REFER; it has been tested
  28. # with Cisco 7960, Mitel 5055, Grandstream and Pingtel; Windows
  29. # Messenger does not support REFER. Never tested on solaris.
  30. # Some cisco 7960 images don't work (in particular, POS30202
  31. # doesnt, POS3-03-8-21 does)
  32. #
  33. # History:
  34. # --------
  35. # 2003-03-01 bug_fix: route set reversed
  36. # 2003-02-27 dialog support completed (jiri)
  37. # 2003-04-28 dialog info precomputed in SER (jiri)
  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:[email protected]"
  44. echo "destination unspecified -- taking default value $TARGET"
  45. else
  46. TARGET="$2"
  47. fi
  48. # address of user wishing to initiate conversation
  49. if [ -z "$1" ] ; then
  50. URI="sip:[email protected]"
  51. echo "caller unspecified -- taking default value $URI"
  52. else
  53. URI="$1"
  54. fi
  55. #---------------------------------
  56. # fixed config data
  57. FIFO="/tmp/ser_fifo"
  58. # address of controller
  59. FROM="<sip:[email protected]>"
  60. CSEQ="1"
  61. CALLIDNR=`date '+%s'`$$
  62. CALLID="${CALLIDNR}.fifouacctd"
  63. name="ctd_fifo_$$"
  64. fifo_reply="/tmp/$name"
  65. dlg="/tmp/$CALLID.dlg"
  66. FIXED_DLG=`printf "From: $FROM;tag=$CALLIDNR\nCall-ID: $CALLID\nContact: <sip:caller@!!>"`
  67. #----------------------------------
  68. # generate parts of FIFO-request essential to forming
  69. # subsequent in-dialog reuqests
  70. #
  71. # limitations: parsing broken if <> in display names or
  72. # line-folding used
  73. filter_fl()
  74. {
  75. awk -F ' ' '
  76. BEGIN { IGNORECASE=1; line=0; eoh=0;ret=1 }
  77. END { exit ret; }
  78. {line++; }
  79. # line 1: status code
  80. line==1 && /^2[0-9][0-9] / { ret=0;next; }
  81. line==1 && /^[3-6][0-9][0-9] / { print; print $0 > "/dev/stderr"; next; }
  82. line==1 { print "reply error"; print; next; }
  83. # skip body
  84. /^$/ { eoh=1 }
  85. eoh==1 { next }
  86. # uri and outbound uri at line 2,3: copy and paste
  87. line==2 || line==3 { print $0; next; }
  88. # line 4: Route; empty if ".", copy and paste otherwise
  89. line==4 && /^\.$/ { next; }
  90. # if non-empty, copy and paste it
  91. line==4 { print $0; next; }
  92. # filter out to header field for use in next requests
  93. /^(To|t):/ { print $0; next; }
  94. # anything else will be ignored
  95. {next}
  96. ' # end of awk script
  97. } # end of filter_fl
  98. #---------------------------
  99. # main
  100. # set up exit cleaner
  101. trap "rm -f $dlg $fifo_reply; exit 1" 0
  102. # set up FIFO communication
  103. if [ ! -w $FIFO ] ; then # can I write to FIFO server?
  104. echo "Error opening ser's FIFO $FIFO"
  105. exit 1
  106. fi
  107. mkfifo $fifo_reply # create a reply FIFO
  108. if [ $? -ne 0 ] ; then
  109. echo "error opening reply fifo $fifo_reply"
  110. exit 1
  111. fi
  112. chmod a+w $fifo_reply
  113. # start reader now so that it is ready for replies
  114. # immediately after a request is out
  115. cat < $fifo_reply | filter_fl > $dlg &
  116. fifo_job="$!"
  117. # initiate dummy INVITE with pre-3261 "on-hold"
  118. # (note the dots -- they mean in order of appearance:
  119. # outbound uri, end of headers, end of body; eventualy
  120. # the FIFO request must be terminated with an empty line)
  121. cat > $FIFO <<EOF
  122. :t_uac_dlg:$name
  123. INVITE
  124. $URI
  125. .
  126. $FIXED_DLG
  127. To: <$URI>
  128. CSeq: $CSEQ INVITE
  129. Content-Type: application/sdp
  130. .
  131. v=0
  132. o=click-to-dial 0 0 IN IP4 0.0.0.0
  133. s=session
  134. c=IN IP4 0.0.0.0
  135. b=CT:1000
  136. t=0 0
  137. m=audio 9 RTP/AVP 0
  138. a=rtpmap:0 PCMU/8000
  139. .
  140. EOF
  141. # wait for reply
  142. wait $fifo_job # returns completion status of filter_fl
  143. if [ "$?" -ne "0" ] ; then
  144. echo "invitation failed"
  145. exit 1
  146. fi
  147. echo "invitation succeeded"
  148. # proceed to REFER now
  149. if [ \! -r $dlg ] ; then
  150. echo "dialog broken"
  151. exit 1
  152. fi
  153. CSEQ=`expr $CSEQ + 1`
  154. # start reader now so that it is ready for replies
  155. # immediately after a request is out
  156. cat < $fifo_reply | filter_fl > /dev/null &
  157. fifo_job="$!"
  158. # dump the REFER request to FIFO server
  159. cat > $FIFO <<EOF
  160. :t_uac_dlg:$name
  161. REFER
  162. `cat $dlg`
  163. $FIXED_DLG
  164. CSeq: $CSEQ REFER
  165. Referred-By: $FROM
  166. Refer-To: $TARGET
  167. .
  168. .
  169. EOF
  170. # report REFER status
  171. wait $fifo_job
  172. ref_ret="$?"
  173. if [ "$ref_ret" -ne "0" ] ; then
  174. echo "refer failed"
  175. else
  176. echo "refer succeeded"
  177. fi
  178. # well, URI is trying to call TARGET but still maintains the
  179. # dummy call we established with previous INVITE transaction:
  180. # tear it down
  181. # dump the BYE request to FIFO server
  182. CSEQ=`expr $CSEQ + 1`
  183. cat < $fifo_reply | filter_fl > /dev/null &
  184. fifo_job="$!"
  185. cat > $FIFO <<EOF
  186. :t_uac_dlg:$name
  187. BYE
  188. `cat $dlg`
  189. $FIXED_DLG
  190. CSeq: $CSEQ BYE
  191. .
  192. .
  193. EOF
  194. # report BYE status
  195. wait $fifo_job
  196. ret="$?"
  197. if [ "$ret" -ne "0" ] ; then
  198. echo "bye failed"
  199. exit 1
  200. fi
  201. echo "bye succeeded"
  202. # clean-up
  203. trap 0
  204. rm -f $dlg $fifo_reply
  205. exit $ref_ret