Example #1
0
def do_nothing(client_yate, server_yate, testid, targetid, callid, remoteid, duration):
    """
    Defines incall activity. Does nothing for specified number of seconds.
    """
    logger.debug("[%d] doing nothing on %s for %d s." % (testid, callid, duration))
    yield sleep(duration)
    getResult()
    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
Example #2
0
def do_nothing(client_yate, server_yate, testid, targetid, callid, remoteid, duration):
    """
    Defines incall activity. Does nothing for specified number of seconds.
    """
    logger.debug("[%d] doing nothing on %s for %d s." % (testid, callid, duration))
    yield sleep(duration)
    getResult()
    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
Example #3
0
def blind_transfer(yate, callid, targetid, transferto, returnto):
    try:
        yate.msg(
            "chan.masquerade",
            {"message" : "call.execute",                
             "id": targetid, "callto": transferto}).enqueue()

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

        notanswered =  yate.onmsg(
            "chan.disconnected",
            lambda m : m["id"] == targetid,
            until = end)

        answered =  yate.onwatch(
            "call.answered",
            lambda m : m["targetid"] == targetid,
            until = end)

        yield XOR(answered, notanswered)
        what, m = getResult()

        if what == 0:
            logger.debug("Blind transfer to: %s done" % transferto)
            m.ret(False)    
            return
        else:
            logger.debug(
                "Blind transfer to: %s failed. Returning to %s" % \
                (transferto, returnto))

            route = yate.msg("call.route",
                             {"called": returnto},
                             until = end)
            yield route.dispatch()

            if not getResult():
                logger.debug("Can't return to: %s" % returnto)
                m.ret(False)
                return
            
            yate.msg("chan.masquerade",
                     {"message" : "call.execute",                
                      "id": m["id"],
                      "callto": route.getRetValue(),
                      "called": returnto}).enqueue()
            yate.ret(m, True)
            
    except AbandonedException, e:
        logger.debug(
            "Blind transfer to: %s failed. Peer has disconnected" % \
            transferto)
Example #4
0
def pbx(yate, callid, targetid, callto, called):
    # Pbx function provides dtmf interface to pbx functions

    logger.debug("Pbx for %s, %s  started" % (callto, callid))
    try:
        # run until hangup:
        end = yate.onwatch("chan.hangup", lambda m: m["id"] == callid)

        while True:
            last_time = time.time()
            ext = ""
            while True:
                yield yate.onmsg("chan.dtmf",
                                 lambda m: m["id"] == callid,
                                 end,
                                 autoreturn=True)
                getResult()
                text = dtmf["text"]
                dtmf.ret(False)
                current_time = time.time()
                if last_time - current_time > 3:
                    ext = text
                else:
                    # * or # initializes transfer
                    if text in ["#", "*"]:
                        break
                    else:
                        ext += text

            # Let routing module resolve the extension

            route = yate.msg("call.route", {"called": ext})
            yield route.dispatch()

            if not getResult():
                # Abandon transfer in case of bad extension
                logger.debug(
                    "Can't route extension: %s. Abandoning transfer." % ext)
                continue
            else:
                print route
                ext = route.getRetValue()

            if (text in ["*"]):
                logger.debug("doing supervised transfer on %s to %s." %
                             (callid, ext))
                go(supervised_transfer(yate, callid, targetid, ext, called))
                break
            else:
                logger.debug("Blind transfer on %s to %s." % (callid, ext))
                go(blind_transfer(yate, callid, targetid, ext, called))
        logger.debug("Pbx for %s finished" % callid)
    except AbandonedException, e:
        logger.debug("Pbx for %s abandoned" % callid)
Example #5
0
def blind_transfer(yate, callid, targetid, transferto, returnto):
    try:
        yate.msg("chan.masquerade", {
            "message": "call.execute",
            "id": targetid,
            "callto": transferto
        }).enqueue()

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

        notanswered = yate.onmsg("chan.disconnected",
                                 lambda m: m["id"] == targetid,
                                 until=end)

        answered = yate.onwatch("call.answered",
                                lambda m: m["targetid"] == targetid,
                                until=end)

        yield XOR(answered, notanswered)
        what, m = getResult()

        if what == 0:
            logger.debug("Blind transfer to: %s done" % transferto)
            m.ret(False)
            return
        else:
            logger.debug(
                "Blind transfer to: %s failed. Returning to %s" % \
                (transferto, returnto))

            route = yate.msg("call.route", {"called": returnto}, until=end)
            yield route.dispatch()

            if not getResult():
                logger.debug("Can't return to: %s" % returnto)
                m.ret(False)
                return

            yate.msg(
                "chan.masquerade", {
                    "message": "call.execute",
                    "id": m["id"],
                    "callto": route.getRetValue(),
                    "called": returnto
                }).enqueue()
            yate.ret(m, True)

    except AbandonedException, e:
        logger.debug(
            "Blind transfer to: %s failed. Peer has disconnected" % \
            transferto)
Example #6
0
def detect_dtmf_and_do_nothing(client_yate, server_yate, testid, targetid, callid, remoteid, duration):
    """
    Defines incall activity. Enables dtmf detection on server and does nothing
    for specified number of seconds.
    """
    server_yate.msg("chan.masquerade",
        attrs = {"message" : "chan.detectdtmf",
                 "id": remoteid,
                 "consumer": "dtmf/"}).enqueue()

    logger.debug("[%d] detecting dtmf on %s for %d s." % (testid, callid, duration))
    yield sleep(duration)
    getResult()
    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
Example #7
0
def detect_dtmf_and_do_nothing(client_yate, server_yate, testid, targetid, callid, remoteid, duration):
    """
    Defines incall activity. Enables dtmf detection on server and does nothing
    for specified number of seconds.
    """
    server_yate.msg("chan.masquerade",
        attrs = {"message" : "chan.detectdtmf",
                 "id": remoteid,
                 "consumer": "dtmf/"}).enqueue()
        
    logger.debug("[%d] detecting dtmf on %s for %d s." % (testid, callid, duration))
    yield sleep(duration)
    getResult()
    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
Example #8
0
def main(yate, called):
    # Main function will start pbx function for connections comming to a
    # given extension. 

    logger.debug("Watching for calls to: %s" % called)    

    while True:
        # Notice that message watches have to be used here to get
	# call.execute attributes after message is handled:
   
        yield yate.onwatch("call.execute", lambda m : m["called"] == called)
        execute = getResult()

        end = yate.onwatch(
            "chan.hangup",
            lambda m : m["id"] == execute["targetid"])

        answered = yate.onwatch(
            "call.answered",
            lambda m : m["id"] == execute["targetid"] , end)

        answered.addCallbacks(
            lambda m, yate, callto: go(pbx(yate, m["id"], m["targetid"], callto, called)),
            lambda m: None,
            [yate, execute["callto"]])
Example #9
0
 def getRemoteId(d):
     yield d
     route = getResult()
     route["called"] = route["called"].replace(impossible_prefix, "")
     remoteid = route["id"]
     route.ret(False)
     yield remoteid
     return
Example #10
0
 def getRemoteId(d):
     yield d
     route = getResult()
     route["called"] = route["called"].replace(impossible_prefix, "")
     remoteid = route["id"]
     route.ret(False)
     yield remoteid
     return
def main(yate):
    #    print "Received message :-)"
    #    execute = getResult()
    #    print "Result"
    #    if not execute:
    #        print "...broken"
    #    else:
    #        print "OK"
    #    yield yate.installMsgHandler("call.route", prio = 50)
    #    if not getResult():
    #        print "WTF"
    #    print "Waiting!"
    #    yield yate.onmsg("call.route", lambda m : True)
    #    print "Got result!"
    #    test = getResult()
    #    if not getResult():
    #        print "WTF2"
    try:
        #        print "Printing!"
        #        print "Message: %s %s %s" % (test["caller"], test["callername"], test["called"])
        #        print "Direct: %s" % (test["direct"])
        execute = yate.msg("call.execute", {
            "callto": "dumb/",
            "caller": "crypto_addict",
            "target": "100"
        })
        yield execute.dispatch()
        ex_r = getResult()
        if not ex_r:
            print "FAILURE"
        else:
            print "SUCCESS"
        dtmf = yate.msg("chan.dtmf", {"targetid": ex_r["id"], "text": "1234"})
        yield dtmf.dispatch()
        if not getResult():
            print "FAILURE"
        else:
            print "SUCCESS"
    except BaseException as e:
        logging.exception("foo")
Example #12
0
def main(yate, called):
    # Main function will start pbx function for connections comming to a
    # given extension.

    logger.debug("Watching for calls to: %s" % called)

    while True:
        # Notice that message watches have to be used here to get
        # call.execute attributes after message is handled:

        yield yate.onwatch("call.execute", lambda m: m["called"] == called)
        execute = getResult()

        end = yate.onwatch("chan.hangup",
                           lambda m: m["id"] == execute["targetid"])

        answered = yate.onwatch("call.answered",
                                lambda m: m["id"] == execute["targetid"], end)

        answered.addCallbacks(
            lambda m, yate, callto: go(
                pbx(yate, m["id"], m["targetid"], callto, called)),
            lambda m: None, [yate, execute["callto"]])
Example #13
0
def load(client_yate, server_yate, target, handler, con_max, tests, monitor):
    """
    Generate load. Needs:
        client and server yate connections;
        target number;
        handler function that defines incall activity;
        starts not more than con_max concurrent calls;
        tests is a list of tests to execute
        monitor is a extension that will be used to monitor tests.
    """
    
    concurrent = []
    monitored = []

    successes, failures = {}, {}

    def success(_, t, start):
        successes[t] = time.time() - start 

    def failure(f, t, start):
        failures[t] = (time.time() - start, f)

    yield server_yate.installMsgHandler("call.route", prio = 50)
    getResult()
    yield client_yate.installWatchHandler("call.answered")
    getResult()
    yield client_yate.installWatchHandler("chan.hangup")
    getResult()
    yield server_yate.installWatchHandler("test.checkpoint")
    getResult()    
   
    if monitor:
        monitorid = None
        monitor_room = None

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

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

                dumbid = execute["id"]
                monitorid = execute["targetid"]

                execute = client_yate.msg(
                    "chan.masquerade",
                    {"message": "call.execute",
                     "id": execute["targetid"],
                     "lonely": "true",
                     "voice": "false",
                     "echo": "false",
                     "smart": "true",
                     "callto": "conf/"})
                yield execute.dispatch()
                if getResult():
                    monitor_room = execute["room"]
                    logger.debug("Monitor conference created.")
                    yield client_yate.msg("call.drop", {"id": dumbid}).dispatch()
                    getResult()
                else:
                    logger.warn("can't create monitor conference on %s" % monitor)
                    monitor = None
            except AbandonedException:
                logger.debug("Monitor connection not answered.")
                monitor = None                

    count = 0

    for t in tests:
        concurrent = select_non_called(concurrent)        
        if len(concurrent) >= con_max:
            logger.debug("waiting on concurrency limit: %d" % con_max)
            yield defer.DeferredList(concurrent, fireOnOneCallback=True)
            _, fired = getResult()
            concurrent.remove(concurrent[fired])

        count = count + 1
        start = time.time()

        route = server_yate.onmsg(
            "call.route",
            lambda m : m["driver"] != "dumb" and m["called"].find(impossible_prefix) >= 0)

        def getRemoteId(d):
            yield d
            route = getResult()
            route["called"] = route["called"].replace(impossible_prefix, "")
            remoteid = route["id"]
            route.ret(False)
            yield remoteid
            return

        remoteid_def = go(getRemoteId(route))
      
        execute = client_yate.msg(
            "call.execute",
            {"callto": "dumb/",
             "target": target % impossible_prefix,
             "maxcall": 1000})

        yield execute.dispatch()

        try:            
            if not getResult():
                route.cancel()
                raise AbandonedException("Call to: %s failed." % target)

            callid = execute["id"]        

            end = client_yate.onwatch(
                "chan.hangup",
                lambda m, callid = callid : m["id"] == callid)

            yield OR(remoteid_def, end, patient = False)

            end_first, remoteid  = getResult()

            if end_first:
                raise AbandonedException("Call to: %s hungup." % target)

            logger.debug("[%d] outgoing call to %s" % (count, callid))
        
            yield client_yate.onwatch(
                "call.answered",
                lambda m : m["targetid"] ==  callid,
                until = end)
            answered = getResult()

            targetid = execute["targetid"]

            monitoring = False

            if monitor and not monitored :
                logger.debug("[%d] monitoring: %s" % (count, callid))
                monitored.append(callid)
                end.addCallback(
                    lambda _, targetid = targetid: client_yate.msg("call.drop", {"id": targetid}).enqueue())

                yield client_yate.msg(
                    "chan.masquerade",
                    {"message": "call.conference",
                     "id": callid,
                     "room": monitor_room}).dispatch()
                getResult()
                monitoring = True

            logger.debug("[%d] recording: %s" % (count, str(callid)))
            client_yate.msg(
                "chan.masquerade",
                {"message": "chan.attach",
                 "id": callid,
#                 "source": "moh/default",
                 "source": "tone/silence",                 
                 "consumer": "wave/record//tmp/recording%s.slin" % \
                     callid.replace("/", "-"),
                 "maxlen": 0}).enqueue()

#            yield remoteid_def
#            remoteid = getResult()

            logger.debug(
                "[%d] running test with local=(%s, %s) remote=%s" %
                (count, targetid, callid, remoteid))

            start = time.time()

            result = go(handler(
                client_yate, server_yate,
                count,
                targetid,                
                callid, remoteid, t))

            result.addCallbacks(success, failure,
                                callbackArgs=(count, start),
                                errbackArgs=(count, start))

            if monitoring:
                result.addCallback(
                    lambda _, mon_id: monitored.remove(mon_id),
                    callid)
                
            concurrent.append(result)
        except AbandonedException, e:
            if not route.called:
                route.cancel()
            logger.warn("[%d] outgoing call to %s abandoned" % (count, callid))
            failure(Failure(e), count, start)            
Example #14
0
    def one_step(step):
        if "c:" in step or "s:" in step:
            media = step.split("|")
            consumer = None
            source = None
            for m in media:
                if m.startswith("c:"):
                    consumer = m[2:]
                elif m.startswith("s:"):
                    source = m[2:]
            if source or consumer:
                attrs = {"message": "chan.attach",
                         "id": callid}
                if source:
                    attrs["source"] = source
                if consumer:
                    attrs["consumer"] = consumer
                client_yate.msg("chan.masquerade", attrs).enqueue()
        elif step == "...":
            logger.debug("[%d] call %s extended" % (testid, callid))
            #tester.extended_calls.append(callid)
            return

        elif "?" in step:
            i = step.find("?")
            check = step[:i]

            timeout = None
            if len(step) > i + 1:
                timeout = int(step[i+1:])

            check_def = server_yate.onwatch(
                    "test.checkpoint",
                    lambda m : m["id"] == remoteid and m["check"] == check,
                    until = end[0])

            if timeout:
                logger.debug(
                    "[%d] waiting for: %ds for checkpoint: %s on: %s" % \
                             (testid, timeout, check, remoteid))
                yield XOR(check_def, sleep(timeout))
                what, _ = getResult()
                if what > 0:
                    logger.warn(
                        "[%d] timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (testid, timeout, check, remoteid))
##                     client_yate.msg("call.drop", {"id": callid}).enqueue()
##                     logger.debug(
##                         "[%d] dropping connection because of timeout: %s" % (testid, remoteid))
                    raise Exception("Timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (timeout, check, remoteid))
                logger.debug(
                    "[%d] checkpoint: %s on: %s passed" % \
                    (testid, check, remoteid))
            else:
                logger.debug(
                    "[%d] Waiting for checkpoint: '%s' on: %s" % \
                        (testid, check, remoteid))
                yield check_def
                getResult()
        elif "!" in step:
            check = step[:-1]
            error = server_yate.onwatch(
                    "test.checkpoint",
                    lambda m : m["id"] == remoteid and m["check"] == check,
                    until = end[0])
            end[0] = OR(end[0], error)

        elif step in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#", "*"]:
            logger.debug("[%d] Sending dtmf: %s to %s" % (testid, step, targetid))
            client_yate.msg(
                "chan.dtmf",
                {"id": callid, "targetid": targetid, "text": step}).enqueue()
        elif "&" in step:
            timeout = int(step[1:])
            ignore_hangup[0] = True
            logger.debug("[%d] Waiting for 'end' checkpoint after hangup for: %d s." % (testid, timeout))
            yield OR(end[0], sleep(timeout), patient = False)
            getResult()
            raise AbandonedException("Timeout while waiting for end.")
        else:
            t = 1
            if "*" in step:
                try:
                    t = int(step[2:])
                except ValueError:
                    pass
            logger.debug("[%d] Sleeping for: %d s." % (testid, t))
            yield OR(end[0], sleep(t), patient = False)
            getResult()
Example #15
0
def dtmf_etc(client_yate, server_yate, testid, targetid, callid, remoteid, test):
    """
    Defines incall activity. Activity is defined in a string, according
    to the following rules:
      1-9,*,#     - sends x as dtmf
      connected?  - waits for test.checkpoint message with check==connected
      connected?x - waits for test.checkpoint message with check==connected for x secs
      error!      - raise exception on test.checkpoint message with check==error
      s:x,c:y     - does chan.attach with source==s and consumer==c
      _           - 1s break, _*x - x times 1s
      ...         - ends tester thread but does not drop connection
    Example: _,1,1? - waits 1 second, sends 1, waits for 1 checkpoint.
    """

    end = [server_yate.onwatch("chan.hangup", lambda m : m["id"] == remoteid)]
    ignore_hangup = [False]

    def one_step(step):
        if "c:" in step or "s:" in step:
            media = step.split("|")
            consumer = None
            source = None
            for m in media:
                if m.startswith("c:"):
                    consumer = m[2:]
                elif m.startswith("s:"):
                    source = m[2:]
            if source or consumer:
                attrs = {"message": "chan.attach",
                         "id": callid}
                if source:
                    attrs["source"] = source
                if consumer:
                    attrs["consumer"] = consumer
                client_yate.msg("chan.masquerade", attrs).enqueue()
        elif step == "...":
            logger.debug("[%d] call %s extended" % (testid, callid))
            #tester.extended_calls.append(callid)
            return

        elif "?" in step:
            i = step.find("?")
            check = step[:i]

            timeout = None
            if len(step) > i + 1:
                timeout = int(step[i+1:])

            check_def = server_yate.onwatch(
                    "test.checkpoint",
                    lambda m : m["id"] == remoteid and m["check"] == check,
                    until = end[0])

            if timeout:
                logger.debug(
                    "[%d] waiting for: %ds for checkpoint: %s on: %s" % \
                             (testid, timeout, check, remoteid))
                yield XOR(check_def, sleep(timeout))
                what, _ = getResult()
                if what > 0:
                    logger.warn(
                        "[%d] timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (testid, timeout, check, remoteid))
##                     client_yate.msg("call.drop", {"id": callid}).enqueue()
##                     logger.debug(
##                         "[%d] dropping connection because of timeout: %s" % (testid, remoteid))
                    raise Exception("Timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (timeout, check, remoteid))
                logger.debug(
                    "[%d] checkpoint: %s on: %s passed" % \
                    (testid, check, remoteid))
            else:
                logger.debug(
                    "[%d] Waiting for checkpoint: '%s' on: %s" % \
                        (testid, check, remoteid))
                yield check_def
                getResult()
        elif "!" in step:
            check = step[:-1]
            error = server_yate.onwatch(
                    "test.checkpoint",
                    lambda m : m["id"] == remoteid and m["check"] == check,
                    until = end[0])
            end[0] = OR(end[0], error)

        elif step in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#", "*"]:
            logger.debug("[%d] Sending dtmf: %s to %s" % (testid, step, targetid))
            client_yate.msg(
                "chan.dtmf",
                {"id": callid, "targetid": targetid, "text": step}).enqueue()
        elif "&" in step:
            timeout = int(step[1:])
            ignore_hangup[0] = True
            logger.debug("[%d] Waiting for 'end' checkpoint after hangup for: %d s." % (testid, timeout))
            yield OR(end[0], sleep(timeout), patient = False)
            getResult()
            raise AbandonedException("Timeout while waiting for end.")
        else:
            t = 1
            if "*" in step:
                try:
                    t = int(step[2:])
                except ValueError:
                    pass
            logger.debug("[%d] Sleeping for: %d s." % (testid, t))
            yield OR(end[0], sleep(t), patient = False)
            getResult()


    def parse(toparse):
        last = None
        for t in toparse:
            if t == ",":
                def x(a, b):
                    yield go(a)
                    getResult()
                    yield go(b)
                    getResult()
                last = (x(last, parse(toparse)))
            elif t == "(":
                last = parse(toparse)
                if toparse.next() != ")":
                    raise Excepion("Unmatched bracket!")
            elif t == ")":
                toparse.back(t)
                break
            elif t == "|":
                def x(a, b):
                    yield OR(go(a), go(b))
                    r = getResult()
                last = x(last, parse(toparse))
            else:
                last = one_step(t)

        if last:
            return last
        else:
            return None

    try:
        yield go(parse(peep(tokenize(test))))
        getResult()

        yield sleep(0.1)
        getResult()
    except Exception, e:
        logger.info("[%d] dropping: %s" % (testid, callid))

        d = OR(client_yate.msg("call.drop", {"id": callid}).dispatch(),
           server_yate.msg("call.drop", {"id": remoteid}).dispatch())

        if type(e) == type(AbandonedException("")) and ignore_hangup[0]:
            yield server_yate.onwatch(
                "test.checkpoint",
                lambda m : m["id"] == remoteid and m["check"] == "end",
                until = sleep(1))
            getResult()
            logger.debug("[%d] call %s finished" % (testid, callid))
            return

        yield d
        getResult()

        logger.debug("[%d] call %s finished" % (testid, callid))

        raise e
Example #16
0
 def x(a, b):
     yield OR(go(a), go(b))
     r = getResult()
Example #17
0
 def x(a, b):
     yield go(a)
     getResult()
     yield go(b)
     getResult()
Example #18
0
        getResult()
    except Exception, e:
        logger.info("[%d] dropping: %s" % (testid, callid))

        d = OR(client_yate.msg("call.drop", {"id": callid}).dispatch(),
           server_yate.msg("call.drop", {"id": remoteid}).dispatch())

        if type(e) == type(AbandonedException("")) and ignore_hangup[0]:
            yield server_yate.onwatch(
                "test.checkpoint",
                lambda m : m["id"] == remoteid and m["check"] == "end",
                until = sleep(1))
            getResult()
            logger.debug("[%d] call %s finished" % (testid, callid))
            return

        yield d
        getResult()

        logger.debug("[%d] call %s finished" % (testid, callid))

        raise e

    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
    yield server_yate.msg("call.drop", {"id": remoteid}).dispatch()
    getResult()

    logger.debug("[%d] call %s finished" % (testid, callid))
Example #19
0
def load(client_yate, server_yate, target, handler, con_max, tests, monitor):
    """
    Generate load. Needs:
        client and server yate connections;
        target number;
        handler function that defines incall activity;
        starts not more than con_max concurrent calls;
        tests is a list of tests to execute
        monitor is a extension that will be used to monitor tests.
    """

    concurrent = []
    monitored = []

    successes, failures = {}, {}

    def success(_, t, start):
        successes[t] = time.time() - start

    def failure(f, t, start):
        failures[t] = (time.time() - start, f)

    yield server_yate.installMsgHandler("call.route", prio = 50)
    getResult()
    yield client_yate.installWatchHandler("call.answered")
    getResult()
    yield client_yate.installWatchHandler("chan.hangup")
    getResult()
    yield server_yate.installWatchHandler("test.checkpoint")
    getResult()

    if monitor:
        monitorid = None
        monitor_room = None

        logger.debug("Creating monitoring connection.")

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

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

                dumbid = execute["id"]
                monitorid = execute["targetid"]

                execute = client_yate.msg(
                    "chan.masquerade",
                    {"message": "call.execute",
                     "id": execute["targetid"],
                     "lonely": "true",
                     "voice": "false",
                     "echo": "false",
                     "smart": "true",
                     "callto": "conf/"})
                yield execute.dispatch()
                if getResult():
                    monitor_room = execute["room"]
                    logger.debug("Monitor conference created.")
                    yield client_yate.msg("call.drop", {"id": dumbid}).dispatch()
                    getResult()
                else:
                    logger.warn("can't create monitor conference on %s" % monitor)
                    monitor = None
            except AbandonedException:
                logger.debug("Monitor connection not answered.")
                monitor = None

    count = 0

    for t in tests:
        concurrent = select_non_called(concurrent)
        if len(concurrent) >= con_max:
            logger.debug("waiting on concurrency limit: %d" % con_max)
            yield defer.DeferredList(concurrent, fireOnOneCallback=True)
            _, fired = getResult()
            concurrent.remove(concurrent[fired])

        count = count + 1
        start = time.time()

        route = server_yate.onmsg(
            "call.route",
            lambda m : m["driver"] != "dumb" and m["called"].find(impossible_prefix) >= 0)

        def getRemoteId(d):
            yield d
            route = getResult()
            route["called"] = route["called"].replace(impossible_prefix, "")
            remoteid = route["id"]
            route.ret(False)
            yield remoteid
            return

        remoteid_def = go(getRemoteId(route))

        execute = client_yate.msg(
            "call.execute",
            {"callto": "dumb/",
             "target": target % impossible_prefix,
             "maxcall": 1000})

        yield execute.dispatch()

        try:
            if not getResult():
                route.cancel()
                raise AbandonedException("Call to: %s failed." % target)

            callid = execute["id"]

            end = client_yate.onwatch(
                "chan.hangup",
                lambda m, callid = callid : m["id"] == callid)

            yield OR(remoteid_def, end, patient = False)

            end_first, remoteid  = getResult()

            if end_first:
                raise AbandonedException("Call to: %s hungup." % target)

            logger.debug("[%d] outgoing call to %s" % (count, callid))

            yield client_yate.onwatch(
                "call.answered",
                lambda m : m["targetid"] ==  callid,
                until = end)
            answered = getResult()

            targetid = execute["targetid"]

            monitoring = False

            if monitor and not monitored :
                logger.debug("[%d] monitoring: %s" % (count, callid))
                monitored.append(callid)
                end.addCallback(
                    lambda _, targetid = targetid: client_yate.msg("call.drop", {"id": targetid}).enqueue())

                yield client_yate.msg(
                    "chan.masquerade",
                    {"message": "call.conference",
                     "id": callid,
                     "room": monitor_room}).dispatch()
                getResult()
                monitoring = True

            logger.debug("[%d] recording: %s" % (count, str(callid)))
            client_yate.msg(
                "chan.masquerade",
                {"message": "chan.attach",
                 "id": callid,
#                 "source": "moh/default",
                 "source": "tone/silence",
                 "consumer": "wave/record//tmp/recording%s.slin" % \
                     callid.replace("/", "-"),
                 "maxlen": 0}).enqueue()

#            yield remoteid_def
#            remoteid = getResult()

            logger.debug(
                "[%d] running test with local=(%s, %s) remote=%s" %
                (count, targetid, callid, remoteid))

            start = time.time()

            result = go(handler(
                client_yate, server_yate,
                count,
                targetid,
                callid, remoteid, t))

            result.addCallbacks(success, failure,
                                callbackArgs=(count, start),
                                errbackArgs=(count, start))

            if monitoring:
                result.addCallback(
                    lambda _, mon_id: monitored.remove(mon_id),
                    callid)

            concurrent.append(result)
        except AbandonedException, e:
            if not route.called:
                route.cancel()
            logger.warn("[%d] outgoing call to %s abandoned" % (count, callid))
            failure(Failure(e), count, start)
Example #20
0
 def x(a, b):
     yield go(a)
     getResult()
     yield go(b)
     getResult()
Example #21
0
 def x(a, b):
     yield OR(go(a), go(b))
     r = getResult()
Example #22
0
def dtmf_etc(client_yate, server_yate, testid, targetid, callid, remoteid,
             test):
    """
    Defines incall activity. Activity is defined in a string, according
    to the following rules:
      1-9,*,#     - sends x as dtmf
      connected?  - waits for test.checkpoint message with check==connected
      connected?x - waits for test.checkpoint message with check==connected for x secs
      error!      - raise exception on test.checkpoint message with check==error
      s:x,c:y     - does chan.attach with source==s and consumer==c
      _           - 1s break, _*x - x times 1s
      ...         - ends tester thread but does not drop connection
    Example: _,1,1? - waits 1 second, sends 1, waits for 1 checkpoint.
    """

    end = [server_yate.onwatch("chan.hangup", lambda m: m["id"] == remoteid)]
    ignore_hangup = [False]

    def one_step(step):
        if "c:" in step or "s:" in step:
            media = step.split("|")
            consumer = None
            source = None
            for m in media:
                if m.startswith("c:"):
                    consumer = m[2:]
                elif m.startswith("s:"):
                    source = m[2:]
            if source or consumer:
                attrs = {"message": "chan.attach", "id": callid}
                if source:
                    attrs["source"] = source
                if consumer:
                    attrs["consumer"] = consumer
                client_yate.msg("chan.masquerade", attrs).enqueue()
        elif step == "...":
            logger.debug("[%d] call %s extended" % (testid, callid))
            #tester.extended_calls.append(callid)
            return

        elif "?" in step:
            i = step.find("?")
            check = step[:i]

            timeout = None
            if len(step) > i + 1:
                timeout = int(step[i + 1:])

            check_def = server_yate.onwatch(
                "test.checkpoint",
                lambda m: m["id"] == remoteid and m["check"] == check,
                until=end[0])

            if timeout:
                logger.debug(
                    "[%d] waiting for: %ds for checkpoint: %s on: %s" % \
                             (testid, timeout, check, remoteid))
                yield XOR(check_def, sleep(timeout))
                what, _ = getResult()
                if what > 0:
                    logger.warn(
                        "[%d] timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (testid, timeout, check, remoteid))
                    ##                     client_yate.msg("call.drop", {"id": callid}).enqueue()
                    ##                     logger.debug(
                    ##                         "[%d] dropping connection because of timeout: %s" % (testid, remoteid))
                    raise Exception("Timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (timeout, check, remoteid))
                logger.debug(
                    "[%d] checkpoint: %s on: %s passed" % \
                    (testid, check, remoteid))
            else:
                logger.debug(
                    "[%d] Waiting for checkpoint: '%s' on: %s" % \
                        (testid, check, remoteid))
                yield check_def
                getResult()
        elif "!" in step:
            check = step[:-1]
            error = server_yate.onwatch(
                "test.checkpoint",
                lambda m: m["id"] == remoteid and m["check"] == check,
                until=end[0])
            end[0] = OR(end[0], error)

        elif step in [
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#", "*"
        ]:
            logger.debug("[%d] Sending dtmf: %s to %s" %
                         (testid, step, targetid))
            client_yate.msg("chan.dtmf", {
                "id": callid,
                "targetid": targetid,
                "text": step
            }).enqueue()
        elif "&" in step:
            timeout = int(step[1:])
            ignore_hangup[0] = True
            logger.debug(
                "[%d] Waiting for 'end' checkpoint after hangup for: %d s." %
                (testid, timeout))
            yield OR(end[0], sleep(timeout), patient=False)
            getResult()
            raise AbandonedException("Timeout while waiting for end.")
        else:
            t = 1
            if "*" in step:
                try:
                    t = int(step[2:])
                except ValueError:
                    pass
            logger.debug("[%d] Sleeping for: %d s." % (testid, t))
            yield OR(end[0], sleep(t), patient=False)
            getResult()

    def parse(toparse):
        last = None
        for t in toparse:
            if t == ",":

                def x(a, b):
                    yield go(a)
                    getResult()
                    yield go(b)
                    getResult()

                last = (x(last, parse(toparse)))
            elif t == "(":
                last = parse(toparse)
                if next(toparse) != ")":
                    raise Exception("Unmatched bracket!")
            elif t == ")":
                toparse.back(t)
                break
            elif t == "|":

                def x(a, b):
                    yield OR(go(a), go(b))
                    r = getResult()

                last = x(last, parse(toparse))
            else:
                last = one_step(t)

        if last:
            return last
        else:
            return None

    try:
        yield go(parse(peep(tokenize(test))))
        getResult()

        yield sleep(0.1)
        getResult()
    except Exception as e:
        logger.info("[%d] dropping: %s" % (testid, callid))

        d = OR(
            client_yate.msg("call.drop", {
                "id": callid
            }).dispatch(),
            server_yate.msg("call.drop", {
                "id": remoteid
            }).dispatch())

        if type(e) == type(AbandonedException("")) and ignore_hangup[0]:
            yield server_yate.onwatch(
                "test.checkpoint",
                lambda m: m["id"] == remoteid and m["check"] == "end",
                until=sleep(1))
            getResult()
            logger.debug("[%d] call %s finished" % (testid, callid))
            return

        yield d
        getResult()

        logger.debug("[%d] call %s finished" % (testid, callid))

        raise e

    logger.debug("[%d] dropping: %s" % (testid, callid))
    yield client_yate.msg("call.drop", {"id": callid}).dispatch()
    getResult()
    yield server_yate.msg("call.drop", {"id": remoteid}).dispatch()
    getResult()

    logger.debug("[%d] call %s finished" % (testid, callid))
Example #23
0
    def one_step(step):
        if "c:" in step or "s:" in step:
            media = step.split("|")
            consumer = None
            source = None
            for m in media:
                if m.startswith("c:"):
                    consumer = m[2:]
                elif m.startswith("s:"):
                    source = m[2:]
            if source or consumer:
                attrs = {"message": "chan.attach", "id": callid}
                if source:
                    attrs["source"] = source
                if consumer:
                    attrs["consumer"] = consumer
                client_yate.msg("chan.masquerade", attrs).enqueue()
        elif step == "...":
            logger.debug("[%d] call %s extended" % (testid, callid))
            #tester.extended_calls.append(callid)
            return

        elif "?" in step:
            i = step.find("?")
            check = step[:i]

            timeout = None
            if len(step) > i + 1:
                timeout = int(step[i + 1:])

            check_def = server_yate.onwatch(
                "test.checkpoint",
                lambda m: m["id"] == remoteid and m["check"] == check,
                until=end[0])

            if timeout:
                logger.debug(
                    "[%d] waiting for: %ds for checkpoint: %s on: %s" % \
                             (testid, timeout, check, remoteid))
                yield XOR(check_def, sleep(timeout))
                what, _ = getResult()
                if what > 0:
                    logger.warn(
                        "[%d] timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (testid, timeout, check, remoteid))
                    ##                     client_yate.msg("call.drop", {"id": callid}).enqueue()
                    ##                     logger.debug(
                    ##                         "[%d] dropping connection because of timeout: %s" % (testid, remoteid))
                    raise Exception("Timeout while waiting %d s for checkpoint: %s on: %s" % \
                        (timeout, check, remoteid))
                logger.debug(
                    "[%d] checkpoint: %s on: %s passed" % \
                    (testid, check, remoteid))
            else:
                logger.debug(
                    "[%d] Waiting for checkpoint: '%s' on: %s" % \
                        (testid, check, remoteid))
                yield check_def
                getResult()
        elif "!" in step:
            check = step[:-1]
            error = server_yate.onwatch(
                "test.checkpoint",
                lambda m: m["id"] == remoteid and m["check"] == check,
                until=end[0])
            end[0] = OR(end[0], error)

        elif step in [
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "#", "*"
        ]:
            logger.debug("[%d] Sending dtmf: %s to %s" %
                         (testid, step, targetid))
            client_yate.msg("chan.dtmf", {
                "id": callid,
                "targetid": targetid,
                "text": step
            }).enqueue()
        elif "&" in step:
            timeout = int(step[1:])
            ignore_hangup[0] = True
            logger.debug(
                "[%d] Waiting for 'end' checkpoint after hangup for: %d s." %
                (testid, timeout))
            yield OR(end[0], sleep(timeout), patient=False)
            getResult()
            raise AbandonedException("Timeout while waiting for end.")
        else:
            t = 1
            if "*" in step:
                try:
                    t = int(step[2:])
                except ValueError:
                    pass
            logger.debug("[%d] Sleeping for: %d s." % (testid, t))
            yield OR(end[0], sleep(t), patient=False)
            getResult()
Example #24
0
def pbx(yate, callid, targetid, callto, called):
    # Pbx function provides dtmf interface to pbx functions
    
    logger.debug("Pbx for %s, %s  started" % (callto, callid))
    try:
        # run until hangup:
        end = yate.onwatch(
            "chan.hangup",
            lambda m : m["id"] ==callid)


        while True:
            last_time = time.time()
            ext = ""        
            while True:            
                yield yate.onmsg(
                    "chan.dtmf",
                    lambda m : m["id"] == callid,
                    end,
                    autoreturn = True)
                getResult()
                text = dtmf["text"]
                dtmf.ret(False)
                current_time = time.time()
                if last_time - current_time > 3:
                    ext = text
                else:
                    # * or # initializes transfer                    
                    if text in ["#", "*"]:
                        break
                    else:
                        ext += text
                       
            # Let routing module resolve the extension

            route = yate.msg("call.route",
                     {"called": ext})
            yield route.dispatch()
            
            if not getResult():
                # Abandon transfer in case of bad extension
                logger.debug(
                    "Can't route extension: %s. Abandoning transfer." % ext)
                continue
            else:
                print route
                ext = route.getRetValue()

            if(text in ["*"]):
                logger.debug(
                    "doing supervised transfer on %s to %s." % (callid, ext))
                go(supervised_transfer(yate, callid, targetid, ext, called))
                break
            else:
                logger.debug(
                    "Blind transfer on %s to %s." % (callid, ext))
                go(blind_transfer(
                    yate, callid, targetid, ext, called))
        logger.debug("Pbx for %s finished" % callid)
    except AbandonedException, e:
        logger.debug("Pbx for %s abandoned" % callid)
Example #25
0
            concurrent.append(result)
        except AbandonedException, e:
            if not route.called:
                route.cancel()
            logger.warn("[%d] outgoing call to %s abandoned" % (count, callid))
            failure(Failure(e), count, start)

    logger.debug(
        "Waiting for %d tests to finish" % len(select_non_called(concurrent)))
    yield defer.DeferredList(concurrent)
    logger.info("Test finished!")

    if monitor and monitorid:
        logger.debug("droping monitor connection")
        yield client_yate.msg("call.drop", {"id": monitorid}).dispatch()
        getResult()
        yield sleep(1)
        getResult()

    logger.debug("stopping reactor!")
    reactor.stop()

    logger.info("-"*80)
    logger.info("Summary")
    logger.info("-"*80)
    logger.info("Tests: %d" % (len(successes) + len(failures)))
    if successes:
        logger.info("-"*80)
        logger.info("Successes: %d" % len(successes))
        logger.info("Avg time: %.2f s" %
                    (reduce(lambda x, y: x + y, successes.values(), 0) /