예제 #1
0
 def recvResponse(self, resp, tr):
     code, reason = resp.getSCode()
     if code < 200:
         return None
     if self.te != None:
         self.te.cancel()
         self.te = None
     # When the final response arrives make sure to send BYE
     # if response is positive 200 OK and move into
     # UaStateDisconnected to catch any in-flight BYE from the
     # called party.
     #
     # If the response is negative or redirect go to the UaStateDead
     # immediately, since this means that we won't receive any more
     # requests from the calling party. XXX: redirects should probably
     # somehow reported to the upper level, but it will create
     # significant additional complexity there, since after signalling
     # Failure/Disconnect calling party don't expect any more
     # events to be delivered from the called one. In any case,
     # this should be fine, since we are in this state only when
     # caller already has declared his wilingless to end the session,
     # so that he is probably isn't interested in redirects anymore.
     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()
         self.ua.rUri.setTag(resp.getHFBody('to').getTag())
         req = self.ua.genRequest('BYE')
         self.ua.lCSeq += 1
         self.ua.global_config['_sip_tm'].newTransaction(req, \
           laddress = self.ua.source_address)
         return (UaStateDisconnected, )
     return (UaStateDead, )
예제 #2
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, )
예제 #3
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] = (None, None, None)
                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)
                    else:
                        t.state = UACK
                        t.ack_rAddr = rAddr
                        t.ack_checksum = checksum
                        self.l1rcache[checksum] = (None, None, None)
                        t.teG = Timeout(self.timerG, 64, 1, t)
                        return
                else:
                    self.l1rcache[checksum] = (None, None, None)
                del self.tclient[t.tid]
                t.cleanup()
예제 #4
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)
예제 #5
0
 def recvResponse(self, resp, tr):
     body = resp.getBody()
     code, reason = resp.getSCode()
     scode = (code, reason, body)
     if code < 200:
         if self.ua.p1xx_ts == None:
             self.ua.p1xx_ts = resp.rtime
         self.ua.last_scode = code
         event = CCEventRing(scode, rtime=resp.rtime, origin=self.ua.origin)
         for ring_cb in self.ua.ring_cbs:
             ring_cb(self.ua, resp.rtime, self.ua.origin, code)
         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 None
             else:
                 self.ua.rSDP = body.getCopy()
         else:
             self.ua.rSDP = None
         self.ua.equeue.append(event)
         return None
     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))
             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)
         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)