示例#1
0
文件: SipMsg.py 项目: twmobius/b2bua
 def __init__(self, buf=None):
     self.headers = []
     if buf == None:
         return
     # Locate a body
     self.__mbody = None
     for bdel in ('\r\n\r\n', '\r\r', '\n\n'):
         boff = buf.find(bdel)
         if boff != -1:
             self.__mbody = buf[boff + len(bdel):]
             buf = buf[:boff]
             if len(self.__mbody) == 0:
                 self.__mbody = None
             break
     # Split message into lines and put aside start line
     lines = buf.splitlines()
     self.setSL(lines[0])
     i = 2
     while i < len(lines):
         if lines[i][0] in (' ', '\t'):
             lines[i - 1] += ' ' + lines[i].strip()
             del lines[i]
         else:
             i += 1
     # Parse headers
     self.__content_type = None
     self.__content_length = None
     header_names = []
     for line in lines[1:]:
         try:
             header = SipHeader(line, fixname=True)
             if header.name == 'content-type':
                 self.__content_type = header
             elif header.name == 'content-length':
                 self.__content_length = header
             else:
                 self.headers.append(header)
                 header_names.append(header.name)
         except ESipHeaderCSV as einst:
             for body in einst.bodys:
                 header = SipHeader(name=einst.name, bodys=body)
                 if header.name == 'content-type':
                     self.__content_type = header
                 elif header.name == 'content-length':
                     self.__content_length = header
                 else:
                     self.headers.append(header)
                     header_names.append(header.name)
         except ESipHeaderIgnore:
             continue
     if 'via' not in header_names:
         raise Exception('Via HF is missed')
     if 'to' not in header_names:
         raise Exception('To HF is missed')
     if 'from' not in header_names:
         raise Exception('From HF is missed')
     if 'cseq' not in header_names:
         raise Exception('CSeq HF is missed')
示例#2
0
 def gotreply(self, resp):
     if self.dead:
         return
     if resp.scode < 200:
         return
     if resp.scode >= 200 and resp.scode < 300 and resp.reason != 'Auth Failed':
         contact = None
         if resp.countHFs('contact') > 0:
             contact = resp.getHFBody('contact')
         if contact != None and 'expires' in contact.address.params:
             tout = int(contact.address.params['expires'])
         elif resp.countHFs('expires') > 0:
             tout = resp.getHFBody('expires').getNum()
         else:
             tout = 180
         timer = Timeout(self.doregister, tout)
         if self.rok_cb != None:
             self.rok_cb(timer.etime.realt, contact, self.cb_arg)
         self.atries = 0
         return
     if resp.scode == 401 and resp.countHFs('www-authenticate') != 0 and \
       self.user != None and self.passw != None and self.atries < 3:
         challenge = resp.getHFBody('www-authenticate')
         auth = SipAuthorization(realm=challenge.getRealm(),
                                 nonce=challenge.getNonce(),
                                 method='REGISTER',
                                 uri=str(self.rmsg.ruri),
                                 username=self.user,
                                 password=self.passw)
         for authorization in self.rmsg.getHFs('authorization'):
             self.rmsg.removeHeader(authorization)
         self.rmsg.appendHeader(SipHeader(name='authorization', body=auth))
         self.atries += 1
         self.doregister()
         return
     if resp.scode == 407 and resp.countHFs('proxy-authenticate') != 0 and \
       self.user != None and self.passw != None and self.atries < 3:
         challenge = resp.getHFBody('proxy-authenticate')
         auth = SipProxyAuthorization(realm=challenge.getRealm(),
                                      nonce=challenge.getNonce(),
                                      method='REGISTER',
                                      uri=str(self.rmsg.ruri),
                                      username=self.user,
                                      password=self.passw)
         for authorization in self.rmsg.getHFs('proxy-authorization'):
             self.rmsg.removeHeader(authorization)
         self.rmsg.appendHeader(
             SipHeader(name='proxy-authorization', body=auth))
         self.atries += 1
         self.doregister()
         return
     if self.rfail_cb != None:
         self.rfail_cb(resp.getSL(), self.cb_arg)
     Timeout(self.doregister, 60)
     self.atries = 0
示例#3
0
    def recvRequest(self, req):
        if req.getHFBody('to').getTag() != None:
            # Request within dialog, but no such dialog
            return (req.genResponse(481,
                                    'Call Leg/Transaction Does Not Exist'),
                    None, None)
        if req.getMethod() == 'INVITE':
            # New dialog
            if req.countHFs('via') > 1:
                via = req.getHFBody('via', 1)
            else:
                via = req.getHFBody('via', 0)
            remote_ip = via.getTAddr()[0]
            source = req.getSource()

            # First check if request comes from IP that
            # we want to accept our traffic from
            if '_accept_ips' in self.global_config and \
              not source[0] in self.global_config['_accept_ips']:
                resp = req.genResponse(403, 'Forbidden')
                return (resp, None, None)

            challenge = None
            if self.global_config['auth_enable']:
                # Prepare challenge if no authorization header is present.
                # Depending on configuration, we might try remote ip auth
                # first and then challenge it or challenge immediately.
                if self.global_config['digest_auth'] and \
                  req.countHFs('authorization') == 0:
                    challenge = SipHeader(name='www-authenticate')
                    challenge.getBody().realm = req.getRURI().host
                # Send challenge immediately if digest is the
                # only method of authenticating
                if challenge != None and self.global_config.getdefault(
                        'digest_auth_only', False):
                    resp = req.genResponse(401, 'Unauthorized')
                    resp.appendHeader(challenge)
                    return (resp, None, None)

            pass_headers = []
            for header in self.global_config['_pass_headers']:
                hfs = req.getHFs(header)
                if len(hfs) > 0:
                    pass_headers.extend(hfs)
            cc = CallController(remote_ip, source, self.global_config,
                                pass_headers)
            cc.challenge = challenge
            rval = cc.uaA.recvRequest(req)
            self.ccmap.append(cc)
            return rval
        if req.getMethod() in ('NOTIFY', 'PING'):
            # Whynot?
            return (req.genResponse(200, 'OK'), None, None)
        return (req.genResponse(501, 'Not Implemented'), None, None)
示例#4
0
    def recvRequest(self, req):
        if req.getHFBody('to').getTag() != None:
            # Request within dialog, but no such dialog
            return (req.genResponse(481, 'Call Leg/Transaction Does Not Exist'), None, None)
        if req.getMethod() == 'INVITE':
            # New dialog
            if req.countHFs('via') > 1:
                via = req.getHFBody('via', 1)
            else:
                via = req.getHFBody('via', 0)
            remote_ip = via.getTAddr()[0]
            source = req.getSource()

            # First check if request comes from IP that
            # we want to accept our traffic from
            if self.global_config.has_key('_accept_ips') and \
              not source[0] in self.global_config['_accept_ips']:
                resp = req.genResponse(403, 'Forbidden')
                return (resp, None, None)

            challenge = None
            if self.global_config['auth_enable']:
                # Prepare challenge if no authorization header is present.
                # Depending on configuration, we might try remote ip auth
                # first and then challenge it or challenge immediately.
                if self.global_config['digest_auth'] and \
                  req.countHFs('authorization') == 0:
                    challenge = SipHeader(name = 'www-authenticate')
                    challenge.getBody().realm = req.getRURI().host
                # Send challenge immediately if digest is the
                # only method of authenticating
                if challenge != None and self.global_config.getdefault('digest_auth_only', False):
                    resp = req.genResponse(401, 'Unauthorized')
                    resp.appendHeader(challenge)
                    return (resp, None, None)

            pass_headers = []
            for header in self.global_config['_pass_headers']:
                hfs = req.getHFs(header)
                if len(hfs) > 0:
                    pass_headers.extend(hfs)
            cc = CallController(remote_ip, source, self.global_config, pass_headers)
            cc.challenge = challenge
            rval = cc.uaA.recvRequest(req)
            self.ccmap.append(cc)
            return rval
        if req.getMethod() in ('NOTIFY', 'PING'):
            # Whynot?
            return (req.genResponse(200, 'OK'), None, None)
        return (req.genResponse(501, 'Not Implemented'), None, None)
示例#5
0
文件: UA.py 项目: twmobius/b2bua
 def sendUasResponse(self, scode, reason, body = None, contacts = None, \
   reason_rfc3326 = None, extra_headers = None, ack_wait = False):
     uasResp = self.uasResp.getCopy()
     uasResp.setSCode(scode, reason)
     uasResp.setBody(body)
     if contacts != None:
         for contact in contacts:
             uasResp.appendHeader(SipHeader(name='contact', body=contact))
     if reason_rfc3326 != None:
         uasResp.appendHeader(SipHeader(body=reason_rfc3326))
     if extra_headers != None:
         uasResp.appendHeaders(extra_headers)
     if ack_wait:
         ack_cb = self.recvACK
     else:
         ack_cb = None
     self.global_config['_sip_tm'].sendResponse(uasResp, ack_cb = ack_cb, \
       lossemul = self.uas_lossemul)
示例#6
0
 def cancelTransaction(self, t, reason=None):
     # If we got at least one provisional reply then (state == RINGING)
     # then start CANCEL transaction, otherwise deffer it
     if t.state != RINGING:
         t.cancelPending = True
     else:
         if reason != None:
             t.cancel.appendHeader(SipHeader(body=reason))
         self.newTransaction(t.cancel, userv=t.userv)
示例#7
0
 def recvRequest(self, req):
     via0 = SipVia()
     via0.genBranch()
     via1 = req.getHF('via')
     req.insertHeaderBefore(via1, SipHeader(name='via', body=via0))
     req.setTarget(self.destination)
     print(req)
     self.global_config['_sip_tm'].newTransaction(req, self.recvResponse)
     return (None, None, None)
示例#8
0
文件: UA.py 项目: twmobius/b2bua
 def genRequest(self, method, body = None, nonce = None, realm = None, SipXXXAuthorization = SipAuthorization, \
   reason = None, max_forwards = None):
     if self.outbound_proxy != None:
         target = self.outbound_proxy
     else:
         target = self.rAddr
     if max_forwards != None:
         max_forwards_hf = SipMaxForwards(number=max_forwards)
     else:
         max_forwards_hf = None
     req = SipRequest(method=method,
                      ruri=self.rTarget,
                      to=self.rUri,
                      fr0m=self.lUri,
                      cseq=self.lCSeq,
                      callid=self.cId,
                      contact=self.lContact,
                      routes=self.routes,
                      target=target,
                      cguid=self.cGUID,
                      user_agent=self.local_ua,
                      maxforwards=max_forwards_hf)
     if nonce != None and realm != None and self.username != None and self.password != None:
         auth = SipXXXAuthorization(realm=realm,
                                    nonce=nonce,
                                    method=method,
                                    uri=str(self.rTarget),
                                    username=self.username,
                                    password=self.password)
         req.appendHeader(SipHeader(body=auth))
     if body != None:
         req.setBody(body)
     if self.extra_headers != None:
         req.appendHeaders(self.extra_headers)
     if reason != None:
         req.appendHeader(SipHeader(body=reason))
     self.reqs[self.lCSeq] = req
     return req
示例#9
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))
示例#10
0
 def __init__(self, sroute = None, cself = None):
     if cself != None:
         self.rnum = cself.rnum
         self.addrinfo = cself.addrinfo
         self.cld = cself.cld
         self.cld_set = cself.cld_set
         self.hostport = cself.hostport
         self.hostonly = cself.hostonly
         self.credit_time = cself.credit_time
         self.crt_set = cself.crt_set
         self.expires = cself.expires
         self.no_progress_expires = cself.no_progress_expires
         self.no_reply_expires = cself.no_reply_expires
         self.forward_on_fail = cself.forward_on_fail
         self.user = cself.user
         self.passw = cself.passw
         self.cli = cself.cli
         self.cli_set = cself.cli_set
         self.params = dict(cself.params)
         self.ainfo = cself.ainfo
         if cself.extra_headers != None:
             self.extra_headers = tuple([x.getCopy() for x in cself.extra_headers])
         return
     route = sroute.split(';')
     if route[0].find('@') != -1:
         self.cld, self.hostport = route[0].split('@', 1)
         if len(self.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.
             self.cld = None
         self.cld_set = True
     else:
         self.hostport = route[0]
     if not self.hostport.startswith('['):
         hostport = self.hostport.split(':', 1)
         af = 0
         self.hostonly = hostport[0]
     else:
         hostport = self.hostport[1:].split(']', 1)
         if len(hostport) > 1:
             if len(hostport[1]) == 0:
                 del hostport[1]
             else:
                 hostport[1] = hostport[1][1:]
         af = AF_INET6
         self.hostonly = '[%s]' % hostport[0]
     if len(hostport) == 1:
         port = SipConf.default_port
     else:
         port = int(hostport[1])
     self.ainfo = getaddrinfo(hostport[0], port, af, SOCK_STREAM)
     self.params = {}
     extra_headers = []
     for a, v in [x.split('=', 1) for x in route[1:]]:
         if a == 'credit-time':
             self.credit_time = int(v)
             if self.credit_time < 0:
                 self.credit_time = None
             self.crt_set = True
         elif a == 'expires':
             self.expires = int(v)
             if self.expires < 0:
                 self.expires = None
         elif a == 'hs_scodes':
             self.params['huntstop_scodes'] = tuple([int(x) for x in v.split(',') if len(x.strip()) > 0])
         elif a == 'np_expires':
             self.no_progress_expires = int(v)
             if self.no_progress_expires < 0:
                 self.no_progress_expires = None
         elif a == 'nr_expires':
             self.no_reply_expires = int(v)
             if self.no_reply_expires < 0:
                 self.no_reply_expires = None
         elif a == 'forward_on_fail':
             self.forward_on_fail = True
         elif a == 'auth':
             self.user, self.passw = v.split(':', 1)
         elif a == 'cli':
             self.cli = v
             if len(self.cli) == 0:
                 self.cli = None
             self.cli_set = True
         elif a == 'cnam':
             caller_name = unquote(v)
             if len(caller_name) == 0:
                 caller_name = None
             self.params['caller_name'] = caller_name
         elif a == 'ash':
             ash = SipHeader(unquote(v))
             extra_headers.append(ash)
         elif a == 'rtpp':
             self.params['rtpp'] = (int(v) != 0)
         elif a == 'op':
             host_port = v.split(':', 1)
             if len(host_port) == 1:
                 self.params['outbound_proxy'] = (v, 5060)
             else:
                 self.params['outbound_proxy'] = (host_port[0], int(host_port[1]))
         else:
             self.params[a] = v
     if len(extra_headers) > 0:
         self.extra_headers = tuple(extra_headers)
示例#11
0
 def setWarning(self, eistr):
     self.warning = SipHeader(body=SipWarning(text=eistr))
示例#12
0
 def __init__(self, buf = None, method = None, ruri = None, sipver = 'SIP/2.0', to = None, fr0m = None, via = None, cseq = None, \
              callid = None, maxforwards = None, body = None, contact = None, routes = (), target = None, cguid = None,
              user_agent = None, expires = None):
     SipMsg.__init__(self, buf)
     if buf != None:
         try:
             SipMsg.init_body(self)
         except ESipParseException as e:
             try:
                 e.sip_response = self.genResponse(
                     400, 'Bad Request - %s' % str(e))
             except Exception as e1:
                 print('BUG: Double exception, should not be happening:\n',
                       str(e1))
             raise e
         return
     self.method = method
     self.ruri = ruri
     if target == None:
         if len(routes) == 0:
             self.setTarget(self.ruri.getAddr())
         else:
             self.setTarget(routes[0].getAddr())
     else:
         self.setTarget(target)
     self.sipver = sipver
     self.appendHeader(SipHeader(name='via', body=via))
     if via == None:
         self.getHFBody('via').genBranch()
     self.appendHeaders([SipHeader(name='route', body=x) for x in routes])
     self.appendHeader(SipHeader(name='max-forwards', body=maxforwards))
     self.appendHeader(SipHeader(name='from', body=fr0m))
     if to == None:
         to = SipTo(address=SipAddress(url=ruri))
     self.appendHeader(SipHeader(name='to', body=to))
     self.appendHeader(SipHeader(name='call-id', body=callid))
     self.appendHeader(
         SipHeader(name='cseq', body=SipCSeq(cseq=cseq, method=method)))
     if contact != None:
         self.appendHeader(SipHeader(name='contact', body=contact))
     if expires == None and method == 'INVITE':
         expires = SipHeader(name='expires')
         self.appendHeader(expires)
     elif expires != None:
         expires = SipHeader(name='expires', body=expires)
         self.appendHeader(expires)
     if user_agent != None:
         self.user_agent = user_agent
         self.appendHeader(SipHeader(name='user-agent', bodys=user_agent))
     else:
         self.appendHeader(SipHeader(name='user-agent'))
     if cguid != None:
         self.appendHeader(SipHeader(name='cisco-guid', body=cguid))
         self.appendHeader(SipHeader(name='h323-conf-id', body=cguid))
     if body != None:
         self.setBody(body)
示例#13
0
    def incomingResponse(self, msg, t, checksum):
        # In those two states upper level already notified, only do ACK retransmit
        # if needed
        if t.state == TERMINATED:
            return

        if t.state == TRYING:
            # Stop timers
            if t.teA != None:
                t.teA.cancel()
                t.teA = None

        if t.state in (TRYING, RINGING):
            if t.teB != None:
                t.teB.cancel()
                t.teB = None

            if msg.getSCode()[0] < 200:
                # Privisional response - leave everything as is, except that
                # change state and reload timeout timer
                if t.state == TRYING:
                    t.state = RINGING
                    if t.cancelPending:
                        self.newTransaction(t.cancel, userv=t.userv)
                        t.cancelPending = False
                t.teB = Timeout(self.timerB, t.expires, 1, t)
                self.l1rcache[checksum] = SipTMRetransmitO()
                if t.resp_cb != None:
                    if t.cb_ifver == 1:
                        t.resp_cb(msg)
                    else:
                        t.resp_cb(msg, t)
            else:
                # Final response - notify upper layer and remove transaction
                if t.resp_cb != None:
                    if t.cb_ifver == 1:
                        t.resp_cb(msg)
                    else:
                        t.resp_cb(msg, t)
                if t.needack:
                    # Prepare and send ACK if necessary
                    fcode = msg.getSCode()[0]
                    tag = msg.getHFBody('to').getTag()
                    if tag != None:
                        t.ack.getHFBody('to').setTag(tag)
                    rAddr = None
                    if msg.getSCode()[0] >= 200 and msg.getSCode()[0] < 300:
                        # Some hairy code ahead
                        if msg.countHFs('contact') > 0:
                            rTarget = msg.getHFBody(
                                'contact').getUrl().getCopy()
                        else:
                            rTarget = None
                        routes = [
                            x.getCopy() for x in msg.getHFBodys('record-route')
                        ]
                        routes.reverse()
                        if len(routes) > 0:
                            if not routes[0].getUrl().lr:
                                if rTarget != None:
                                    routes.append(
                                        SipRoute(address=SipAddress(
                                            url=rTarget)))
                                rTarget = routes.pop(0).getUrl()
                                rAddr = rTarget.getAddr()
                            else:
                                rAddr = routes[0].getAddr()
                        elif rTarget != None:
                            rAddr = rTarget.getAddr()
                        if rTarget != None:
                            t.ack.setRURI(rTarget)
                        if rAddr != None:
                            t.ack.setTarget(rAddr)
                        t.ack.delHFs('route')
                        t.ack.appendHeaders(
                            [SipHeader(name='route', body=x) for x in routes])
                    if fcode >= 200 and fcode < 300:
                        t.ack.getHFBody('via').genBranch()
                    if rAddr == None:
                        rAddr = t.address
                    if not t.uack:
                        self.transmitMsg(t.userv, t.ack, rAddr, checksum,
                                         t.compact)
                        if t.req_out_cb != None:
                            t.req_out_cb(t.ack)
                    else:
                        t.state = UACK
                        t.ack_rAddr = rAddr
                        t.ack_checksum = checksum
                        self.l1rcache[checksum] = SipTMRetransmitO()
                        t.teG = Timeout(self.timerG, 64, 1, t)
                        return
                else:
                    self.l1rcache[checksum] = SipTMRetransmitO()
                del self.tclient[t.tid]
                t.cleanup()
示例#14
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