Nathan's Weblog
   


This is Nathan Lutchansky's weblog, Copyright (C) 2003-2005 Nathan Lutchansky.

Contact

  • Email
  • Web page
  • Categories

  • Tech
  • Personal
  • Subscribe

  • Atom feed
  • RSS feed
  • LiveJournal

  •        

    Mon, 01 Dec 2003
    More on my SIP platform

    As I said last time, I'm trying to figure out the best way to drive an IVR system using Perl. All of the platform components, like the SIP agent and RTP streamer, talk to the central control script using D-Bus calls: events like incoming calls generate asynchronous events and the control script can use method calls to perform actions like answering the call, playing sounds, etc. In practice, this makes the individual components become nice non-threaded event-driven things, which improves the scalability. Unfortunately, it also makes the control scripts more complicated.

    I'd like users to be able to write scripts like this:

    $call->answer();
    $call->play_sound( "hello.wav" );
    for(;;)
    {
    	$call->play_sound( "main_menu.wav" );
    	$a = $call->get_dtmf_digit();
    	if( $a == 1 )
    	{
    		$call->transfer( $numbers{"marketing"} );
    		break;
    	} elsif( $a == 2 )
    	{
    		$call->transfer( $numbers{"accounting"} );
    		break;
    	} else
    	{
    		$call->play_sound( "invalid_entry.wav" );
    	}
    }
    $call->hangup();
    

    This seems simple, until you think about asynchronous events. What happens if the caller never enters a digit? Do we time out? If so, do we break out with die() or return an error from get_dtmf_digit()? If we return an error, does the programmer have to check for errors every time the script waits for input? What if the user enters multiple digits? Do we throw the extras away, or buffer them in case we need more input?

    It gets even worse when dealing with scripts that might block. What happens if a database call freezes and the caller hangs up? When do we notify the script? Do we kill it immediately, to free up resources and prevent the system from being tied up? Or do we wait for the database call to time out to allow temporary files and what-not to be cleaned up?

    The other problem I'm contemplating is the abstraction between Perl and C. The D-Bus stuff has to live in C since there's no Perl interface to D-Bus. But do I make the Perl->C interface specific to the signals and methods used by this SIP platform, or do I make it generic enough to be used with any D-Bus component? If I go for the generic approach, does that complicate scripts since I can no longer diddle directly with the Perl interpreter? If I go for application-specific calls, does that limit compatibility with future components?

    Right now I'm leaning towards the simplest implementations, just to get something out the door. But I still get that nagging feeling that I'm going to cause myself some pain later down the road...

    [/tech/voip] Posted at: 22:07

    Comments

    Your Comment

     
    Name:
    URL/Email: [http://... or mailto:you@wherever] (optional)
    Title: (optional)
    Comment:
    Save my Name and URL/Email for next time