phone.py :  » Web-Services » Shtoom » shtoom-0.2 » shtoom » app » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Services » Shtoom 
Shtoom » shtoom 0.2 » shtoom » app » phone.py
# Copyright (C) 2004 Anthony Baxter

# The Phone app.

from shtoom.app.interfaces import Application
from shtoom.app.base import BaseApplication
from twisted.internet import defer
from twisted.python import log
from shtoom.exceptions import CallFailed

from shtoom.audio import FMT_PCMU,FMT_GSM,FMT_SPEEX,FMT_DVI4
from shtoom.audio import getAudioDevice

class Phone(BaseApplication):
    __implements__ = ( Application, )

    def __init__(self, ui=None, audio=None):
        # Mapping from callcookies to rtp object
        self._rtp = {}
        # Mapping from callcookies to call objects
        self._calls = {}
        self._pendingRTP = {}
        self._audio = audio
        self._audioFormat = None
        self.ui = ui

    def boot(self, options=None):
        from shtoom.ui.select import findUserInterface

        from shtoom.opts import buildOptions
        if options is None:
            options = buildOptions(self)
        self.initOptions(options)

        if self.ui is None:
            self.ui = findUserInterface(self, self.getPref('ui'))
        BaseApplication.boot(self)

    def register(self):
        register_uri = self.getPref('register_uri')
        if register_uri is not None:
            self.sip.register()

    def start(self):
        "Start the application."
        from twisted.internet import reactor
        self.register()
        reactor.run()
        self.ui.resourceUsage()

    def getAuth(self, method, realm):
        self.ui.getString("Please enter user,passwd for %s at %s"%(method, realm))

    def acceptCall(self, call, **calldesc):
        print "acceptCall for %r"%calldesc

        if self._audio is None:
            self.openAudioDevice()
        calltype = calldesc.get('calltype')
        d = defer.Deferred()
        d.addCallback(lambda x: self._createRTP(cookie,
                                                calldesc['fromIP'],
                                                calldesc['withSTUN']))
        cookie = self.getCookie()
        self._calls[cookie] = call
        if calltype == 'outbound':
            # Outbound call, trigger the callback immediately
            self.ui.callStarted(cookie)
            d.callback('')
        elif calltype == 'inbound':
            # Otherwise we chain callbacks
            self.ui.incomingCall(calldesc['desc'], cookie, d)
        else:
            raise ValueError, "unknown call type %s"%(calltype)
        return cookie, d

    def _createRTP(self, cookie, fromIP, withSTUN):
        from shtoom.rtp import RTPProtocol
        rtp = RTPProtocol(self, cookie)
        self._rtp[cookie] = rtp
        d = rtp.createRTPSocket(fromIP,withSTUN)
        return d

    def selectFormat(self, callcookie, rtpmap):
        rtp =  self._rtp[callcookie]
        for entry,desc in rtpmap:
            if entry == rtp.PT_pcmu:
                self._audio.selectFormat(FMT_PCMU)
                self._audioFormat = entry
                break
            elif entry == rtp.PT_gsm:
                self._audio.selectFormat(FMT_GSM)
                self._audioFormat = entry
                break
            else:
                raise ValueError, "couldn't set to %r"%entry
        else:
            raise ValueError, "no working formats"

    def getSDP(self, callcookie):
        from shtoom.multicast.SDP import SimpleSDP
        rtp =  self._rtp[callcookie]
        s = SimpleSDP()
        s.setPacketSize(160)
        addr = rtp.getVisibleAddress()
        s.setServerIP(addr[0])
        s.setLocalPort(addr[1])
        fmts = self._audio.listFormats()
        if FMT_GSM in fmts:
            s.addRtpMap('GSM', 8000) # GSM 06.10
        if FMT_PCMU in fmts:
            s.addRtpMap('PCMU', 8000) # G711 ulaw
        if FMT_SPEEX in fmts:
            s.addRtpMap('speex', 8000, payload=110)
            #s.addRtpMap('speex', 16000, payload=111)
        if FMT_DVI4 in fmts:
            s.addRtpMap('DVI4', 8000)
            #s.addRtpMap('DVI4', 16000)
        return s

    def startCall(self, callcookie, remoteAddr, cb):
        log.msg("reopening audio")
        self._audio.reopen()
        log.msg("reopened audio")
        self._rtp[callcookie].startSendingAndReceiving(remoteAddr)
        self.ui.callConnected(callcookie)
        cb(callcookie)

    def endCall(self, callcookie, reason=''):
        rtp = self._rtp.get(callcookie)
        if rtp:
            rtp = self._rtp[callcookie]
            rtp.stopSendingAndReceiving()
            del self._rtp[callcookie]
            if self._calls.get(callcookie):
                del self._calls[callcookie]
            self.closeAudioDevice()
        self.ui.callDisconnected(callcookie, reason)

    def openAudioDevice(self):
        if self._audio is None:
            audioPref = self.getPref('audio')
            audio_in = self.getPref('audio_infile')
            audio_out = self.getPref('audio_outfile')
            if audio_in and audio_out:
                aF = ( audio_in, audio_out )
            else:
                aF = None
            log.msg("Getting new audio device")
            self._audio = getAudioDevice('rw', audioPref, aF)
            self._audio.close()
            log.msg("Got new audio device")

    def closeAudioDevice(self):
        self._audio.close()
        self._audio = None

    def receiveRTP(self, callcookie, payloadType, payloadData):
        fmt = None
        if payloadType == 0:
            fmt = FMT_PCMU
        elif payloadType == 3:
            fmt = FMT_GSM
        if fmt:
            try:
                self._audio.write(payloadData, fmt)
            except IOError:
                pass
        elif payloadType in (13, 19):
            # comfort noise
            pass
        else:
            print "unexpected RTP PT %s len %d"%(rtpPTDict.get(payloadType,str(payloadType)), len(datagram))

    def giveRTP(self, callcookie):
        # Check that callcookie is the active call!
  bytes = self._audio.read()
  if bytes is None:
            return None
        else:
      return self._audioFormat, bytes

    def placeCall(self, sipURL):
        return self.sip.placeCall(sipURL)

    def dropCall(self, cookie):
        call = self._calls.get(cookie)
        if call:
            call.dropCall()
        else:
            self.ui.callDisconnected(None, "no call")

    def startDTMF(self, cookie, digit):
        rtp = self._rtp[cookie]
        rtp.startDTMF(digit)

    def stopDTMF(self, cookie, digit):
        rtp = self._rtp[cookie]
        rtp.stopDTMF(digit)

    def statusMessage(self, message):
        self.ui.statusMessage(message)

    def debugMessage(self, message):
        self.ui.debugMessage(message)

    def appSpecificOptions(self, opts):
        import os.path

        from shtoom.Options import OptionGroup,StringOption,ChoiceOption
        app = OptionGroup('shtoom', 'Shtoom')
        app.addOption(ChoiceOption('ui','use UI for interface', choices=['qt','gnome','tk','text']))
        app.addOption(ChoiceOption('audio','use AUDIO for interface', choices=['oss', 'fast', 'port']))
        app.addOption(StringOption('audio_infile','read audio from this file'))
        app.addOption(StringOption('audio_outfile','write audio to this file'))
        opts.addGroup(app)
        opts.setOptsFile('.shtoomrc')

    def authCred(self, method, uri, realm='unknown', retry=False):
        "Place holder for now"
        user = self.getPref('register_authuser')
        passwd = self.getPref('register_authpasswd')
        if user is not None and passwd is not None and retry is False:
            return defer.succeed((self.getPref('register_authuser'), 
                                 self.getPref('register_authpasswd')))
        elif hasattr(self.ui, 'getAuth'):
            return self.ui.getAuth("Auth needed for %s %s, realm '%s'"%(method, uri, realm))
        else:
            return defer.fail(CallFailed("No auth available"))

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.