Author: derek Date: Fri Jun 8 00:05:34 2007 New Revision: 272 Added: sofaswitch/trunk/callflow/docs/app1.sgml sofaswitch/trunk/callflow/docs/chap1.sgml sofaswitch/trunk/callflow/docs/chap2.sgml sofaswitch/trunk/callflow/docs/chap3.sgml Log: Add these files, which are the split up chapters from description.sgml Added: sofaswitch/trunk/callflow/docs/app1.sgml ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/docs/app1.sgml Fri Jun 8 00:05:34 2007 @@ -0,0 +1,21 @@ +<appendix> +<title>Building these docs</title> +<para> +The documentation for %callflow was generated from multiple +<literal>.sgml</literal> and <literal>.xml</literal files. The utility +<screenshot> +xsltproc +</screenshot> +was used to process the supplied files to generate <literal>html</literal> +files and several auxillary help files. The generated files were compressed +into one <literal>.zip</literal> file. When the &callflow; utility runs, it +reads in the supplied zip file (which contains the index information). A +<literal>wxWidgets</literal> class is used to display the html documentation. +</para> + +<para> +The file <literal>makedoc.xsl</literal> contains the stylesheet commands that +are used when converting the docbook file <literal>callflow.xml</literal> into html. +</para> +</sect1> +</appendix> Added: sofaswitch/trunk/callflow/docs/chap1.sgml ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/docs/chap1.sgml Fri Jun 8 00:05:34 2007 @@ -0,0 +1,103 @@ +<chapter> +<title>Introduction</title> +<para>&callflow; is a utility which has been designed to enable the user to control +the various entities in the &sofaswitch; system. This utility allows the +user to graphically design call setup, connection, and teardown. This utility +takes the graphical layout and generates Python code, which implements the +desired operation. </para> + +<para>Python is areasonably tidy language, cross platform, straightforward syntax and does not +have the dependency hell of perl. Sadly, nothing is easy, and it takes +considerable effort to write Python scripts to control &sofaswitch; utilities. A +graphical approach is preferable. +</para> + +<para> +The user will be exposed to some Python, but at a relatively simple +level. These blocks of Python code are regular expressions and label +defination. Consequently, it is straightforward, and quite manageable for the +novice. The example flow graphs contain many blocks of Python code, which are +a useful guide to the novice. +</para> + +<para>The following section gives an overview of the operation of +&callflow;. Subsequent chapters describe the operation of &callflow; by means +of examples, and by a detailed description of each available control structure. +</para> + +<sect1> <title>Overview of operation</title> +<para>Various items are selected from the tool bar, and placed on the screen. These are connected +together. Once the flow diagram is completed, it is compiled by selection of +the compile button. Two files are generated. +<itemizedlist> + <listitem><para>a graph file, which describes the items + on the screen, their internal settings ,and how they are connected. </para></listitem> + <listitem><para>a Python file, which contains Python documentation and Python code to run + any graph file, and one line which invokes the reading of the generated + graph file.</para></listitem> +</itemizedlist> +</para> + +<para> +The Python executable is, in fact, able to process any graph file. This happens +as the Python executable contains all the methods for all known types of +items. Indeed, if you compile two different graphs on the screen, the only +difference in the generated Python code is the specified graph +file. Consequently, it is possible for the one Python executable to load +multiple graph files and do multiple concurrent calls. +</para> + +<para>Prior to execution of the Python file, it is expected the server is +running. The compiled Python script will contain instructions (as set by the +user) to request nodes at the different &sofaswitch; +entities. Should there be no reply (the entity is not running) there will be +a timeout, and the user's code will need to respond accordingly. This Python +script can be executed in a console, and the user can monitor the messages +that flow to/from the server to see how things are progressing. Once the +script has been tested with 1 call, multiple calls can be handled by multiple +instances of the script.</para> + +<para> +Each Python file invokes the handling of variables for all items on the screen +within one instance of the <literal>Controller</literal> class. Should a +separate graph be required to simultaneously, it will be run within a second +instance of the <literal>Controller</literal> class. Thus, all graphs are kept +totally separate. Should the user wish to share data between different +executing graphs, thread safe structures such as databases should be used. To +communicate between different instances of the <literal>Controller</literal> +class, one may send messages via the server. +</para> + +<para> +For safety, variables required should be limited to the scope of the class that +this graph is running. Consequently, if there are multiple instances of this +graph being used, there will be no variable collision. It is therefore +suggested that all variables have the string <literal>self</literal> before +them. Consequently, you would refer to the variable <literal>i</literal> as +<literal>self.i</literal> +</para> + +<para>One difficulty with Python is the inability to handle threads well. They +are available, but are very heavyweight in terms of system load, but provide +limited gain. To illustrate, a multi threaded Python application will run at +the same speed on a multiprocessor box as on a single cpu box. Worse, each new +thread running in Python is a whole new running interpreter, which consumes +system resources. This posed a problem - if the controller is going to handle +lots of concurrent calls, it would be poor practice to place each controller +handled call into a separate Python thread. </para> + +<para> We therefore base this code around +<ulink URL="http://twistedmatrix.com/trac"></ulink> an event driven network +framework written in Python. Using Twisted solved the handling of the any +number of asynchronous events.. Further, we could have one psuedo thread per +call, but in reality there is one thread in operation. One psuedo thread per +call makes things much simpler to analyse. </para> + +<para>The Python code will process the items on the graph, until it reaches +the end of the current graph. Execution then waits for a event to happen, +which move the current point of execution back to the relevant event handler. +Thus, a call flow graph in this system will only have one start point, but may +have many termination points. +</para> +</sect1> +</chapter> Added: sofaswitch/trunk/callflow/docs/chap2.sgml ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/docs/chap2.sgml Fri Jun 8 00:05:34 2007 @@ -0,0 +1,241 @@ +<chapter> +<title> Example flow graphs for &callflow;</title> +<para> +We provide in this chapter multiple examples of the usage of +&callflow;. These have been designed to give the reader an +idea of the different components available, and how they link together. A full +scale PBX will combine these elements together. +</para> + +<para> +One should remember that each graph is designed to handle one call. Events are +posted to each graph, that are relevant to each call. Multiple calls can be +handled simultaneously by spawning off graphs with the aid of the +<literal>Load New Graph</literal> widget. Thus, on receiving notification of an +incoming call, one would spawn of a <literal>Load New Graph</literal>, which is +designed to handle that particular incoming call. +</para> + +<sect1> +<title>Hello World example</title> +<para> +Perhaps the simplest example of a graph you can create is the standard "Hello +World" example, shown here, in figure <xref linkend="helloworldexample"/>. +<figure id="helloworldexample"> +<title>The obligatory Hello World example</title> +<mediaobject> +<imageobject> +<imagedata fileref="helloworld.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</figure> + +An example of a simple call flow graph. The properties of the Python object in the middle have been adjusted to contain + code to print text to the console. On execution, a text message is sent to the console. +</para> + +<para> +Python will start executing at the very top box, process the code in the +middle, and then terminate at the bottom. The operation of the three boxes (top to bottom) is +<itemizedlist> + <listitem><para>On loading of this graph, execution will start at this box. It is an error to + have two such flow generation boxes on the page.</para></listitem> + <listitem><para>Execute the Python code, which has been defined by + the user, in the properties of this instance of the Python code + box.</para></listitem> + <listitem><para>The skull and crossbones symbol indicates ther +termination of this thread of execution, and then disconnect from the +server. All future events are ignored. Other threads of execution on other +pages are not influenced. + </para></listitem> </itemizedlist> </para> + +<para>Program flow is invariably top to +bottom. Arrows are drawn on the output and input of each box to indicate where +the flow is going. You will notice four black circles, filled, on this +graph. They indicate a connection between the different entities. +</para> +</sect1> + +<sect1> +<title>For Loops</title> +<para> +The flow of execution is to follow the graph on the screen and behaves likes a +for loop in the pogramming language "C". Thus, start at the beginning, +initialise the loop variable, evaluate the termination clause and goto the +body of the for loop or the end block (if the termination clause is false). On +completion of the body of the for loop, return back to the start. Execute the +increment operation and then evaluate the termination condition. If the +termination condition is false, execute the body of the for loop. The +initialisation, increment operator, and termination condition, consist of +Python code that is set in the preferences at the beginning of the for loop +(right mouse button on the for loop entity). A simple example of a for loop is +shown in figure <xref linkend="forloopexample"/>. +<figure id="forloopexample"> +<title>Example of a for loop</title> +<mediaobject> +<imageobject> +<imagedata fileref="forloop.png" align="center" format="PNG"></imagedata> +</imageobject></mediaobject> +</figure> +</para> + +<para> While processing each of the nodes in the supplied graph, it is +ignoring all timer events. Execution continues until it falls of the end of +the graph, or passes through an Eventer type structure and goes nowhere. Once +execution has gone nowhere, the system will process pending events. +</para> + + + +</sect1> + + +<sect1> +<title>Event handling</title> +<para> +We describe the handling of events in this section, with a simple example. +Consider the figure <xref linkend="simpleeventexample"/>. +<figure id="simpleeventexample"> +<title>Example of event handling</title> +<mediaobject> +<imageobject> +<imagedata fileref="simpleevent.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</figure> +</para> + +<para> +Execution starts at the top, moves to the next node which sends off a request +to obtain a new worker node. Then, the eventer box is entered, where we +register to receive any event that contains the word "NEW" (we are searching +for all events advising of a new node). At which point, execution continues to +the right, and goes into the lower "execute Python code" box, which prints a +message. Finally, execution moves into the bottom most box, and is suspended. +</para> + +<para> +At this point, we rely upon the twisted module in Python to call methods +indicating that things have happened (e.g. a timer, data received from network +etc). On receipt of a message about a new node, execution is moved to the box +on the star output of the eventer box. Thus, the left Python code box is +executed, which (in this case) reports the id of the voip node created. +Execution then moves to the skull and cross bones and terminates. +</para> + + +<para> +Of crucial importance is that the user should note that all events (such as network +and timer) are only processed when execution has stopped. Thus, execution has +to have moved to a suspend execution box. In the graphic above, execution is +suspended when it moves to the right side of the graph and down. After the +event has happened, execution moves to the skull and crossbones and this entire +graph is terminated. +</para> + +<para> +The eventer object, on selecting the right mouse button, brings up a properties +box that has multiple fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> +<row> <entry> + <literal>Event Sought</literal></entry> <entry><para>The +event this box waits for can be described as text or Python code, which is +matched as a regular expression to each event. The user should specify the +event in Python code or as text.</para></entry></row> +<row> + <entry><literal>Python variable:source of the event</literal></entry> + <entry><para>The source of the event (node id or timer) is + recorded in the specified Python variable.</para></entry> </row> + <row> + <entry><literal>Python variable:name of the event</literal></entry> + <entry><para>The name of the event (such as <literal>RequestNode</literal>) + is stored in the specified Python variable</para></entry></row> + <row> + <entry><literal>Python variable:generated data</literal></entry> + <entry><para>This Python variable may not receive a value (and will be set +to <literal>None</literal>), but sometimes will get a value, to be used in +subsequent elements of this graph. One example is when the user requests a node +from a remote &sofaswitch; entity. The received node id will +be stored in this variable. Alternatively, DTMF data received from a remote +&sofaswitch; entity will be stored in this +variable.</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</sect1> + + +<sect1> +<title>Trivial transfer audio</title> +<para> +Key to the operation of &sofaswitch; is the ability to move +audio from one entity to another. This audio passes directly betweeen +entities, and does not go via the server. The &sofaswitch; +entities themselves worry about the transport of the data. The trivial example in +figure <xref linkend="trivialtransferexample"/> shows the transfer of audio from +the sound entity back to the sound entity. Consequently, audio that is captured +at the mic will be directed to the speaker. The sound entity has therefore been told to +talk to itself. +<figure id="trivialtransferexample"> +<title>Trivial example of the transfer of audio</title> +<mediaobject> +<imageobject> +<imagedata fileref="trivialtransfer.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</figure> +</para> + +<para> +In this example, there is no request process for a "sound" entity. The code +just assumes a "sound" entity is there, and writes directly to it. Should this +assumption be wrong, and "sound" is not available, there will be no error. The +message server will receive the transfer request, and silently drop it on the +floor. +</para> + +<para> +There is no limit on the when the transfer media request is sent, or on how +many are sent. Thus, as the call progresses, one can transfer media to an +answering machine (to record audio/play a message), conference device or to an +outgoing voip/tdm call. In this way, one can build a full IVR system by +connecting the audio stream to different objects as required. +</para> +</sect1> + + +<sect1> +<title>Transfer audio, and timer example</title> +<para> +We describe the handling of events in this section, with a simple example. +Consider the figure <xref linkend="amtestexample"/>. +<figure id="amtestexample"> +<title>Example of audio transfer between &sofaswitch; nodes, +and timers.</title> +<mediaobject> +<imageobject> +<imagedata fileref="amtest.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</figure> +</para> + +<para> +This graph connects an answering machine node to the sound card node. The +answering machine node, on creation, is asked to record audio from the sound +card, and send audio to the sound card. When DTMF character is received from +the sound card, or node termination event occurs, the test is ended. On test +end, the sound card is asked to direct audio to itself, and a timer is started. +</para> + +<para> + The timer is a mechanism to stop the immediate handling of items on this +graph, and all outstanding messages are sent, and events are handled. Thus, the +message to the sound entity is actually sent. On the timer completing, death +happens and this graph is closed down. +</para> +</sect1> +</chapter> Added: sofaswitch/trunk/callflow/docs/chap3.sgml ============================================================================== --- (empty file) +++ sofaswitch/trunk/callflow/docs/chap3.sgml Fri Jun 8 00:05:34 2007 @@ -0,0 +1,1583 @@ +<chapter> +<title>Description of each control box in &callflow;</title> +<para> +Each of the available control structures in the &callflow; +program is described in this section. In particular, the different parameters +available are explained. Posible applications for each control box are given, +to aid the user in deciding which one to use. +</para> + +<para> +All of the control structures in this application have optional parameters. +Usually, these are strings, with no quotes required, and this is the case for +parameters such as tool tips. Sometimes, the parameters are labelled as being +Python code. In this case, you can specifiy a Python variable, so a possible +value could be <literal>self.amNode</literal>. Alternatively, you can specify +a string, which is indicated by placing double quotes at either end. Which +makes <literal>"voip"</literal> an example of valid string Python code. +</para> + + + + +<sect1> +<title>Conditional execution</title> +<para> +Consider the figure <xref linkend="conditionalicon"/> which shows the icon +and graph representation of the control structure used to direct the flow of +execution, given the outcome of a Python statement. +<figure id="conditionalicon"> +<title>Conditonal control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject><imageobject> + <imagedata fileref="../html/ControlsIf.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject></mediaobject> +</para></entry> +<entry><para> +<mediaobject><imageobject> +<imagedata fileref="../html/conditional.png" align="center" format="PNG"></imagedata> +</imageobject></mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +This control structure will execute the user supplied Python code, and direct +the flow of execution to the bottom (true result) or right (false result). +</para> + +<para> + It is valid to connect the output of this control structure to another +structure, even though the destination structure is already connected +elsewhere. In this case, the flow of execution is not amiguous. +</para> + +<para> +The code that is evaluated (to determine which way to go) is not evaluated +until the compiled graph is executed. Should the condition test generate an +exception when it is evaluated, a message will be printed and the flow of +execution moves to the false direction. +</para> + + +<para> +The Conditional control structure, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain a description of the test to be completed. +</para></entry></row> + +<row> <entry><literal> Test (Python code) +</literal></entry> +<entry><para> +The Python code that generates a <literal>true</literal> or +<literal>false</literal> value is entered here. The code has access to all the +variables defined previously while processing the current graph. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + +<sect1> +<title>Death - terminate processing of this graph</title> +<para> +Consider the figure <xref linkend="deathicon"/> which shows the icon +and graph representation of the control structure used to immediately terminate +all processing of this graph. +<figure id="deathicon"> +<title>Death control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../bitmaps/death.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Death.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +On evaluation of the compiled code, execution of all elements in this graph +is terminated. All current or pending events are ignored. All outstanding +timers are ignored. Messages which have been defined to be sent out (such as +termination of a remote node) are dropped. +</para> + +<para> +If the graph which executes the death control structrue is the one launched +from the command line, it is applied to all graphs. However, if this is a child +graph (launched from a "load new graph" control structure), then death only +applies the child graph. Consequently, the parent graph can receive incoming +calls, and send all incoming calls to multiple child graphs. Each child graph +may execute the death control structure, and not influence the other calls. +</para> + +<para> +The outcome of executing this control structure is very simple - it will remove +the id associated with this graph (<literal>self.myId</literal>) from the +server. +</para> + +<para> +The death control structure, on selecting the right mouse button, brings up a properties +box that has one field +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain some meaningful comment about the +circumstances around the shutdown, or perhaps leave this field blank. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + +<sect1> +<title>End a call</title> +<para> +Consider the figure <xref linkend="endcallicon"/> which shows the icon +and graph representation of the control structure used to end a call, or +terminate a &sofaswitch; node. Thus, you could use this +control structure to terminate a voip call or close down an answering machine +worker node. +<figure id="endcallicon"> +<title>End call control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/endcall.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/EndCall.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +This control structure causes the remote worker node to die. Thus, one would +hangup the call, and then create a new worker node to make a new call. There +is no intention of allowing a voip node (say) to make multiple consequetive +calls. The code is build around "One node, one call". +</para> + +<para> +Created nodes from the answering machine, and conference room will, once they +have passed the intial "use in 2 seconds timeout", endeavour to live +forever. There is no automatic means of destroying these nodes. On graph +closedown, these nodes are not deleted - some other graph might have taken +control of the nodes. To remove these created nodes, one has to use this +control structure. +</para> + +<para> +The end call control structure, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain information about the worker node to +be closed down. +</para></entry></row> + +<row> <entry><literal>Worker node for termination (Python code) +</literal></entry> +<entry><para> +This field describes the identity of the remote node that is to be +terminated. If the value could not be evaluated, there will be a +warning message on running the generated Python code. If the supplied value +does not match any node in existance, nothing will happen - the message server +will silenty drop the termination message. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + + + +<sect1> +<title>Event collection and registration</title> +<para> +Consider the figure <xref linkend="eventicon"/> which shows the icon +and graph representation of the control structure used to collect events, and register +for events. +<figure id="eventicon"> +<title>Event control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/eventer.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Eventer.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +This control structure is central to the processing of each graph. With this +item, we have made it possible for the system to respond to network and timer +events. Further, this structure provides a general means of registering to +receive an event. Multiple event control structrures can be on a graph, where +each structure waits for a different event. +</para> + +<para> +In our implementation, events are collected in the background, and then +processed after execution has fallen into a "Suspend Processing" box, which is +described below. +</para> + +<para> +The Event control structure has two outputs: +<itemizedlist> + <listitem><para>On the right, which is where execution goes after registering for an + event.</para></listitem> + <listitem><para>On the bottom, which is where execution returns to after detecting the + event. This output is labelled with a star on the graph page.</para></listitem> +</itemizedlist> +</para> + + + +<para> +The Event control structure, on selecting the right mouse button, brings up a properties +box that has multiple fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain a description of the event sought. +</para></entry></row> + +<row> <entry><literal>Event sought (Python code)</literal></entry> +<entry><para> +Either this, or the next element on this table, should be filled in. The code +is evaluated, which should produce a string. This string is treated as a +regular expresssion, and compared with the available events. +</para></entry></row> + +<row> <entry><literal>Event sought(Regular Exp)</literal></entry> +<entry><para> +This string is treated as a +regular expresssion, and compared with the available events. Thus, the string +<literal>DTMF</literal> will match all strings containing these letters, from +all nodes in this graph. +</para></entry></row> + +<row> <entry><literal>Python variable: source of the event</literal></entry> +<entry><para> +Describes the identity of the &sofaswitch; node that +generated the event. In the case of a Timer event, it will be set to <literal>None</literal>. +</para></entry></row> + +<row> <entry><literal>Python variable: name of the event</literal></entry> +<entry><para> +This Python variable describes the name of the event that has occurrd +</para></entry></row> + +<row> <entry><literal>Python variable: generated data +</literal></entry> +<entry><para> +Contains any associated data with the event. So, for <literal>DTMF</literal> it +will contain the detected stream of characters. For an incoming voip call, it +will contain the identity of the remote person who made the call. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> +</para> + +<para> + When this structure is first entered, to register to receive an event, all of +the Python variables listed in the above table are initialised to +<literal>None</literal>. +</para> +</sect1> + + + + + + + + + +<sect1> +<title>Join items</title> +<para> +Consider the figure <xref linkend="joinlinesicon"/> which shows the icon +representation of the control structure used to +<figure id="joinlinesicon"> +<title>Join control element</title> +<informaltable frame="none"> +<tgroup cols="1"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/joinlines.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> </row> +<row><entry><para>icon </para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +Items on the drawing screen may be joined directly - one to another, or joined +with this structure, which is multiline segment object. Select the toolbar +icon, move to the drawing area, and left click to mark the points on the shape +and complete with the right mouse button. Once completed, you may move the +shape by selecting it with the left button or shift left to select multiple +objects. +</para> + +<para> +When there is a valid connection at both ends of this object, a filled black +circle is drawn at each end. Attempting to connect the outputs of two control +structures together is not valid, and no filled black circles will be drawn. +</para> + +<para> +It is entirely valid to have the output of several items connected to one +item. There is no ambiguity over where the flow of execution should +go. However, connecting the output of one control item to multiple other +control items is incorrect, as the correct direction for execution is not +determinable. +</para> + + + +<para> +The join items object, on selecting the right mouse button, brings up a properties +box that has one fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain comment about the logic +flow. Alternatively, you could clear this field to minimise the amount of +displayed text to the screen. +</para></entry></row> +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + + + + + +<sect1> +<title>Load new graph</title> +<para> +Consider the figure <xref linkend="loadnewgraphicon"/> which shows the icon +and graph representation of the control structure used to load a new graph file +into the currently running Python executable. +<figure id="loadnewgraphicon"> +<title>Load new graph control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/newgraph.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/loadnewgraph.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + + +<para> +This item provides the means to extend one graph so that it can launch child +processes. It is similar to the C command <literal>system</literal>, except +that control returns immediately to the parent process and does not wait for +execution to finish in the child process. +</para> + +<para> +It is not similar to threads in C, as the child process does not have access to +the memory of the parent process. Nor is it similar to +<literal>fork()</literal> in C, as there is no duplication of the parent +process. +</para> + +<para> +As a convenience, the child process always has a Python variable, +<literal>self.parentId</literal> defined, which contains the id of the child +process. The child may send a message (via the server) to the parent Id +indicating status. The variable <literal>self.parentId</literal> is +<literal>None</literal>, if there is no parent. +</para> + +<para> +The load new graph control object, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain information about the purpose of the +child graph. +</para></entry></row> + +<row> <entry><literal>new graph file (Python code)</literal></entry> +<entry><para> +Specifies the path and directory to the new graph file. The default path is the +directory of the currently running Python executable. +</para></entry></row> + +<row> <entry><literal>Python variable to pass to the child</literal></entry> +<entry><para> +One Python variable (which may be a list) is past to the child graph. This +(typically) would contain the id of &sofaswitch; worker +nodes that are in existance which are available to do any desired task. +</para></entry></row> + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + + + + +<sect1> +<title>Make a call</title> +<para> +Consider the figure <xref linkend="makecallicon"/> which shows the icon +and graph representation of the control structure used to cause a +&sofaswitch; entity to initiate a TDM or voip call. +<figure id="makecallicon"> +<title>Make call control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/makecall.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/MakeCall.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +One possible call destination that was used during testing is the voip node +itself. I setup multiple concurrent incoming and outgoing calls, simply by +getting the voip node to make a call to "h323:127.0.0.1". +</para> + + +<para> +The Make a call control object, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain information about the destination of +this call. +</para></entry></row> + +<row> <entry><literal> +Worker node to activate (Python code) +</literal></entry> +<entry><para> +The worker node is a preexisting node on some external application that was +created in response to a "Request Node" operation. Causing the node to make a +call will mark the node as in use, and it will not be destroyed 2 seconds after creation. +</para></entry></row> + +<row> <entry><literal> +Call destination (Python code) +</literal></entry> +<entry><para> +The call destination is somewhere capable of receiving a call. For a voip +call, one possible destination is the H323 test site set up by Craig +Southeren, which is given as "h323:h323.voxgratia.org" +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> +</para> + +</sect1> + + + + + + + + +<sect1> +<title>Execute arbitrary Python command</title> +<para> +Consider the figure <xref linkend="Pythonicon"/> which shows the icon +and graph representation of the control structure used to define and execute an +arbitrary Python command. +<figure id="Pythonicon"> +<title>Execute arbitrary Python code control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Python.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Python.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +The Python code that is executed is carried out within a +<literal>try..except</literal> environment, so graph execution is not stopped if +the code is faulty. Further, quote marks (<literal>"</literal>) are +correctly managed, so a valid code statement would be +<literal>print "Id of this instance is ", self.myId</literal> +</para> + +<para> +The arbitrary Python code control object, on selecting the right mouse button, +brings up a properties box that has multiple fields which are described in the +table below. This control object is ideal for debugging, and can contain Python +print statements to report on values stored in variables or program status, or +when events have been detected. +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain a comment about the purpose of the +Python code +</para></entry></row> + +<row> <entry><literal> +Python code +</literal></entry> +<entry><para> +The arbitrary Python code which is to be executed. You have access to all the +internal variables used in the execution of this graph. It is possible to +simply put a print statement in there as a debugging technique. It is +encouraged that you put short, quickly executed statements here, as all other +actions are suspended while processing this item. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> +</para> + +<para> +When the Python executable processes a graph file, the following variables are +available for the user to access. Sometimes, it is helpful to include a print +statement in development graphs to report on these variables. The user may +modify these variables (at their own peril) to give interesting results. For +example, one could modify <literal>self.data[a]</literal> to control which node +in the graph is executed next. + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal>self.data[a]</literal></entry> +<entry><para> + The data structure describing this node on the graph. +</para></entry></row> + +<row> <entry><literal>self.pendingEvents</literal></entry> +<entry><para> +Holds the name of timers waiting to expire. +</para></entry></row> + +<row> <entry><literal>self.isMaster</literal></entry> +<entry><para> +Boolean flag, if this graph is generated directly from the command line. +</para></entry></row> + +<row> <entry><literal>self.parentId</literal></entry> +<entry><para> +The id assigned to the parent graph by the server, or <literal>None</literal> +(if this graph is generated directly from the command line). +</para></entry></row> + +<row> <entry><literal>self.myId</literal></entry> +<entry><para> +The id assigned to this graph by the server. +</para></entry></row> + +<row> <entry><literal>self.currentHandlers</literal></entry> +<entry><para> +List of registered handlers, which is populated by the Eventer control +structure. +</para></entry></row> + +<row> <entry><literal>self.generatedEvents</literal></entry> +<entry><para> +A list of events we have to examine at the next opportunity. This list will +include expired timers and packets from the network. +</para></entry></row> + +<row> <entry><literal>self.keepGoing</literal></entry> +<entry><para> +A flag to indicate that we should keep working along this graph. If set to +<literal>false</literal> , it is equivalent to processing a Suspend Processing. +</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> + + +</sect1> + + + + + +<sect1> +<title>Read from file</title> +<para> +Consider the figure <xref linkend="readfromfileicon"/> which shows the icon +and graph representation of the control structure used to request an answering +machine node to read audio from a S16_LE wav file. Audio read from the wav file +is sent to the node designated by previous/subsequent transfer media commands. +<figure id="readfromfileicon"> +<title>Read from file control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/readfromfile.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/playfromfile.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +You may switch an answering machine node to read from a different file at any time. +Multiple answering machine nodes may read from the same file at the same time. +</para> + +<para> +Should you specify an invalid file to read from no audio will be sent by this +worker node. +</para> + +<para> +You may specify the file to read from at any time after the creation of the +answering machine worker node. +</para> + +<para> +As noted before, if a requested node from the &sofaswitch; +entity answering machine is not used in the 2 second period after creation, it +is silently destroyed. Issuing this command will stop the destruction, and mark +the created node as being "in use" +</para> + +<para> +The eblank object, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain +</para></entry></row> + +<row> <entry><literal> +</literal></entry> +<entry><para> +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + + +<sect1> +<title>Request node</title> +<para> +Consider the figure <xref linkend="requestnodeicon"/> which shows the icon +and graph representation of the control structure used to request a worker node +from a &sofaswitch; entity. +<figure id="requestnodeicon"> +<title>Request node control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/RequestNode.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/requestnode.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +Request Node is a key component of the SofaSwitch suite of applications. With +this item, the controller asks the designated application to supply one worker +node for use by this call graph. Alternatively, this is the mechanism by which +this call graph gets remote entities who can handle media data. +</para> + +<para> +Once created, the requested worker has a lifetime of 2 seconds. This lifetime is +set by the designated application. If the requested worker is not acknowledged +after 2 seconds, it is silently destroyed by the designated application. +</para> + +<para> +On receiving advise the node has been created, and its identity, this call +graph can advise the node to <literal>transfer media to itself</literal>. Once +this command is made, the requested node is safe from death by timeout. +</para> + +<para> +In most cases, the controlling entity is required to request a node before +using the node. This is certainly the case for the answering machine and +conference server. However, when dealing with an incoming call (voip/tdm etc), +the process is changed slightly. The remote &sofaswitch; +entity is required to create a node to deal with the incoming call. The +controller is then advised of the incoming call, and the id of the newly +created node. From this point, the controller deals with the incoming call by +communicating directly with the newly created node. +</para> + +<para> +The request node object, on selecting the right mouse button, brings up a +properties box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain the destination +&sofaswitch; entity, timer duration, and or what this node +is required for. +</para></entry></row> + +<row> <entry><literal> +Request node from (Python code) +</literal></entry> +<entry><para> +Specifies the &sofaswitch; entity that will supply the worker node. +</para></entry></row> + +<row> <entry><literal> +Timer period (seconds) +</literal></entry> +<entry><para> +This Python code specifies the maximum time we are prepared to wait for an +answer to our requests. A float value of <literal>1.4</literal> indicates 1400 +milliseconds. If there is no response in the specified time period, we have an +indication the remote node is "dead". +</para></entry></row> + +<row> <entry><literal> +Timer label +</literal></entry> +<entry><para> +This label is used in the eventer structure, and "fires" when there has been no +answer in the specified time period. +</para></entry></row> + +<row> <entry><literal> +Additional information (Python code) +</literal></entry> +<entry><para> +The additional information field is used to provide details that some +&sofaswitch; applications want. For example, the conference +utility needs information on which room the requested node should be in. +</para></entry></row> + + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + +<sect1> +<title>Start for loop</title> +<para> +Consider the figure <xref linkend="StartForLoopIcon"/> which shows the icon +and graph representation of the control structure used to begin a <literal>for +loop</literal>. +<figure id="StartForLoopIcon"> +<title>Start for loop control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Controlsfor.png" align="center" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/startfor.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + + +<para>It is entirely up to the user what the initialisation, increment and +completion code actually is. Consequently, one may create an infinite for +loop with ease. Further, it is acceptable to have flow paths that break out of +the for loop without completing all preset loops.</para> + +<para> +It is worth nothing that the initialisation, increment, and termination +condition are Python code that is not tested until this code is used to manage +different &sofaswitch; entities. Thus, if you have +supplied invalid Python code, an error message will be printed and operation +will attempt to continue. The termination condtion will, in the case of an +error, evaluate to TRUE, and execution will move past the end of the loop. +</para> + +<para> +The for loop control object, on selecting the right mouse button, brings up a properties +box that has multiple fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain information about the loop counter, +intitialisation and termination. +</para></entry></row> + +<row> <entry><literal> +Initialise (Python code) +</literal></entry> +<entry><para> +The Python code which initialises the loop variable. It is wise to create a +variable that is stored in the class representing this graph, so the text +<literal>self.</literal> is at the beginning of the variable name. +</para></entry></row> + +<row> <entry><literal> +Test for terminatin (Python code) +</literal></entry> +<entry><para> +This test should evaluated to <literal>true</literal> or +<literal>false</literal>. By making this test always resulting in +<literal>true</literal> one has an infinite loop. +</para></entry></row> + +<row> <entry><literal> +Increment (Python code) +</literal></entry> +<entry><para> +This code is designed to increment the Python variable. One may leave this +field empty for special loop types. Thus, the loop could be set up to loop for +a period of time, not number of iterations. +</para></entry></row> + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + +<sect1> +<title>Start graph processing</title> +<para> +Consider the figure <xref linkend="graphprocessicon"/> which shows the icon +and graph representation of the control structure used to initiate processing +of this graph. +<figure id="graphprocessicon"> +<title>Start graph processing control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/Controlsstart.png" align="right" scale="300" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/startflow.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + + +<para> +When this graph is processed, this item indicates that a new identity on the +server will be created, for each control structure on this graph to communicate +with. Thus, on instantiation, this graph will be identified as identity +<literal>c290</literal> (say). Any messages sent via the server will be +labelled as being sent by <literal>c290</literal>. +</para> + +<para> +It is mandatory that there is only one of these items on each graph. Placing +more than Start of graph processing item on the drawing area is ambiguous - +where would call processing start ? +</para> + + + +<para> +The initiate graph processing object, on selecting the right mouse button, brings up a properties +box that has one fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain text describing the purpose of this graph. +</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</sect1> + + + + + +<sect1> +<title>Suspend graph processing</title> +<para> +Consider the figure <xref linkend="suspendprocessingicon"/> which shows the icon +and graph representation of the control structure used to suspend the +processing of the graph. +<figure id="suspendprocessingicon"> +<title>Suspend graph processing control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/ControlsEndHere.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="current/endflow.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +This control structure is provided as a means for temporarily holding up graph +processing, while we wait for external events. If processing does fall into +here, external events will move graph processing to an Event Collection item as +required. Note that if graph processing was such that some events were never +registered for, then execution will be permanently stuck in this control structure. +</para> + +<para> +When execution is in the Suspend graph processing control +structure, waiting for an event to happen, there is no CPU penalty. +</para> + +<para> +The Suspend graph processing control structure, on selecting the right mouse button, brings up a properties +box that has one field, + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you could extend this to contain the event being waited on. +</para></entry></row> + +</tbody> +</tgroup> +</informaltable> + + +</para> +</sect1> + + + + + + + +<sect1> +<title>Timer</title> +<para> +Consider the figure <xref linkend="timericon"/>, which contains the toolbar icon +and graph represeentation of the control structure used to create a timer. +<figure id="timericon"> +<title>Timer control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/miniclock.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/starttimer.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row></tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +The timer object, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool Tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to describe the purpose of this timer, or duration. +</para></entry></row> +<row> <entry><literal> +Timer period (seconds, Python code) +</literal></entry> +<entry><para> +The time period is specified in units of seconds. You may use a floating point +number here with an exponent, or a Python variable. Thus, one would specify a +delay of 1200 milliseconds as <literal>1.2</literal>. +</para></entry></row> +<row> <entry><literal> +timer label (Python code) +</literal></entry> +<entry><para> +This text is used to determine which timer has fired that is on this graph. The +eventer control structure should be told to match on this string (or a +substring), when waiting for an event. +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> + +<para> +Timer events which are +generated when processing a different graph are never passed to this +graph. Consequently, if you have multiple instances of this graph in operation, +the same label (to identify the timer) can be used. +</para> + +<para> +As before, note that expired timers are not detected until the flow of +execution has been suspended, or paused. +</para> + +</sect1> + + + + + + + + + +<sect1> +<title>Transfer of audio between two &sofaswitch; entities</title> +<para> +Consider the figure <xref linkend="transfermediaicon"/>, which shows the icon +and graph representation of the control structure used to enable the flow of audio between +two &sofaswitch; entities. +<figure id="transfermediaicon"> +<title>Transfer audio control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/transfermedia.png" align="right" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="current/TransferMedia.png" align="left" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +One possible use is when we wish to record an incoming voip call. In this case, +we will request and create a voip and an answering machine node. Then, issue this +command to one of the two created nodes. It is not our responsibility to worry +abount media format, or ports/addresses. It is our responsibility to issue the +connect command. +</para> + +<para> +Alternatively, suppose we wish to connect one TDM (standard phone line) call +to another TDM call. In this case, both TDM worker nodes happen to be on the +same machine, via the same phone card. On reception of the Transfer Media +command, the nodes will do a direct bridging of the audio between them. +</para> + +<para> +After requesting a node, it stays in existance for 2 seconds. If it is not used +in that time, the worker node is silently deleted. One +way of preventing that death is to do a Transfer Media command to that node +just created. If the recipient node is not ready, one can do a transer media +request to a non existant node. This will keep the requested node in existance, +and the person at the other end will not hear an eacho. +</para> + +<para> +The transfer audio object, on selecting the right mouse button, brings up a properties +box that has multiple fields +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool Tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain a description of the two nodes that +will be connected +</para></entry></row> + +<row> <entry><literal> +First SofaSwitch worker(Python) +</literal></entry> +<entry><para> +This text is evaluated as Python code, and specifies one of the two entities +which is to connect audio. +</para></entry></row> + +<row> <entry><literal> +Second SofaSwitch worker(Python) +</literal></entry> +<entry><para> +This text is evaluated as Python code, and specifies the second of the two entities +which is to connect audio. +</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</sect1> + + + + + +<sect1> +<title>Write to file</title> +<para> +Consider the figure <xref linkend="writetofileicon"/>, which shows the icon +and graph representation of the control structure used to cause the answering +machine to write incoming audio to a file. +<figure id="writetofileicon"> +<title>Write to file control element</title> +<informaltable frame="none"> +<tgroup cols="2"> +<tbody> +<row><entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="../html/writetofile.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry> +<entry><para> +<mediaobject> +<imageobject> +<imagedata fileref="current/recordtofile.png" align="center" format="PNG"></imagedata> +</imageobject> +</mediaobject> +</para></entry></row> +<row><entry><para>icon </para></entry> + <entry><para>graph representation</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</figure> +</para> + +<para> +This control structure causes the designated answering machine node to write +audio to the wave file (format S16_LE). +</para> + +<para> +You may switch an answering machine node to write to a different file at any +time. On switching files, the answering machine node will close the current +file and attempt to use the new file. It is valid to set the file name to the +same value. In this case, the old recorded data is lost, and audio is written +to the beginning of the current file. +</para> + +<para> +Should you specify an invalid file to write to, no audio will be written. +</para> + + +<para> +The write to file control object, on selecting the right mouse button, brings up a properties +box that has multiple fields + +<informaltable frame="all"> +<tgroup cols="2"> +<tbody> + +<row> <entry><literal> +Tool Tip +</literal></entry> +<entry><para> +The text which is displayed when the mouse hovers over this object for 3 seconds. +Ideally, you should extend this to contain information about the destination +file, or other meaningful details. +</para></entry></row> + +<row> <entry><literal> +Filename to contain new audio (Python code) +</literal></entry> +<entry><para> +This Python code specifies the filename and directory of the file to write +audio to. The directory path specification is relative to the directory in +which the answering machine entity was run from. +</para></entry></row> + +<row> <entry><literal> +Answering machine node (Python code) +</literal></entry> +<entry><para> +This Python code describes the id of the answering machine worker node that we +control. The answering machine node would have been created by a "Request node" command. +</para></entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</sect1> + + +</chapter>