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, )
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, )
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, )
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, )
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)
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)