示例#1
0
 def connect(self, ua):
     if self.connect_done or self.disconnect_done:
         return
     event = CCEventFail((503, 'Post-early-session Failure'), \
       origin = 'switch')
     ua.recvEvent(event)
     self.connect_done = True
示例#2
0
 def placeOriginate(self, oroute):
     cId, cGUID, cli, cld, body, auth, caller_name = self.eTry.getData()
     cld = oroute.cld
     self.huntstop_scodes = oroute.params.get('huntstop_scodes', ())
     if 'static_tr_out' in self.global_config:
         cld = re_replace(self.global_config['static_tr_out'], cld)
     if oroute.hostport == 'sip-ua':
         host = self.source[0]
         nh_address, same_af = self.source, True
     else:
         host = oroute.hostonly
         nh_address, same_af = oroute.getNHAddr(self.source)
     if not oroute.forward_on_fail and self.global_config['acct_enable']:
         self.acctO = RadiusAccounting(self.global_config, 'originate', \
           send_start = self.global_config['start_acct_enable'], lperiod = \
           self.global_config.getdefault('alive_acct_int', None))
         self.acctO.ms_precision = self.global_config.getdefault(
             'precise_acct', False)
         self.acctO.setParams(oroute.params.get('bill-to', self.username), oroute.params.get('bill-cli', oroute.cli), \
           oroute.params.get('bill-cld', cld), self.cGUID, self.cId, host)
     else:
         self.acctO = None
     self.acctA.credit_time = oroute.credit_time
     conn_handlers = [self.oConn]
     disc_handlers = []
     if not oroute.forward_on_fail and self.global_config['acct_enable']:
         disc_handlers.append(self.acctO.disc)
     self.uaO = UA(self.global_config, self.recvEvent, oroute.user, oroute.passw, nh_address, oroute.credit_time, tuple(conn_handlers), \
       tuple(disc_handlers), tuple(disc_handlers), dead_cbs = (self.oDead,), expire_time = oroute.expires, \
       no_progress_time = oroute.no_progress_expires, extra_headers = oroute.extra_headers)
     self.uaO.local_ua = self.global_config['_uaname']
     self.uaO.no_reply_time = oroute.no_reply_expires
     if self.source != oroute.params.get('outbound_proxy', None):
         self.uaO.outbound_proxy = oroute.params.get('outbound_proxy', None)
     if self.rtp_proxy_session != None and oroute.params.get('rtpp', True):
         self.uaO.on_local_sdp_change = self.rtp_proxy_session.on_caller_sdp_change
         self.uaO.on_remote_sdp_change = self.rtp_proxy_session.on_callee_sdp_change
         self.rtp_proxy_session.caller.raddress = nh_address
         if body != None:
             body = body.getCopy()
         self.proxied = True
     self.uaO.kaInterval = self.global_config['keepalive_orig']
     if 'group_timeout' in oroute.params:
         timeout, skipto = oroute.params['group_timeout']
         Timeout(self.group_expires, timeout, 1, skipto)
     if self.global_config.getdefault('hide_call_id', False):
         cId = SipCallId(
             md5(str(cId).encode()).hexdigest() + ('-b2b_%d' % oroute.rnum))
     else:
         cId += '-b2b_%d' % oroute.rnum
     event = CCEventTry((cId, cGUID, oroute.cli, cld, body, auth, \
       oroute.params.get('caller_name', self.caller_name)))
     if self.eTry.max_forwards != None:
         event.max_forwards = self.eTry.max_forwards - 1
         if event.max_forwards <= 0:
             self.uaA.recvEvent(CCEventFail((483, 'Too Many Hops')))
             self.state = CCStateDead
             return
     event.reason = self.eTry.reason
     self.uaO.recvEvent(event)
示例#3
0
 def createUa0(self, param):
     self.global_config['_sip_logger'].write(
         'requestCallback %s==>' % (self.id), param)
     res = param.get('invite')
     if (res == None):
         return
     if res == "0":
         self._number = res
         self.uaA.recvEvent(
             CCEventFail((480, 'No Number'),
                         rtime=self._invite_event.rtime))
     else:
         self._number, _type, _gateway, _vos_ip = res.split("|")
         cId, cGUID, cli, cld, body, auth, caller_name = self._invite_event.getData(
         )
         oli = self.cli
         if _type == "3":
             oli = cli + cld[8:]
         event = self._invite_event
         event.data = (SipCallId(), cGUID, oli, self._number, body, auth,
                       caller_name)
         parts = _vos_ip.split(':')
         port = '5060'
         if len(parts) == 2:
             port = parts[1]
         self.uaO = UA(self.global_config,
                       event_cb=self.recvEvent,
                       nh_address=tuple([parts[0], int(port)]))
         self.uaO.recvEvent(event)
示例#4
0
 def connect(self, ua):
     if self.connect_done or self.connect_done:
         return
     event = CCEventFail((501, 'Post-ring Failure'), \
       origin = 'switch')
     ua.recvEvent(event)
     self.connect_done = True
示例#5
0
 def ring(self, ua):
     if self.connect_done or self.disconnect_done:
         return
     event = CCEventFail((502, 'Pre-ring Failure'), \
       origin = 'switch')
     ua.recvEvent(event)
     self.ring_done = True
     self.connect_done = True
示例#6
0
 def recvEvent(self, event, ua):
     if not isinstance(event, CCEventUpdate):
         return (b_test_reinvite.recvEvent(self, event, ua))
     if self.debug_lvl > 0:
         print('Bob(%s): Incoming event: %s, generating failure' %
               (self.cli, str(event)))
     event = CCEventFail((408, 'Nobody is Home'))
     ua.recvEvent(event)
示例#7
0
 def rDone(self, results):
     # Check that we got necessary result from Radius
     if len(results) != 2 or results[1] != 0:
         if isinstance(self.uaA.state, UasStateTrying):
             if self.challenge != None:
                 event = CCEventFail((401, 'Unauthorized'))
                 event.extra_header = self.challenge
             else:
                 event = CCEventFail((403, 'Auth Failed'))
             self.uaA.recvEvent(event)
             self.state = CCStateDead
         return
     if self.global_config['acct_enable']:
         self.acctA = RadiusAccounting(self.global_config, 'answer', \
           send_start = self.global_config['start_acct_enable'], lperiod = \
           self.global_config.getdefault('alive_acct_int', None))
         self.acctA.ms_precision = self.global_config.getdefault('precise_acct', False)
         self.acctA.setParams(self.username, self.cli, self.cld, self.cGUID, self.cId, self.remote_ip)
     else:
         self.acctA = FakeAccounting()
     # Check that uaA is still in a valid state, send acct stop
     if not isinstance(self.uaA.state, UasStateTrying):
         self.acctA.disc(self.uaA, time(), 'caller')
         return
     cli = [x[1][4:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CLI:')]
     if len(cli) > 0:
         self.cli = cli[0]
         if len(self.cli) == 0:
             self.cli = None
     caller_name = [x[1][5:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CNAM:')]
     if len(caller_name) > 0:
         self.caller_name = caller_name[0]
         if len(self.caller_name) == 0:
             self.caller_name = None
     credit_time = [x for x in results[0] if x[0] == 'h323-credit-time']
     if len(credit_time) > 0:
         global_credit_time = int(credit_time[0][1])
     else:
         global_credit_time = None
     if not self.global_config.has_key('static_route'):
         routing = [x for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('Routing:')]
         if len(routing) == 0:
             self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (2)')))
             self.state = CCStateDead
             return
         routing = [x[1][8:].split(';') for x in routing]
     else:
         routing = [self.global_config['static_route'].split(';')]
     rnum = 0
     for route in routing:
         rnum += 1
         if route[0].find('@') != -1:
             cld, host = route[0].split('@')
             if len(cld) == 0:
                 # Allow CLD to be forcefully removed by sending `Routing:@host' entry,
                 # as opposed to the Routing:host, which means that CLD should be obtained
                 # from the incoming call leg.
                 cld = None
         else:
             cld = self.cld
             host = route[0]
         credit_time = global_credit_time
         expires = None
         no_progress_expires = None
         forward_on_fail = False
         user = None
         passw = None
         cli = self.cli
         parameters = {}
         parameters['extra_headers'] = self.pass_headers[:]
         for a, v in [x.split('=') for x in route[1:]]:
             if a == 'credit-time':
                 credit_time = int(v)
                 if credit_time < 0:
                     credit_time = None
             elif a == 'expires':
                 expires = int(v)
                 if expires < 0:
                     expires = None
             elif a == 'hs_scodes':
                 parameters['huntstop_scodes'] = tuple([int(x) for x in v.split(',') if len(x.strip()) > 0])
             elif a == 'np_expires':
                 no_progress_expires = int(v)
                 if no_progress_expires < 0:
                     no_progress_expires = None
             elif a == 'forward_on_fail':
                 forward_on_fail = True
             elif a == 'auth':
                 user, passw = v.split(':', 1)
             elif a == 'cli':
                 cli = v
                 if len(cli) == 0:
                     cli = None
             elif a == 'cnam':
                 caller_name = unquote(v)
                 if len(caller_name) == 0:
                     caller_name = None
                 parameters['caller_name'] = caller_name
             elif a == 'ash':
                 ash = SipHeader(unquote(v))
                 parameters['extra_headers'].append(ash)
             elif a == 'rtpp':
                 parameters['rtpp'] = (int(v) != 0)
             elif a == 'gt':
                 timeout, skip = v.split(',', 1)
                 parameters['group_timeout'] = (int(timeout), rnum + int(skip))
             else:
                 parameters[a] = v
         if self.global_config.has_key('max_credit_time'):
             if credit_time == None or credit_time > self.global_config['max_credit_time']:
                 credit_time = self.global_config['max_credit_time']
         if credit_time == 0 or expires == 0:
             continue
         self.routes.append((rnum, host, cld, credit_time, expires, no_progress_expires, forward_on_fail, user, \
           passw, cli, parameters))
         #print 'Got route:', host, cld
     if len(self.routes) == 0:
         self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (3)')))
         self.state = CCStateDead
         return
     self.state = CCStateARComplete
     self.placeOriginate(self.routes.pop(0))
示例#8
0
 def rDone(self, results):
     # Check that we got necessary result from Radius
     if len(results) != 2 or results[1] != 0:
         if isinstance(self.uaA.state, UasStateTrying):
             if self.challenge != None:
                 event = CCEventFail((401, 'Unauthorized'))
                 event.extra_header = self.challenge
             else:
                 event = CCEventFail((403, 'Auth Failed'))
             self.uaA.recvEvent(event)
             self.state = CCStateDead
         return
     if self.global_config['acct_enable']:
         self.acctA = RadiusAccounting(self.global_config, 'answer', \
           send_start = self.global_config['start_acct_enable'], lperiod = \
           self.global_config.getdefault('alive_acct_int', None))
         self.acctA.ms_precision = self.global_config.getdefault(
             'precise_acct', False)
         self.acctA.setParams(self.username, self.cli, self.cld, self.cGUID,
                              self.cId, self.remote_ip)
     else:
         self.acctA = FakeAccounting()
     # Check that uaA is still in a valid state, send acct stop
     if not isinstance(self.uaA.state, UasStateTrying):
         self.acctA.disc(self.uaA, MonoTime(), 'caller')
         return
     cli = [
         x[1][4:] for x in results[0]
         if x[0] == 'h323-ivr-in' and x[1].startswith('CLI:')
     ]
     if len(cli) > 0:
         self.cli = cli[0]
         if len(self.cli) == 0:
             self.cli = None
     caller_name = [
         x[1][5:] for x in results[0]
         if x[0] == 'h323-ivr-in' and x[1].startswith('CNAM:')
     ]
     if len(caller_name) > 0:
         self.caller_name = caller_name[0]
         if len(self.caller_name) == 0:
             self.caller_name = None
     credit_time = [x for x in results[0] if x[0] == 'h323-credit-time']
     if len(credit_time) > 0:
         credit_time = int(credit_time[0][1])
     else:
         credit_time = None
     if not '_static_route' in self.global_config:
         routing = [
             x for x in results[0]
             if x[0] == 'h323-ivr-in' and x[1].startswith('Routing:')
         ]
         if len(routing) == 0:
             self.uaA.recvEvent(
                 CCEventFail((500, 'Internal Server Error (2)')))
             self.state = CCStateDead
             return
         routing = [B2BRoute(x[1][8:]) for x in routing]
     else:
         routing = [
             self.global_config['_static_route'].getCopy(),
         ]
     rnum = 0
     for oroute in routing:
         rnum += 1
         max_credit_time = self.global_config.getdefault(
             'max_credit_time', None)
         oroute.customize(rnum, self.cld, self.cli, credit_time, self.pass_headers, \
           max_credit_time)
         if oroute.credit_time == 0 or oroute.expires == 0:
             continue
         self.routes.append(oroute)
         #print 'Got route:', oroute.hostport, oroute.cld
     if len(self.routes) == 0:
         self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (3)')))
         self.state = CCStateDead
         return
     self.state = CCStateARComplete
     self.placeOriginate(self.routes.pop(0))
示例#9
0
 def recvEvent(self, event, ua):
     if ua == self.uaA:
         if self.state == CCStateIdle:
             if not isinstance(event, CCEventTry):
                 # Some weird event received
                 self.uaA.recvEvent(CCEventDisconnect(rtime=event.rtime))
                 return
             self.cId, cGUID, self.cli, self.cld, body, auth, self.caller_name = event.getData(
             )
             self.cGUID = cGUID.hexForm()
             if self.cld == None:
                 self.uaA.recvEvent(
                     CCEventFail((500, 'Internal Server Error (1)'),
                                 rtime=event.rtime))
                 self.state = CCStateDead
                 return
             if body != None and '_allowed_pts' in self.global_config:
                 try:
                     body.parse()
                 except:
                     self.uaA.recvEvent(
                         CCEventFail((400, 'Malformed SDP Body'),
                                     rtime=event.rtime))
                     self.state = CCStateDead
                     return
                 allowed_pts = self.global_config['_allowed_pts']
                 mbody = body.content.sections[0].m_header
                 if mbody.transport.lower() == 'rtp/avp':
                     old_len = len(mbody.formats)
                     mbody.formats = [
                         x for x in mbody.formats if x in allowed_pts
                     ]
                     if len(mbody.formats) == 0:
                         self.uaA.recvEvent(
                             CCEventFail((488, 'Not Acceptable Here')))
                         self.state = CCStateDead
                         return
                     if old_len > len(mbody.formats):
                         body.content.sections[0].optimize_a()
             if self.cld.startswith('nat-'):
                 self.cld = self.cld[4:]
                 if body != None:
                     body.content += 'a=nated:yes\r\n'
                 event.data = (self.cId, cGUID, self.cli, self.cld, body,
                               auth, self.caller_name)
             if 'static_tr_in' in self.global_config:
                 self.cld = re_replace(self.global_config['static_tr_in'],
                                       self.cld)
                 event.data = (self.cId, cGUID, self.cli, self.cld, body,
                               auth, self.caller_name)
             if '_rtp_proxy_clients' in self.global_config:
                 self.rtp_proxy_session = Rtp_proxy_session(self.global_config, call_id = self.cId, \
                   notify_socket = self.global_config['b2bua_socket'], \
                   notify_tag = quote('r %s' % str(self.id)))
                 self.rtp_proxy_session.callee.raddress = (self.remote_ip,
                                                           5060)
                 self.rtp_proxy_session.insert_nortpp = True
             self.eTry = event
             self.state = CCStateWaitRoute
             if not self.global_config['auth_enable']:
                 self.username = self.remote_ip
                 self.rDone(((), 0))
             elif auth == None or auth.username == None or len(
                     auth.username) == 0:
                 self.username = self.remote_ip
                 self.auth_proc = self.global_config['_radius_client'].do_auth(self.remote_ip, self.cli, self.cld, self.cGUID, \
                   self.cId, self.remote_ip, self.rDone)
             else:
                 self.username = auth.username
                 self.auth_proc = self.global_config[
                     '_radius_client'].do_auth(auth.username, self.cli,
                                               self.cld, self.cGUID,
                                               self.cId, self.remote_ip,
                                               self.rDone, auth.realm,
                                               auth.nonce, auth.uri,
                                               auth.response)
             return
         if self.state not in (CCStateARComplete, CCStateConnected,
                               CCStateDisconnecting) or self.uaO == None:
             return
         self.uaO.recvEvent(event)
     else:
         if (isinstance(event, CCEventFail) or isinstance(event, CCEventDisconnect)) and self.state == CCStateARComplete and \
           (isinstance(self.uaA.state, UasStateTrying) or isinstance(self.uaA.state, UasStateRinging)) and len(self.routes) > 0:
             if isinstance(event, CCEventFail):
                 code = event.getData()[0]
             else:
                 code = None
             if code == None or code not in self.huntstop_scodes:
                 self.placeOriginate(self.routes.pop(0))
                 return
         self.uaA.recvEvent(event)
示例#10
0
 def rDone(self, results):
     # Check that we got necessary result from Radius
     if len(results) != 2 or results[1] != 0:
         if isinstance(self.uaA.state, UasStateTrying):
             if self.challenge != None:
                 event = CCEventFail((401, 'Unauthorized'))
                 event.extra_header = self.challenge
             else:
                 event = CCEventFail((403, 'Auth Failed'))
             self.uaA.recvEvent(event)
             self.state = CCStateDead
         return
     if self.global_config['acct_enable']:
         self.acctA = RadiusAccounting(self.global_config, 'answer', \
           send_start = self.global_config['start_acct_enable'], lperiod = \
           self.global_config.getdefault('alive_acct_int', None))
         self.acctA.ms_precision = self.global_config.getdefault('precise_acct', False)
         self.acctA.setParams(self.username, self.cli, self.cld, self.cGUID, self.cId, self.remote_ip)
     else:
         self.acctA = FakeAccounting()
     # Check that uaA is still in a valid state, send acct stop
     if not isinstance(self.uaA.state, UasStateTrying):
         self.acctA.disc(self.uaA, MonoTime(), 'caller')
         return
     cli = [x[1][4:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CLI:')]
     if len(cli) > 0:
         self.cli = cli[0]
         if len(self.cli) == 0:
             self.cli = None
     caller_name = [x[1][5:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CNAM:')]
     if len(caller_name) > 0:
         self.caller_name = caller_name[0]
         if len(self.caller_name) == 0:
             self.caller_name = None
     credit_time = [x for x in results[0] if x[0] == 'h323-credit-time']
     if len(credit_time) > 0:
         credit_time = int(credit_time[0][1])
     else:
         credit_time = None
     if not '_static_route' in self.global_config:
         routing = [x for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('Routing:')]
         if len(routing) == 0:
             self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (2)')))
             self.state = CCStateDead
             return
         routing = [B2BRoute(x[1][8:]) for x in routing]
     else:
         routing = [self.global_config['_static_route'].getCopy(),]
     rnum = 0
     for oroute in routing:
         rnum += 1
         max_credit_time = self.global_config.getdefault('max_credit_time', None)
         oroute.customize(rnum, self.cld, self.cli, credit_time, self.pass_headers, \
           max_credit_time)
         if oroute.credit_time == 0 or oroute.expires == 0:
             continue
         self.routes.append(oroute)
         #print 'Got route:', oroute.hostport, oroute.cld
     if len(self.routes) == 0:
         self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (3)')))
         self.state = CCStateDead
         return
     self.state = CCStateARComplete
     self.placeOriginate(self.routes.pop(0))
示例#11
0
 def rDone(self, results):
     # Check that we got necessary result from Radius
     if len(results) != 2 or results[1] != 0:
         if isinstance(self.uaA.state, UasStateTrying):
             if self.challenge != None:
                 event = CCEventFail((401, 'Unauthorized'))
                 event.extra_header = self.challenge
             else:
                 event = CCEventFail((403, 'Auth Failed'))
             self.uaA.recvEvent(event)
             self.state = CCStateDead
         return
     if self.global_config['acct_enable']:
         self.acctA = RadiusAccounting(self.global_config, 'answer', \
           send_start = self.global_config['start_acct_enable'], lperiod = \
           self.global_config.getdefault('alive_acct_int', None))
         self.acctA.ms_precision = self.global_config.getdefault('precise_acct', False)
         self.acctA.setParams(self.username, self.cli, self.cld, self.cGUID, self.cId, self.remote_ip)
     else:
         self.acctA = FakeAccounting()
     # Check that uaA is still in a valid state, send acct stop
     if not isinstance(self.uaA.state, UasStateTrying):
         self.acctA.disc(self.uaA, time(), 'caller')
         return
     cli = [x[1][4:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CLI:')]
     if len(cli) > 0:
         self.cli = cli[0]
         if len(self.cli) == 0:
             self.cli = None
     caller_name = [x[1][5:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CNAM:')]
     if len(caller_name) > 0:
         self.caller_name = caller_name[0]
         if len(self.caller_name) == 0:
             self.caller_name = None
     credit_time = [x for x in results[0] if x[0] == 'h323-credit-time']
     if len(credit_time) > 0:
         global_credit_time = int(credit_time[0][1])
     else:
         global_credit_time = None
     if not self.global_config.has_key('static_route'):
         routing = [x for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('Routing:')]
         if len(routing) == 0:
             self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (2)')))
             self.state = CCStateDead
             return
         routing = [x[1][8:].split(';') for x in routing]
     else:
         routing = [self.global_config['static_route'].split(';')]
     rnum = 0
     for route in routing:
         rnum += 1
         if route[0].find('@') != -1:
             cld, host = route[0].split('@', 1)
             if len(cld) == 0:
                 # Allow CLD to be forcefully removed by sending `Routing:@host' entry,
                 # as opposed to the Routing:host, which means that CLD should be obtained
                 # from the incoming call leg.
                 cld = None
         else:
             cld = self.cld
             host = route[0]
         credit_time = global_credit_time
         expires = None
         no_progress_expires = None
         forward_on_fail = False
         user = None
         passw = None
         cli = self.cli
         parameters = {}
         parameters['extra_headers'] = self.pass_headers[:]
         for a, v in [x.split('=', 1) for x in route[1:]]:
             if a == 'credit-time':
                 credit_time = int(v)
                 if credit_time < 0:
                     credit_time = None
             elif a == 'expires':
                 expires = int(v)
                 if expires < 0:
                     expires = None
             elif a == 'hs_scodes':
                 parameters['huntstop_scodes'] = tuple([int(x) for x in v.split(',') if len(x.strip()) > 0])
             elif a == 'np_expires':
                 no_progress_expires = int(v)
                 if no_progress_expires < 0:
                     no_progress_expires = None
             elif a == 'forward_on_fail':
                 forward_on_fail = True
             elif a == 'auth':
                 user, passw = v.split(':', 1)
             elif a == 'cli':
                 cli = v
                 if len(cli) == 0:
                     cli = None
             elif a == 'cnam':
                 caller_name = unquote(v)
                 if len(caller_name) == 0:
                     caller_name = None
                 parameters['caller_name'] = caller_name
             elif a == 'ash':
                 ash = SipHeader(unquote(v))
                 parameters['extra_headers'].append(ash)
             elif a == 'rtpp':
                 parameters['rtpp'] = (int(v) != 0)
             elif a == 'gt':
                 timeout, skip = v.split(',', 1)
                 parameters['group_timeout'] = (int(timeout), rnum + int(skip))
             elif a == 'op':
                 host_port = v.split(':', 1)
                 if len(host_port) == 1:
                     parameters['outbound_proxy'] = (v, 5060)
                 else:
                     parameters['outbound_proxy'] = (host_port[0], int(host_port[1]))
             else:
                 parameters[a] = v
         if self.global_config.has_key('max_credit_time'):
             if credit_time == None or credit_time > self.global_config['max_credit_time']:
                 credit_time = self.global_config['max_credit_time']
         if credit_time == 0 or expires == 0:
             continue
         self.routes.append((rnum, host, cld, credit_time, expires, no_progress_expires, forward_on_fail, user, \
           passw, cli, parameters))
         #print 'Got route:', host, cld
     if len(self.routes) == 0:
         self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (3)')))
         self.state = CCStateDead
         return
     self.state = CCStateARComplete
     self.placeOriginate(self.routes.pop(0))
示例#12
0
    def recvResponse(self, resp, tr):
        body = resp.getBody()
        code, reason = resp.getSCode()
        scode = (code, reason, body)
        self.ua.last_scode = code

        if self.ua.no_reply_timer != None:
            self.ua.no_reply_timer.cancel()
            self.ua.no_reply_timer = None
            if code == 100 and self.ua.no_progress_time != None:
                self.ua.no_progress_timer = TimeoutAbsMono(
                    self.ua.no_progress_expires, self.ua.no_progress_time)
            elif code < 200 and self.ua.expire_time != None:
                self.ua.expire_timer = TimeoutAbsMono(self.ua.expires,
                                                      self.ua.expire_time)
        if code == 100:
            if self.ua.p100_ts == None:
                self.ua.p100_ts = resp.rtime
            self.ua.equeue.append(
                CCEventRing(scode, rtime=resp.rtime, origin=self.ua.origin))
            return None
        if self.ua.no_progress_timer != None:
            self.ua.no_progress_timer.cancel()
            self.ua.no_progress_timer = None
            if code < 200 and self.ua.expire_time != None:
                self.ua.expire_timer = TimeoutAbsMono(self.ua.expires,
                                                      self.ua.expire_time)
        if code < 200:
            event = CCEventRing(scode, rtime=resp.rtime, origin=self.ua.origin)
            if body != None:
                if self.ua.on_remote_sdp_change != None:
                    self.ua.on_remote_sdp_change(
                        body,
                        lambda x: self.ua.delayed_remote_sdp_update(event, x))
                    self.ua.p1xx_ts = resp.rtime
                    return (UacStateRinging, self.ua.ring_cbs, resp.rtime,
                            self.ua.origin, code)
                else:
                    self.ua.rSDP = body.getCopy()
            else:
                self.ua.rSDP = None
            self.ua.equeue.append(event)
            self.ua.p1xx_ts = resp.rtime
            return (UacStateRinging, self.ua.ring_cbs, resp.rtime,
                    self.ua.origin, code)
        if self.ua.expire_timer != None:
            self.ua.expire_timer.cancel()
            self.ua.expire_timer = None
        if code >= 200 and code < 300:
            if resp.countHFs('contact') > 0:
                self.ua.rTarget = resp.getHFBody('contact').getUrl().getCopy()
            self.ua.routes = [
                x.getCopy() for x in resp.getHFBodys('record-route')
            ]
            self.ua.routes.reverse()
            if len(self.ua.routes) > 0:
                if not self.ua.routes[0].getUrl().lr:
                    self.ua.routes.append(
                        SipRoute(address=SipAddress(url=self.ua.rTarget)))
                    self.ua.rTarget = self.ua.routes.pop(0).getUrl()
                    self.ua.rAddr = self.ua.rTarget.getAddr()
                elif self.ua.outbound_proxy != None:
                    self.ua.routes.append(
                        SipRoute(address=SipAddress(url=self.ua.rTarget)))
                    self.ua.rTarget = self.ua.routes[0].getUrl().getCopy()
                    self.ua.rTarget.lr = False
                    self.ua.rTarget.other = tuple()
                    self.ua.rTarget.headers = tuple()
                else:
                    self.ua.rAddr = self.ua.routes[0].getAddr()
            else:
                self.ua.rAddr = self.ua.rTarget.getAddr()
            tag = resp.getHFBody('to').getTag()
            if tag == None:
                print('tag-less 200 OK, disconnecting')
                scode = (502, 'Bad Gateway')
                self.ua.equeue.append(
                    CCEventFail(scode, rtime=resp.rtime,
                                origin=self.ua.origin))
                # Generate and send BYE
                if resp.countHFs('contact') > 0:
                    self.ua.rTarget = resp.getHFBody(
                        'contact').getUrl().getCopy()
                self.ua.routes = [
                    x.getCopy() for x in resp.getHFBodys('record-route')
                ]
                self.ua.routes.reverse()
                if len(self.ua.routes) > 0:
                    if not self.ua.routes[0].getUrl().lr:
                        self.ua.routes.append(
                            SipRoute(address=SipAddress(url=self.ua.rTarget)))
                        self.ua.rTarget = self.ua.routes.pop(0).getUrl()
                        self.ua.rAddr = self.ua.rTarget.getAddr()
                    elif self.ua.outbound_proxy != None:
                        self.ua.routes.append(
                            SipRoute(address=SipAddress(url=self.ua.rTarget)))
                        self.ua.rTarget = self.ua.routes[0].getUrl().getCopy()
                        self.ua.rTarget.lr = False
                        self.ua.rTarget.other = tuple()
                        self.ua.rTarget.headers = tuple()
                    else:
                        self.ua.rAddr = self.ua.routes[0].getAddr()
                else:
                    self.ua.rAddr = self.ua.rTarget.getAddr()
                req = self.ua.genRequest('BYE')
                self.ua.lCSeq += 1
                self.ua.global_config['_sip_tm'].newTransaction(req, \
                  laddress = self.ua.source_address, compact = self.ua.compact_sip)
                return (UaStateFailed, self.ua.fail_cbs, resp.rtime,
                        self.ua.origin, scode[0])
            self.ua.rUri.setTag(tag)
            if not self.ua.late_media or body == None:
                self.ua.late_media = False
                event = CCEventConnect(scode,
                                       rtime=resp.rtime,
                                       origin=self.ua.origin)
                self.ua.startCreditTimer(resp.rtime)
                self.ua.connect_ts = resp.rtime
                rval = (UaStateConnected, self.ua.conn_cbs, resp.rtime,
                        self.ua.origin)
            else:
                event = CCEventPreConnect(scode,
                                          rtime=resp.rtime,
                                          origin=self.ua.origin)
                tr.uack = True
                self.ua.pending_tr = tr
                rval = (UaStateConnected, )
            if body != None:
                if self.ua.on_remote_sdp_change != None:
                    self.ua.on_remote_sdp_change(
                        body,
                        lambda x: self.ua.delayed_remote_sdp_update(event, x))
                    return rval
                else:
                    self.ua.rSDP = body.getCopy()
            else:
                self.ua.rSDP = None
            self.ua.equeue.append(event)
            return rval
        if code in (301, 302) and resp.countHFs('contact') > 0:
            scode = (code, reason, body,
                     (resp.getHFBody('contact').getUri().getCopy(), ))
            self.ua.equeue.append(
                CCEventRedirect(scode, rtime=resp.rtime,
                                origin=self.ua.origin))
        elif code == 300 and resp.countHFs('contact') > 0:
            redirects = tuple(x.getUri().getCopy()
                              for x in resp.getHFBodys('contact'))
            scode = (code, reason, body, redirects)
            self.ua.equeue.append(
                CCEventRedirect(scode, rtime=resp.rtime,
                                origin=self.ua.origin))
        else:
            event = CCEventFail(scode, rtime=resp.rtime, origin=self.ua.origin)
            if self.ua.pass_auth:
                if code == 401 and resp.countHFs('www-authenticate') != 0:
                    event.challenge = resp.getHF('www-authenticate').getCopy()
                elif code == 407 and resp.countHFs('proxy-authenticate') != 0:
                    event.challenge = resp.getHF(
                        'proxy-authenticate').getCopy()
            if resp.countHFs('reason') != 0:
                event.reason = resp.getHFBody('reason').getCopy()
            self.ua.equeue.append(event)
        self.ua.disconnect_ts = resp.rtime
        return (UaStateFailed, self.ua.fail_cbs, resp.rtime, self.ua.origin,
                code)
示例#13
0
 def recvEvent(self, event):
     if isinstance(event, CCEventDisconnect) or isinstance(
             event, CCEventFail) or isinstance(event, CCEventRedirect):
         #print 'event', event, 'received in the Connected state sending BYE'
         redirect = None
         if isinstance(event, CCEventDisconnect):
             redirect = event.getData()
         elif isinstance(event, CCEventRedirect):
             redirects = event.getData()
             if redirects != None:
                 redirect = redirects[0]
         if redirect != None and self.ua.useRefer:
             req = self.ua.genRequest('REFER', reason=event.reason)
             self.ua.lCSeq += 1
             also = SipReferTo(address=redirect)
             req.appendHeader(SipHeader(name='refer-to', body=also))
             rby = SipReferredBy(address=SipAddress(
                 url=self.ua.lUri.getUrl()))
             req.appendHeader(SipHeader(name='referred-by', body=rby))
             self.ua.global_config['_sip_tm'].newTransaction(req, self.rComplete, \
               laddress = self.ua.source_address, compact = self.ua.compact_sip)
         else:
             req = self.ua.genRequest('BYE', reason=event.reason)
             self.ua.lCSeq += 1
             if redirect != None:
                 also = SipAlso(address=redirect)
                 req.appendHeader(SipHeader(name='also', body=also))
             self.ua.global_config['_sip_tm'].newTransaction(req, \
               laddress = self.ua.source_address, compact = self.ua.compact_sip)
         self.ua.cancelCreditTimer()
         self.ua.disconnect_ts = event.rtime
         return (UaStateDisconnected, self.ua.disc_cbs, event.rtime,
                 event.origin)
     if isinstance(event, CCEventUpdate):
         body = event.getData()
         if str(self.ua.lSDP) == str(body):
             if self.ua.rSDP != None:
                 self.ua.equeue.append(CCEventConnect((200, 'OK', self.ua.rSDP.getCopy()), \
                     rtime = event.rtime, origin = event.origin))
             else:
                 self.ua.equeue.append(CCEventConnect((200, 'OK', None), rtime = event.rtime, \
                   origin = event.origin))
             return None
         if body != None and self.ua.on_local_sdp_change != None and body.needs_update:
             try:
                 self.ua.on_local_sdp_change(
                     body,
                     lambda x: self.ua.recvEvent(event),
                     en_excpt=True)
             except Exception as e:
                 event = CCEventFail((400, 'Malformed SDP Body'),
                                     rtime=event.rtime)
                 event.setWarning(str(e))
                 self.ua.equeue.append(event)
             return None
         if event.max_forwards != None:
             if event.max_forwards <= 0:
                 self.ua.equeue.append(
                     CCEventFail((483, 'Too Many Hops'), rtime=event.rtime))
                 return None
             max_forwards_hf = SipMaxForwards(number=event.max_forwards - 1)
         else:
             max_forwards_hf = None
         req = self.ua.genRequest('INVITE', body, reason = event.reason, \
           max_forwards = max_forwards_hf)
         self.ua.lCSeq += 1
         self.ua.lSDP = body
         self.ua.tr = self.ua.global_config['_sip_tm'].newTransaction(req, self.ua.recvResponse, \
           laddress = self.ua.source_address, cb_ifver = 2, compact = self.ua.compact_sip)
         return (UacStateUpdating, )
     if isinstance(event, CCEventInfo):
         body = event.getData()
         req = self.ua.genRequest('INFO', reason=event.reason)
         req.setBody(body)
         self.ua.lCSeq += 1
         self.ua.global_config['_sip_tm'].newTransaction(req, None, \
           laddress = self.ua.source_address, compact = self.ua.compact_sip)
         return None
     if self.ua.pending_tr != None and isinstance(event, CCEventConnect):
         if self.ua.expire_timer != None:
             self.ua.expire_timer.cancel()
             self.ua.expire_timer = None
         code, reason, body = event.getData()
         if body != None and self.ua.on_local_sdp_change != None and body.needs_update:
             self.ua.on_local_sdp_change(body,
                                         lambda x: self.ua.recvEvent(event))
             return None
         self.ua.startCreditTimer(event.rtime)
         self.ua.connect_ts = event.rtime
         self.ua.lSDP = body
         self.ua.pending_tr.ack.setBody(body)
         self.ua.global_config['_sip_tm'].sendACK(self.ua.pending_tr)
         self.ua.pending_tr = None
         for callback in self.ua.conn_cbs:
             callback(self.ua, event.rtime, self.ua.origin)
         return None
     #print 'wrong event %s in the Connected state' % event
     return None
示例#14
0
    def recvResponse(self, resp, tr):
        body = resp.getBody()
        code, reason = resp.getSCode()
        scode = (code, reason, body)
        if code < 200:
            self.ua.equeue.append(
                CCEventRing(scode, rtime=resp.rtime, origin=self.ua.origin))
            return None
        if code >= 200 and code < 300:
            event = CCEventConnect(scode,
                                   rtime=resp.rtime,
                                   origin=self.ua.origin)
            if body != None:
                if self.ua.on_remote_sdp_change != None:
                    cb_func = lambda x: self.ua.delayed_remote_sdp_update(
                        event, x)
                    try:
                        self.ua.on_remote_sdp_change(body,
                                                     cb_func,
                                                     en_excpt=True)
                    except Exception as e:
                        event = CCEventFail((502, 'Bad Gateway'),
                                            rtime=event.rtime)
                        event.setWarning('Malformed SDP Body received from ' \
                          'downstream: "%s"' % str(e))
                        return self.updateFailed(event)
                    return (UaStateConnected, )
                else:
                    self.ua.rSDP = body.getCopy()
            else:
                self.ua.rSDP = None
            self.ua.equeue.append(event)
            return (UaStateConnected, )
        if code in (301, 302) and resp.countHFs('contact') > 0:
            scode = (code, reason, body,
                     (resp.getHFBody('contact').getUri().getCopy(), ))
            event = CCEventRedirect(scode,
                                    rtime=resp.rtime,
                                    origin=self.ua.origin)
        elif code == 300 and resp.countHFs('contact') > 0:
            redirects = tuple(x.getUri().getCopy()
                              for x in resp.getHFBodys('contact'))
            scode = (code, reason, body, redirects)
            event = CCEventRedirect(scode,
                                    rtime=resp.rtime,
                                    origin=self.ua.origin)
        else:
            event = CCEventFail(scode, rtime=resp.rtime, origin=self.ua.origin)
            try:
                event.reason = resp.getHFBody('reason')
            except:
                pass

        if code in (408, 481):
            # If the response for a request within a dialog is a 481
            # (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the
            # UAC SHOULD terminate the dialog.  A UAC SHOULD also terminate a
            # dialog if no response at all is received for the request (the
            # client transaction would inform the TU about the timeout.)
            return self.updateFailed(event)

        self.ua.equeue.append(event)
        return (UaStateConnected, )