def register_primary(sip_ep, secondary_numbers, expiration_in_seconds=360): sip_ep.re_register_timer = Timer( expiration_in_seconds / 2, register_primary, (sip_ep, secondary_numbers, expiration_in_seconds)) sip_ep.re_register_timer.start() sip_ep.parameters["expires"] = expiration_in_seconds sip_ep.parameters["primary"] = sip_ep.number sip_ep.parameters["primary_port"] = sip_ep.port if not sip_ep.parameters["epid"]: sip_ep.parameters["epid"] = "SC" + util.randStr(6) debug("Sent register from " + sip_ep.number) sip_ep.send_new(message_string=message["Register_primary"], expected_response="200 OK") debug("Got 200OK to register from " + sip_ep.number) if not sip_ep.secondary_lines: # first registration for n in secondary_numbers: line = SipEndpoint(n) line.use_link(sip_ep.link) sip_ep.secondary_lines.append(line) for line in sip_ep.secondary_lines: sleep(0.1) register_secondary(sip_ep, line) subscribe_primary(sip_ep) for line in sip_ep.secondary_lines: try: subscribe_secondary(line) line.registered = True except: debug(traceback.format_exc()) raise debug("Subscribed " + line.number + " on " + sip_ep.number) sip_ep.registered = True
def start_new_dialog(self): """ Refresh the SIP dialog specific parameters """ self.parameters.update({ "callId": util.randomCallID(), "fromTag": util.randomTag(), "viaBranch": util.randomBranch(), "epid": lambda x=6: "SC" + util.randStr(x), "cseq": 1 })
def register_primary(sip_ep, expiration_in_seconds=360): sip_ep.parameters["expires"] = expiration_in_seconds sip_ep.parameters["primary"] = sip_ep.number sip_ep.parameters["primary_port"] = sip_ep.port if not sip_ep.parameters["epid"]: sip_ep.parameters["epid"] = "SC" + util.randStr(6) sip_ep.send_new(message_string=message["Register_primary"], expected_response="200 OK") sip_ep.send_new(message_string=message["Subscribe_secondary"], expected_response="200 OK") subscribe_dialog = sip_ep.waitForMessage("NOTIFY").get_dialog() #subscribe_dialog = sip_ep.current_dialog sip_ep.reply(message_string=message["200_OK_1"]) notify_dialog = sip_ep.waitForMessage("SUBSCRIBE").get_dialog() notify_after_subscribe(sip_ep, notify_dialog) sip_ep.link.register_for_event(("SUBSCRIBE", {}, message["200_OK_1"])) sip_ep.link.register_for_event(("NOTIFY", subscribe_dialog, message["200_OK_1"])) sip_ep.link.register_for_event(("CANCEL", {}, ""))
def reply(self, message_string): """ Send a response to a previously received message """ if "callId" not in self.parameters or not self.parameters['callId']: raise Exception("Cannot reply when we are not in a dialog") m = buildMessage(message_string, self.parameters) for h in ("To", "From", "Via", "Call-ID"): m[h] = self.last_received_message[h] # do we need to set the to tag for all responses? check rfc3261 if "tag=" not in m['To']: m['To'] += ";tag=" + util.randStr(8) if message_string.strip().startswith("SIP"): # Sip response. Use received CSeq m["CSeq"] = self.last_received_message["CSeq"] else: # This is not a response, but a new request in the same dialog, so fix the CSeq # TODO: fix CSeq according to RFC3261 and ACK according to section 17.1.1.3 self.parameters["cseq"] += 1 m["CSeq"] = "{} {}".format(self.parameters["cseq"], m.method) self.link.send(m.contents())
def WaitForCall(user): " Start an agent. Wait for INVITE messages" L = link[user] expectedMessage = "INVITE" while L: # Will stop when we set the link of the user to None try: inBytes = L.waitForData() inmessage = parseBytes(inBytes) assert inmessage.type==expectedEvent,\ "User {} expected {} but got {}".format(user,expectedEvent,inmessage.event) #print("User:{} received {}".format(user,inmessage)) except timeout: pass finally: L = link[user] try: data.parameters["userB"] = user data.parameters["source_port"] = link[user].port m = buildMessage(message["Trying_1"], data.parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = inmessageb[h] #print(m) link[user].send(m.contents()) data.parameters["source_port"] = link[user].port Ringing = buildMessage(message["Ringing_1"], data.parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): Ringing[h] = inmessageb[h] toTag = ";tag=" + util.randStr(8) Ringing["To"] = Ringing["To"] + toTag #print(Ringing) link[user].send(Ringing.contents()) data.parameters["source_port"] = link[user].port m = buildMessage(message["200_OK_SDP_1"], data.parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Ringing[h] m["To"] = m["To"] + toTag #print(m) link[user].send(m.contents()) inBytes = link[user].waitForData() ack = parseBytes(inBytes) #print("IN:",ack) assert ack.type=="Request" and ack.method=="ACK",\ "Sent:\n{}Received:\n{}".format(m,ack) inBytes = link[user].waitForData() Bye = parseBytes(inBytes) #print("IN:",Bye) assert Bye.type=="Request" and Bye.method=="BYE",\ "A side sent:\n{}B side received:\n{}".format(m,inmessage) data.parameters["source_port"] = link[user].port m = buildMessage(message["200_OK_1"], data.parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Bye[h] #print(m) link[user].send(m.contents()) finally: # When call is done wait for next call AgentState(user)
agentThreads = [] busyCallers = [] talkDuration = 10 # Create thread local data data = local() data.parameters = util.dict_2({ "dest_ip_orig": "10.5.42.44", "dest_ip_psap": "10.9.65.45", "dest_port": 5060, "transport": "tcp", "callId": util.randomCallID, "fromTag": util.randomTag, "source_ip": "10.2.31.5", # "source_port":5080, "viaBranch": util.randomBranch, "epid": lambda x=6: "SC" + util.randStr(x), "bodyLength": "0", "expires": "1800" }) def getxml(name): return os.path.join(xmlpath, name) def ConnectSip(user_range, baseLocalPort, localIP=util.getLocalIP()): " Open the connections for the users " connection_pool = {} localPort = baseLocalPort for user in user_range: C = TCPClient(localIP, localPort)
def flow(users): usera = next(users) userb = next(users) parameters["userA"] = usera parameters["userB"] = userb serverThreads.append( util.serverThread(WaitForCstaEvents, usera, assertLeg="A")) serverThreads.append( util.serverThread(WaitForCstaEvents, userb, assertLeg="B")) parameters["source_port"] = link[usera].port Invite = buildMessage(message["Invite_SDP_1"], parameters) # print(Invite) link[usera].send(Invite.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) # print("IN:",inmessage) assert inmessage.type == "Response" and inmessage.status == "100 Trying", \ "Sent:\n{}Received:\n{}".format(Invite, inmessage) # inBytes=linkCsta[usera].waitForData() # cstaevent=parseBytes_csta(inBytes) # assert cstaevent.event=="ServiceInitiated", "Expected:{} Received:{}".format("ServiceInitiated",str(cstaevent)) inBytes = link[userb].waitForData() inmessageb = parseBytes(inBytes) # print("IN:",inmessageb) assert inmessageb.type == "Request" and inmessageb.method == "INVITE", \ "A side sent:\n{}and got Trying, but B side received:\n{}".format(Invite, inmessage) parameters["source_port"] = link[userb].port m = buildMessage(message["Trying_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = inmessageb[h] # print(m) link[userb].send(m.contents()) parameters["source_port"] = link[userb].port Ringing = buildMessage(message["Ringing_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): Ringing[h] = inmessageb[h] toTag = ";tag=" + util.randStr(8) Ringing["To"] = Ringing["To"] + toTag # print(Ringing) link[userb].send(Ringing.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) # print("IN:",inmessage) assert inmessage.type == "Response" and inmessage.status == "180 Ringing", \ "B side sent:\n{}but A side received:\n{}".format(Ringing, inmessage) parameters["source_port"] = link[userb].port m = buildMessage(message["200_OK_SDP_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Ringing[h] m["To"] = m["To"] + toTag # print(m) link[userb].send(m.contents()) inBytes = link[userb].waitForData() ack = parseBytes(inBytes) # print("IN:",ack) assert ack.type == "Request" and ack.method == "ACK", \ "Sent:\n{}Received:\n{}".format(m, ack) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) # print("IN:",inmessage) assert inmessage.type == "Response" and inmessage.status == "200 OK", \ "B side got:\n{}but A side received:\n{}".format(ack, inmessage) parameters["source_port"] = link[usera].port m = buildMessage(message["Ack_1"], parameters) for h in ("To", "From", "Call-ID"): m[h] = inmessage[h] # print(m) link[usera].send(m.contents()) sleep(talkDuration) parameters["source_port"] = link[usera].port m = buildMessage(message["Bye_1"], parameters) for h in ("To", "From", "Call-ID"): m[h] = inmessage[h] # print(m) link[usera].send(m.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) # print("IN:",inmessage) assert inmessage.type == "Response" and inmessage.status == "200 OK", \ "Sent:\n{}Received:\n{}".format(m, inmessage) inBytes = link[userb].waitForData() Bye = parseBytes(inBytes) # print("IN:",Bye) assert Bye.type == "Request" and Bye.method == "BYE", \ "A side sent:\n{}B side received:\n{}".format(m, inmessage) parameters["source_port"] = link[userb].port m = buildMessage(message["200_OK_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Bye[h] # print(m) link[userb].send(m.contents())
def WaitForCall(user, param): " Start an agent. Wait for INVITE messages" parameters = copy(param) parameters["number"] = 0 L = link[user] expectedMessage = "INVITE" while L: # Will stop when we set the link of the user to None try: inBytes = L.waitForData() invite = parseBytes(inBytes) assert invite.type=="Request" and invite.method==expectedMessage,\ "User {} expected {} but got:\n{}".format(user,expectedMessage,invite) #print("User:{} received {}".format(user,inmessage)) break except timeout: pass finally: L = link[user] if not L: return try: parameters["userB"] = user parameters["source_port"] = link[user].port m = buildMessage(message["Trying_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = invite[h] #print(m) link[user].send(m.contents()) Ringing = buildMessage(message["Ringing_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): Ringing[h] = invite[h] for h in ("Allow", "Allow-Events", "X-Siemens-Call-Type"): if h in invite.headers: Ringing[h] = invite[h] toTag = ";tag=" + util.randStr(8) Ringing["To"] = Ringing["To"] + toTag #print(Ringing) link[user].send(Ringing.contents()) sleep(0.5) m = buildMessage(message["200_OK_SDP_1"], parameters) # Preserve Content-Length bkp = m["Content-Length"] for h in Ringing.headers: #("To", "From", "CSeq","Via","Call-ID","Contact"): m[h] = Ringing[h] m["Content-Length"] = bkp link[user].send(m.contents()) inBytes = link[user].waitForData() ack = parseBytes(inBytes) #print("IN:",ack) assert ack.type=="Request" and ack.method=="ACK",\ "Sent:\n{}Received:\n{}".format(m,ack) nobye = True acceptable = ("BYE", "UPDATE") while nobye: inBytes = link[user].waitForData(2 * parameters["talkDuration"]) inmessage = parseBytes(inBytes) nobye = not (inmessage.type == "Request" and inmessage.method == "BYE") assert inmessage.type=="Request" and inmessage.method in acceptable,\ "Expected one of {} but received :\n{}".format(str(acceptable),inmessage) m = buildMessage(message["200_OK_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = inmessage[h] #print(m) link[user].send(m.contents()) except: traceback.print_exc() finally: # When call is done wait for next call del parameters WaitForCall(user, param)
def flow(): parameters["userA"] = usera parameters["userB"] = userb parameters["expires"] = "0" Invite = buildMessage(message["Invite_SDP_1"], parameters) print(Invite) link[usera].send(Invite.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) print("IN:", inmessage) assert inmessage.type == "Response" and inmessage.status == "100 Trying" inBytes = link[userb].waitForData() inmessageb = parseBytes(inBytes) print("IN:", inmessageb) assert inmessageb.type == "Request" and inmessageb.method == "INVITE" parameters["callId"] = inmessage["Call-ID"] m = buildMessage(message["Trying_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = inmessageb[h] print(m) link[userb].send(m.contents()) Ringing = buildMessage(message["Ringing_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): Ringing[h] = inmessageb[h] toTag = ";tag=" + util.randStr(8) Ringing["To"] = Ringing["To"] + toTag print(Ringing) link[userb].send(Ringing.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) print("IN:", inmessage) assert inmessage.type == "Response" and inmessage.status == "180 Ringing" m = buildMessage(message["200_OK_SDP_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Ringing[h] m["To"] = m["To"] + toTag print(m) link[userb].send(m.contents()) inBytes = link[userb].waitForData() inmessage = parseBytes(inBytes) print("IN:", inmessage) assert inmessage.type == "Request" and inmessage.method == "ACK" inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) print("IN:", inmessage) assert inmessage.type == "Response" and inmessage.status == "200 OK" m = buildMessage(message["Ack_1"], parameters) for h in ("To", "From", "Call-ID"): m[h] = inmessage[h] print(m) link[usera].send(m.contents()) sleep(talkDuration) m = buildMessage(message["Bye_1"], parameters) for h in ("To", "From", "Call-ID"): m[h] = inmessage[h] print(m) link[usera].send(m.contents()) inBytes = link[usera].waitForData() inmessage = parseBytes(inBytes) print("IN:", inmessage) assert inmessage.type == "Response" and inmessage.status == "200 OK" inBytes = link[userb].waitForData() Bye = parseBytes(inBytes) print("IN:", Bye) assert Bye.type == "Request" and Bye.method == "BYE" m = buildMessage(message["200_OK_1"], parameters) for h in ("To", "From", "CSeq", "Via", "Call-ID"): m[h] = Bye[h] print(m) link[userb].send(m.contents())