⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apps.sgml

📁 SIP Express Router, Linux下的SIP代理服务器,小巧实用,开发测试VoIP设备和应用的必备.
💻 SGML
📖 第 1 页 / 共 2 页
字号:
    <chapter>	<title>Application Writing</title>	<para>	    <application moreinfo="none">ser</application> offers several	    ways to couple its functionality with applications. The coupling	    is bidirectional: <application moreinfo="none">ser</application>	    can utilize external applications and external applications can	    utilize <application moreinfo="none">ser</application>. 	    An example of the former direction would be an external program	    determining a least-cost route for a called destination  using 	    a pricing table. An example of the latter case	    is a web application for server provisioning.	    Such an application may want to send instant 	    messages, query all current user's locations and monitor server	    health. An existing web interface to <application moreinfo="none">ser</application>,	    <application moreinfo="none">serweb</application>, actually	    does all of it. 	</para>	<para>	    The easiest, language-independent way of using external logic 	    from <application moreinfo="none">ser</application> is provided	    by exec module. exec module allows <application moreinfo="none">ser</application>	    to start external programs on receipt of a request. The	    programs can execute arbitrary logic and/or affect routing of SIP	    requests. A great benefit of this programming method is it	    is language-independent. Programmers may use programming languages	    that are effective or with which they are best familiar.	    <xref linkend="usingexec"> gives additional examples illustrating 	    use of the exec module.	</para>	<para>	    Another method for extending <application moreinfo="none">ser</application>	    capabilities is to write new modules in C. This method takes	    deeper understanding of <application moreinfo="none">ser</application>	    internals but gains the highest flexibility. Modules can implement	    arbitrary brand-new commands upon which <application moreinfo="none">ser</application>	    scripts can rely on. Guidelines on module programming can be	    found in <application moreinfo="none">ser</application>	    programmer's handbook available from iptel.org website.	</para>	<para>	    To address needs of applications wishing to leverage	    <application moreinfo="none">ser</application>,	    <application moreinfo="none">ser</application> exports	    parts of its functionality via its built-in	    "Application FIFO server". This is a simple textual	    interface that allows any external applications	    to communicate with the server. It can be used to	    send instant messages, manipulate user contacts,	    watch server health, etc. Programs written in any	    language (PHP, shell scripts, Perl, C, etc.) can	    utilize this feature. How to use it is shown in	    <xref linkend="fifoserver">.	</para>	<section id="usingexec">	    <title>Using exec Module</title>	    <para>				The easiest way is to couple <application moreinfo="none">ser</application>		with external applications via the <emphasis>exec</emphasis>		module. This module allows execution of logic and URI manipulation 		by external applications on request receipt. While very		simple, many useful services can be		implemented this way. External applications can be written in		any programming language and do not be aware of SIP at all.		<application moreinfo="none">ser</application> interacts with		the application via standard input/output and environment 		variables.			    </para>		    <para>		For example, an external shell script		may send an email whenever a request for a user arrives.	    </para>	    <example>		<title>Using exec: Step 1</title>		<programlisting format="linespecific"># send email if a request for user "jiri" arrivesif (uri=~"^sip:jiri@") {     exec_msg("echo 'body: call arrived'|mail -s 'call for you' jiri");}		</programlisting>	    </example> <!-- step 1 -->	    <para>		In this example, the <command moreinfo="none">exec_msg</command> 		action starts an external shell. It passes a received SIP request		to shell's input. In the shell, <command>mail</command> command		is called to send a notification by e-mail.		The script however features several simplifications:		<orderedlist inheritnum="ignore" continuation="restarts">		    <listitem>			<para>			    The email notification does not tell who was calling.			</para>		    </listitem>		    <listitem>			<para>			    The logic is not general: it only supports one well-known user (jiri).			</para>		    </listitem>		    <listitem>			<para>			    The logic is stateless. It will be executed on			    every retransmission.			</para>		    </listitem>		    <listitem>			<para>			    It is a script fragment not explaining the 			    context. This particular example may be for			    example used to report on missed calls.			</para>		    </listitem>		</orderedlist>		All of these simplifications are addressed step-by-step		in the following examples.	    </para>	    <example> <!-- step 2: who called me -->		<title>Using exec: Step 2, Who Called Me</title>		<para>		    This example shows how to display caller's address		    in email notification. The trick is easy: process		    request received on shell program's input		    and grep From header field.		</para>		<programlisting format="linespecific">&execstep2;		</programlisting>		<para>			The following two figures show an example SIP request and			email notification generated on its receipt.					    <screen format="linespecific"><![CDATA[INVITE sip:jiri@iptel.org SIP/2.0Via: SIP/2.0/UDP 195.37.77.100:5040Max-Forwards: 10From: "alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104fTo: <sip:jiri@iptel.org>Call-ID: d10815e0-bf17-4afa-8412-d9130a793d96@213.20.128.35CSeq: 2 INVITEContact: <sip:123.20.128.35:9315>Content-Type: application/sdpContent-Length: 451--- SDP payload snipped ---]]>		    </screen>				    email received:					<screen format="linespecific"><![CDATA[Date: Thu, 12 Dec 2002 14:25:02 +0100From: root <root@cat.iptel.org>To: jiri@cat.iptel.orgSubject: request for youFrom: "alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104frequest received]]>		    </screen>		</para>		<para>		    There is another way to learn values of request		    header fields, simpler than use of <command moreinfo="none">grep</command>. 		    <application moreinfo="none">ser</application>		    parses header fields and passes their values in 		    environment variables. Their names correspond		    to header field names prefixed with "SIP_HF_".		<programlisting format="linespecific"># send email if a request for "jiri" arrivesif (uri=~"^sip:jiri@") {     exec_msg("echo request received from $SIP_HF_FROM | mail -s 'request for you' jiri");};		</programlisting>		    Moreover, several other values are passed in environment		    variables. <varname>SIP_TID</varname> is a token uniquely identifying 		    transaction, to which the request belongs. <varname>SIP_DID</varname>		    includes to-tag, and is empty in requests creating a dialog.		    <varname>SIP_SRCIP</varname> includes IP address, from which the		    request was sent. <varname>SIP_RURI</varname> and <varname>SIP_ORURI</varname>		    include current request-uri and original request-uri respectively,		    <varname>SIP_USER</varname> and <varname>SIP_OUSER</varname> username		    parts of these. The following listing shows environment variables		    passed to a shell script on receipt of the previous message:		    <programlisting format="linespecific"><![CDATA[SIP_HF_MAX_FORWARDS=10SIP_HF_VIA=SIP/2.0/UDP 195.37.77.100:5040SIP_HF_CSEQ=2 INVITESIP_HF_FROM="alice" <sip:alice@iptel.org>;tag=76ff7a07-c091-4192-84a0-d56e91fe104fSIP_ORUI=sip:jiri@iptel.orgSIP_HF_CONTENT_LENGTH=451SIP_TID=3b6b8295db0835815847b1f35f3b29b8SIP_DID=SIP_RURI=iptel.orgSIP_HF_TO=<sip:jiri@iptel.org>SIP_OUSER=jiriSIP_HF_CALLID=d10815e0-bf17-4afa-8412-d9130a793d96@213.20.128.35SIP_SRCIP=195.37.77.100SIP_HF_CONTENT_TYPE=application/sdpSIP_HF_CONTACT=<sip:123.20.128.35:9315>]]>		    </programlisting>				    		</para>	    </example> <!-- step 2, who called me -->	    <example>  <!-- step 3,  make the script work for anyone -->		<title>Using exec: step 3, Make The Script Work For Anyone</title>		<para>		    A drawback of the previous example is it works only		    for one well-known user: request URI is matched against		    his SIP address and notification is sent to his hard-wired email		    address. In real scenarios, one would like		    to enable such a service for all users without enumerating		    their addresses in the script. The missing piece		    is translation of user's SIP name to his email address.		    This information is maintained in subscriber profiles,		    stored in MySQL by <application moreinfo="none">ser</application>.		    To translate the username to email address, the executed script		    needs to query the MySQL database. That is what this example		    shows. First, an SQL query is constructed which looks up		    email address of user, for whom a request arrived. If the		    query does not return a valid email address, the script		    returns with an error status and <application moreinfo="none">ser</application>		    script replies with "user does not exist". Otherwise		    an email notification is sent.				    <programlisting format="linespecific">&execstep3;		    </programlisting>		</para>	    </example> <!-- step 3 make the script work for anyone -->	    <example> <!-- step 4, stateful processing -->		<title>Adding Stateful Processing</title>		<para>		    The previously improved example still features a shortcoming.		    When a message retransmission arrives due to a network		    mistake such as lost reply, the email notification is		    executed again and again. That happens because the script		    is stateless, i.e., no track of current transactions is		    kept. The script does not know whether a request is		    a new or a retransmitted one. Transaction management may		    be introduced by use of tm module as described in		    <xref linkend="statefulua">. In the script,		    <command moreinfo="none">t_newtran</command> is first		    called to absorb requests retransmission -- if they		    occur, script does not continue. Then, as in the previous		    example, an exec module action is called. Eventually,		    a reply is sent statefully.		    <note>			<para>			    Note carefully: it is important that the stateful			    reply processing (<command moreinfo="none">t_reply</command>)			    is used as opposed to using stateless replies			    (<command moreinfo="none">sl_send_reply</command>).			    Otherwise, the outgoing reply would not affect			    transactional context and would not be resent on			    receipt of a request retransmission.			</para>		    </note>		    <programlisting format="linespecific">&execstep4;		    </programlisting>		    		</para>	    </example> <!-- step 4,  stateful processing -->	    <example> <!-- step 5, full exec use -->		<title>Full Example of exec Use</title>		<para>		    The last example iteration shows how to integrate the		    email notification on missed calls with the default		    <application moreinfo="none">ser</application> script		    (see <xref linkend="defaultscript">). It generates an		    email for every call invitation to an off-line user.		    <programlisting format="linespecific">&execstep5;		    </programlisting>		</para>		    		<para>		    Production "missed calls" services may want to 		    report on calls missed for other reasons than		    being off-line too. Particularly, users may wish to be		    reported calls missed due to call cancellation,		    busy status or a downstream failure. Such missed		    calls can be easily reported to syslog or mysql		    using the acc module (see <xref linkend="missedcalls">).		    The other, more general way, is to return to request		    processing on receipt of a negative reply.		    (see <xref linkend="replyprocessingsection">). Before		    a request is forwarded, it is labeled to be		    re-processed in a <command moreinfo="none">failure_route</command>		    on receipt of a negative reply -- this is what		    <command moreinfo="none">t_on_failure</command> action		    is used for. It does not matter what caused the transaction		    to fail -- it may be unresponsive downstream server,		    server responding with 6xx, or server sending a 487		    reply, because an INVITE was canceled. When any such		    circumstances occur (i.e., transaction does not complete		    with a 2xx status code), <command moreinfo="none">failure_route</command>		    is entered.		</para>		<para>		    The following <application moreinfo="none">ser</application>		    script reports missed calls in all possible cases.		    It reports them when a user is off-line as well as when		    a user is on-line, but INVITE transaction does not complete		    successfully.		    <programlisting format="linespecific">&execstep5b;		    </programlisting>		</para>			    </example> <!-- step 5, full exec use -->	</section> <!-- using exec -->	<section id="fifoserver">	    <title>Application FIFO Server</title>	    <para>	    Application FIFO server is a very powerful method to program	    SIP services. The most valuable benefit	    is it works with SIP-unaware applications	    written in any programming language. Textual nature of the	    FIFO interface allows for easy integration with a lot of	    existing programs. Today, <application moreinfo="none">ser</application>'s	    complementary web-interface, <application moreinfo="none">serweb</application>,	    written in PHP, leverages the FIFO interface when displaying	    and changing user location records stored in server's memory.	    It uses this interface to send instant messages too, without	    any knowledge of underlying <acronym>SIP</acronym> stack.	    Another application relying on the FIFO interface is 	    <application moreinfo="none">serctl</application>, <application moreinfo="none">ser</application>	    management utility. The command-line utility can browse	    server's in-memory user-location database, display 	    running processes and operational statistics.	    </para>	    <para>		The way the FIFO server works is similar to how 		<filename moreinfo="none">/proc</filename> filesystem works		on some operating systems. It provides a human-readable way		to access <application moreinfo="none">ser</application>'s		internals. Applications dump their requests into the FIFO		server and receive a status report when request processing		completes. <application moreinfo="none">ser</application>		exports a lot of its functionality located in both the		core and external modules through the FIFO server. 		</para>	    <para>		FIFO requests are formed easily. They begin with a command		enclosed in colons and followed by name of file or pipe (relative		to <filename moreinfo="none">/tmp/</filename> path), to which		a reply should be printed. The first request line may be		followed by additional lines with command-specific 		parameters. For example, the <command moreinfo="none">t_uac_dlg</command>		FIFO command for initiating a transaction allows 		to pass additional header fields and message body to		a newly created transaction. Each request is terminated by		an empty line. Whole requests must be sent by applications		atomically in a single batch to avoid mixing with		requests from other applications. Requests are sent to		pipe at which <application moreinfo="none">ser</application>		listens (filename configured by the <varname>fifo</varname> config		file option).	    </para>	    <para>		An easy way to use the FIFO interface is via the		<application moreinfo="none">serctl</application>		command-line tool. When called along with "fifo",		FIFO command name, and optional parameters, the tool		generates a FIFO request and prints request result.		The following example shows use of this tool with		the <command moreinfo="none">uptime</command> and		<command moreinfo="none">which</command> commands.		<command moreinfo="none">uptime</command> returns		server's running time, <command moreinfo="none">which</command>		returns list of available FIFO commands. Note that only		the built-in FIFO command set is displayed as no modules		were loaded in this example.		<example>		    <title>Use of <application moreinfo="none">serctl</application> 		    to Access FIFO Server</title>		    <programlisting format="linespecific">[jiri@cat test]$ serctl fifo uptimeNow: Fri Dec  6 17:56:10 2002Up Since: Fri Dec  6 17:56:07 2002Up time: 3 [sec][jiri@cat test]$ serctl fifo which

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -