示例#1
0
 def startCreditTimer(self, rtime):
     if self.credit_time != None:
         self.credit_times[0] = rtime + self.credit_time
         self.credit_time = None
     try:
         credit_time = min([x for x in self.credit_times.values() if x != None])
     except ValueError:
         return
     self.credit_timer = TimeoutAbs(self.credit_expires, credit_time, credit_time)
示例#2
0
 def recvEvent(self, event):
     if isinstance(event, CCEventRing):
         scode = event.getData()
         if scode == None:
             code, reason, body = (180, 'Ringing', None)
         else:
             code, reason, body = scode
             if code == 100:
                 return None
             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.lSDP = body
         self.ua.sendUasResponse(code, reason, body)
         if self.ua.no_progress_timer != None:
             self.ua.no_progress_timer.cancel()
             self.ua.no_progress_timer = None
             if self.ua.expire_time != None:
                 self.ua.expire_timer = TimeoutAbs(self.ua.expires,
                                                   self.ua.expire_time)
         if self.ua.p1xx_ts == None:
             self.ua.p1xx_ts = event.rtime
         return (UasStateRinging, self.ua.ring_cbs, event.rtime,
                 event.origin, code)
     elif isinstance(event, CCEventConnect) or isinstance(
             event, CCEventPreConnect):
         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
         if event.extra_headers != None:
             extra_headers = tuple(event.extra_headers)
         else:
             extra_headers = None
         self.ua.lSDP = body
         if self.ua.no_progress_timer != None:
             self.ua.no_progress_timer.cancel()
             self.ua.no_progress_timer = None
         if isinstance(event, CCEventConnect):
             self.ua.sendUasResponse(code, reason, body, self.ua.lContact, ack_wait=False, \
                                     extra_headers=extra_headers)
             if self.ua.expire_timer != None:
                 self.ua.expire_timer.cancel()
                 self.ua.expire_timer = None
             self.ua.startCreditTimer(event.rtime)
             self.ua.connect_ts = event.rtime
             return (UaStateConnected, self.ua.conn_cbs, event.rtime,
                     event.origin)
         else:
             self.ua.sendUasResponse(code, reason, body, self.ua.lContact, ack_wait=True, \
                                     extra_headers=extra_headers)
             return (UaStateConnected, )
     elif isinstance(event, CCEventRedirect):
         scode = event.getData()
         if scode == None:
             scode = (500, 'Failed', None, None)
         self.ua.sendUasResponse(
             scode[0], scode[1], scode[2],
             SipContact(address=SipAddress(url=scode[3])))
         if self.ua.expire_timer != None:
             self.ua.expire_timer.cancel()
             self.ua.expire_timer = None
         if self.ua.no_progress_timer != None:
             self.ua.no_progress_timer.cancel()
             self.ua.no_progress_timer = None
         self.ua.disconnect_ts = event.rtime
         return (UaStateFailed, self.ua.fail_cbs, event.rtime, event.origin,
                 scode[0])
     elif isinstance(event, CCEventFail):
         scode = event.getData()
         if scode == None:
             scode = (500, 'Failed')
         extra_headers = []
         if event.extra_headers != None:
             extra_headers.extend(event.extra_headers)
         if event.challenge != None:
             extra_headers.append(event.challenge)
         if len(extra_headers) == 0:
             extra_headers = None
         else:
             extra_headers = tuple(extra_headers)
         self.ua.sendUasResponse(scode[0], scode[1], reason_rfc3326=event.reason, \
                                 extra_headers=extra_headers)
         if self.ua.expire_timer != None:
             self.ua.expire_timer.cancel()
             self.ua.expire_timer = None
         if self.ua.no_progress_timer != None:
             self.ua.no_progress_timer.cancel()
             self.ua.no_progress_timer = None
         self.ua.disconnect_ts = event.rtime
         return (UaStateFailed, self.ua.fail_cbs, event.rtime, event.origin,
                 scode[0])
     elif isinstance(event, CCEventDisconnect):
         # import sys, traceback
         # traceback.print_stack(file = sys.stdout)
         self.ua.sendUasResponse(500,
                                 'Disconnected',
                                 reason_rfc3326=event.reason)
         if self.ua.expire_timer != None:
             self.ua.expire_timer.cancel()
             self.ua.expire_timer = None
         if self.ua.no_progress_timer != None:
             self.ua.no_progress_timer.cancel()
             self.ua.no_progress_timer = None
         self.ua.disconnect_ts = event.rtime
         return (UaStateDisconnected, self.ua.disc_cbs, event.rtime,
                 event.origin, self.ua.last_scode)
     # print 'wrong event %s in the Trying state' % event
     return None
示例#3
0
 def recvRequest(self, req):
     if req.getMethod() != 'INVITE':
         #print 'wrong request %s in the Trying state' % req.getMethod()
         return None
     self.ua.origin = 'caller'
     #print 'INVITE received in the Idle state, going to the Trying state'
     if req.countHFs('cisco-guid') != 0:
         try:
             self.ua.cGUID = req.getHFBody('cisco-guid').getCopy()
         except:
             self.ua.cGUID = SipCiscoGUID()
     elif req.countHFs('h323-conf-id') != 0:
         try:
             self.ua.cGUID = req.getHFBody('h323-conf-id').getCopy()
         except:
             self.ua.cGUID = SipCiscoGUID()
     else:
         self.ua.cGUID = SipCiscoGUID()
     self.ua.uasResp = req.genResponse(100,
                                       'Trying',
                                       server=self.ua.local_ua)
     self.ua.lCSeq = 100  # XXX: 100 for debugging so that incorrect CSeq generation will be easily spotted
     if self.ua.lContact == None:
         self.ua.lContact = SipContact()
     self.ua.rTarget = req.getHFBody('contact').getUrl().getCopy()
     self.ua.routes = [
         x.getCopy() for x in self.ua.uasResp.getHFBodys('record-route')
     ]
     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()
     self.ua.rAddr0 = self.ua.rAddr
     self.ua.global_config['_sip_tm'].sendResponse(
         self.ua.uasResp, lossemul=self.ua.uas_lossemul)
     self.ua.uasResp.getHFBody('to').setTag(self.ua.lTag)
     self.ua.lUri = SipFrom(
         address=self.ua.uasResp.getHFBody('to').getUri())
     self.ua.rUri = SipTo(
         address=self.ua.uasResp.getHFBody('from').getUri())
     self.ua.cId = self.ua.uasResp.getHFBody('call-id')
     self.ua.global_config['_sip_tm'].regConsumer(
         self.ua, str(self.ua.cId), compact=self.ua.compact_sip)
     if req.countHFs('authorization') == 0:
         auth = None
     else:
         auth = req.getHFBody('authorization').getCopy()
     body = req.getBody()
     self.ua.branch = req.getHFBody('via').getBranch()
     event = CCEventTry((self.ua.cId, self.ua.cGUID, self.ua.rUri.getUrl().username, req.getRURI().username, body, auth, \
       self.ua.rUri.getUri().name), rtime = req.rtime, origin = self.ua.origin)
     try:
         event.reason = req.getHFBody('reason')
     except:
         pass
     try:
         event.max_forwards = req.getHFBody('max-forwards').getNum()
     except:
         pass
     if self.ua.expire_time != None:
         self.ua.expire_time += event.rtime
     if self.ua.no_progress_time != None:
         self.ua.no_progress_time += event.rtime
         if self.ua.expire_time != None and self.ua.no_progress_time >= self.ua.expire_time:
             self.ua.no_progress_time = None
     if self.ua.no_progress_time != None:
         self.ua.no_progress_timer = TimeoutAbs(self.ua.no_progress_expires,
                                                self.ua.no_progress_time)
     elif self.ua.expire_time != None:
         self.ua.expire_timer = TimeoutAbs(self.ua.expires,
                                           self.ua.expire_time)
     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.setup_ts = req.rtime
             return (UasStateTrying, )
         else:
             self.ua.rSDP = body.getCopy()
     else:
         self.ua.rSDP = None
     self.ua.equeue.append(event)
     self.ua.setup_ts = req.rtime
     return (UasStateTrying, )
示例#4
0
 def recvEvent(self, event):
     if isinstance(event, CCEventTry):
         if self.ua.setup_ts == None:
             self.ua.setup_ts = event.rtime
         self.ua.origin = 'callee'
         cId, cGUID, callingID, calledID, body, auth, callingName = 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
         if cId == None:
             self.ua.cId = SipCallId()
         else:
             self.ua.cId = cId.getCopy()
         self.ua.global_config['_sip_tm'].regConsumer(
             self.ua, str(self.ua.cId))
         self.ua.rTarget = SipURL(username=calledID,
                                  host=self.ua.rAddr0[0],
                                  port=self.ua.rAddr0[1])
         self.ua.rUri = SipTo(address=SipAddress(
             url=self.ua.rTarget.getCopy(), hadbrace=True))
         self.ua.rUri.getUrl().port = None
         self.ua.lUri = SipFrom(address=SipAddress(url=SipURL(
             username=callingID),
                                                   hadbrace=True,
                                                   name=callingName))
         self.ua.lUri.getUrl().port = None
         self.ua.lUri.setTag(self.ua.lTag)
         self.ua.lCSeq = 200
         self.ua.lContact = SipContact()
         self.ua.lContact.getUrl().username = callingID
         self.ua.routes = []
         self.ua.cGUID = cGUID
         self.ua.lSDP = body
         req = self.ua.genRequest('INVITE', body, reason=event.reason)
         self.ua.lCSeq += 1
         self.ua.tr = self.ua.global_config['_sip_tm'].newTransaction(req, self.ua.recvResponse, \
           laddress = self.ua.source_address)
         self.ua.auth = None
         if self.ua.expire_time != None:
             self.ua.expire_time += event.rtime
         if self.ua.no_progress_time != None:
             self.ua.no_progress_time += event.rtime
             if self.ua.expire_time != None and self.ua.no_progress_time >= self.ua.expire_time:
                 self.ua.no_progress_time = None
         if self.ua.no_reply_time != None:
             if self.ua.no_reply_time < 32:
                 self.ua.no_reply_time += event.rtime
                 if self.ua.expire_time != None and self.ua.no_reply_time >= self.ua.expire_time:
                     self.ua.no_reply_time = None
                 elif self.ua.no_progress_time != None and self.ua.no_reply_time >= self.ua.no_progress_time:
                     self.ua.no_reply_time = None
             else:
                 self.ua.no_reply_time = None
         if self.ua.no_reply_time != None:
             self.ua.no_reply_timer = TimeoutAbs(self.ua.no_reply_expires,
                                                 self.ua.no_reply_time)
         elif self.ua.no_progress_time != None:
             self.ua.no_progress_timer = TimeoutAbs(
                 self.ua.no_progress_expires, self.ua.no_progress_time)
         elif self.ua.expire_time != None:
             self.ua.expire_timer = TimeoutAbs(self.ua.expires,
                                               self.ua.expire_time)
         return (UacStateTrying, )
     if isinstance(event, CCEventFail) or isinstance(
             event, CCEventRedirect) or isinstance(event,
                                                   CCEventDisconnect):
         return (UaStateDead, self.ua.disc_cbs, event.rtime, event.origin)
     return None
示例#5
0
 def recvResponse(self, resp):
     body = resp.getBody()
     code, reason = resp.getSCode()
     scode = (code, reason, body)
     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 = TimeoutAbs(
                 self.ua.no_progress_expires, self.ua.no_progress_time)
         elif code < 200 and self.ua.expire_time != None:
             self.ua.expire_timer = TimeoutAbs(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 = TimeoutAbs(self.ua.expires,
                                               self.ua.expire_time)
     if code < 200:
         self.ua.last_scode = code
         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.getCopy())))
                 self.ua.rTarget = self.ua.routes.pop(0).getUrl()
                 self.ua.rAddr = self.ua.rTarget.getAddr()
             else:
                 self.ua.rAddr = self.ua.routes[0].getAddr()
         else:
             self.ua.rAddr = self.ua.rTarget.getAddr()
         self.ua.rUri.setTag(resp.getHFBody('to').getTag())
         event = CCEventConnect(scode,
                                rtime=resp.rtime,
                                origin=self.ua.origin)
         self.ua.startCreditTimer(resp.rtime)
         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.connect_ts = resp.rtime
                 return (UaStateConnected, self.ua.conn_cbs, resp.rtime,
                         self.ua.origin)
             else:
                 self.ua.rSDP = body.getCopy()
         else:
             self.ua.rSDP = None
         self.ua.equeue.append(event)
         self.ua.connect_ts = resp.rtime
         return (UaStateConnected, self.ua.conn_cbs, resp.rtime,
                 self.ua.origin)
     if code in (301, 302) and resp.countHFs('contact') > 0:
         scode = (code, reason, body,
                  resp.getHFBody('contact').getUrl().getCopy())
         self.ua.equeue.append(
             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
         self.ua.equeue.append(event)
     self.ua.disconnect_ts = resp.rtime
     return (UaStateFailed, self.ua.fail_cbs, resp.rtime, self.ua.origin,
             code)
示例#6
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 = TimeoutAbs(
                    self.ua.no_progress_expires, self.ua.no_progress_time)
            elif code < 200 and self.ua.expire_time != None:
                self.ua.expire_timer = TimeoutAbs(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 = TimeoutAbs(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)
                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').getUrl().getCopy())
            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)