apps.xml 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
  4. <section id="application_writing" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <sectioninfo>
  6. <revhistory>
  7. <revision>
  8. <revnumber>$Revision$</revnumber>
  9. <date>$Date$</date>
  10. </revision>
  11. </revhistory>
  12. </sectioninfo>
  13. <title>Application Writing</title>
  14. <para>
  15. <application>ser</application> offers several
  16. ways to couple its functionality with applications. The coupling
  17. is bidirectional: <application>ser</application>
  18. can utilize external applications and external applications can
  19. utilize <application>ser</application>.
  20. An example of the former direction would be an external program
  21. determining a least-cost route for a called destination using
  22. a pricing table. An example of the latter case
  23. is a web application for server provisioning.
  24. Such an application may want to send instant
  25. messages, query all current user's locations and monitor server
  26. health. An existing web interface to <application>ser</application>,
  27. <application>serweb</application>, actually
  28. does all of it.
  29. </para>
  30. <para>
  31. The easiest, language-independent way of using external logic
  32. from <application>ser</application> is provided
  33. by exec module. exec module allows <application>ser</application>
  34. to start external programs on receipt of a request. The
  35. programs can execute arbitrary logic and/or affect routing of SIP
  36. requests. A great benefit of this programming method is it
  37. is language-independent. Programmers may use programming languages
  38. that are effective or with which they are best familiar.
  39. <xref linkend="usingexec"/> gives additional examples illustrating
  40. use of the exec module.
  41. </para>
  42. <para>
  43. Another method for extending <application>ser</application>
  44. capabilities is to write new modules in C. This method takes
  45. deeper understanding of <application>ser</application>
  46. internals but gains the highest flexibility. Modules can implement
  47. arbitrary brand-new commands upon which <application>ser</application>
  48. scripts can rely on. Guidelines on module programming can be
  49. found in <application>ser</application>
  50. programmer's handbook available from iptel.org website.
  51. </para>
  52. <para>
  53. To address needs of applications wishing to leverage
  54. <application>ser</application>,
  55. <application>ser</application> exports
  56. parts of its functionality via its built-in
  57. "Application FIFO server". This is a simple textual
  58. interface that allows any external applications
  59. to communicate with the server. It can be used to
  60. send instant messages, manipulate user contacts,
  61. watch server health, etc. Programs written in any
  62. language (PHP, shell scripts, Perl, C, etc.) can
  63. utilize this feature. How to use it is shown in
  64. <xref linkend="fifoserver"/>.
  65. </para>
  66. <section id="usingexec">
  67. <title>Using exec Module</title>
  68. <para>
  69. The easiest way is to couple <application>ser</application>
  70. with external applications via the <emphasis>exec</emphasis>
  71. module. This module allows execution of logic and URI manipulation
  72. by external applications on request receipt. While very
  73. simple, many useful services can be
  74. implemented this way. External applications can be written in
  75. any programming language and do not be aware of SIP at all.
  76. <application>ser</application> interacts with
  77. the application via standard input/output and environment
  78. variables.
  79. </para>
  80. <para>
  81. For example, an external shell script
  82. may send an email whenever a request for a user arrives.
  83. </para>
  84. <example>
  85. <title>Using exec: Step 1</title>
  86. <programlisting>
  87. # send email if a request for user "jiri" arrives
  88. if (uri=~"^sip:jiri@") {
  89. exec_msg("echo 'body: call arrived'|mail -s 'call for you' jiri");
  90. }
  91. </programlisting>
  92. </example> <!-- step 1 -->
  93. <para>
  94. In this example, the <command>exec_msg</command>
  95. action starts an external shell. It passes a received SIP request
  96. to shell's input. In the shell, <command>mail</command> command
  97. is called to send a notification by e-mail.
  98. The script however features several simplifications:
  99. <orderedlist inheritnum="ignore" continuation="restarts">
  100. <listitem>
  101. <para>
  102. The email notification does not tell who was calling.
  103. </para>
  104. </listitem>
  105. <listitem>
  106. <para>
  107. The logic is not general: it only supports one well-known user (jiri).
  108. </para>
  109. </listitem>
  110. <listitem>
  111. <para>
  112. The logic is stateless. It will be executed on
  113. every retransmission.
  114. </para>
  115. </listitem>
  116. <listitem>
  117. <para>
  118. It is a script fragment not explaining the
  119. context. This particular example may be for
  120. example used to report on missed calls.
  121. </para>
  122. </listitem>
  123. </orderedlist>
  124. All of these simplifications are addressed step-by-step
  125. in the following examples.
  126. </para>
  127. <example> <!-- step 2: who called me -->
  128. <title>Using exec: Step 2, Who Called Me</title>
  129. <para>
  130. This example shows how to display caller's address
  131. in email notification. The trick is easy: process
  132. request received on shell program's input
  133. and grep From header field.
  134. </para>
  135. <programlisting>
  136. <xi:include href="../../examples/exec_s2.cfg" parse="text"/>
  137. </programlisting>
  138. <para>
  139. The following two figures show an example SIP request and
  140. email notification generated on its receipt.
  141. <screen>
  142. <![CDATA[
  143. INVITE sip:[email protected] SIP/2.0
  144. Via: SIP/2.0/UDP 195.37.77.100:5040
  145. Max-Forwards: 10
  146. From: "alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
  147. To: <sip:[email protected]>
  148. Call-ID: [email protected]
  149. CSeq: 2 INVITE
  150. Contact: <sip:123.20.128.35:9315>
  151. Content-Type: application/sdp
  152. Content-Length: 451
  153. --- SDP payload snipped ---
  154. ]]>
  155. </screen>
  156. email received:
  157. <screen>
  158. <![CDATA[
  159. Date: Thu, 12 Dec 2002 14:25:02 +0100
  160. From: root <[email protected]>
  161. To: [email protected]
  162. Subject: request for you
  163. From: "alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
  164. request received
  165. ]]>
  166. </screen>
  167. </para>
  168. <para>
  169. There is another way to learn values of request
  170. header fields, simpler than use of <command>grep</command>.
  171. <application>ser</application>
  172. parses header fields and passes their values in
  173. environment variables. Their names correspond
  174. to header field names prefixed with "SIP_HF_".
  175. <programlisting>
  176. # send email if a request for "jiri" arrives
  177. if (uri=~"^sip:jiri@") {
  178. exec_msg("echo request received from $SIP_HF_FROM | mail -s 'request for you' jiri");
  179. };
  180. </programlisting>
  181. Moreover, several other values are passed in environment
  182. variables. <varname>SIP_TID</varname> is a token uniquely identifying
  183. transaction, to which the request belongs. <varname>SIP_DID</varname>
  184. includes to-tag, and is empty in requests creating a dialog.
  185. <varname>SIP_SRCIP</varname> includes IP address, from which the
  186. request was sent. <varname>SIP_RURI</varname> and <varname>SIP_ORURI</varname>
  187. include current request-uri and original request-uri respectively,
  188. <varname>SIP_USER</varname> and <varname>SIP_OUSER</varname> username
  189. parts of these. The following listing shows environment variables
  190. passed to a shell script on receipt of the previous message:
  191. <programlisting>
  192. <![CDATA[
  193. SIP_HF_MAX_FORWARDS=10
  194. SIP_HF_VIA=SIP/2.0/UDP 195.37.77.100:5040
  195. SIP_HF_CSEQ=2 INVITE
  196. SIP_HF_FROM="alice" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104f
  197. SIP_ORUI=sip:[email protected]
  198. SIP_HF_CONTENT_LENGTH=451
  199. SIP_TID=3b6b8295db0835815847b1f35f3b29b8
  200. SIP_DID=
  201. SIP_RURI=iptel.org
  202. SIP_HF_TO=<sip:[email protected]>
  203. SIP_OUSER=jiri
  204. [email protected]
  205. SIP_SRCIP=195.37.77.100
  206. SIP_HF_CONTENT_TYPE=application/sdp
  207. SIP_HF_CONTACT=<sip:123.20.128.35:9315>
  208. ]]>
  209. </programlisting>
  210. </para>
  211. </example> <!-- step 2, who called me -->
  212. <example> <!-- step 3, make the script work for anyone -->
  213. <title>Using exec: step 3, Make The Script Work For Anyone</title>
  214. <para>
  215. A drawback of the previous example is it works only
  216. for one well-known user: request URI is matched against
  217. his SIP address and notification is sent to his hard-wired email
  218. address. In real scenarios, one would like
  219. to enable such a service for all users without enumerating
  220. their addresses in the script. The missing piece
  221. is translation of user's SIP name to his email address.
  222. This information is maintained in subscriber profiles,
  223. stored in MySQL by <application>ser</application>.
  224. To translate the username to email address, the executed script
  225. needs to query the MySQL database. That is what this example
  226. shows. First, an SQL query is constructed which looks up
  227. email address of user, for whom a request arrived. If the
  228. query does not return a valid email address, the script
  229. returns with an error status and <application>ser</application>
  230. script replies with "user does not exist". Otherwise
  231. an email notification is sent.
  232. <programlisting>
  233. <xi:include href="../../examples/exec_s3.cfg" parse="text"/>
  234. </programlisting>
  235. </para>
  236. </example> <!-- step 3 make the script work for anyone -->
  237. <example> <!-- step 4, stateful processing -->
  238. <title>Adding Stateful Processing</title>
  239. <para>
  240. The previously improved example still features a shortcoming.
  241. When a message retransmission arrives due to a network
  242. mistake such as lost reply, the email notification is
  243. executed again and again. That happens because the script
  244. is stateless, i.e., no track of current transactions is
  245. kept. The script does not know whether a request is
  246. a new or a retransmitted one. Transaction management may
  247. be introduced by use of tm module as described in
  248. <xref linkend="statefulua"/>. In the script,
  249. <command>t_newtran</command> is first
  250. called to absorb requests retransmission -- if they
  251. occur, script does not continue. Then, as in the previous
  252. example, an exec module action is called. Eventually,
  253. a reply is sent statefully.
  254. <note>
  255. <para>
  256. Note carefully: it is important that the stateful
  257. reply processing (<command>t_reply</command>)
  258. is used as opposed to using stateless replies
  259. (<command>sl_send_reply</command>).
  260. Otherwise, the outgoing reply would not affect
  261. transactional context and would not be resent on
  262. receipt of a request retransmission.
  263. </para>
  264. </note>
  265. <programlisting>
  266. <xi:include href="../../examples/exec_s4.cfg" parse="text"/>
  267. </programlisting>
  268. </para>
  269. </example> <!-- step 4, stateful processing -->
  270. <example> <!-- step 5, full exec use -->
  271. <title>Full Example of exec Use</title>
  272. <para>
  273. The last example iteration shows how to integrate the
  274. email notification on missed calls with the default
  275. <application>ser</application> script
  276. (see <xref linkend="defaultscript"/>). It generates an
  277. email for every call invitation to an off-line user.
  278. <programlisting>
  279. <xi:include href="../../examples/exec_s5.cfg" parse="text"/>
  280. </programlisting>
  281. </para>
  282. <para>
  283. Production "missed calls" services may want to
  284. report on calls missed for other reasons than
  285. being off-line too. Particularly, users may wish to be
  286. reported calls missed due to call cancellation,
  287. busy status or a downstream failure. Such missed
  288. calls can be easily reported to syslog or mysql
  289. using the acc module (see <xref linkend="missedcalls"/>).
  290. The other, more general way, is to return to request
  291. processing on receipt of a negative reply.
  292. (see <xref linkend="replyprocessingsection"/>). Before
  293. a request is forwarded, it is labeled to be
  294. re-processed in a <command>failure_route</command>
  295. on receipt of a negative reply -- this is what
  296. <command>t_on_failure</command> action
  297. is used for. It does not matter what caused the transaction
  298. to fail -- it may be unresponsive downstream server,
  299. server responding with 6xx, or server sending a 487
  300. reply, because an INVITE was canceled. When any such
  301. circumstances occur (i.e., transaction does not complete
  302. with a 2xx status code), <command>failure_route</command>
  303. is entered.
  304. </para>
  305. <para>
  306. The following <application>ser</application>
  307. script reports missed calls in all possible cases.
  308. It reports them when a user is off-line as well as when
  309. a user is on-line, but INVITE transaction does not complete
  310. successfully.
  311. <programlisting>
  312. <xi:include href="../../examples/exec_s5b.cfg" parse="text"/>
  313. </programlisting>
  314. </para>
  315. </example> <!-- step 5, full exec use -->
  316. </section> <!-- using exec -->
  317. <section id="fifoserver">
  318. <title>Application FIFO Server</title>
  319. <para>
  320. Application FIFO server is a very powerful method to program
  321. SIP services. The most valuable benefit
  322. is it works with SIP-unaware applications
  323. written in any programming language. Textual nature of the
  324. FIFO interface allows for easy integration with a lot of
  325. existing programs. Today, <application>ser</application>'s
  326. complementary web-interface, <application>serweb</application>,
  327. written in PHP, leverages the FIFO interface when displaying
  328. and changing user location records stored in server's memory.
  329. It uses this interface to send instant messages too, without
  330. any knowledge of underlying <acronym>SIP</acronym> stack.
  331. Another application relying on the FIFO interface is
  332. <application>serctl</application>, <application>ser</application>
  333. management utility. The command-line utility can browse
  334. server's in-memory user-location database, display
  335. running processes and operational statistics.
  336. </para>
  337. <para>
  338. The way the FIFO server works is similar to how
  339. <filename>/proc</filename> filesystem works
  340. on some operating systems. It provides a human-readable way
  341. to access <application>ser</application>'s
  342. internals. Applications dump their requests into the FIFO
  343. server and receive a status report when request processing
  344. completes. <application>ser</application>
  345. exports a lot of its functionality located in both the
  346. core and external modules through the FIFO server.
  347. </para>
  348. <para>
  349. FIFO requests are formed easily. They begin with a command
  350. enclosed in colons and followed by name of file or pipe (relative
  351. to <filename>/tmp/</filename> path), to which
  352. a reply should be printed. The first request line may be
  353. followed by additional lines with command-specific
  354. parameters. For example, the <command>t_uac_dlg</command>
  355. FIFO command for initiating a transaction allows
  356. to pass additional header fields and message body to
  357. a newly created transaction. Each request is terminated by
  358. an empty line. Whole requests must be sent by applications
  359. atomically in a single batch to avoid mixing with
  360. requests from other applications. Requests are sent to
  361. pipe at which <application>ser</application>
  362. listens (filename configured by the <varname>fifo</varname> config
  363. file option).
  364. </para>
  365. <para>
  366. An easy way to use the FIFO interface is via the
  367. <application>serctl</application>
  368. command-line tool. When called along with "fifo",
  369. FIFO command name, and optional parameters, the tool
  370. generates a FIFO request and prints request result.
  371. The following example shows use of this tool with
  372. the <command>uptime</command> and
  373. <command>which</command> commands.
  374. <command>uptime</command> returns
  375. server's running time, <command>which</command>
  376. returns list of available FIFO commands. Note that only
  377. the built-in FIFO command set is displayed as no modules
  378. were loaded in this example.
  379. <example>
  380. <title>Use of <application>serctl</application>
  381. to Access FIFO Server</title>
  382. <programlisting>
  383. [jiri@cat test]$ serctl fifo uptime
  384. Now: Fri Dec 6 17:56:10 2002
  385. Up Since: Fri Dec 6 17:56:07 2002
  386. Up time: 3 [sec]
  387. [jiri@cat test]$ serctl fifo which
  388. ps
  389. which
  390. version
  391. uptime
  392. print
  393. </programlisting>
  394. </example>
  395. The request which the <application>serctl</application>
  396. command-line tool sent to FIFO server looked like this:
  397. <example>
  398. <title><command>uptime</command> FIFO Request</title>
  399. <programlisting>
  400. :uptime:ser_receiver_1114
  401. </programlisting>
  402. </example>
  403. This request contains no parameters and consists only of
  404. command name enclosed in colons and name of file, to which
  405. a reply should be printed. FIFO replies consist of a status
  406. line followed by optional parameters. The status line consists,
  407. similarly to <acronym>SIP</acronym> reply status, of
  408. a three-digit status code and a reason phrase. Status codes
  409. with leading digit 2 (200..299) are considered positive,
  410. any other values indicate an error. For example, FIFO server
  411. returns "500" if execution of a non-existing FIFO command is
  412. requested.
  413. <example>
  414. <title>FIFO Errors</title>
  415. <programlisting>
  416. [jiri@cat sip_router]$ serctl fifo foobar
  417. 500 command 'foobar' not available
  418. </programlisting>
  419. </example>
  420. <example>
  421. <title>Showing User Contacts Using serctl</title>
  422. <para>
  423. Another example of use of FIFO is accessing server's
  424. in-memory user location database. That's a very powerful
  425. feature: web applications and other tools can use it
  426. to gain users access to the database. They can add new
  427. contacts (like permanent gateway destinations), remove
  428. and review users' whereabouts. The example here utilizes
  429. FIFO command <command>ul_show_contact</command> to
  430. retrieve current whereabouts of user "jiri".
  431. <programlisting>
  432. <![CDATA[
  433. [jiri@fox ser]$ serctl fifo ul_show_contact location jiri
  434. <sip:195.37.78.160:14519>;q=0.00;expires=1012
  435. ]]>
  436. </programlisting>
  437. </para>
  438. </example>
  439. </para>
  440. <para>
  441. The user location example demonstrates an essential feature
  442. of the FIFO server: extensibility. It is able to export new
  443. commands implemented in new modules.
  444. Currently, usrloc module exports FIFO
  445. commands for maintaining in-memory user location
  446. database and tm module exports FIFO commands for
  447. management of SIP transactions. See the
  448. example in
  449. <filename>examples/web_im/send_im.php</filename>
  450. for how to initiate a SIP transaction
  451. (instant message)
  452. from a PHP script via the FIFO server. This example
  453. uses FIFO command
  454. <command>t_uac_dlg</command>. The command
  455. is followed by parameters: header fields and
  456. message body. The same FIFO command can be used from
  457. other environments to send instant messages too. The
  458. following example shows how to send instant messages
  459. from a shell script.
  460. <example>
  461. <title>Sending IM From Shell Script</title>
  462. <programlisting>
  463. #!/bin/sh
  464. #
  465. # call this script to send an instant message; script parameters
  466. # will be displayed in message body
  467. #
  468. # parameters mean: message type, request-URI, outbound server is
  469. # left blank ("."), required header fields From and To follow,
  470. # then optional header fields terminated by dot and optional
  471. # dot-terminated body
  472. cat &gt; /tmp/ser_fifo &lt;&lt;EOF
  473. :t_uac_dlg:hh
  474. NOTIFY
  475. sip:[email protected]
  476. .
  477. From: sip:[email protected]
  478. To: sip:[email protected]
  479. foo: bar_special_header
  480. x: y
  481. p_header: p_value
  482. Contact: &lt;sip:[email protected]:9&gt;
  483. Content-Type: text/plain; charset=UTF-8
  484. .
  485. Hello world!!!! $@
  486. .
  487. EOF
  488. </programlisting>
  489. </example>
  490. </para>
  491. <example>
  492. <title>Manipulation of User Contacts</title>
  493. <para>
  494. The following example shows use of FIFO server to change
  495. user's contacts. This may be very practical, if for example
  496. a user wishes to set up his cell phone number as his temporary
  497. contact. The cell phone, which is behind a PSTN gateway, cannot
  498. register automatically using SIP. The user needs to set
  499. forwarding manually through some convenient web interface.
  500. The web interface needs to have the ability to upload new user's
  501. contacts to <application>ser</application>.
  502. This is what the <command>ul_add</command> FIFO
  503. command is good for. Parameterized by user's name, table name,
  504. expiration time and weight, it allows external applications to
  505. introduce new contacts to server's in-memory user location table.
  506. </para>
  507. <para>
  508. The example is borrowed from <application>serweb</application>,
  509. <application>ser</application>'s web
  510. PHP-written interface.
  511. It consists of a short "stub" function which carries out
  512. all mechanics of FIFO communication and of forming the FIFO
  513. request.
  514. </para>
  515. <programlisting>
  516. <![CDATA[
  517. /* construct and send a FIFO command; the command parameters $sip_address,
  518. $expires are PHP variables originating from an HTML form
  519. */
  520. $fifo_cmd=":ul_add:".$config->reply_fifo_filename."\n".
  521. $config->ul_table."\n". //table
  522. $user_id."\n". //username
  523. $sip_address."\n". //contact
  524. $expires."\n". //expires
  525. $config->ul_priority."\n\n"; //priority
  526. $message=write2fifo($fifo_cmd, $errors, $status);
  527. /* .......... snip .................. */
  528. /* this is the stub function for communicating with FIFO server.
  529. it dumps a request to FIFO server, opens a reply FIFO and
  530. reads server's reply from it
  531. */
  532. function write2fifo($fifo_cmd, &$errors, &$status){
  533. global $config;
  534. /* open fifo now */
  535. $fifo_handle=fopen( $config->fifo_server, "w" );
  536. if (!$fifo_handle) {
  537. $errors[]="sorry -- cannot open fifo"; return;
  538. }
  539. /* create fifo for replies */
  540. @system("mkfifo -m 666 ".$config->reply_fifo_path );
  541. /* add command separator */
  542. $fifo_cmd=$fifo_cmd."\n";
  543. /* write fifo command */
  544. if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
  545. @unlink($config->reply_fifo_path);
  546. @fclose($fifo_handle);
  547. $errors[]="sorry -- fifo writing error"; return;
  548. }
  549. @fclose($fifo_handle);
  550. /* read output now */
  551. @$fp = fopen( $config->reply_fifo_path, "r");
  552. if (!$fp) {
  553. @unlink($config->reply_fifo_path);
  554. $errors[]="sorry -- fifo reading error"; return;
  555. }
  556. $status=fgetS($fp,256);
  557. if (!$status) {
  558. @unlink($config->reply_fifo_path);
  559. $errors[]="sorry -- fifo reading error"; return;
  560. }
  561. $rd=fread($fp,8192);
  562. @unlink($config->reply_fifo_path);
  563. return $rd;
  564. }
  565. ]]>
  566. </programlisting>
  567. </example>
  568. <para>
  569. See
  570. <xref linkend="fiforeference"/> for a complete listing
  571. of FIFO commands available with current
  572. <application>ser</application>
  573. distribution.
  574. </para>
  575. <section>
  576. <title>Advanced Example: Click-To-Dial</title>
  577. <para>
  578. A very useful SIP application is phonebook with
  579. "click-to-dial" feature. It allows users to keep their
  580. phonebooks on the web and dial by clicking on an entry.
  581. The great advantage is that you can use the phonebook
  582. alone with any phone you have. If you temporarily use
  583. another phone, upgrade it permanently with another make,
  584. or use multiple phones in parallel, your phonebook will
  585. stay with you on the web. You just need to click an entry
  586. to initiate a call. Other scenario using "click-to-dial"
  587. feature includes "click to be connected with our
  588. sales representative".
  589. </para>
  590. <para>
  591. There are basically two ways how to build such a feature:
  592. distributed and centralized. We prefer the distributed
  593. approach since it is very robust and light-weighted.
  594. The "click-to-dial" application just needs to instruct
  595. the calling user to call a destination and that's it.
  596. (That's done using "REFER" method.)
  597. Then, the calling user takes over whereas the initiating
  598. application disappears from signaling and
  599. is no longer involved in subsequent communication. Which
  600. is good because such a simple design scales well.
  601. </para>
  602. <para>
  603. The other design alternative is use of a B2BUA
  604. <footnote>
  605. <para>
  606. See <filename>
  607. draft-ietf-sipping-3pcc-02.txt
  608. </filename> for more details.
  609. </para>
  610. </footnote>
  611. which acts as a "middleman" involved in signaling during the
  612. whole session. It is complex: ringing needs to be achieved
  613. using a media server, it introduces session state,
  614. mangling of SIP payloads, complexity when QoS reservation
  615. is used and possibly other threats which result from
  616. e2e-unfriendly design. The only benefit
  617. is it works even for poor phones which do not support
  618. REFER -- which should not matter because you do not wish
  619. to buy such.
  620. </para>
  621. <para>
  622. So how does "distributed click-to-dial" application
  623. work? It is simple. The core piece is sending a REFER
  624. request to the calling party. REFER method is typically
  625. used for call transfer and it means "set up a call
  626. to someone else".
  627. </para>
  628. <para>
  629. There is an issue -- most phones
  630. don't accept unsolicited REFER. If a malicious
  631. user made your phone to call thirty destinations without
  632. your agreement, you would certainly not appreciate it.
  633. The workaround is that first of all the click-to-dial
  634. application gives you a "wrapper call". If you accept it,
  635. the application will send a REFER which will be considered
  636. by the phone as a part of approved communication and
  637. granted. Be aware that without cryptography,
  638. security is still weak. Anyone who saw an INVITE can
  639. generate an acceptable REFER.
  640. <note>
  641. <para>
  642. The wrapper INVITE may or may not be used
  643. in future. The Internet draft
  644. draft-ietf-sipping-service-examples
  645. mentions the click-to-dial application
  646. without use of the dummy INVITE. As of
  647. today, most telephones do need it.
  648. </para>
  649. </note>
  650. <example>
  651. <title>Call-Flow for Click-To-Dial Using REFER</title>
  652. <programlisting>
  653. CTD Caller Callee
  654. #1 INVITE
  655. -----------------&gt;
  656. ...
  657. caller answers
  658. #2 200
  659. &lt;-----------------
  660. #3 ACK
  661. -----------------&gt;
  662. #4 REFER
  663. -----------------&gt;
  664. #5 202
  665. &lt;-----------------
  666. #6 BYE
  667. -----------------&gt;
  668. #7 200
  669. &lt;-----------------
  670. #8 INVITE
  671. ------------------&gt;
  672. #9 180 ringing
  673. &lt;------------------
  674. #1 click-to-dial (CTD) is started and the "wrapper call" is initiated
  675. INVITE caller
  676. From: controller
  677. To: caller
  678. SDP: on hold
  679. #2 calling user answes
  680. 200 OK
  681. From: controller
  682. To: caller
  683. #3 CTD acknowledges
  684. ACK caller
  685. From controller
  686. To: caller
  687. #4 CTD initiates a transfer
  688. REFER caller
  689. From: controller
  690. To: caller
  691. Refer-To: callee
  692. Refered-By: controller
  693. #5 caller confirms delivery of REFER
  694. 202 Accepted
  695. From: controller
  696. To: caller
  697. #6 CTD terminates the wrapper call -- it is no longer needed
  698. BYE caller
  699. From: controller
  700. To: caller
  701. #7 BYE is confirmed
  702. 200 Ok
  703. From: controller
  704. To: caller
  705. #8 caller initates transaction solicited through REFER
  706. INVITE callee
  707. From: caller
  708. To: callee
  709. Referred-By: controller
  710. #9 that's it -- it is now up to callee to answer the INVITE
  711. 180 ringing
  712. From: caller
  713. To: callee
  714. </programlisting>
  715. </example>
  716. </para>
  717. <para>
  718. Implementation of this scenario is quite
  719. straight-forward: you initiate INVITE, BYE and
  720. REFER transaction.
  721. Source code of the example written in Bourne shell
  722. is available in source distrubtion, in
  723. <filename>examples/ctd.sh</filename>.
  724. A PHP implementation exists as well as a part of
  725. <application>serweb</application>.
  726. </para>
  727. <example>
  728. <title>Running the CTD Example</title>
  729. <programlisting>
  730. [jiri@cat examples]$ ./ctd.sh
  731. destination unspecified -- taking default value sip:[email protected]
  732. caller unspecified -- taking default value sip:[email protected]
  733. invitation succeeded
  734. refer succeeded
  735. bye succeeded
  736. </programlisting>
  737. </example>
  738. </section> <!-- click-to-dial -->
  739. <!-- for some reason, this does not work :-(
  740. <example>
  741. <title>Initiating a SIP Transaction from PHP via FIFO</title>
  742. <programlisting>
  743. <textobject>
  744. <textdata fileref="../../examples/web_im/send_im.php">
  745. </textobject>
  746. </programlisting>
  747. </example>
  748. -->
  749. </section> <!-- FIFO server -->
  750. </section>