sofaswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
June 2007
- 1 participants
- 69 discussions
22 Jun '07
Author: derek
Date: Thu Jun 21 21:35:27 2007
New Revision: 333
Modified:
sofaswitch/trunk/callflow/tests/for_if_loop.src
sofaswitch/trunk/callflow/tests/loadgraph.src
sofaswitch/trunk/callflow/tests/makevoipcall.src
Log:
Modify and tidy graphs.
Modified: sofaswitch/trunk/callflow/tests/for_if_loop.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/for_if_loop.src (original)
+++ sofaswitch/trunk/callflow/tests/for_if_loop.src Thu Jun 21 21:35:27 2007
@@ -1 +1 @@
-9<B>250<B>198<B>250,254,326,198<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>280<B>138<B>280,144,326,138<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>250<B>222<B>255,222,250,254<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>234<B>29<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>10<B>310<B>138<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "greater than (or equal to) 5", self.i<ms><special> <B><Shape>3<B>225<B>75<B> extra <special>Tool Tip<ms>Start For<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 10<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>9<B>218<B>100<B>225,100,218,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>239<B>162<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "less than five ", self.i<ms><special> <B><Shape>5<B>230<B>119<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.i < 5<ms><special> <B><Shape>4<B>218<B>254<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>20<B>239<B>301<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>
+9<B>129<B>142<B>161,142,161,142,129,142,129,307,162,308<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>177<B>221<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "less than five ", self.i<ms><special> <B><Shape>1<B>168<B>70<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>10<B>206<B>194<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "greater than (or equal to) 5", self.i<ms><special> <B><Shape>4<B>162<B>283<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>9<B>194<B>254<B>222,254,222,279,194,283<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>168<B>170<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.i < 5<ms><special> <B><Shape>20<B>182<B>329<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>3<B>161<B>117<B> extra <special>Tool Tip<ms>Start For<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 10<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/loadgraph.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/loadgraph.src (original)
+++ sofaswitch/trunk/callflow/tests/loadgraph.src Thu Jun 21 21:35:27 2007
@@ -1 +1 @@
-10<B>390<B>181<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have generated the new graph on loop counter", self.i<ms><special> <B><Shape>18<B>381<B>127<B> extra <special>Tool Tip<ms>Load New Graph<ms><special>new graph file (Python code)<ms>"child.graph"<ms><special>Python variable to pass to child<ms>self.i<ms><special> <B><Shape>4<B>372<B>238<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>9<B>322<B>107<B>374,107,322,107,322,260,372,263<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>20<B>392<B>420<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>3<B>374<B>82<B> extra <special>Tool Tip<ms>Start For - to make lots of graphs<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 3<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>1<B>379<B>35<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>9<B>443<B>356<B>443,356,500,356,538,356<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>510<B>356<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>393<B>334<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>thistimer<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>12<B>381<B>280<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds, Python code)<ms>1<ms><special>Timer label (Python code)<ms>"thistimer"<ms><special> <B><Shape>10<B>389<B>373<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "end the master now"<ms><special> <B><Shape>
+10<B>392<B>482<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "end the master now"<ms><special> <B><Shape>4<B>372<B>238<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>3<B>374<B>82<B> extra <special>Tool Tip<ms>Start For - to make lots of graphs<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 3<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>10<B>388<B>336<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Wait for children to finish "<ms><special> <B><Shape>14<B>396<B>443<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>thistimer<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>18<B>381<B>127<B> extra <special>Tool Tip<ms>Load New Graph<ms><special>new graph file (Python code)<ms>"child.graph"<ms><special>Python variable to pass to child<ms>self.i<ms><special> <B><Shape>12<B>378<B>283<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds, Python code)<ms>1<ms><special>Timer label (Python code)<ms>"thistimer"<ms><special> <B><Shape>9<B>322<B>107<B>374,107,322,107,322,260,372,263<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>513<B>469<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>10<B>390<B>385<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " "<ms><special> <B><Shape>10<B>390<B>181<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have generated the new graph on loop counter", self.i<ms><special> <B><Shape>20<B>395<B>529<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>1<B>379<B>35<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>9<B>444<B>468<B>444,468,501,468,539,468<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/makevoipcall.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/makevoipcall.src (original)
+++ sofaswitch/trunk/callflow/tests/makevoipcall.src Thu Jun 21 21:35:27 2007
@@ -1,4 +1,4 @@
-9<B>165<B>334<B>165,598,174,656,394,653,401,334,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>155<B>205<B>155,206,215,205<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>200<B>207<B> extra <special>Tool Tip<ms>wait for arrival of sound node<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>soundREQ<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.soundNode<ms><special> <B><Shape>9<B>203<B>527<B>203,527,248,528<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>140<B>548<B> extra <special>Tool Tip<ms>Test for dtmf data of "9"<ms><special>Test (Python code)<ms>self.dtmfData=="9"<ms><special> <B><Shape>14<B>102<B>185<B> extra <special>Tool Tip<ms>have a voip node from the voip module<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>voipREQ<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.voipNode<ms><special> <B><Shape>14<B>552<B>256<B> extra <special>Tool Tip<ms>test timer on request of voip<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestvoip<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>13<B>90<B>229<B> extra <special>Tool Tip<ms>Stop Timer on the voip request<ms><special>Timer to stop<ms>requestvoip<ms><special> <B><Shape>15<B>141<B>457<B> extra <special>Tool Tip<ms>Transfer Media between the voip and sound node<ms><special>First SofaSwitch worker (python)<ms>self.voipNode<ms><special>Second SofaSwitch worker (python)<ms>self.soundNode<ms><special> <B><Shape>20<B>312<B>286<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>2<B>263<B>551<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>10<B>99<B>268<B> extra <special>Tool Tip<ms>report we have a voip node<ms><special>Python Code<ms>print "Have a new voip node on ", self.voipNode<ms><special> <B><Shape>19<B>226<B>667<B> extra <special>Tool Tip<ms>Send Dtmf to the voip node<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>DTMF to send to worker node (python code)<ms>self.dtmfData<ms><special> <B><Shape>14<B>589<B>280<B> extra <special>Tool Tip<ms>Test timer on request of sound<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestsound<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>13<B>189<B>250<B> extra <special>Tool Tip<ms>Stop Timer on the request for a sound node<ms><special>Timer to stop<ms>requestsound<ms><special> <B><Shape>14<B>310<B>232<B> extra <special>Tool Tip<ms>Wait for timer, which
-indicates end everything<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>endeverything<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>2<B>445<B>470<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>235<B>528<B> extra <special>Tool Tip<ms>Wait for voip call to end<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>Terminating<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>9<B>190<B>573<B>190,573,246,621,251,667<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>7<B>447<B>383<B> extra <special>Tool Tip<ms>End Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special> <B><Shape>11<B>88<B>95<B> extra <special>Tool Tip<ms>Request voip node<ms><special>Request node from (Python code)<ms>"voip"<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestvoip<ms><special>Additional information (Python code)<ms><ms><special> <B><Shape>22<B>97<B>52<B> extra <special>Tool Tip<ms>Register for events from voip node<ms><special>Node to receive events from (Python code)<ms>"voip"<ms><special> <B><Shape>1<B>88<B>9<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>14<B>153<B>505<B> extra <special>Tool Tip<ms>Wait for DTMF data<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.dtmfData<ms><special> <B><Shape>15<B>448<B>338<B> extra <special>Tool Tip<ms>Make sound node
-talk to itself<ms><special>First SofaSwitch worker (python)<ms>"sound"<ms><special>Second SofaSwitch worker (python)<ms>"sound"<ms><special> <B><Shape>9<B>250<B>229<B>250,229,325,229<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>360<B>254<B>360,254,567,254<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>166<B>354<B>215,354,166,357<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>115<B>328<B>115,328,166,357<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>473<B>330<B>602,330,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>12<B>446<B>426<B> extra <special>Tool Tip<ms>Timer which initates a shutdown, after some tidyup
- messages etc have been sent.<ms><special>Timer period (seconds, Python code)<ms>1<ms><special>Timer label (Python code)<ms>"endeverything"<ms><special> <B><Shape>9<B>248<B>325<B>248,578,380,580,384,325,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>165<B>598<B>165,598,174,660<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>6<B>141<B>406<B> extra <special>Tool Tip<ms>Make Call to a remote entity<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>Call destination (python code)<ms>self.scriptArgs<ms><special> <B><Shape>9<B>473<B>306<B>565,306,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>191<B>382<B>191,382,237,383<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>199<B>294<B> extra <special>Tool Tip<ms>report we have a sound node<ms><special>Python Code<ms>print " have a sound node of ", self.soundNode<ms><special> <B><Shape>11<B>90<B>139<B> extra <special>Tool Tip<ms>Request sound node<ms><special>Request node from (Python code)<ms>"sound"<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestsound<ms><special>Additional information (Python code)<ms><ms><special> <B><Shape>2<B>616<B>300<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>2<B>212<B>383<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>5<B>141<B>357<B> extra <special>Tool Tip<ms>TEST: have a sound and voip node.<ms><special>Test (Python code)<ms>(self.voipNode != None) and (self.soundNode != None)<ms><special> <B><Shape>2<B>228<B>712<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>
+15<B>448<B>338<B> extra <special>Tool Tip<ms>Make sound node
+talk to itself<ms><special>First SofaSwitch worker (python)<ms>"sound"<ms><special>Second SofaSwitch worker (python)<ms>"sound"<ms><special> <B><Shape>9<B>155<B>205<B>155,206,215,205<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>473<B>306<B>565,306,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>12<B>446<B>426<B> extra <special>Tool Tip<ms>Timer which initates a shutdown, after some tidyup
+ messages etc have been sent.<ms><special>Timer period (seconds, Python code)<ms>1<ms><special>Timer label (Python code)<ms>"endeverything"<ms><special> <B><Shape>20<B>312<B>286<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>9<B>473<B>330<B>602,330,473,338<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>11<B>88<B>95<B> extra <special>Tool Tip<ms>Request voip node<ms><special>Request node from (Python code)<ms>"voip"<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestvoip<ms><special>Additional information (Python code)<ms><ms><special> <B><Shape>13<B>90<B>229<B> extra <special>Tool Tip<ms>Stop Timer on the voip request<ms><special>Timer to stop<ms>requestvoip<ms><special> <B><Shape>5<B>140<B>548<B> extra <special>Tool Tip<ms>Test for dtmf data of "9"<ms><special>Test (Python code)<ms>self.dtmfData=="9"<ms><special> <B><Shape>9<B>156<B>338<B>473,338,409,347,413,712,156,711,165,598<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>248<B>338<B>473,338,378,339,380,616,249,618,248,578<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>199<B>294<B> extra <special>Tool Tip<ms>report we have a sound node<ms><special>Python Code<ms>print " have a sound node of ", self.soundNode<ms><special> <B><Shape>7<B>447<B>383<B> extra <special>Tool Tip<ms>End Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special> <B><Shape>13<B>189<B>250<B> extra <special>Tool Tip<ms>Stop Timer on the request for a sound node<ms><special>Timer to stop<ms>requestsound<ms><special> <B><Shape>2<B>168<B>626<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>1<B>88<B>9<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>9<B>203<B>527<B>203,527,248,528<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>19<B>168<B>575<B> extra <special>Tool Tip<ms>Send Dtmf to the voip node<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>DTMF to send to worker node (python code)<ms>self.dtmfData<ms><special> <B><Shape>9<B>191<B>382<B>191,382,237,383<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>141<B>357<B> extra <special>Tool Tip<ms>TEST: have a sound and voip node.<ms><special>Test (Python code)<ms>(self.voipNode != None) and (self.soundNode != None)<ms><special> <B><Shape>14<B>589<B>280<B> extra <special>Tool Tip<ms>Test timer on request of sound<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestsound<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>2<B>445<B>470<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>2<B>616<B>300<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>9<B>115<B>328<B>115,328,166,357<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>102<B>185<B> extra <special>Tool Tip<ms>have a voip node from the voip module<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>voipREQ<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.voipNode<ms><special> <B><Shape>14<B>552<B>256<B> extra <special>Tool Tip<ms>test timer on request of voip<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestvoip<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>14<B>235<B>528<B> extra <special>Tool Tip<ms>Wait for voip call to end<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>Terminating<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>11<B>90<B>139<B> extra <special>Tool Tip<ms>Request sound node<ms><special>Request node from (Python code)<ms>"sound"<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestsound<ms><special>Additional information (Python code)<ms><ms><special> <B><Shape>2<B>263<B>551<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>200<B>207<B> extra <special>Tool Tip<ms>wait for arrival of sound node<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>soundREQ<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.soundNode<ms><special> <B><Shape>9<B>250<B>229<B>250,229,325,229<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>6<B>141<B>406<B> extra <special>Tool Tip<ms>Make Call to a remote entity<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>Call destination (python code)<ms>self.scriptArgs<ms><special> <B><Shape>15<B>141<B>457<B> extra <special>Tool Tip<ms>Transfer Media between the voip and sound node<ms><special>First SofaSwitch worker (python)<ms>self.voipNode<ms><special>Second SofaSwitch worker (python)<ms>self.soundNode<ms><special> <B><Shape>9<B>360<B>254<B>360,254,567,254<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>99<B>268<B> extra <special>Tool Tip<ms>report we have a voip node<ms><special>Python Code<ms>print "Have a new voip node on ", self.voipNode<ms><special> <B><Shape>9<B>166<B>354<B>215,354,166,357<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>212<B>383<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>153<B>505<B> extra <special>Tool Tip<ms>Wait for DTMF data<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.dtmfData<ms><special> <B><Shape>22<B>97<B>52<B> extra <special>Tool Tip<ms>Register for events from voip node<ms><special>Node to receive events from (Python code)<ms>"voip"<ms><special> <B><Shape>14<B>310<B>232<B> extra <special>Tool Tip<ms>Wait for timer, which
+indicates end everything<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>endeverything<ms><special>Python variable: source of the event<ms>self.eventSource<ms><special>Python variable: name of the event<ms>self.eventName<ms><special>Python variable: generated data<ms>self.eventData<ms><special> <B><Shape>
1
0
21 Jun '07
Author: derek
Date: Wed Jun 20 21:03:40 2007
New Revision: 332
Added:
sofaswitch/trunk/callflow/tests/for_if_loop.src
Log:
Add new file to demonstrate if structure
Added: sofaswitch/trunk/callflow/tests/for_if_loop.src
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/tests/for_if_loop.src Wed Jun 20 21:03:40 2007
@@ -0,0 +1 @@
+9<B>250<B>198<B>250,254,326,198<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>280<B>138<B>280,144,326,138<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>250<B>222<B>255,222,250,254<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>234<B>29<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>10<B>310<B>138<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "greater than (or equal to) 5", self.i<ms><special> <B><Shape>3<B>225<B>75<B> extra <special>Tool Tip<ms>Start For<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 10<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>9<B>218<B>100<B>225,100,218,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>239<B>162<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "less than five ", self.i<ms><special> <B><Shape>5<B>230<B>119<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.i < 5<ms><special> <B><Shape>4<B>218<B>254<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>20<B>239<B>301<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>
1
0
20 Jun '07
Author: derek
Date: Wed Jun 20 01:40:29 2007
New Revision: 331
Modified:
sofaswitch/trunk/callflow/src/dnd.cpp
Log:
Make certain connected points are drawn with full solid circles.
Modified: sofaswitch/trunk/callflow/src/dnd.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/dnd.cpp (original)
+++ sofaswitch/trunk/callflow/src/dnd.cpp Wed Jun 20 01:40:29 2007
@@ -753,8 +753,10 @@
ioPointsLinked = false;
- if (style == Connected)
- dc.DrawCircle(locn, 3);
+ if (style == Connected) {
+ dc.SetBrush(wxBrush(*wxBLACK, wxSOLID) );
+ dc.DrawCircle(locn, 3);
+ }
}
void DndShape::DrawBox(wxDC &dc, int xOff, int yOff, int width, int height)
1
0
Author: derek
Date: Tue Jun 19 21:40:42 2007
New Revision: 330
Modified:
sofaswitch/trunk/overview/chap2.sgml
Log:
Put in new log of an outgoing voip call. This log better illustrates
preallocated nodes.
Modified: sofaswitch/trunk/overview/chap2.sgml
==============================================================================
--- sofaswitch/trunk/overview/chap2.sgml (original)
+++ sofaswitch/trunk/overview/chap2.sgml Tue Jun 19 21:40:42 2007
@@ -632,45 +632,70 @@
repeated, because the log below shows incoming and outgoing messages to the
server.
<programlisting>
+20/ 6/2007 10:31:25.582597 Recv New node of voip
+20/ 6/2007 10:31:25.586112 Recv New node of voip1
+20/ 6/2007 10:31:25.586585 Recv New node of voip2
+20/ 6/2007 10:31:25.586962 Recv New node of voip3
+20/ 6/2007 10:31:25.587423 Recv New node of voip4
+20/ 6/2007 10:31:25.587715 Recv New node of voip5
+20/ 6/2007 10:31:25.588115 Recv New node of voip6
+20/ 6/2007 10:31:25.588520 Recv New node of voip7
+20/ 6/2007 10:31:25.588935 Recv New node of voip8
+20/ 6/2007 10:31:25.589782 Recv New node of voip9
+20/ 6/2007 10:31:25.590308 Recv New node of voip10
+20/ 6/2007 10:32:58.645980 Recv New node of sound
+20/ 6/2007 10:33:28. 93320 Recv New node of ?
+20/ 6/2007 10:33:28. 93480 Recv from c1 whoami
+20/ 6/2007 10:33:28. 93556 Send to c1 c1
+20/ 6/2007 10:33:28. 94871 Recv from c1 voip:reporttome
+20/ 6/2007 10:33:28. 95018 Send to voip c1:reporttome
+20/ 6/2007 10:33:28. 95058 Recv from c1 voip:REQUESTNEWID
+20/ 6/2007 10:33:28. 95099 Send to voip c1:REQUESTNEWID
+20/ 6/2007 10:33:28. 95122 Recv from c1 sound:REQUESTNEWID
+20/ 6/2007 10:33:28. 95171 Send to sound c1:REQUESTNEWID
+20/ 6/2007 10:33:28. 95615 Recv from voip AdviseOnTermination c1
+20/ 6/2007 10:33:28. 95652 Recv from voip c1:REQUESTNEWID voip1
+20/ 6/2007 10:33:28. 95699 Send to c1 voip:REQUESTNEWID voip1
+20/ 6/2007 10:33:28. 95837 Recv from voip1 AdviseOnTermination c1
+20/ 6/2007 10:33:28. 95954 Recv from sound AdviseOnTermination c1
+20/ 6/2007 10:33:28. 95982 Recv from sound c1:REQUESTNEWID sound
+20/ 6/2007 10:33:28. 96018 Send to c1 sound:REQUESTNEWID sound
+20/ 6/2007 10:33:28. 96490 Recv New node of voip11
+20/ 6/2007 10:33:28. 99172 Recv from c1 voip1:CALLNODE iax2:guest@conference.freeswitch.org/42
+20/ 6/2007 10:33:28. 99269 Send to voip1 c1:CALLNODE iax2:guest@conference.freeswitch.org/42
+20/ 6/2007 10:33:28. 99296 Recv from c1 voip1:TRANSFERUDP sound
+20/ 6/2007 10:33:28. 99336 Send to voip1 c1:TRANSFERUDP sound
+20/ 6/2007 10:33:28. 99622 Recv from voip1 AdviseOnTermination c1
+20/ 6/2007 10:33:33.754578 Recv from voip1 sound:TRANSFERUDP sound 192.168.1.109:60000
+20/ 6/2007 10:33:33.754679 Send to sound voip1:TRANSFERUDP sound 192.168.1.109:60000
+20/ 6/2007 10:33:33.756003 Recv from sound voip1:TRANSFERUDP sound 192.168.1.108:63000 done
+20/ 6/2007 10:33:33.756074 Send to voip1 sound:TRANSFERUDP sound 192.168.1.108:63000 done
+20/ 6/2007 10:33:34. 39595 Recv from voip1 c1:CallEstablished voip1
+20/ 6/2007 10:33:34. 39690 Send to c1 voip1:CallEstablished voip1
+20/ 6/2007 11:23:22.196723 Send to c1 sound:Terminating
+20/ 6/2007 11:23:22.199184 Recv from c1 sound:TRANSFERUDP sound
+20/ 6/2007 11:23:22.199243 Recv from c1 voip1:HANGUP
+20/ 6/2007 11:23:22.199307 Send to voip1 c1:HANGUP
+20/ 6/2007 11:23:23.200669 Send to c1 voip1:Terminating
+20/ 6/2007 11:23:23.203249 Recv from c1 sound:TRANSFERUDP sound
+20/ 6/2007 11:23:23.203308 Recv from c1 voip1:HANGUP
-19/ 6/2007 9:52:25.980656 Recv New node of sound
-19/ 6/2007 9:52:49.562018 Recv New node of ?
-19/ 6/2007 9:52:49.562316 Recv from c83 whoami
-19/ 6/2007 9:52:49.562376 Send to c83 c83
-19/ 6/2007 9:52:49.570221 Recv from c83 voip:reporttome
-19/ 6/2007 9:52:49.570343 Send to voip c83:reporttome
-19/ 6/2007 9:52:49.570371 Recv from c83 voip:REQUESTNEWID
-19/ 6/2007 9:52:49.570424 Send to voip c83:REQUESTNEWID
-19/ 6/2007 9:52:49.570446 Recv from c83 sound:REQUESTNEWID
-19/ 6/2007 9:52:49.571467 Send to sound c83:REQUESTNEWID
-19/ 6/2007 9:52:49.572196 Recv from sound AdviseOnTermination c83
-19/ 6/2007 9:52:49.572238 Recv from sound c83:REQUESTNEWID sound
-19/ 6/2007 9:52:49.572288 Send to c83 sound:REQUESTNEWID sound
-19/ 6/2007 9:52:49.885411 Recv from voip AdviseOnTermination c83
-19/ 6/2007 9:52:49.965734 Recv from voip22 AdviseOnTermination c83
-19/ 6/2007 9:52:49.966074 Recv from voip c83:REQUESTNEWID voip22
-19/ 6/2007 9:52:49.966137 Send to c83 voip:REQUESTNEWID voip22
-19/ 6/2007 9:52:49.967668 Recv from c83 voip22:CALLNODE iax2:guest@conference.freeswitch.org/42
-19/ 6/2007 9:52:49.967791 Send to voip22 c83:CALLNODE iax2:guest@conference.freeswitch.org/42
-19/ 6/2007 9:52:49.967820 Recv from c83 voip22:TRANSFERUDP sound
-19/ 6/2007 9:52:49.967862 Send to voip22 c83:TRANSFERUDP sound
-19/ 6/2007 9:52:49.976023 Recv from voip22 AdviseOnTermination c83
-19/ 6/2007 9:52:50. 91997 Recv New node of voip32
-19/ 6/2007 9:52:55.641031 Recv from voip22 sound:TRANSFERUDP sound 192.168.1.109:60010
-19/ 6/2007 9:52:55.641122 Send to sound voip22:TRANSFERUDP sound 192.168.1.109:60010
-19/ 6/2007 9:52:55.642802 Recv from sound voip22:TRANSFERUDP sound 192.168.1.108:63000 done
-19/ 6/2007 9:52:55.642878 Send to voip22 sound:TRANSFERUDP sound 192.168.1.108:63000 done
-19/ 6/2007 9:52:56. 74599 Recv from voip22 c83:CallEstablished voip22
-19/ 6/2007 9:52:56. 74687 Send to c83 voip22:CallEstablished voip22
-19/ 6/2007 10:43:33.733437 Send to c83 sound:Terminating
-19/ 6/2007 10:43:33.735661 Recv from c83 sound:TRANSFERUDP sound
-19/ 6/2007 10:43:33.735691 Recv from c83 voip22:HANGUP
-19/ 6/2007 10:43:33.735739 Send to voip22 c83:HANGUP
</programlisting>
</para>
<para>
The key events in the above log can be summarized by the list below
+<listitem><para>
+The voip node starts, and registers the supervisor with the label
+<literal>voip</literal>. The voip supervisor then preallocates 10 nodes, ready
+to be assigned to an incoming our outgoing call. By having preallocated nodes,
+we minimise the delay in setting up a new call. Note also that it is entirely
+wrong for any other node to start using one of these preallocated
+calls. Indeed, it is only the server who knows about these preallocated
+nodes. Information on these preallocated nodes is not made available to any
+other &sofaswitch; entity.
+</para></listitem>
+
<itemizedlist><listitem><para>
The sound node is started, and connects to the server. The server reports that
a new node has started, where the new node has identified itself as
@@ -678,9 +703,9 @@
</para></listitem>
<listitem><para>
A controller script is started, which has no fixed/preset identity. It
-therefore connects to the server with no id (and uses <literal>?</literal>). In
-the third and fourth line, we see how the controller script requests the server
-to tell the script what its identity is.
+therefore connects to the server with no id (and uses <literal>?</literal>). We
+see (at time <literal> 10:33:28. 93480</literal>) how the controller script requests the server
+to provide identity information.
</para></listitem>
<listitem><para>
@@ -694,52 +719,49 @@
</para></listitem>
<listitem><para>
-The nodes <literal>sound</literal>, <literal>voip</literal>, and
-<literal>voip22</literal> advise the server that on termination, node
-<literal>c83</literal> should receive a message that they died.
+Node <literal>c1</literal> will receive a message from the server when the
+nodes <literal>sound</literal>, <literal>voip</literal>, and
+<literal>voip1</literal> terminate, because of the
+<literal>AdviseOnTermination</literal> command.
</para></listitem>
<listitem><para>
-<literal>voip</literal> sends a message to <literal>c83</literal> stating that
-it has created a new worker node (<literal>voip22</literal>) for use.
+<literal>voip</literal> sends a message to <literal>c1</literal> stating that
+it has created a new worker node (<literal>voip1</literal>) for use.
</para></listitem>
<listitem><para>
-<literal>voip22</literal> is asked to make a voip call to
+<literal>voip1</literal> is asked to make a voip call to
<literal>iax2:guest@conference.freeswitch.org/42</literal>. In this case, the
call will use the IAX2 voip protocol.
</para></listitem>
<listitem><para>
Immediately after the call is created, the <literal>transferudp</literal>
-process is initiated. The controller (<literal>c83</literal>) causes the audio
-input&output of <literal>voip22</literal> and <literal>sound</literal> to be connected.
+process is initiated. The controller (<literal>c1</literal>) causes the audio
+input&output of <literal>voip1</literal> and <literal>sound</literal> to be connected.
</para></listitem>
<listitem><para>
In the middle of the <literal>transferudp</literal> message exchange, there is
-a comment about a new node, <literal>voip32</literal>. This new node is created
-by the <literal>voip</literal> supervisor ahead of time. In this setup, the
-<literal>voip</literal> supervisor has a total of 10 nodes prebuilt, already
-connected to the server which are ready for use. Thus, the moment the
-<literal>voip</literal> supervisor receives a request for a new worker, it can
-reply with an available worker.
+a comment about a new node, <literal>voip11</literal>. This new node is created
+by the <literal>voip</literal> supervisor which has responded to assigning
+<literal>voip1</literal> to a call.
</para></listitem>
<listitem><para>
-The voip worker <literal>voip22</literal> sends a message at <literal>
-9:52:56. 74687</literal> to say that the call is established.
+The voip worker <literal>voip1</literal> sends a message at <literal>10:33:34. 39595</literal> to say that the call is established.
</para></listitem>
<listitem><para>
The worker <literal>sound</literal> is terminated by
<literal>Ctrl-C</literal>. The server detects this and sends a message to the
-controller at <literal>10:43:33.733437</literal>
+controller at <literal>11:23:22.196723</literal>
</para></listitem>
<listitem><para>
The call is disestablished. The controller closes down
-<literal>voip22</literal> and directs <literal>sound</literal> to redirect
+<literal>voip1</literal> and directs <literal>sound</literal> to redirect
audio to itself. Since the <literal>sound</literal> node is already dead, this
<literal>transferudp</literal> command is dropped.
</para></listitem>
1
0
Author: derek
Date: Tue Jun 19 00:25:44 2007
New Revision: 329
Modified:
sofaswitch/trunk/overview/chap2.sgml
Log:
Tidyups.
Modified: sofaswitch/trunk/overview/chap2.sgml
==============================================================================
--- sofaswitch/trunk/overview/chap2.sgml (original)
+++ sofaswitch/trunk/overview/chap2.sgml Tue Jun 19 00:25:44 2007
@@ -434,7 +434,7 @@
responsible for handling one call.
<informaltable frame="all">
-<tgroup cols="4">
+<tgroup cols="3">
<tbody>
<row>
<entry><literal> controller10 </literal></entry>
@@ -618,8 +618,8 @@
<para>
In this example, a voip node is being asked to call a remote entity. Audio data
-from the voip worker will be transfered to the &sofaswitch; entity "sound". The
-"sound" entity is mainly for testing, and connects a sound card to the
+from the voip worker will be transfered to the &sofaswitch; entity <literal>sound</literal>. The
+<literal>sound</literal> entity is mainly for testing, and connects a sound card to the
&sofaswitch; environment. The voip node is running on the box at I.P address
<literal>192.168.1.109</literal>. The sound node is running on the box at
I.P. address <literal>192.168.1.108</literal>.
1
0
Author: derek
Date: Tue Jun 19 00:23:31 2007
New Revision: 328
Added:
sofaswitch/trunk/overview/app1.sgml
sofaswitch/trunk/overview/chap1.sgml
sofaswitch/trunk/overview/chap2.sgml
Log:
Add these files, which are part of the move to docbook for documents.
Added: sofaswitch/trunk/overview/app1.sgml
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/overview/app1.sgml Tue Jun 19 00:23:31 2007
@@ -0,0 +1,77 @@
+<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
+<screen>
+xsltproc
+</screen>
+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, the
+generated zip file is read in. 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. It is likely that the third line in this file (which specifies the
+location of the docbook stylesheet to generate html) will need to be changed
+for your particular system.
+</para>
+
+<para>
+Under windows, you are still going to use docbook to transform the
+<literal>.xml</literal> file into html documentation. You will need to follow
+similar steps to those described in a
+<ulink url="http://www.codeproject.com/winhelp/docbook_howto.asp">windows
+guide</ulink>, but you will end up with native windows looking documentation.
+</para>
+
+<para>
+The unix command
+<screen>
+xsltproc makedoc.xsl callflow.xml
+</screen>
+will generate output something like
+<screen>
+Writing ch01.html for chapter
+Writing ch02s02.html for sect1
+Writing ch02s03.html for sect1
+Writing ch02s04.html for sect1
+Writing ch02s05.html for sect1
+Writing ch02.html for chapter
+Writing ch03s02.html for sect1
+Writing ch03s03.html for sect1
+Writing ch03s04.html for sect1
+Writing ch03s05.html for sect1
+Writing ch03s06.html for sect1
+Writing ch03s07.html for sect1
+Writing ch03s08.html for sect1
+Writing ch03s09.html for sect1
+Writing ch03s10.html for sect1
+Writing ch03s11.html for sect1
+Writing ch03s12.html for sect1
+Writing ch03s13.html for sect1
+Writing ch03s14.html for sect1
+Writing ch03s15.html for sect1
+Writing ch03s16.html for sect1
+Writing ch03.html for chapter
+Writing apa.html for appendix
+Writing index.html for book
+Writing callflow.hhp
+Writing callflow.hhc
+</screen>
+Once the actual html is generated, the zip file must be created. This zip file
+contains the files generated by the <literal>xsltproc</literal> command and the
+image files referenced by the .sgml files. On
+Unix, the command is
+<screen>
+ find . -name \*.html -or -name \*.hh\* -or -name \*.png | xargs zip doc.zip
+</screen>
+The generated <literal>doc.zip</literal> file must be in the same directory as
+where the &callflow; executable is run from.
+</para>
+
+</appendix>
Added: sofaswitch/trunk/overview/chap1.sgml
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/overview/chap1.sgml Tue Jun 19 00:23:31 2007
@@ -0,0 +1,50 @@
+<chapter>
+<title>Synopsis of &sofaswitch;</title>
+<titleabbrev>Synopsis</titleabbrev>
+
+<para>
+&sofaswitch; is the result of a detailed analsysis of freely available
+audio switches. The available switches are (essentially) monolithic monsters
+that are unmaintainable, and hard to configure. Further, we saw numerous add on
+packages (consisting of hundreds/thousands lines of code) to provide new
+functionality. Vast chunks of code were duplicated from one component to
+another, with resulting loss of reliability and configurability.
+</para>
+
+<para>
+An audio switch is, essentially, a means of connecting multiple different
+streams of audio together in a controlled manner. Consequently, &sofaswitch;
+was written to do just that. Different components to handle different incoming
+audio sources (audio file, voip, TDM, conference), a common "glue" protocol,
+and a control system.
+</para>
+
+<para>
+ &sofaswitch; is a suite of programs. Together, these programs provide the
+functionality of a PBX. Operation of these programs is controlled by one
+program, which can be written in any language.
+</para>
+
+
+<para>
+The programs in the &sofaswitch; suite communicate with each viah TCP and UDP
+packets. Consequently, there is no requirement for the programs to have the
+same license. Further, operation of the &sofaswitch; system is
+modularised. Consequently, failure in one prrogram will not stop another
+program
+</para>
+
+<para>
+The current testing regime has shown the software to be 32 and 64 bit clean. It
+compiles and runs fine on Suse 10, Redhat 9, and Fedora Core 1. We expect it
+to compile and run correctly on windows.
+</para>
+
+<para>
+The user of the &sofaswitch; system has the minimum of limitations on how
+different components are joined together. Thus, a call generator, answering
+machine with IVR, conference system with IVR can be created with ease.
+</para>
+
+</chapter>
+
Added: sofaswitch/trunk/overview/chap2.sgml
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/overview/chap2.sgml Tue Jun 19 00:23:31 2007
@@ -0,0 +1,749 @@
+<chapter>
+<title>Format & content of the TCP control message</title>
+<titleabbrev>Control message protocol</titleabbrev>
+
+<para>
+In this chapter we explain the format of the TCP messages, which are used to
+control the operation of the different &sofaswitch; components. Also described
+is the relationship between different components, which is required for the
+communications protocol to make any "sense". Some justification is given for
+the choices made. However, there will be some topics that no amount of
+justification/discussion will be convincing enough.
+</para>
+
+
+<para>
+As stated before, &sofaswitch; consists of many different running applications,
+where each different application may run on a different machine and will have a
+different purpose. Consequently, there is a need for a standardised method of
+communication between the applications which will work transparently across
+OS's, hardware types, and network types.
+</para>
+
+<sect1><title>Micro Management</title>
+<para>
+A key element in understanding why we chose where communication flows is that
+we are opposed to "micro manaagement". By "micro management", we refer to the
+practice where one part of the software has an excessive interest in the
+minute details of another component in the software. For more details, see
+<ulink url="http://en.wikipedia.org/wiki/Micromanagement">wikipedia-micro management</ulink>
+</para>
+
+<para>
+To illustrate, the Controlling entity directs two nodes to send audio between
+them. There are two distinct methods for implementing this:
+<itemizedlist>
+<listitem><para>
+ for the Controller to work out what ports are available in the two nodes,
+ and then advise both nodes to which port to send the audio data
+ </para></listitem>
+ <listitem><para>
+ two nodes are told they are talking to each other by the Controller.
+ Then, the two nodes discuss amongst themselves
+ how they communicate (which could be via tcp, bridging, pipes, etc)
+ </para></listitem>
+</itemizedlist>
+</para>
+
+<para>
+The first approach is micro management - the Controller does not need to know
+about ports. Worse, it constrains the two nodes to only talk via network
+ports. The second approach is harder - the nodes are all given some
+"intelligence" and have to be able to respond to a wider range of messages.
+The second approach does give flexibility though. If the two nodes are (for
+example) on the same telephony card on a PC, they can send audio between them
+via direct bridging.
+</para>
+</sect1>
+
+<sect1><title> Entities provided by &sofaswitch;</title>
+<para>
+There are several distinct entities used by &sofaswitch;. It is important to
+understand the difference between them, and how the entities interact.
+</para>
+
+<para>
+<informaltable frame="all">
+<tgroup cols="2">
+<tbody>
+<row><entry><para>Worker</para></entry>
+<entry><para> handles commands associated with one particular audio circuit.
+ In a voip application, which is capable of handling 30 (say) concurrent calls,
+ there will be (at most) 30 active Workers.
+</para></entry></row>
+<row><entry><para>Server</para></entry>
+<entry><para>responsible for establishing (as required) new
+ Workers. It can be used to terminate the &sofaswitch;
+ application. Messages which are appropriate for a particular
+ Worker are never ever sent via the Supervisor
+</para></entry></row>
+<row><entry><para>Server </para></entry>
+<entry><para>
+is responsible for passing control messages between
+ different &sofaswitch; entities. There is only one instance of
+ a Server in the &sofaswitch; network, so all control messages
+ pass through the Server. Thus, the Server knows about every
+ active &sofaswitch; entity.
+</para></entry></row>
+<row><entry><para>Controller</para></entry>
+<entry><para>
+is responsible for generating control mesasges to
+ get things to happen. It is this entity who initiates
+ responses from the &sofaswitch; system as real world events
+ happen. There may be multiple active Controllers - this is a
+ matter of implementation for the user.
+</para></entry></row>
+</tbody></tgroup></informaltable>
+</para>
+
+<para>
+Even the controller can be split up into a Worker/Supervisor distinction. The
+Worker in the controller sends commands appropriate to managing one current
+call. The Supervisor creates Workers to handle new calls, as required. How the
+Controller is configured/written is entirely up to the user. We have provided
+Python examples, and a graphical editor to generate those Python examples, but
+the user may choose to implement a completely different system.
+</para>
+
+<para>
+Workers and Supervisors exist together inside one running application to
+handle voice calls. The Worker is the only entity who "touches" raw audio
+data. Everything else worries about control. The Supervisor is in direct
+contact with 1 (or more) Workers. Thus, the supervisor is responsible for
+Worker creation/initiation/deletion. There are several SofaSwitch
+applications (am, mcu, voip), each of which contain one Supervisor and
+multiple workers. By sending audio between the different workers, we can
+create the functionality of a voice switch.
+</para>
+
+<para>
+We have a "star" shaped network, as all control messages go via the
+server. However, this is not strictly true as raw audio will pass directly
+between any two workers. Alternatively, audio is never ever passed through the
+server. This design decision was made so that any extra burst of processing
+required on the server will not slow down/interrupt audio traffic. Further,
+removing audio traffic from the server reduces the load on the server
+considerably.
+</para>
+</sect1>
+
+<sect1><title>The contents of all messages</title>
+<para>
+Control communication is always via text messages in TCP packets. The last
+byte in every message is a zero byte. By using a zero byte, we can determine
+if the remote stack has concatenated consecutive TCP messages.
+</para>
+
+<para>
+Prior to any communication, a node must connect to the server and
+identify itself. Once identified, anyone connected to that server can
+talk to the node. A node (suppose it is "switch") will first do a TCP
+Connect to this server. This server will then spawn of a TCPConnection
+class to listen for all further communications from switch. Node
+switch then sends a zero terminated string of
+</para>
+
+<para> <literal>switch 0</literal>
+ (string, with a trailing zero byte)</para>
+
+<para>
+to this server. This string identifies the remote node to this server. On
+receipt of this string, the server can make a unique label for the
+TCPConnection class, and add it to the internal list. Once the TCPConnection
+class has been added to the internal list, full bidirectional comms is now
+possible with node "switch".
+</para>
+
+<para>
+The server assumes all remote nodes will correctly choose a valid unique ID.
+My preference is that the supervisor connects with a label such as
+"controller", "voip", or "am". Workers spawned by that supervisor have a
+number appended to the supervisor's label. Thus, the voip supervisor connects
+as "voip". All workers spawned by the voip supervisor will be called "voip1",
+"voip2", etc. This naming scheme makes debugging somewhat easier, as you can
+identify, from the label, the origin/destination of a message.
+</para>
+
+<para>
+In some cases, the connecting node has no idea what unique ID to specify. It
+will (in this case) use the string "?"0 and let the server assign a unique ID.
+The connecting node can then use the command "whoami" to enquire of the server
+to find out what unique ID was assigned. This indentification process is ideal
+for Controllers. You can invoke multiple instances of the same script to do
+some task, and know that all control instances have unique ids.
+</para>
+
+<para>
+A control message, which is sent via the server has the format
+</para>
+
+<para><literal>
+ remoteNode : message 0</literal>
+ (string, with a trailing zero byte)</para>
+
+<para>
+The server changes the message, and sends it to the remote node as
+</para>
+<para><literal>
+sourceNode : message 0</literal>
+ (string, with a trailing zero byte
+</para>
+
+<para>
+Thus, this server has changed the message. This is acceptable, as it
+means that the receiving node is able to determine who sent the
+message. The receiving node cannot determine the source of the message
+by socket analysis. This happens as the network stack of the receiving
+node will always say that the source of each packet is this message
+server.
+</para>
+
+<para>
+To illustrate, suppose A sends the message <literal>status</literal> to B.
+A sends to the sever
+</para>
+
+<para><literal>B:status 0</literal>
+ (string, with a trailing zero byte)</para>
+
+<para>
+the server receives this packet and then sends to B
+</para>
+
+<para><literal>A:status 0</literal>
+ (string, with a trailing zero byte)</para>
+
+<para>
+When B receives this message, B knows the source of the message and can respond
+accordingly. Further, should the server concatanate two TCP messages together,
+B can accurately split the two messages. The source of each message in a
+concatanated block can be easily determined.
+</para>
+</sect1>
+
+<sect1>
+<title>Worker/Supervisor commands</title>
+
+<para>
+The following commands are provided in this protocol. They are
+designed to be sent from a Worker/Supervisor to a
+Worker/Supervisor. Most will be sent by Workers, but there is no check
+if the source is allowed to send this message. Indeed, it is possible
+for any node connected to the server to control any other node
+connected to the server.
+</para>
+
+
+<para>
+<informaltable frame="all">
+<tgroup cols="2">
+<tbody>
+<row><entry><para><literal>hangup</literal></para></entry>
+<entry><para>The Worker which receives this terminates the current call
+</para></entry></row>
+
+<row><entry><para><literal>callnode</literal></para></entry>
+<entry><para>
+Causes a Worker/Supervisor to start a voip call to voip destination. This command is
+ not relevant for an answering machine type node.
+</para></entry></row>
+
+<row><entry><para><literal>status </literal></para></entry>
+<entry><para>
+ A query on the Worker/Supervisor's status. If an argument is supplied, then
+ status is required of that entity. For example, you could specify the status of a
+ particular conference room</para></entry></row>
+
+<row><entry><para><literal> duration</literal></para></entry>
+<entry><para>
+A query for the worker to reply with the duration of the current call, or the
+ supervisor to reply with how long it has been up </para></entry></row>
+
+<row><entry><para><literal> identify </literal></para></entry>
+<entry><para>
+ The node will reply with an english sentence describing how long it has been up
+</para></entry></row>
+
+<row><entry><para><literal>debug</literal></para></entry>
+<entry><para>
+ casue the receiving node to turn on (or not) debugging features. Typically,
+this will make the recipient generate text, which goes to the console.
+</para></entry></row>
+
+<row><entry><para><literal> answer</literal></para></entry>
+<entry><para>
+ the worker node will answer the incoming voip call or not. There will be the
+ word <literal>true</literal> or <literal>false</literal> after the word
+ <literal>answer</literal>, to say if we answer the call.
+</para></entry></row>
+<row><entry><para><literal>transferudp</literal></para></entry>
+<entry><para>
+Used in the exchange to advise remote nodes of where the local udp receive port is
+</para></entry></row>
+<row><entry><para><literal>queryaddress</literal></para></entry>
+<entry><para>
+ no longer used, as it has been superseded by the transferudp command
+</para></entry></row>
+
+<row><entry><para><literal>adviseaddress</literal></para></entry>
+<entry><para>
+ no longer used, as it has been superseded by the transferudp command
+</para></entry></row>
+
+<row><entry><para><literal>quitnow</literal></para></entry>
+<entry><para>
+Is only processable by a Supervisor node Worker nodes will ignore this
+command. The &sofaswitch; application that processes this
+command will exit, and cease execution.
+</para></entry></row>
+
+<row><entry><para><literal>help </literal></para></entry>
+<entry><para>
+ cause the recipient node to reply with the list of understood commands. This
+is particularly helpful when you are controlling &sofaswitch; applications
+manually by commands typed in at the console.
+</para></entry></row>
+
+<row><entry><para><literal>querydestaddress</literal></para></entry>
+<entry><para>
+ no longer used, as it has been superseded by the transferudp command
+</para></entry></row>
+
+<row><entry><para><literal>senddtmf </literal></para></entry>
+<entry><para>
+advise the recipient worker to send the folling dtmf stream to the remote voip node.
+ Typically, a voip worker would receive this message, and send dtmf to the
+ other end of the call.
+</para></entry></row>
+
+<row><entry><para><literal>receiveddtmf</literal></para></entry>
+<entry><para>
+A worker node has detected a DTMF sequence, and is passing the detected
+ sequence back to the controller. Typically, a voip worker would be able to
+ detect DTMF, and is passing this on to the controller. The sound node, and
+ telephone line handlers can also detect DTMF events (which are alternatively
+ key pad presses)
+</para></entry></row>
+
+<row><entry><para><literal>reporttome </literal></para></entry>
+<entry><para>
+A supervisor (or worker) this message. A controller will send this message. The
+ recipient of this message will then send all queries (e.g. answer call) to the source
+ of this mesasge In this way, the
+controller will register to receive notification of events from the recipient
+of this message.
+</para></entry></row>
+
+<row><entry><para><literal>setreceivedmsgfile</literal></para></entry>
+<entry><para>
+An answering machine Worker will receive this message, and write incoming
+ audio to the specified file
+</para></entry></row>
+
+
+<row><entry><para><literal>setannouncementfile</literal></para></entry>
+<entry><para>
+An answering machine Worker will receive this message, and read audio from
+ the specified file, and send this audio to the address specified in the
+ previous transfer udp message.
+</para></entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+</sect1>
+
+
+<sect1>
+<title>Server commands</title>
+<para>
+Some commands are actioned by the server, and not passed on to the
+destination node. These commands do not have a destination node
+specified. They are therefore of the format:
+</para>
+
+<para>
+ <literal>command 0</literal>
+ (string, with a trailing zero byte)</para>
+
+<para>
+which contains no colon character, and is terminated by a zero
+byte.
+</para>
+
+<para>
+<informaltable frame="all">
+<tgroup cols="2">
+<tbody>
+<row><entry><para><literal>quitnow </literal></para></entry>
+<entry><para>
+ Cause the server to end. On ending, every application
+ connected to the server will end also.
+</para></entry></row>
+
+<row><entry><para><literal>list </literal></para></entry>
+<entry><para>
+ Cause the server to respond with a list of all the currently
+ connected nodes. The command "list" is similar to the notion
+ of presence as used in XMPP, except that here, presence is
+ driven by the client.
+</para></entry></row>
+
+<row><entry><para><literal>whoami</literal></para></entry>
+<entry><para>
+ A request to the server to advise us who we are. This command
+ is useful when we are some controller who has connected to
+ the server and set the server to generate a unique Id for
+ us. It is also a debugging tool from the command prompt case
+ - we can enquire of the server to report our ID.
+</para></entry></row>
+<row><entry><para><literal>adviseontermination remNode</literal></para></entry>
+<entry><para>
+ This commands the server to (on this node terminating) send a
+ message to <literal>remNode</literal>. The message will
+ advise <literal>remNode</literal> that this this node has died. Thus, the
+ controller will get a message if the box running the answer
+ machine (for example) is unplugged.
+ Alternatively, if the application that generated this message crashes,
+<literal>remNode</literal> will receive a termination message (sent from the server).
+</para></entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+
+</sect1>
+
+
+<sect1>
+<title>Description & example of the <literal>transferdp</literal> command</title>
+
+<para>
+We stated above that audio is carried on UDP packets between &sofaswitch;
+worker nodes. Further, it was noted that the Controller is not required to know
+about the method by which the audio is transferred. We describe here how the
+exchange of audio between two worker nodes is managed. This example is based
+around the audio being carried in UDP packets.
+</para>
+
+<para>
+Below is a sequence of three messages, as sent by worker nodes, to setup the
+transfer of audio beteen the worker nodes of <literal>voip41</literal> (voice
+over ip worker) and <literal>am3</literal> (answering machine worker). Note
+that <literal>controller10</literal> is a worker node in the controller, and is
+responsible for handling one call.
+
+<informaltable frame="all">
+<tgroup cols="4">
+<tbody>
+<row>
+<entry><literal> controller10 </literal></entry>
+<entry> sends </entry>
+<entry><literal> voip41: transferudp am3
+</literal></entry></row>
+
+<row><entry><literal> voip41 </literal></entry>
+<entry> sends </entry>
+<entry><literal> am3:192.168.1.109:6204
+</literal></entry></row>
+
+<row><entry><literal> am3 </literal></entry>
+<entry> sends </entry>
+<entry><literal> voip41:192.168.1.54: 45021 done
+</literal></entry></row>
+</tbody></tgroup></informaltable>
+</para>
+
+<para>
+The <literal>controller10</literal> tells <literal>voip41</literal> that it has
+to send audio to the <literal>am3</literal> node. Once the controller has sent
+this message, the controller has no further news on if anything has
+happened. <literal>voip41</literal> receives the transferudp message and
+advises <literal>am3</literal> of an ip/port address. This second message in
+the transfer advises <literal>am3</literal> of where to send audio data
+to. <literal>am3</literal>, on receipt of message 2, can start sending audio to
+the address specified in message 2. <literal>am3</literal> then advises
+<literal>voip41</literal> of the address that <literal>voip41</literal> should
+send audio to. When <literal>voip41</literal> receives message 3,
+<literal>voip41</literal> can start sending audio to port 45021 of ip adresss
+<literal>192.168.1.54</literal>. On receipt of message 3,
+<literal>voip41</literal> will send no more messages, as message 3 contains the
+word <literal>done</literal>.
+</para>
+
+<para>
+Note that in this example, <literal>voip41</literal> decided that audio had to
+be sent via UDP. If <literal>voip41</literal> shared some other interprocess
+communication system with <literal>am3</literal>, then the format of the second
+and third message could have been entirely different.
+</para>
+
+</sect1>
+
+<sect1><title> Example of a Supervisor requesting a new id</title>
+<para>
+The controller supervisor has decided it needs a new worker in a
+sofaswitch application. Since the controller supervisor is not
+interested in micro management, the controller supervisor will create
+a worker node. Consequently, the controller forks/thread create
+(whatever) and creates a new Worker node (<literal>controller10</literal>). Now,
+<literal>controller10</literal> sends the message
+<literal>voip requestnewid</literal>
+to the <literal>voip</literal> &sofaswitch; application supervisor.
+The voip supervisor creates a new worker
+(<literal>voip20</literal>). The voip supervisor sends a message to <literal>controller10</literal> stating
+that a newid has been created, and it is <literal>voip20</literal>. The messages, as received by the server are:
+</para>
+
+<para>
+<informaltable frame="all">
+<tgroup cols="3">
+<tbody>
+<row><entry> <literal>controller10</literal> </entry>
+<entry>sends</entry>
+<entry><literal>voip:requestnewid</literal></entry></row>
+
+<row><entry> <literal>voip</literal> </entry>
+<entry>sends</entry>
+<entry><literal>controller10:requestnewid voip20</literal></entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+
+<para>
+Then, <literal>controller10</literal> will send messages to <literal>voip20</literal> asking it to
+transferudp, or make a call, or whatever.
+</para>
+</sect1>
+
+
+
+<sect1><title> Example of calling a remote voip address</title>
+<para>
+The controller supervisor should not issue the <literal>callnode</literal>
+command. Given that we do not believe in micro management, we will let the
+controller supervisor to create a controller-worker thread/process to issue the
+<literal>callnode</literal> command. The controller worker will be called
+<literal>controller10</literal>. The messages that are sent are:
+</para>
+
+<para>
+<informaltable frame="all">
+<tgroup cols="3">
+<tbody>
+<row><entry> <literal>controller10</literal> </entry>
+<entry>sends</entry>
+<entry><literal>voip:requestnewid</literal></entry></row>
+
+<row><entry> <literal>voip</literal> </entry>
+<entry>sends</entry>
+<entry><literal>controller10:requestnewid voip20</literal></entry></row>
+
+<row><entry> <literal>controller10</literal> </entry>
+<entry>sends</entry>
+<entry><literal>voip20:callnode h323:h323.voxgratia.org</literal></entry></row>
+
+<row><entry> <literal>voip20</literal> </entry>
+<entry>sends</entry>
+<entry><literal>controller10:callestablished voip20</literal></entry></row>
+
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+
+<para>
+The <literal>callestablished</literal> message is sent when the call is up and running.
+In this example, <literal>controller10</literal> knew who was making the call. However,
+it need not be so. The controller does not have to request a new id to initiate a voip call to a remote node.
+Instead, the controller can ask the voip supervisor to create a new call.
+</para>
+
+<para>
+In this case the voip supervisor will create a voip worker, and get the voip worker
+to make the voip call. The voip worker will then advise (from this example)
+<literal>controller10</literal> that the call is established, and the id of the
+voip worker. Here, the controller worker is required to wait for the call
+established message to find out who is managing the call.
+</para>
+
+<para>
+Thus, the voip supervisor can be used to create a Worker (which then implements
+the <literal>callnode</literal> command) In this case, a suitable message flow would be:
+</para>
+
+<para>
+<informaltable frame="all">
+<tgroup cols="3">
+<tbody>
+<row><entry> <literal>controller10</literal> </entry>
+<entry>sends</entry>
+<entry><literal>voip:callnode h323:h323.voxgratia.org</literal></entry></row>
+<row><entry> <literal>voip20</literal> </entry>
+<entry>sends</entry>
+<entry><literal>controller10:callestablished voip20</literal></entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+
+
+<para>
+Once the controller know who the worker nodes are, it can start the
+<literal>transferudp</literal> sequence. However if the voip worker and am
+worker complete the <literal>transferudp</literal> sequence before the call is
+established (from the voip perspective), and the controller then tells the am
+worker the announcement file, the very first part of the announcement file will
+not be heard by the remote voip node.
+</para>
+
+<para>
+Consequently, the am announcement file should be set after the call is
+established. The am received message file can be set at any time. Although,
+setting the am announcement file too late will mean that the first part of the
+incoming voice call will be missed.
+</para>
+</sect1>
+
+<sect1>
+<title>Complete example, Make outgoing call</title>
+<para>
+In this section, we put "everthing together", and describe the commands issued
+when a voip call to a remote node is made. To add to the realisim, we capture
+the messages as seen by the server. The server can report all incoming and
+outgoing messages. Perusal of this log will help the reader to understand what
+has happened.
+</para>
+
+<para>
+In this example, a voip node is being asked to call a remote entity. Audio data
+from the voip worker will be transfered to the &sofaswitch; entity "sound". The
+"sound" entity is mainly for testing, and connects a sound card to the
+&sofaswitch; environment. The voip node is running on the box at I.P address
+<literal>192.168.1.109</literal>. The sound node is running on the box at
+I.P. address <literal>192.168.1.108</literal>.
+</para>
+
+<para>
+The log of messages from the &sofaswitch; server is provided below. Notice that
+this log (generated by the server) contains a column that indicates if the
+source of the message, or destination of the message. Thus, most memssages are
+repeated, because the log below shows incoming and outgoing messages to the
+server.
+<programlisting>
+
+19/ 6/2007 9:52:25.980656 Recv New node of sound
+19/ 6/2007 9:52:49.562018 Recv New node of ?
+19/ 6/2007 9:52:49.562316 Recv from c83 whoami
+19/ 6/2007 9:52:49.562376 Send to c83 c83
+19/ 6/2007 9:52:49.570221 Recv from c83 voip:reporttome
+19/ 6/2007 9:52:49.570343 Send to voip c83:reporttome
+19/ 6/2007 9:52:49.570371 Recv from c83 voip:REQUESTNEWID
+19/ 6/2007 9:52:49.570424 Send to voip c83:REQUESTNEWID
+19/ 6/2007 9:52:49.570446 Recv from c83 sound:REQUESTNEWID
+19/ 6/2007 9:52:49.571467 Send to sound c83:REQUESTNEWID
+19/ 6/2007 9:52:49.572196 Recv from sound AdviseOnTermination c83
+19/ 6/2007 9:52:49.572238 Recv from sound c83:REQUESTNEWID sound
+19/ 6/2007 9:52:49.572288 Send to c83 sound:REQUESTNEWID sound
+19/ 6/2007 9:52:49.885411 Recv from voip AdviseOnTermination c83
+19/ 6/2007 9:52:49.965734 Recv from voip22 AdviseOnTermination c83
+19/ 6/2007 9:52:49.966074 Recv from voip c83:REQUESTNEWID voip22
+19/ 6/2007 9:52:49.966137 Send to c83 voip:REQUESTNEWID voip22
+19/ 6/2007 9:52:49.967668 Recv from c83 voip22:CALLNODE iax2:guest@conference.freeswitch.org/42
+19/ 6/2007 9:52:49.967791 Send to voip22 c83:CALLNODE iax2:guest@conference.freeswitch.org/42
+19/ 6/2007 9:52:49.967820 Recv from c83 voip22:TRANSFERUDP sound
+19/ 6/2007 9:52:49.967862 Send to voip22 c83:TRANSFERUDP sound
+19/ 6/2007 9:52:49.976023 Recv from voip22 AdviseOnTermination c83
+19/ 6/2007 9:52:50. 91997 Recv New node of voip32
+19/ 6/2007 9:52:55.641031 Recv from voip22 sound:TRANSFERUDP sound 192.168.1.109:60010
+19/ 6/2007 9:52:55.641122 Send to sound voip22:TRANSFERUDP sound 192.168.1.109:60010
+19/ 6/2007 9:52:55.642802 Recv from sound voip22:TRANSFERUDP sound 192.168.1.108:63000 done
+19/ 6/2007 9:52:55.642878 Send to voip22 sound:TRANSFERUDP sound 192.168.1.108:63000 done
+19/ 6/2007 9:52:56. 74599 Recv from voip22 c83:CallEstablished voip22
+19/ 6/2007 9:52:56. 74687 Send to c83 voip22:CallEstablished voip22
+19/ 6/2007 10:43:33.733437 Send to c83 sound:Terminating
+19/ 6/2007 10:43:33.735661 Recv from c83 sound:TRANSFERUDP sound
+19/ 6/2007 10:43:33.735691 Recv from c83 voip22:HANGUP
+19/ 6/2007 10:43:33.735739 Send to voip22 c83:HANGUP
+</programlisting>
+</para>
+
+<para>
+The key events in the above log can be summarized by the list below
+<itemizedlist><listitem><para>
+The sound node is started, and connects to the server. The server reports that
+a new node has started, where the new node has identified itself as
+<literal>sound</literal>.
+</para></listitem>
+<listitem><para>
+A controller script is started, which has no fixed/preset identity. It
+therefore connects to the server with no id (and uses <literal>?</literal>). In
+the third and fourth line, we see how the controller script requests the server
+to tell the script what its identity is.
+</para></listitem>
+
+<listitem><para>
+The controller requests a worker node from the <literal>voip</literal> node and
+from the <literal>sound</literal> node.
+</para></listitem>
+
+<listitem><para>
+The controller receives a message that <literal>sound</literal> is available
+for use.
+</para></listitem>
+
+<listitem><para>
+The nodes <literal>sound</literal>, <literal>voip</literal>, and
+<literal>voip22</literal> advise the server that on termination, node
+<literal>c83</literal> should receive a message that they died.
+</para></listitem>
+
+<listitem><para>
+<literal>voip</literal> sends a message to <literal>c83</literal> stating that
+it has created a new worker node (<literal>voip22</literal>) for use.
+</para></listitem>
+
+<listitem><para>
+<literal>voip22</literal> is asked to make a voip call to
+<literal>iax2:guest@conference.freeswitch.org/42</literal>. In this case, the
+call will use the IAX2 voip protocol.
+</para></listitem>
+
+<listitem><para>
+Immediately after the call is created, the <literal>transferudp</literal>
+process is initiated. The controller (<literal>c83</literal>) causes the audio
+input&output of <literal>voip22</literal> and <literal>sound</literal> to be connected.
+</para></listitem>
+
+<listitem><para>
+In the middle of the <literal>transferudp</literal> message exchange, there is
+a comment about a new node, <literal>voip32</literal>. This new node is created
+by the <literal>voip</literal> supervisor ahead of time. In this setup, the
+<literal>voip</literal> supervisor has a total of 10 nodes prebuilt, already
+connected to the server which are ready for use. Thus, the moment the
+<literal>voip</literal> supervisor receives a request for a new worker, it can
+reply with an available worker.
+</para></listitem>
+
+<listitem><para>
+The voip worker <literal>voip22</literal> sends a message at <literal>
+9:52:56. 74687</literal> to say that the call is established.
+</para></listitem>
+
+<listitem><para>
+The worker <literal>sound</literal> is terminated by
+<literal>Ctrl-C</literal>. The server detects this and sends a message to the
+controller at <literal>10:43:33.733437</literal>
+</para></listitem>
+
+<listitem><para>
+The call is disestablished. The controller closes down
+<literal>voip22</literal> and directs <literal>sound</literal> to redirect
+audio to itself. Since the <literal>sound</literal> node is already dead, this
+<literal>transferudp</literal> command is dropped.
+</para></listitem>
+</itemizedlist>
+</para>
+</sect1>
+</chapter>
\ No newline at end of file
1
0
18 Jun '07
Author: derek
Date: Sun Jun 17 22:16:50 2007
New Revision: 327
Added:
sofaswitch/trunk/overview/
sofaswitch/trunk/overview/overview.cxx
- copied unchanged from r252, /sofaswitch/trunk/overview.cxx
Removed:
sofaswitch/trunk/overview.cxx
Log:
Start to reorganise the overview summary docs..
1
0
15 Jun '07
Author: derek
Date: Thu Jun 14 21:26:44 2007
New Revision: 326
Modified:
sofaswitch/trunk/callflow/docs/app1.sgml
sofaswitch/trunk/callflow/docs/chap1.sgml
sofaswitch/trunk/callflow/docs/makedoc.xsl
Log:
Minor tidyups to get it to work more often, first time.
Modified: sofaswitch/trunk/callflow/docs/app1.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/app1.sgml (original)
+++ sofaswitch/trunk/callflow/docs/app1.sgml Thu Jun 14 21:26:44 2007
@@ -22,6 +22,14 @@
</para>
<para>
+Under windows, you are still going to use docbook to transform the
+<literal>.xml</literal> file into html documentation. You will need to follow
+similar steps to those described in a
+<ulink url="http://www.codeproject.com/winhelp/docbook_howto.asp">windows
+guide</ulink>, but you will end up with native windows looking documentation.
+</para>
+
+<para>
The unix command
<screen>
xsltproc makedoc.xsl callflow.xml
Modified: sofaswitch/trunk/callflow/docs/chap1.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/chap1.sgml (original)
+++ sofaswitch/trunk/callflow/docs/chap1.sgml Thu Jun 14 21:26:44 2007
@@ -72,7 +72,7 @@
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
+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>
Modified: sofaswitch/trunk/callflow/docs/makedoc.xsl
==============================================================================
--- sofaswitch/trunk/callflow/docs/makedoc.xsl (original)
+++ sofaswitch/trunk/callflow/docs/makedoc.xsl Thu Jun 14 21:26:44 2007
@@ -1,6 +1,6 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
- <xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/1.69.1/htmlhelp/htmlhelp.xsl"/>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/htmlhelp/htmlhelp.xsl"/>
<xsl:param name="htmlhelp.use.hhk" select="1"/>
<xsl:param name="htmlhelp.button.next" select="1"/>
<xsl:param name="htmlhelp.button.previous" select="1"/>
@@ -17,3 +17,22 @@
<xsl:param name="use.id.as.filename" select="1"/>
</xsl:stylesheet>
+
+
+ <!--
+The third line of the above file is such that everytime you run xsltproc with this file, it goes to the web to get
+the .xsl file from sourceforge. If you don't have net access, you can use a different command.
+Below are two equivalent commands. One is from a suse 10.2 box, the other from a suse 10.1 box.
+If you use the command below, you may have to modify it according to your system.
+
+ Make certain you have xsltproc installed.
+
+
+ <xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/1.69.1/htmlhelp/htmlhelp.xsl"/>
+
+ <xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/1.71.1/htmlhelp/htmlhelp.xsl"/>
+-->
+
+
+
+
1
0
14 Jun '07
Author: derek
Date: Wed Jun 13 22:36:35 2007
New Revision: 325
Modified:
sofaswitch/trunk/callflow/docs/chap1.sgml
sofaswitch/trunk/callflow/docs/chap2.sgml
Log:
More updates. Get ulink to work. Add more cross references.
Modified: sofaswitch/trunk/callflow/docs/chap1.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/chap1.sgml (original)
+++ sofaswitch/trunk/callflow/docs/chap1.sgml Wed Jun 13 22:36:35 2007
@@ -87,11 +87,15 @@
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>
+<ulink url="http://twistedmatrix.com/trac">Twisted</ulink>, an event driven
+network framework written in Python. Using <ulink
+url="http://twistedmatrix.com/trac">Twisted</ulink> solved the handling of the
+any number of asynchronous events.. From a users point of view, we have one
+thread per call and graph management is simplified. The reality is that there
+are two Python threads in operation, one to do <ulink
+url="http://twistedmatrix.com/trac">Twisted</ulink>, and one to execute the
+graphs.
+</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,
Modified: sofaswitch/trunk/callflow/docs/chap2.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/chap2.sgml (original)
+++ sofaswitch/trunk/callflow/docs/chap2.sgml Wed Jun 13 22:36:35 2007
@@ -11,8 +11,10 @@
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
+<literal>Load New Graph</literal> widget
+(section <xref endterm="LoadNewGraph" linkend="LoadNewGraphSec"/>).
+For example then, on receiving notification of an
+incoming call, one would spawn of a new graph which is
designed to handle that particular incoming call.
</para>
@@ -138,8 +140,9 @@
</para>
<para> While processing each of the nodes in the supplied graph, it is
-ignoring all timer events. Execution continues until it is suspended
-(section <xref endterm="SuspendProcessing" linkend="SuspendProcessingSec"/>).
+ignoring all timer events. When the for loop has been completed, execution is
+terminated. The termination control object is explained elsewhere (section
+<xref endterm="TerminateProcessing" linkend="TerminateProcessingSec"/>).
Once execution has been suspended, the system will process pending events.
</para>
@@ -170,14 +173,15 @@
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.
+message. Finally, execution moves into the bottom most box, and is suspended
+(<xref endterm="SuspendProcessing" linkend="SuspendProcessingSec"/>)
</para>
<para>
-At this point, we rely upon the twisted module in Python to call methods
+At this point, we rely upon the <ulink url="http://twistedmatrix.com/trac">Twisted</ulink> 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
+etc). On receipt of a message about a new node, execution is moved to 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>
@@ -234,11 +238,19 @@
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 xrefstyle="select:
+transport of the data. Since the audio data does not go via the control
+circuits, the control system is not burdened by attempting to handle the
+packets in real time. Further, should the control system abnormally terminate,
+the current calls will continue.
+</para>
+
+<para>
+The trivial example in figure <xref xrefstyle="select:
labelnumber" 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.
+therefore been told to talk to itself. Further details on audio transfer are
+found in section <xref endterm="TransferAudio" linkend="TransferAudioSec"/>.
<figure id="trivialtransferexample">
<title>Trivial example of the transfer of audio</title>
<mediaobject>
1
0
14 Jun '07
Author: derek
Date: Wed Jun 13 20:06:45 2007
New Revision: 324
Modified:
sofaswitch/trunk/callflow/docs/chap2.sgml
sofaswitch/trunk/callflow/docs/chap3.sgml
Log:
More tidyups.
Modified: sofaswitch/trunk/callflow/docs/chap2.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/chap2.sgml (original)
+++ sofaswitch/trunk/callflow/docs/chap2.sgml Wed Jun 13 20:06:45 2007
@@ -16,8 +16,9 @@
designed to handle that particular incoming call.
</para>
-<sect1>
+<sect1 id="HelloWorkdExampleSec">
<title>Hello World example</title>
+<titleabbrev id="HelloWorldExample">Hello World Example</titleabbrev>
<para>
Perhaps the simplest example of a graph you can create is the standard "Hello
World" example, shown here, in figure <xref xrefstyle="select: labelnumber"
@@ -112,8 +113,9 @@
</sect1>
-<sect1>
+<sect1 id="ForLoopsSec">
<title>For Loops</title>
+<titleabbrev id="ForLoops">For Loops</titleabbrev>
<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,
@@ -146,8 +148,9 @@
</sect1>
-<sect1>
+<sect1 id="EventHandlingExampleSec">
<title>Event handling</title>
+<titleabbrev id="EventHandlingExample">Event handling</titleabbrev>
<para>
We describe the handling of events in this section, with a simple example,
shown in figure <xref xrefstyle="select: labelnumber" linkend="simpleeventexample"/>.
@@ -224,8 +227,9 @@
</sect1>
-<sect1>
+<sect1 id="TrivialTransferSec">
<title>Trivial transfer of audio</title>
+<titleabbrev id="TrivialTransfer">Trivial Transfer</titleabbrev>
<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
@@ -263,8 +267,9 @@
</sect1>
-<sect1>
+<sect1 id="TransferTimerExampleSec">
<title>Transfer audio, and timer example</title>
+<titleabbrev id="TransferTimerExample">Transfer & timer example</titleabbrev>
<para>
We describe the handling of events in this section, with a simple example
(figure <xref xrefstyle="select: labelnumber" linkend="amtestexample"/>).
@@ -295,8 +300,9 @@
</para>
</sect1>
-<sect1>
+<sect1 id="ProcessingIssuesSec">
<title>Processing issues</title>
+<titleabbrev id="ProcessingIssues">Processing Issues</titleabbrev>
<para> We have described how &callflow; uses the twisted module
(<ulink URL="http://twistedmatrix.com/trac"></ulink>) in Python to handle
events. Further, the outcome of this has been stated as
@@ -328,7 +334,7 @@
message is only sent when execution of control items on this graph is
suspended. The third item on this graph causes the id assigned to this
graph to be deleted. Thus, on processing the terminate processing control item
-(section <xref endterm="TermProc" linkend="TerminateProcessing"/>),
+(section <xref endterm="TerminateProcessing" linkend="TerminateProcessingSec"/>),
the message that was queued for sending is never sent. Perusal of the message
log on the server will show the creation of a new node (this graph) and the
destruction of this node.
Modified: sofaswitch/trunk/callflow/docs/chap3.sgml
==============================================================================
--- sofaswitch/trunk/callflow/docs/chap3.sgml (original)
+++ sofaswitch/trunk/callflow/docs/chap3.sgml Wed Jun 13 20:06:45 2007
@@ -19,8 +19,9 @@
-<sect1>
+<sect1 id="AcceptCallSec">
<title>Accept call (yes/no)</title>
+<titleabbrev id="AcceptCall">Accept Call</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber" linkend="answercallicon"/> which shows the icon
and graph representation of the control structure used to indicate to a remote
@@ -96,8 +97,9 @@
-<sect1>
+<sect1 id="ConditionalExecutionSec">
<title>Conditional execution</title>
+<titleabbrev id="ConditionalExecution">Conditional Execution</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="conditionalicon"/> which shows the icon
and graph representation of the control structure used to direct the flow of
@@ -182,9 +184,9 @@
-<sect1 id="TerminateProcessing">
+<sect1 id="TerminateProcessingSec">
<title>Death - terminate processing of this graph</title>
-<titleabbrev id="TermProc">Terminate Processing</titleabbrev>
+<titleabbrev id="TerminateProcessing">Terminate Processing</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="deathicon"/> which shows the icon
and graph representation of the control structure used to immediately terminate
@@ -267,8 +269,9 @@
-<sect1>
+<sect1 id="EndCallSec">
<title>End a call</title>
+<titleabbrev id="EndCall">End Call</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="endcallicon"/> which shows the icon
and graph representation of the control structure used to end a call, or
@@ -354,8 +357,9 @@
-<sect1>
+<sect1 id="EndForLoopSec">
<title>End for loop</title>
+<titleabbrev id="EndForLoop">End For Loop</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber" linkend="endforloopicon"/> which shows the icon
and graph representation of the control structure used to indicate the end of a
@@ -438,9 +442,9 @@
-<sect1>
-<title>End timer
-</title>
+<sect1 id="EndTimerSec">
+<title>End timer</title>
+<titleabbrev id="EndTimer">End Timer</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber" linkend="endtimericon"/> which shows the icon
and graph representation of the control structure used to terminate a running
@@ -519,8 +523,9 @@
-<sect1>
+<sect1 id="EventCollectionRegistrationSec">
<title>Event collection and registration</title>
+<titleabbrev id="EventCollectionRegistration">Event Collection/Registration</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="eventicon"/> which shows the icon
and graph representation of the control structure used to collect events, and register
@@ -674,8 +679,9 @@
-<sect1>
+<sect1 id="JoinItemsSec">
<title>Join items</title>
+<titleabbrev id="JoinItems">Join Items</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="joinlinesicon"/> which shows the icon
representation of the control structure used to
@@ -769,8 +775,9 @@
-<sect1>
+<sect1 id="LoadNewGraphSec">
<title>Load new graph</title>
+<titleabbrev id="LoadNewGraph">Load New Graph</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="loadnewgraphicon"/> which shows the icon
and graph representation of the control structure used to load a new graph file
@@ -945,8 +952,9 @@
-<sect1>
+<sect1 id="MakeCallSec">
<title>Make a call</title>
+<titleabbrev id="MakeCall">Make Call</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="makecallicon"/> which shows the icon
and graph representation of the control structure used to cause a
@@ -1035,8 +1043,9 @@
-<sect1>
+<sect1 id="ExecutePythonSec">
<title>Execute arbitrary Python command</title>
+<titleabbrev id="ExecutePython">Execute Python</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="Pythonicon"/> which shows the icon
and graph representation of the control structure used to define and execute an
@@ -1179,8 +1188,9 @@
-<sect1>
+<sect1 id="ReadFromFileSec">
<title>Read from file</title>
+<titleabbrev id="ReadFromFile">Read From File</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="readfromfileicon"/> which shows the icon
and graph representation of the control structure used to request an answering
@@ -1264,8 +1274,8 @@
-<sect1>
-<title id="MasterNodeSec">Master node</title>
+<sect1 id="MasterNodeSec">
+<title>Master node</title>
<titleabbrev id="MasterNode">Master node</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber"
@@ -1347,8 +1357,9 @@
-<sect1>
+<sect1 id="MessageSendArbitrarySec">
<title>Message - send arbitrary &sofaswitch; command</title>
+<titleabbrev id="MessageSendArbitrary">Message Send</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber" linkend="messageicon"/> which shows the icon
and graph representation of the control structure used to send an arbitrary
@@ -1434,8 +1445,9 @@
-<sect1>
+<sect1 id="RequestNodeSec">
<title>Request node</title>
+<titleabbrev id="RequestNode">Request Node</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="requestnodeicon"/> which shows the icon
and graph representation of the control structure used to request a worker node
@@ -1557,8 +1569,9 @@
-<sect1>
+<sect1 id="SendDtmfSec">
<title>Send DTMF</title>
+<titleabbrev id="SendDtmf">Send DTMF</titleabbrev>
<para>
Consider figure <xref xrefstyle="select: labelnumber" linkend="senddtmficon"/> which shows the icon
and graph representation of the control structure used to cause DTMF to be sent
@@ -1647,8 +1660,9 @@
-<sect1>
+<sect1 id="StartForLoopSec">
<title>Start for loop</title>
+<titleabbrev id="StartForLoop">Start For Loop</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="StartForLoopIcon"/> which shows the icon
and graph representation of the control structure used to begin a <literal>for
@@ -1747,8 +1761,9 @@
</sect1>
-<sect1>
+<sect1 id="StartGraphProcessingSec">
<title>Start graph processing</title>
+<titleabbrev id="StartGraphProcessing">Start Graph Processing</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="graphprocessicon"/> which shows the icon
and graph representation of the control structure used to initiate processing
@@ -1820,8 +1835,8 @@
-<sect1>
-<title id="SuspendProcessingSec">Suspend graph processing</title>
+<sect1 id="SuspendProcessingSec">
+<title>Suspend graph processing</title>
<titleabbrev id="SuspendProcessing">Suspend processing</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="suspendprocessingicon"/> which shows the icon
@@ -1897,8 +1912,9 @@
-<sect1>
+<sect1 id="Timer Sec">
<title>Timer</title>
+<titleabbrev id="Timer">Timer</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="timericon"/>, which contains the toolbar icon
and graph represeentation of the control structure used to create a timer.
@@ -1988,8 +2004,9 @@
-<sect1>
+<sect1 id="TransferAudioSec">
<title>Transfer of audio between two &sofaswitch; entities</title>
+<titleabbrev id="TransferAudio">Transfer Audio</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="transfermediaicon"/>, which shows the icon
and graph representation of the control structure used to enable the flow of audio between
@@ -2087,8 +2104,9 @@
-<sect1>
+<sect1 id="WriteToFileSec">
<title>Write to file</title>
+<titleabbrev id="WriteToFile">Write To File</titleabbrev>
<para>
Consider the figure <xref xrefstyle="select: labelnumber" linkend="writetofileicon"/>, which shows the icon
and graph representation of the control structure used to cause the answering
1
0