? a ? b ? b2bua_radius.init ? c ? delicense.py ? relicense.py Index: UA.py =================================================================== RCS file: /cvsroot/sippy/sippy/UA.py,v retrieving revision 1.11 diff -d -u -r1.11 UA.py --- UA.py 26 Feb 2009 09:56:59 -0000 1.11 +++ UA.py 2 Apr 2009 23:47:54 -0000 @@ -244,12 +244,12 @@ self.reqs[self.lCSeq] = req return req - def sendUasResponse(self, scode, reason, body = None, contact = None): + def sendUasResponse(self, scode, reason, body = None, contacts = ()): self.uasResp.setSCode(scode, reason) self.uasResp.setBody(body) self.uasResp.delHFs('www-authenticate') self.uasResp.delHFs('contact') - if contact != None: + for contact in contacts: self.uasResp.appendHeader(SipHeader(name = 'contact', body = contact)) self.global_config['sip_tm'].sendResponse(self.uasResp) Index: UacStateRinging.py =================================================================== RCS file: /cvsroot/sippy/sippy/UacStateRinging.py,v retrieving revision 1.6 diff -d -u -r1.6 UacStateRinging.py --- UacStateRinging.py 26 Nov 2008 19:46:41 -0000 1.6 +++ UacStateRinging.py 2 Apr 2009 23:47:55 -0000 @@ -87,7 +87,8 @@ self.ua.equeue.append(event) return (UaStateConnected, self.ua.conn_cbs, resp.rtime) if code in (301, 302) and resp.countHFs('contact') > 0: - scode = (code, reason, body, resp.getHFBody('contact').getUrl().getCopy()) + contacts = tuple([x.getUrl().getCopy() for x in resp.getHFBodys('contact')]) + scode = (code, reason, body, contacts) self.ua.equeue.append(CCEventRedirect(scode, rtime = resp.rtime)) else: self.ua.equeue.append(CCEventFail(scode, rtime = resp.rtime)) Index: UacStateTrying.py =================================================================== RCS file: /cvsroot/sippy/sippy/UacStateTrying.py,v retrieving revision 1.6 diff -d -u -r1.6 UacStateTrying.py --- UacStateTrying.py 26 Nov 2008 19:46:41 -0000 1.6 +++ UacStateTrying.py 2 Apr 2009 23:47:55 -0000 @@ -91,7 +91,8 @@ self.ua.equeue.append(event) return (UaStateConnected, self.ua.conn_cbs, resp.rtime) if code in (301, 302) and resp.countHFs('contact') > 0: - scode = (code, reason, body, resp.getHFBody('contact').getUrl().getCopy()) + contacts = tuple([x.getUrl().getCopy() for x in resp.getHFBodys('contact')]) + scode = (code, reason, body, contacts) self.ua.equeue.append(CCEventRedirect(scode, rtime = resp.rtime)) else: self.ua.equeue.append(CCEventFail(scode, rtime = resp.rtime)) Index: UacStateUpdating.py =================================================================== RCS file: /cvsroot/sippy/sippy/UacStateUpdating.py,v retrieving revision 1.7 diff -d -u -r1.7 UacStateUpdating.py --- UacStateUpdating.py 9 Dec 2008 20:03:23 -0000 1.7 +++ UacStateUpdating.py 2 Apr 2009 23:47:55 -0000 @@ -71,7 +71,8 @@ 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()) + contacts = tuple([x.getUrl().getCopy() for x in resp.getHFBodys('contact')]) + scode = (code, reason, body, contacts) self.ua.equeqe.append(CCEventRedirect(scode, rtime = resp.rtime)) elif code in (408, 481): # If the response for a request within a dialog is a 481 Index: UasStateRinging.py =================================================================== RCS file: /cvsroot/sippy/sippy/UasStateRinging.py,v retrieving revision 1.3 diff -d -u -r1.3 UasStateRinging.py --- UasStateRinging.py 18 Feb 2008 19:49:45 -0000 1.3 +++ UasStateRinging.py 2 Apr 2009 23:47:55 -0000 @@ -55,7 +55,7 @@ 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, self.ua.lContact) + self.ua.sendUasResponse(code, reason, body, (self.ua.lContact,)) if self.ua.expire_timer != None: self.ua.expire_timer.cancel() self.ua.expire_timer = None @@ -64,7 +64,8 @@ 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]))) + self.ua.sendUasResponse(scode[0], scode[1], scode[2], \ + [SipContact(address = SipAddress(url = x)) for x in scode[3]]) if self.ua.expire_timer != None: self.ua.expire_timer.cancel() self.ua.expire_timer = None Index: UasStateTrying.py =================================================================== RCS file: /cvsroot/sippy/sippy/UasStateTrying.py,v retrieving revision 1.3 diff -d -u -r1.3 UasStateTrying.py --- UasStateTrying.py 18 Feb 2008 19:49:45 -0000 1.3 +++ UasStateTrying.py 2 Apr 2009 23:47:55 -0000 @@ -56,7 +56,7 @@ 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, self.ua.lContact) + self.ua.sendUasResponse(code, reason, body, (self.ua.lContact,)) if self.ua.expire_timer != None: self.ua.expire_timer.cancel() self.ua.expire_timer = None @@ -68,7 +68,8 @@ 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]))) + self.ua.sendUasResponse(scode[0], scode[1], scode[2], \ + [SipContact(address = SipAddress(url = x)) for x in scode[3]]) if self.ua.expire_timer != None: self.ua.expire_timer.cancel() self.ua.expire_timer = None Index: UasStateUpdating.py =================================================================== RCS file: /cvsroot/sippy/sippy/UasStateUpdating.py,v retrieving revision 1.5 diff -d -u -r1.5 UasStateUpdating.py --- UasStateUpdating.py 26 Feb 2009 22:32:12 -0000 1.5 +++ UasStateUpdating.py 2 Apr 2009 23:47:56 -0000 @@ -85,13 +85,14 @@ 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, self.ua.lContact) + self.ua.sendUasResponse(code, reason, body, (self.ua.lContact,)) 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]))) + self.ua.sendUasResponse(scode[0], scode[1], scode[2], \ + [SipContact(address = SipAddress(url = x)) for x in scode[3]]) return (UaStateConnected,) elif isinstance(event, CCEventFail): scode = event.getData() Index: b2bua_radius.py =================================================================== RCS file: /cvsroot/sippy/sippy/b2bua_radius.py,v retrieving revision 1.49 diff -d -u -r1.49 b2bua_radius.py --- b2bua_radius.py 26 Feb 2009 09:58:27 -0000 1.49 +++ b2bua_radius.py 2 Apr 2009 23:47:56 -0000 @@ -33,10 +33,12 @@ from Signal import Signal from SipFrom import SipFrom from SipTo import SipTo +from SipAddress import SipAddress from SipURL import SipURL from SipCiscoGUID import SipCiscoGUID from UA import UA -from CCEvents import CCEventRing, CCEventConnect, CCEventDisconnect, CCEventTry, CCEventUpdate, CCEventFail +from CCEvents import CCEventRing, CCEventConnect, CCEventDisconnect, \ + CCEventTry, CCEventUpdate, CCEventFail, CCEventRedirect from UasStateTrying import UasStateTrying from UasStateRinging import UasStateRinging from UaStateDead import UaStateDead @@ -109,6 +111,8 @@ pass_headers = None auth_proc = None proxied = False + redirect_params = None + redirects = None def __init__(self, remote_ip, source, global_config, pass_headers): self.id = CallController.id @@ -120,6 +124,7 @@ self.state = CCStateIdle self.uaO = None self.routes = [] + self.redirects = [] self.remote_ip = remote_ip self.source = source self.pass_headers = pass_headers @@ -187,15 +192,26 @@ return self.uaO.recvEvent(event) else: - if (isinstance(event, CCEventFail) or isinstance(event, CCEventDisconnect)) and self.state == CCStateARComplete and \ - (isinstance(self.uaA.state, UasStateTrying) or isinstance(self.uaA.state, UasStateRinging)) and len(self.routes) > 0: - if isinstance(event, CCEventFail): - code = event.getData()[0] - else: - code = None - if code == None or code not in self.huntstop_scodes: - self.placeOriginate(self.routes.pop(0)) + if (isinstance(self.uaA.state, UasStateTrying) or isinstance(self.uaA.state, UasStateRinging)) and \ + self.state == CCStateARComplete: + if isinstance(event, CCEventRedirect): + # redirect of redirect is not permitted + if len(self.redirects) == 0: + self.redirects = list(event.getData()[3]) + self.placeOriginateRedirect(self.redirects.pop(0)) return + elif (isinstance(event, CCEventFail) or isinstance(event, CCEventDisconnect)) and \ + (len(self.routes) > 0 or len(self.redirects) > 0): + if isinstance(event, CCEventFail): + code = event.getData()[0] + else: + code = None + if code == None or code not in self.huntstop_scodes: + if len(self.redirects) > 0: + self.placeOriginateRedirect(self.redirects.pop(0)) + else: + self.placeOriginate(self.routes.pop(0)) + return self.uaA.recvEvent(event) def rDone(self, results): @@ -342,9 +358,10 @@ disc_handlers = [] if not forward_on_fail and self.global_config['acct_enable']: disc_handlers.append(self.acctO.disc) + extra_headers = parameters.get('extra_headers', None) self.uaO = UA(self.global_config, self.recvEvent, user, passw, (host, port), credit_time, tuple(conn_handlers), \ tuple(disc_handlers), tuple(disc_handlers), dead_cbs = (self.oDead,), expire_time = expires, \ - no_progress_time = no_progress_expires, extra_headers = parameters.get('extra_headers', None)) + no_progress_time = no_progress_expires, extra_headers = extra_headers) if self.rtp_proxy_session != None and parameters.get('rtpp', True): self.uaO.on_local_sdp_change = self.rtp_proxy_session.on_caller_sdp_change self.uaO.on_remote_sdp_change = self.rtp_proxy_session.on_callee_sdp_change @@ -357,6 +374,21 @@ Timeout(self.group_expires, timeout, 1, skipto) self.uaO.recvEvent(CCEventTry((cId + '-b2b_%d' % rnum, cGUID, cli, cld, body, auth, \ parameters.get('caller_name', self.caller_name)))) + self.redirect_params = (cId + '-b2b_%d' % rnum, cGUID, cli, body.getCopy(), auth, \ + caller_name, user, passw, expires, no_progress_expires, extra_headers, \ + tuple(conn_handlers), tuple(disc_handlers)) + + def placeOriginateRedirect(self, contact): + call_id, cGUID, cli, body, auth, caller_name, user, passw, expires, \ + timeout_1xx, extra_headers, conn_handlers, disc_handlers = self.redirect_params + self.uaO = UA(self.global_config, self.recvEvent, user, passw, contact.getAddr(), None, conn_handlers, \ + disc_handlers, dead_cbs = (self.oDead,), expire_time = expires, no_progress_time = timeout_1xx, \ + extra_headers = extra_headers) + self.uaO.kaInterval = self.global_config['ka_orig'] + if self.proxied: + self.uaO.on_local_sdp_change = self.rtp_proxy_session.on_caller_sdp_change + self.uaO.on_remote_sdp_change = self.rtp_proxy_session.on_callee_sdp_change + self.uaO.recvEvent(CCEventTry((call_id, cGUID, cli, contact.username, body, auth, caller_name))) def disconnect(self, rtime = None): self.uaA.disconnect(rtime = rtime) @@ -390,6 +422,7 @@ print 'garbadge collecting', self self.acctA = None self.acctO = None + self.redirect_params = None self.global_config['cmap'].ccmap.remove(self) def oDead(self, ua): @@ -398,6 +431,7 @@ print 'garbadge collecting', self self.acctA = None self.acctO = None + self.redirect_params = None self.global_config['cmap'].ccmap.remove(self) def group_expires(self, skipto):