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