YAYPM:Bridge and then redirect after a hangup

From Yate Documentation
Jump to: navigation, search

This script is given as an example, don't forget to change some information such as yate's extmodule binding ip address and port.

This script will :

  • 1 - make a phone call to 'jmfoucher'
  • 2 - play a sound to 'jmfoucher'
  • 3 - wait for DTMF "1"
  • 4 - after "1" is pressed, 'toto' will be called
  • 5 - when toto answers, toto and jmfoucher will be bridged
  • 6 - if one of them hangs up, then the other one will be transferred to a new channel
  • 7 - a sound will be attached to this new channel
  • 8 - once the sound is finished, the new channel will be hangup
#!/usr/bin/python
from twisted.internet import reactor, defer
from yaypm import TCPDispatcherFactory, AbandonedException
from yaypm.flow import go, getResult

from yaypm.utils import ConsoleFormatter

import logging, yaypm

logger = logging.getLogger("test3")

class myTest(object):

    def __init__(self, client):
        logger.debug(">>> myTest.__init__()")
        self.client = client
        self.run()

    def run(self):
        logger.debug(">>> myTest.run()")
        go(self.test())

    def WatchDisconnected(self, id):
        logger.debug(">>> myTest.WatchDisconnected()")
        try:
            #while True:
            #    logger.debug("dans True du WatchDisconnected")

            end = self.client.onmsg("chan.hangup",
            lambda m: m["id"] == id, autoreturn = True)

            yield self.client.onmsg("chan.disconnected",
                                    lambda m : m["id"] == id,
                                    until=end,
                                    autoreturn=False
                                   )
            disconnected = getResult()

            disconnected.ret("true")

            myid = disconnected['id']

            execute = self.client.msg("chan.masquerade",
                                      {"message": "call.execute",
                                       "id": myid,
                                       "callto": "dumb/",
                                      }
                                     )
            yield execute.dispatch()
            if not getResult():
                logger.warn("La redirection de  myid)
            else:
                logger.debug("La redirection marche comme sur des roulettes :)")

            peerid = execute["peerid"]


            self.client.msg("chan.masquerade",
                            {"message" : "chan.attach",
                             "id": peerid,
                             "source": "wave/play/../../sounds/wp_star_seller_ask.wav",
                             "notify": peerid,
                            }
                           ).enqueue()

           go(self.WatchNotify(peerid))

        except AbandonedException, e:
            logger.debug("Call  id)

    def WatchNotify(self, id):
        logger.debug(">>> myTest.WatchNotify()")
        try:
            #while True:
            #    logger.debug("dans True du WatchNotify")

            end = self.client.onmsg("chan.hangup",
            lambda m: m["id"] == id, autoreturn = True)

            yield self.client.onmsg("chan.notify",
                                    lambda m : m['id'] == id, 
                                    until=end,
                                   )
            notify = getResult()
            if notify:
                notify.ret(True)
            if notify['reason'] == 'eof':
                yield self.client.msg("call.drop", {"id": id}).dispatch()
                getResult()

        except AbandonedException, e:
            logger.debug("Call  id)


    def test(self):
        logger.debug(">>> myTest.test()")

        firsttime = True 

        yield self.client.installMsgHandler("call.route", prio = 50)
        getResult()
        yield self.client.installWatchHandler("call.answered")
        getResult()
        #yield self.client.installWatchHandler("chan.disconnected")
        #getResult()
        yield self.client.installWatchHandler("chan.hangup")
        getResult()

        execute = self.client.msg("call.execute",
         {"callto": "dumb/",
          "caller": "appelant",
          "target": "jmfoucher",
         })
        yield execute.dispatch()
        if not getResult():
            logger.warn("can't create monitor connection on jmfoucher")
            monitor = None
        else:
            logger.debug("can monitor jmfoucher")
            try: 
                end = self.client.onwatch(
                    "chan.hangup",
                    lambda m, callid = execute["id"] : m["id"] == callid)

                yield self.client.onwatch(
                    "call.answered",
                    lambda m : m["id"] ==  execute["targetid"],
                    until = end)
                getResult()
                logger.debug("Monitor connection answered.")

                dumbid = execute["id"]
                monitorid = execute["targetid"]
                callid = execute["id"]
                logger.debug("callid = s" % (callid, monitorid))

                self.client.msg("chan.masquerade",
                {"message" : "chan.attach",
                 "id": callid,
                 "source": "wave/play/../../sounds/wp_star_seller_ask.wav"}).enqueue()

                logger.debug("le son est parti")


                while True:

                    logger.debug("dans le while True")

                    yield self.client.onmsg(
                        "chan.dtmf",
                        lambda m : m["id"] == monitorid,
                        end)
                    dtmf = getResult()

                    logger.debug("Dtmf  dtmf["text"])

                    dtmf.ret(True)

                    if dtmf["text"] == "1":
                        if firsttime:
                            firsttime = False

                            logger.warn("on attache le son sur  callid)

                            self.client.msg("chan.masquerade",
                                {"message" : "chan.attach",
                                 "id": callid,
                                 "source": "wave/play/../../sounds/wp_star_seller_wait.wav"}).enqueue()


                            execute = self.client.msg("call.execute",
                             {"callto": "dumb/",
                              "caller": "jmfoucher",
                              "target": 'toto'})
                            yield execute.dispatch()
                            if not getResult():
                                logger.debug("FAILURE")
                            else:
                                logger.debug("SUCCESS")
                                callid2 = execute["id"]
                                targetid2 = execute["targetid"]
                                logger.debug("callid=s" % (callid, monitorid))
                                logger.debug("callid2=s" % (callid2, targetid2))


                                end = self.client.onmsg("chan.hangup",
                                    lambda m, callid = targetid2 : m["id"] == callid, autoreturn = True)

                                yield self.client.onwatch("call.answered",
                                    lambda m : m["targetid"] == callid2, until = end)

                                answered = getResult()
                                logger.debug("answered= answered)

                                logger.debug("on appelle self.conf")
                                logger.debug("callid = s" % (callid, callid2))

                                connect = self.client.msg(
                                    "chan.connect",
                                    {"id": monitorid,
                                     "targetid": targetid2})
                                yield connect.dispatch()

                                if getResult():
                                    logger.debug("connect SUCCESS")
                                else:
                                    logger.debug("connect FAILURE")

                                go(self.WatchDisconnected(monitorid))
                                go(self.WatchDisconnected(targetid2))


                            #yield yate.msg("call.drop", {"id": targetid}).dispatch()
                            #getResult()


            except AbandonedException, e:
                logger.debug("Call  callid)



def start(host, port):
    logger.debug("dans start")

    local_addr = remote_addr = host
    local_port = remote_port = port

    #go(route(yate))
    def start_client(client_yate):
        logger.debug("client started");
        myTest(client_yate)

    installSignalHandlers = 1
    client_factory = TCPDispatcherFactory(start_client)

    reactor.connectTCP(local_addr, local_port, client_factory)

if __name__ == _main_:

    hdlr = logging.StreamHandler()
    formatter = ConsoleFormatter('%(name)s %(levelname)s %(message)s')
    hdlr.setFormatter(formatter)

    yaypm.logger.addHandler(hdlr)
    yaypm.logger.setLevel(logging.DEBUG)
    #yaypm.flow.logger_flow.setLevel(logging.DEBUG)
    yaypm.logger_messages.setLevel(logging.DEBUG)
    yaypm.logger_messages.setLevel(logging.INFO)

    logger.setLevel(logging.DEBUG)
    logger.addHandler(hdlr)

    #f = TCPDispatcherFactory(start)
    #reactor.connectTCP("192.168.4.87", 5039, f)
    start("192.168.4.87", 5039)
    reactor.run()

See also

Personal tools
Namespaces

Variants
Actions
Preface
Configuration
Administrators
Developers