Exemple #1
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, 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, )
Exemple #2
0
 def recvResponse(self, resp):
     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:
                 self.ua.on_remote_sdp_change(
                     body,
                     lambda x: self.ua.delayed_remote_sdp_update(event, x))
                 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').getUrl().getCopy())
         self.ua.equeue.append(
             CCEventRedirect(scode, rtime=resp.rtime,
                             origin=self.ua.origin))
     elif 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.)
         event = CCEventDisconnect(rtime=resp.rtime, origin=self.ua.origin)
         try:
             event.reason = resp.getHFBody('reason')
         except:
             pass
         self.ua.equeue.append(event)
         self.ua.cancelCreditTimer()
         self.ua.disconnect_ts = resp.rtime
         return (UaStateDisconnected, self.ua.disc_cbs, resp.rtime,
                 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)
     return (UaStateConnected, )
Exemple #3
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'
         if not isinstance(event, CCEventFail):
             redirect = event.getData()
         else:
             redirect = None
         if redirect != None and self.ua.useRefer:
             req = self.ua.genRequest('REFER', reason=event.reason)
             self.ua.lCSeq += 1
             also = SipReferTo(address=SipAddress(url=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=SipAddress(url=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, 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, )
Exemple #4
0
class UacStateUpdating(UaStateGeneric):
    sname = 'Updating(UAC)'
    triedauth = False
    connected = True

    def recvRequest(self, req):
        if req.getMethod() == 'INVITE':
            self.ua.global_config['_sip_tm'].sendResponse(
                req.genResponse(491,
                                'Request Pending',
                                server=self.ua.local_ua))
            return None
        elif req.getMethod() == 'BYE':
            self.ua.global_config['_sip_tm'].cancelTransaction(self.ua.tr)
            self.ua.global_config['_sip_tm'].sendResponse(
                req.genResponse(200, 'OK', server=self.ua.local_ua))
            # print 'BYE received in the Updating state, going to the Disconnected state'
            event = CCEventDisconnect(rtime=req.rtime, origin=self.ua.origin)
            try:
                event.reason = req.getHFBody('reason')
            except:
                pass
            self.ua.equeue.append(event)
            self.ua.cancelCreditTimer()
            self.ua.disconnect_ts = req.rtime
            return (UaStateDisconnected, self.ua.disc_cbs, req.rtime,
                    self.ua.origin)
        # print 'wrong request %s in the state Updating' % req.getMethod()
        return None

    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, 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').getUrl().getCopy())
            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, )
Exemple #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)
Exemple #6
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)