class SipFrom(SipAddressHF): hf_names = ('from', 'f') relaxedparser = True def __init__(self, body=None, address=None): SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name='Anonymous', url=SipURL(host=SipConf.my_address, port=SipConf.my_port)) def getTag(self): return self.address.getParam('tag') def genTag(self): self.address.setParam( 'tag', md5(str((random() * 1000000000L) + time())).hexdigest()) def setTag(self, value): self.address.setParam('tag', value) def delTag(self): self.address.delParam('tag') def getCanName(self, name, compact=False): if compact: return 'f' return 'From'
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) 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) 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: self.ua.on_local_sdp_change(body, lambda x: self.ua.recvEvent(event)) return None req = self.ua.genRequest('INVITE', body, reason=event.reason) 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) return (UacStateUpdating, ) if isinstance(event, CCEventInfo): body = event.getData() req = self.ua.genRequest('INFO', reason=event.reason) req.setBody(body) self.ua.lCSeq += 1 self.ua.global_config['_sip_tm'].newTransaction(req, None, \ laddress = self.ua.source_address) return None #print 'wrong event %s in the Connected state' % event return None
class SipAddressHF(SipGenericHF): address = None relaxedparser = False def __init__(self, body=None, address=None): SipGenericHF.__init__(self, body) if body != None: csvs = [] pidx = 0 while 1: idx = body.find(',', pidx) if idx == -1: break onum = body[:idx].count('<') cnum = body[:idx].count('>') qnum = body[:idx].count('"') if (onum == 0 and cnum == 0 and qnum == 0) or (onum > 0 and \ onum == cnum and (qnum % 2 == 0)): csvs.append(body[:idx]) body = body[idx + 1:] pidx = 0 else: pidx = idx + 1 if (len(csvs) > 0): csvs.append(body) raise ESipHeaderCSV(None, csvs) else: self.parsed = True self.address = address def parse(self): self.address = SipAddress(self.body, relaxedparser=self.relaxedparser) self.parsed = True def __str__(self): return self.localStr() def localStr(self, local_addr=None, local_port=None): if not self.parsed: return self.body return self.address.localStr(local_addr, local_port) def getCopy(self): if not self.parsed: oret = self.__class__(self.body) else: oret = self.__class__(address=self.address.getCopy()) oret.relaxedparser = self.relaxedparser return oret def setBody(self, body): self.address = body def getUri(self): return self.address def getUrl(self): return self.address.url
class SipAddressHF(SipGenericHF): address = None relaxedparser = False def __init__(self, body = None, address = None): SipGenericHF.__init__(self, body) if body != None: csvs = [] pidx = 0 while 1: idx = body.find(',', pidx) if idx == -1: break; onum = body[:idx].count('<') cnum = body[:idx].count('>') qnum = body[:idx].count('"') if (onum == 0 and cnum == 0 and qnum == 0) or (onum > 0 and \ onum == cnum and (qnum % 2 == 0)): csvs.append(body[:idx]) body = body[idx + 1:] pidx = 0 else: pidx = idx + 1 if (len(csvs) > 0): csvs.append(body) raise ESipHeaderCSV(None, csvs) else: self.parsed = True self.address = address def parse(self): self.address = SipAddress(self.body, relaxedparser = self.relaxedparser) self.parsed = True def __str__(self): return self.localStr() def localStr(self, local_addr = None, local_port = None): if not self.parsed: return self.body return self.address.localStr(local_addr, local_port) def getCopy(self): if not self.parsed: oret = self.__class__(self.body) else: oret = self.__class__(address = self.address.getCopy()) oret.relaxedparser = self.relaxedparser return oret def setBody(self, body): self.address = body def getUri(self): return self.address def getUrl(self): return self.address.url
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, )
class SipFrom(SipAddressHF): hf_names = ('from', 'f') relaxedparser = True def __init__(self, body = None, address = None): SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name = 'Anonymous', url = SipURL(host = SipConf.my_address, port = SipConf.my_port)) def getTag(self): return self.address.getParam('tag') def genTag(self): self.address.setParam('tag', md5(str((random() * 1000000000L) + time())).hexdigest()) def setTag(self, value): self.address.setParam('tag', value) def delTag(self): self.address.delParam('tag') def getCanName(self, name, compact = False): if compact: return 'f' return 'From'
def recvEvent(self, event): if isinstance(event, CCEventRing): scode = event.getData() if scode == None: scode = (180, 'Ringing', None) body = scode[2] 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(scode[0], scode[1], body) return None elif isinstance(event, CCEventConnect): 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 self.ua.lSDP = body 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]))) return (UaStateConnected, ) elif isinstance(event, CCEventFail): scode = event.getData() if scode == None: scode = (500, 'Failed') if event.warning != None: extra_headers = (event.warning, ) else: extra_headers = None self.ua.sendUasResponse(scode[0], scode[1], reason_rfc3326=event.reason, \ extra_headers=extra_headers) return (UaStateConnected, ) elif isinstance(event, CCEventDisconnect): self.ua.sendUasResponse(487, 'Request Terminated', reason_rfc3326=event.reason) req = self.ua.genRequest('BYE', reason=event.reason) self.ua.lCSeq += 1 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) # print 'wrong event %s in the Updating state' % event return None
def __init__(self, body=None, address=None): if body == '*': SipGenericHF.__init__(self, body) self.asterisk = True return SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name='Anonymous', url=SipURL(host=SipConf.my_address, port=SipConf.my_port))
def __init__(self, buf = None, method = None, ruri = None, sipver = 'SIP/2.0', to = None, fr0m = None, via = None, cseq = None, \ callid = None, maxforwards = None, body = None, contact = None, routes = (), target = None, cguid = None, user_agent = None, expires = None): SipMsg.__init__(self, buf) if buf != None: return self.method = method self.ruri = ruri if target == None: if len(routes) == 0: self.setTarget(self.ruri.getAddr()) else: self.setTarget(routes[0].getAddr()) else: self.setTarget(target) self.sipver = sipver self.appendHeader(SipHeader(name = 'via', body = via)) if via == None: self.getHFBody('via').genBranch() self.appendHeaders([SipHeader(name = 'route', body = x) for x in routes]) self.appendHeader(SipHeader(name = 'max-forwards', body = maxforwards)) self.appendHeader(SipHeader(name = 'from', body = fr0m)) if to == None: to = SipTo(address = SipAddress(url = ruri)) self.appendHeader(SipHeader(name = 'to', body = to)) self.appendHeader(SipHeader(name = 'call-id', body = callid)) self.appendHeader(SipHeader(name = 'cseq', body = SipCSeq(cseq = cseq, method = method))) if contact != None: self.appendHeader(SipHeader(name = 'contact', body = contact)) if expires == None and method == 'INVITE': expires = SipHeader(name = 'expires') self.appendHeader(expires) elif expires != None: expires = SipHeader(name = 'expires', body = expires) self.appendHeader(expires) if user_agent != None: self.user_agent = user_agent self.appendHeader(SipHeader(name = 'user-agent', bodys = user_agent)) else: self.appendHeader(SipHeader(name = 'user-agent')) if cguid != None: self.appendHeader(SipHeader(name = 'cisco-guid', body = cguid)) self.appendHeader(SipHeader(name = 'h323-conf-id', body = cguid)) if body != None: self.setBody(body)
def parse(self): self.parsed = True self.address = SipAddress(self.body)
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)
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()
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 parse(self): self.address = SipAddress(self.body, relaxedparser=self.relaxedparser) self.parsed = True
def __init__(self, body=None, address=None): SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name='Anonymous', url=SipURL(host=SipConf.my_address, port=SipConf.my_port))
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 if self.ua.p1xx_ts == None: self.ua.p1xx_ts = event.rtime self.ua.sendUasResponse(code, reason, body, retrans = False) for ring_cb in self.ua.ring_cbs: ring_cb(self.ua, event.rtime, event.origin, code) return None 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 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 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') if event.extra_headers != None: extra_headers = tuple(event.extra_headers) else: extra_headers = None 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 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 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 Ringing state' % event return None
def parse(self): self.address = SipAddress(self.body, relaxedparser = self.relaxedparser) self.parsed = True
def __init__(self, body = None, address = None): SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name = 'Anonymous', url = SipURL(host = SipConf.my_address, port = SipConf.my_port))
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 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, )
def __init__(self, body = None, address = None): if body == '*': raise ESipHeaderIgnore() SipAddressHF.__init__(self, body, address) if body == None and address == None: self.address = SipAddress(name = 'Anonymous', url = SipURL(host = SipConf.my_address, port = SipConf.my_port))