Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Taking a SIP of Java



RJ Auburn
Voxeo Corporation
Chief Technology Officer
Telephony
            2
Sucks
        3
Expensive
            4
Complex
          5
Proprietary
              6
This is not how it should be...



                                  7
Simple
         8
Ubiquitous
             9
Open
       10
So what are the layers?



                          11
Application



API      XML        Tools



       Platform



                            12
Application
      Application



API      XML        Tools



       Platform



                            13
Application



API     XML         Tools



       Platform



                            14
Application



API     XML         Tools



       Platform



                            15
Application



API     XML         Tools



       Platform



                            16
Some Basics:
Signaling vs Media



                     17
Call Control vs Media

>   Phone systems often are split into two
    components: Signaling and Media
>   Signaling handle...
Media vs Call Control in the PSTN - SIP

                    Proxy         Proxy
                            SIP
         ...
Media vs Call Control in the PSTN - SS7

                    SCP                    SCP
                                 S...
Media vs Call Control in the PSTN - ISDN


                   D Channel (q.931)
                       Signaling


     De...
All this means is the APIʼs
and standards for media vs
   call control tend to be
           different.


                ...
So now for
a bit about SIP
 (Call Control)


                  23
SIP

>   Session Initiation Protocol (SIP)
    defines how to establish a
    communication session between
    two endpoin...
SIP Communication
                    INVITE
     Alice          180 RINGING   Bob
                    200 OK
            ...
Major SIP Methods

>   INVITE
>   BYE
>   REFER
>   REGISTER
>   SUBSCRIBE
>   NOTIFY
    oh ya...

>   INFO (wait, we are...
Response Codes

>   1xx - Provisional
>   2xx - All is good. Final
>   3xx - Redirects
>   4/5/6xx - Errors




          ...
SIP Resources

>   Internet Engineering Task Force (IETF)
    • RFC 3261
    • Hitchhikerʼs Guide to SIP
>   Open Source I...
So lets talk about...



                        29
Religion
           30
Religion
           31
XML
      32
VoiceXML and CCXML
                     33
VoiceXML

>   Language created by the W3C to
    model computer human dialogs.
>   Supports speech and touchtone.
>   Buil...
CCXML

>   Call Control XML (CCXML) is the
    W3C standard for call control
    using XML
>   Sister standard to VoiceXML...
VoiceXML and CCXML Architecture




                                                   ASR


   Phone         CCXML       ...
Like Tribbles...
                   37
It has taken over the Enterprise...
                                      38
How about some code?



                       39
Sample CCXML/VoiceXML application.

>   Caller dials in to the application
>   Caller is bridged to the subscriber
>   Res...
start



                  isRJ()
      yes                           no

prompt for dest            play twitter status

...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
 <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
 <ccxml xmlns=quot;http://www.w3.org/2002/09...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
Call router + Twitter
 <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
 <ccxml xmlns=quot;http://www.w3.org/2002/09...
Call router + Twitter
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<ccxml xmlns=quot;http://www.w3.org/2002/09/c...
So... How about APIʼs...



                           64
A Favorite of Carriers
                         65
Java
       66
SIP Servlets
  >   Standard Java based API for
      writing SIP applications.
  >   1.0 standardized as JSR-116.
  >   1....
Request Methods

>   doInvite(SipServletRequest req);
>   doAck(SipServletRequest req);
>   doOptions(SipServletRequest re...
Response Methods

>   doProvisionalResponse(SipServletResponse res);
>   doSuccessResponse(SipServletResponse res);
>   do...
Basic Request

public class BasicSIPServlet extends SipServlet {
    protected void doInfo(SipServletRequest req)
       t...
Accessing SIP Headers

protected void doInvite(SipServletRequest req) throws
ServletException, IOException {


   String c...
JSR-309
  >   Java Media Server
      API
  >   Based on the
      CCXML media
      model
  >   Still in draft stage
  > ...
Sample Application Overview

>   Lets try that application again in java...




                              73
start



                  isRJ()
      yes                           no

prompt for dest            play twitter status

...
SIP Flow

     Caller                         App                               Dest
              INVITE - doInvite()
   ...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
  public void init() thro...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter

public class TwitterSIPServlet extends SipServlet {
  SipFactory factory;
    public void init() th...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession      {
   final SipSession mySipSession;
   final SipFactory m...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
 public class TwitterSIPServletSession    {
    final SipSession mySipSession;
    final SipFactory ...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Call router + Twitter
public class TwitterSIPServletSession   {
   final SipSession mySipSession;
   final SipFactory myFa...
Made it to the finish line!
                             103
So. We Have Java...
                      104
But is it Simple?
                    105
Is it cool?
              106
Is It Web 2.0?
                 107
Well Not Exactly...



                      108
So...



        109
Tropo.com



            110
answer();
say(quot;Hello, world!quot;);
      hangup();

      Tropo is Simple
                        111
Ruby




 Telephony in YOUR Language
(thanks to the magic of JSR223)
                                  112
•! answer
•! redirect   •! ask
•! reject     •! say      •! log
              •! record   •! wait      •! call
           ...
•Hosted service
•Accessible via Phone, SIP, Skype etc
•Inbound and Outbound calling
•Free for developers
•No setup costs
•...
What are the Ingredients?
                            115
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
JavaOne - A Sip Of Java - RJ Auburn
Upcoming SlideShare
Loading in …5
×

JavaOne - A Sip Of Java - RJ Auburn

6,765 views

Published on

Slides from my JavaOne talk on June 4th 2009 about developing telephony applications using Java technologies. Includes sample applications in XML, Java and scripting languages.

Published in: Technology
  • Be the first to comment

JavaOne - A Sip Of Java - RJ Auburn

  1. Taking a SIP of Java RJ Auburn Voxeo Corporation Chief Technology Officer
  2. Telephony 2
  3. Sucks 3
  4. Expensive 4
  5. Complex 5
  6. Proprietary 6
  7. This is not how it should be... 7
  8. Simple 8
  9. Ubiquitous 9
  10. Open 10
  11. So what are the layers? 11
  12. Application API XML Tools Platform 12
  13. Application Application API XML Tools Platform 13
  14. Application API XML Tools Platform 14
  15. Application API XML Tools Platform 15
  16. Application API XML Tools Platform 16
  17. Some Basics: Signaling vs Media 17
  18. Call Control vs Media > Phone systems often are split into two components: Signaling and Media > Signaling handles the setup and tear-down of sessions and phone calls. > Media is responsible for the transport voice path 18
  19. Media vs Call Control in the PSTN - SIP Proxy Proxy SIP A B SIP SIP Alice RTP Bob 19
  20. Media vs Call Control in the PSTN - SS7 SCP SCP SS7 A B SS7 7 SS Alice Switched TDM Media Bob 20
  21. Media vs Call Control in the PSTN - ISDN D Channel (q.931) Signaling Dev Dev A B B Channels (23) Media 21
  22. All this means is the APIʼs and standards for media vs call control tend to be different. 22
  23. So now for a bit about SIP (Call Control) 23
  24. SIP > Session Initiation Protocol (SIP) defines how to establish a communication session between two endpoints > Primarily used for voice, but can for IM or virtually any other protocol > Almost always used in client/server configuration with quot;SIP proxiesquot; in control of quot;SIP endpointsquot; • Work going on in P2PSIP - see www.p2psip.org > Text-based protocol, originally modeled on HTTP 24
  25. SIP Communication INVITE Alice 180 RINGING Bob 200 OK ACK RTP (voice) BYE 200 OK 25
  26. Major SIP Methods > INVITE > BYE > REFER > REGISTER > SUBSCRIBE > NOTIFY oh ya... > INFO (wait, we are not supposed to talk about this one) 26
  27. Response Codes > 1xx - Provisional > 2xx - All is good. Final > 3xx - Redirects > 4/5/6xx - Errors 27
  28. SIP Resources > Internet Engineering Task Force (IETF) • RFC 3261 • Hitchhikerʼs Guide to SIP > Open Source Info • VoIP Info Wiki: www.voip-info.org > Industry Sites • SIP Forum: www.sipforum.org • SIP Foundry: www.sipfoundry.org 28
  29. So lets talk about... 29
  30. Religion 30
  31. Religion 31
  32. XML 32
  33. VoiceXML and CCXML 33
  34. VoiceXML > Language created by the W3C to model computer human dialogs. > Supports speech and touchtone. > Built around a form filling model called the FIA. > Voice equivalent to HTML. > Focused on dialogs. Very limited call control. > http://www.w3.org/TR/voicexml/ 34
  35. CCXML > Call Control XML (CCXML) is the W3C standard for call control using XML > Sister standard to VoiceXML > Integrates with VoiceXML for dialog control > Provides a framework for issuing call control commands and handling call control events > http://www.w3.org/TR/ccxml/ 35
  36. VoiceXML and CCXML Architecture ASR Phone CCXML VoiceXML mrcp sip sip TTS rtp 36
  37. Like Tribbles... 37
  38. It has taken over the Enterprise... 38
  39. How about some code? 39
  40. Sample CCXML/VoiceXML application. > Caller dials in to the application > Caller is bridged to the subscriber > Results of the call attempt are posted to Twitter via their REST API 40
  41. start isRJ() yes no prompt for dest play twitter status call dest call rj’s cell end
  42. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 42
  43. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 43
  44. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; <ccxml version=quot;1.0quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign xmlns=quot;http://www.w3.org/2002/09/ccxmlquot;> name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </ccxml> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 44
  45. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 45
  46. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; expr=quot;'init'quot;/> <var name=quot;statequot; </transition> <transition<var name=quot;incomingcallquot;/> event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <eventprocessor statevariable=quot;statequot;> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition</eventprocessor> event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 46
  47. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 47
  48. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <transition event=quot;connection.alertingquot; state=quot;initquot;> <dialogstart src=quot;'caller.vxml'quot; <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <accept/> dest=quot;'tel:+18315551234'quot;/> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall </transition> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 48
  49. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 49
  50. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <transition event=quot;connection.connectedquot; state=quot;initquot; <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> </transition> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 50
  51. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <var name=quot;tURLquot; expr=quot;'http://zscgeek:password@twitter.com/statuses/update.xml'quot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <assign name=quot;statequot; expr=quot;'calling'quot;/> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <vxml xmlns=quot;http://www.w3.org/2001/vxmlquot; version=quot;2.1quot;> <createcall dest=quot;'tel:+18312392883'quot;/> </transition> <form> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <field name=quot;destquot; type=quot;digits?length=10quot;> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> <var name=quot;statusquot; expr=quot;'RJ is on the phone'quot;/> <send <prompt>Welcome RJ. Please enter the phone targettype=quot;'basichttp'quot; name=quot;'update'quot; target=quot;tURLquot; namelist=quot;statusquot;/> </transition> number you wish to reach.</prompt> <transition event=quot;connection.failedquot; state=quot;callingquot;> <filled> <assign name=quot;statequot; expr=quot;'done'quot;/> <var name=quot;statusquot; expr=quot;'RJ is not answering his phone'quot;/> <send <exit namelist=quot;destquot;/> targettype=quot;'basichttp'quot; name=quot;'update'quot; target=quot;tURLquot; namelist=quot;statusquot;/> </filled> </transition> </field> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <assign name=quot;statequot; expr=quot;'done'quot;/> </form> <var name=quot;statusquot; expr=quot;'RJ is off the phone'quot;/> <send targettype=quot;'basichttp'quot; name=quot;'update'quot; </vxml> target=quot;tURLquot; namelist=quot;statusquot;/> </transition> <transition event=quot;send.successfulquot; state=quot;donequot;> <exit/> </transition> </eventprocessor> </ccxml> 51
  52. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 52
  53. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; <transition event=quot;connection.connectedquot; state=quot;initquot;> </transition> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <transition name=quot;statequot; expr=quot;'callconnected'quot;/> <assign event=quot;connection.connectedquot; state=quot;initquot;> <dialogstart src=quot;'caller.vxml'quot; <dialogstart src=quot;'caller.vxml'quot; </transition> </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 53
  54. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <var name=quot;tURLquot; expr=quot;'http://zscgeek:password@twitter.com/statuses/update.xml'quot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <accept/> </transition> <vxml xmlns=quot;http://www.w3.org/2001/vxmlquot; version=quot;2.1quot;> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <form> name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <assign <createcall dest=quot;'tel:+18312392883'quot;/> <block> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <data src=quot;http://twitter.com/statuses/ <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> user_timeline.xml?screen_name=zscgeekquot; <var name=quot;statusquot; expr=quot;'RJ is on the phone'quot;/> <send targettype=quot;'basichttp'quot; name=quot;'update'quot; name=quot;twitterquot; ecmaxmltype=quot;e4xquot; /> target=quot;tURLquot; namelist=quot;statusquot;/> </transition> <prompt>Thank you for calling RJ. <transition event=quot;connection.failedquot; state=quot;callingquot;> <assign We will connect you now. name=quot;statequot; expr=quot;'done'quot;/> <var name=quot;statusquot; expr=quot;'RJ is not answering his phone'quot;/> His twitter status is <send targettype=quot;'basichttp'quot; name=quot;'update'quot; target=quot;tURLquot; namelist=quot;statusquot;/> <value expr=quot;twitter.statuses.status[0].textquot;/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> </prompt> <assign name=quot;statequot; expr=quot;'done'quot;/> <var name=quot;statusquot; expr=quot;'RJ is off the phone'quot;/> </block> <send targettype=quot;'basichttp'quot; name=quot;'update'quot; target=quot;tURLquot; namelist=quot;statusquot;/> </form> event=quot;send.successfulquot; state=quot;donequot;> </transition> <transition </vxml> <exit/> </transition> </eventprocessor> </ccxml> 54
  55. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 55
  56. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> <assign name=quot;statequot; expr=quot;'calling'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <createcall dest=quot;'tel:+18315551234'quot;/> <assign name=quot;statequot; expr=quot;'calling'quot;/> </transition> dest=quot;event$.values.destquot;/> <createcall </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 56
  57. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 57
  58. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <transition name=quot;statequot; expr=quot;'calling'quot;/> <assign event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <createcall dest=quot;'tel:+18315551234'quot;/> <assign name=quot;statequot; expr=quot;'calling'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <createcall dest=quot;event$.values.destquot;/> <assign name=quot;statequot; expr=quot;'calling'quot;/> </transition> dest=quot;event$.values.destquot;/> <createcall </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 58
  59. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 59
  60. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;connection.connectedquot; <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> state=quot;callingquot;> expr=quot;'calling'quot;/> <assign name=quot;statequot; <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; expr=quot;'connected'quot;/> <assign name=quot;statequot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> <createcall dest=quot;event$.values.destquot;/> </transition> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 60
  61. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 61
  62. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; <transition event=quot;connection.failedquot; state=quot;callingquot;> </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <exit/> name=quot;statequot; expr=quot;'calling'quot;/> <assign </transition> dest=quot;'tel:+18315551234'quot;/> <createcall </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <transition name=quot;statequot; expr=quot;'calling'quot;/> <assign event=quot;connection.disconnectedquot; state=quot;connectedquot;> <createcall dest=quot;event$.values.destquot;/> <exit/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> </transition> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 62
  63. Call router + Twitter <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ccxml xmlns=quot;http://www.w3.org/2002/09/ccxmlquot; version=quot;1.0quot;> <var name=quot;statequot; expr=quot;'init'quot;/> <var name=quot;incomingcallquot;/> <eventprocessor statevariable=quot;statequot;> <transition event=quot;connection.alertingquot; state=quot;initquot;> <assign name=quot;incomingcallquot; expr=quot;event$.connectionidquot;/> <accept/> </transition> <transition event=quot;connection.connectedquot; state=quot;initquot; cond=quot;event$.connection.remote=='tel:+18315551234'quot;> <assign name=quot;statequot; expr=quot;'rjconnected'quot;/> <dialogstart src=quot;'rj.vxml'quot; </transition> <transition event=quot;connection.connectedquot; state=quot;initquot;> <assign name=quot;statequot; expr=quot;'callconnected'quot;/> <dialogstart src=quot;'caller.vxml'quot; </transition> <transition event=quot;dialog.exitquot; state=quot;callconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;'tel:+18315551234'quot;/> </transition> <transition event=quot;dialog.exitquot; state=quot;rjconnectedquot;> <assign name=quot;statequot; expr=quot;'calling'quot;/> <createcall dest=quot;event$.values.destquot;/> </transition> <transition event=quot;connection.connectedquot; state=quot;callingquot;> <assign name=quot;statequot; expr=quot;'connected'quot;/> <join id1=quot;event$.connectionidquot; id2=quot;incomingcallquot;/> </transition> <transition event=quot;connection.failedquot; state=quot;callingquot;> <exit/> </transition> <transition event=quot;connection.disconnectedquot; state=quot;connectedquot;> <exit/> </transition> </eventprocessor> </ccxml> 63
  64. So... How about APIʼs... 64
  65. A Favorite of Carriers 65
  66. Java 66
  67. SIP Servlets > Standard Java based API for writing SIP applications. > 1.0 standardized as JSR-116. > 1.1 just released as JSR-289 > Extends the HTTP Servlet model to support SIP and telephony applications > http://www.sipservlet.com/ > Supported by a large number of application servers including Oracle (BEA), IBM, Sun, Voxeo. 67
  68. Request Methods > doInvite(SipServletRequest req); > doAck(SipServletRequest req); > doOptions(SipServletRequest req); > doBye(SipServletRequest req); > doCancel(SipServletRequest req); > doSubscribe(SipServletRequest req); > doNotify(SipServletRequest req); > doMessage(SipServletRequest req); > doInfo(SipServletRequest req); > doPrack(SipServletRequest req); 68
  69. Response Methods > doProvisionalResponse(SipServletResponse res); > doSuccessResponse(SipServletResponse res); > doRedirectResponse(SipServletResponse res); > doErrorResponse(SipServletResponse res); 69
  70. Basic Request public class BasicSIPServlet extends SipServlet { protected void doInfo(SipServletRequest req) throws ServletException, IOException { req.createResponse(SipServletResponse.SC_TRYING).send(); // do stuff req.createResponse(SipServletResponse.SC_OK).send(); } } 70
  71. Accessing SIP Headers protected void doInvite(SipServletRequest req) throws ServletException, IOException { String cpc ; if (req.getHeader(quot;User-Agentquot;).equals(quot;Sonusquot;)) { cpc = req.getHeader(quot;CallPartyquot;); } else if (req.getHeader(quot;User-Agentquot;).equals(quot;ZTEquot;)) { cpc = req.getHeader(quot;CPSquot;); } } 71
  72. JSR-309 > Java Media Server API > Based on the CCXML media model > Still in draft stage > Provides dialog resources, conferencing, media routing to Java applications 72
  73. Sample Application Overview > Lets try that application again in java... 73
  74. start isRJ() yes no prompt for dest play twitter status call dest call rj’s cell end
  75. SIP Flow Caller App Dest INVITE - doInvite() 200 OK ACK doAck() INVITE - transferDialog() 200 OK - doSuccessResponse() ACK 75
  76. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 76
  77. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 77
  78. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { public class TwitterSIPServlet extends SipServlet { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); SipFactory factory; } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ public void init() sipApp = factory.createApplicationSession(); SipApplicationSession throws ServletException { TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), super.init(); factory); sipApp.setAttribute(quot;router-appquot;, service); } factory = (SipFactory)getServletContext() service.init(req); } .getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 78
  79. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 79
  80. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); if(req.isInitial()){ TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); SipApplicationSession sipApp service.init(req); } = factory.createApplicationSession(); } TwitterSIPServletSession service protected void doSuccessResponse(SipServletResponse resp) { } = new TwitterSIPServletSession(req.getSession(), resp.createAck().send(); factory); sipApp.setAttribute(quot;router-appquot;, service); protected void doAck(SipServletRequest req) { service.init(req); final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- } appquot;); service.startDialog(); }} protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 80
  81. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 81
  82. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); protected void doSuccessResponse(SipServletResponse resp) { sipApp.setAttribute(quot;router-appquot;, service); resp.createAck().send(); } service.init(req); }} protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 82
  83. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 83
  84. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doAck(SipServletRequest req) { protected void doInvite(SipServletRequest req) { if(req.isInitial()){ final TwitterSIPServletSession service SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); = (TwitterSIPServletSession) req.getApplicationSession() sipApp.setAttribute(quot;router-appquot;, service); service.init(req); .getAttribute(quot;router-appquot;); } } service.startDialog(); } resp.createAck().send(); protected void doSuccessResponse(SipServletResponse resp) { } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 84
  85. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 85
  86. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); protected void doBye(SipServletRequest req) { sipApp.setAttribute(quot;router-appquot;, service); service.init(req);the frack has cleanup code in // Who } } // slide demo’s anyway? protected }void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 86
  87. Call router + Twitter public class TwitterSIPServlet extends SipServlet { SipFactory factory; public void init() throws ServletException { super.init(); factory =(SipFactory)getServletContext().getAttribute(quot;javax.servlet.sip.SipFactoryquot;); } protected void doInvite(SipServletRequest req) { if(req.isInitial()){ SipApplicationSession sipApp = factory.createApplicationSession(); TwitterSIPServletSession service = new TwitterSIPServletSession(req.getSession(), factory); sipApp.setAttribute(quot;router-appquot;, service); service.init(req); } } protected void doSuccessResponse(SipServletResponse resp) { resp.createAck().send(); } protected void doAck(SipServletRequest req) { final TwitterSIPServletSession service = (TwitterSIPServletSession) req.getApplicationSession().getAttribute(quot;router- appquot;); service.startDialog(); } protected void doBye(SipServletRequest req) { // Need to send BYE request to the other legs } } 87
  88. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 88
  89. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 89
  90. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { public class TwitterSIPServletSession ... { } final SipSession mySipSession; public void startDialog() { final SipFactory myFactory; ... } MediaGroup myMediaGroup; boolean isRJ = false; class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } public TwitterSIPServletSession(SipSession aSipSession, class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... SipFactory aFactory) { } mySipSession = aSipSession; ... myFactory = aFactory; void transferDialog(String uri) throws ServletParseException, IOException { } } } } 90
  91. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 91
  92. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) throws ServletException { MediaSession myMediaSession = MediaSessionFactory.createMediaSession(); public void init(final SipServletRequest req) { ... } NetworkConnection myNetworkConnection = public void startDialog() { myMediaSession.createContainer(NetworkConnectionConfig.c_Basic); ... } myMediaGroup = myMediaSession.createContainer(MediaGroupConfig.c_PlayerSignalDetector); class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } MediaEventListener<NetworkConnectionEvent> myNetworkConnectionListener = new MediaEventListener<NetworkConnectionEvent>() { class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... .... } }; myNetworkConnection.addListener(myNetworkConnectionListener); void transferDialog(String uri) throws ServletParseException, IOException { ... } myNetworkConnection.modify(quot;quot;, new String(req.getRawContent())); } } 92
  93. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } MediaEventListener<NetworkConnectionEvent> myNetworkConnectionListener = new MediaEventListener<NetworkConnectionEvent>() { public void init(final SipServletRequest req) { ... public void onEvent(NetworkConnectionEvent anEvent) { } if (NetworkConnectionConstants.ev_Modify.equals(anEvent.getEventID())) { public void (req.getFrom().getURI().getUser().equals(quot;8312392883quot;)) { startDialog() { ... if } isRJ = true; myMediaGroup.getSignalDetector().addListener( new RJDialerSignalDetectorListener()); class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } else { } myMediaGroup.getSignalDetector().addListener( new CallerPlayerListener()); class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } } myMediaGroup.join(Direction.DUPLEX, myNetworkConnection); String sdpAnswer = myNetworkConnection.getRawLocalSessionDescription(); void transferDialog(String uri) throws ServletParseException, IOException { ... SipServletMessage msg = req.createResponse(200, quot;OKquot;); } msg.setContent(sdpAnswer.getBytes(), quot;application/sdpquot;); } msg.send(); } } }; 93
  94. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 94
  95. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; public void startDialog() { boolean isRJ = false; if (isRJ) { Parameters collectOptions = mediaSessionFactory.createParameters(); public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... prompt = URI.create(quot;data:application/ssml+xml,quot;+ URI } quot;<?xml version=quot;1.0quot;?>quot;+ public void init(final SipServletRequest req) { ... quot;<speak>quot;+ } quot;Welcome RJ. Please enter the phone number you wish to reach.quot;+ quot;</speak>quot;); public void startDialog() { collectOptions.put(SignalDetectorConstants.p_Prompt, prompt); ... } mg.getSignalDetector().receiveSignals(10, null, RTC.bargeIn, collectOptions); } else { class CallerPlayerListener twitter_apiMediaEventListener<PlayerEvent> { net.unto.twitter.Api implements ... = new net.unto.twitter.Api(quot;zscgeekquot;, quot;passwordquot;); } URI prompt = URI.create(quot;data:application/ssml+xml,quot;+ class RJDialerSignalDetectorListener quot;<?xml version=quot;1.0quot;?>quot;+ implements MediaEventListener<SignalDetectorEvent> { ... quot;<speak>quot;+ } quot;Thank you for calling RJ. We will connect you now.quot;+ quot;His twitter status is:quot;+ void transferDialog(String uri) throws ServletParseException, IOException { ... twitter_api.getStatus()+ } quot;</speak>quot;); } myMediaGroup.getPlayer().play(prompt, null, null); } } 95
  96. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 96
  97. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... class CallerPlayerListener implements MediaEventListener<PlayerEvent> { } public void onEvent(PlayerEvent anEvent) { class CallerPlayerListenerquot;+anEvent.getSignalString()); log(quot;Collected: implements MediaEventListener<PlayerEvent> { ... } MediaSession mediaSession = anEvent.getSource().getMediaSession().release(); class RJDialerSignalDetectorListener transferDialog(quot;sip:+18315551234@gateway:5060quot;); implements MediaEventListener<SignalDetectorEvent> { ... } } } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 97
  98. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 98
  99. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { public void startDialog() { ... } public void onEvent(SignalDetectorEvent anEvent) { log(quot;Collected: quot;+anEvent.getSignalString()); class CallerPlayerListener implements = MediaSession mediaSession MediaEventListener<PlayerEvent> { ... } anEvent.getSource().getMediaSession().release(); transferDialog(quot;sip:quot; + anEvent.getSignalString() class RJDialerSignalDetectorListener + quot;@gateway:5060quot;); implements MediaEventListener<SignalDetectorEvent> { ... } } } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 99
  100. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 100
  101. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } void transferDialog(String uri) { public void startDialog() request = SipServletRequest { ... } myFactory.createRequest(mySipSession.getApplicationSession(), quot;INVITEquot;, quot;sip:addressbook@sip-as-uri:5060quot;, class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } uri); request.send(); class RJDialerSignalDetectorListener } implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 101
  102. Call router + Twitter public class TwitterSIPServletSession { final SipSession mySipSession; final SipFactory myFactory; MediaGroup myMediaGroup; boolean isRJ = false; public TwitterSIPServletSession(SipSession aSipSession, SipFactory aFactory) { ... } public void init(final SipServletRequest req) { ... } public void startDialog() { ... } class CallerPlayerListener implements MediaEventListener<PlayerEvent> { ... } class RJDialerSignalDetectorListener implements MediaEventListener<SignalDetectorEvent> { ... } void transferDialog(String uri) throws ServletParseException, IOException { ... } } 102
  103. Made it to the finish line! 103
  104. So. We Have Java... 104
  105. But is it Simple? 105
  106. Is it cool? 106
  107. Is It Web 2.0? 107
  108. Well Not Exactly... 108
  109. So... 109
  110. Tropo.com 110
  111. answer(); say(quot;Hello, world!quot;); hangup(); Tropo is Simple 111
  112. Ruby Telephony in YOUR Language (thanks to the magic of JSR223) 112
  113. •! answer •! redirect •! ask •! reject •! say •! log •! record •! wait •! call •! default •! transfer •! hangup Simple to Learn 113
  114. •Hosted service •Accessible via Phone, SIP, Skype etc •Inbound and Outbound calling •Free for developers •No setup costs •Five minutes from sign-up to live deployment + = GO Simple to Deploy 114
  115. What are the Ingredients? 115

×