📄 sipudp_impl.cxx
字号:
retVal->msg.out=retVal->msg.in->encode(); recFifo->add(retVal); } } } else { cpLog(LOG_INFO, "XXX random lose: message not sent!"); } //update retransDetails count--; if(Udpretransmitoff) count = 0; //// required or else will send 408 up for retransoff! else { if ( ret_status != 0) { count = 0; } else if ((!count) && (ret_status != 0)) { /// flag the message got All its chances retransmit->setCount(1); } } sipMsg->myLock.lock(); /// check if it was canceled already if(sipMsg->retransCount) { sipMsg->retransCount = count; } else { count = 0; } sipMsg->myLock.unlock(); //increment the time to send out. //// we don't want to hold on to messages that don't //// need to be retransmitted if(count) { int timeToGo = retransmit->getTimeToGo(); if (timeToGo == 0) { retransmit->setTimeToGo(retransmitTimeInitial); } else if(timeToGo < retransmitTimeMax) { retransmit->setTimeToGo(timeToGo * 2); } } else retransmit->setTimeToGo(0); //add into Fifo. sendFifo.addDelayMs( retransmit, retransmit->getTimeToGo()); } else //i.e. count == 0 { /// check if this message got all it's chances! if (retransmit->getCount()) { //send 408 if a command, other than an ACK. if ((sipMsg->msg.type != SIP_ACK) && (sipMsg->msg.type != SIP_STATUS)) { cpLog(LOG_DEBUG_STACK, "THE COUNT IS [ %d ]\n",retransmit->getCount()); cpLog(LOG_DEBUG_STACK, "The SipMeaasge is \n%s\n",sipMsg->msg.out.logData()); Data toBeEaten = sipMsg->msg.out; Sptr<SipMsg> mmsg = SipMsg::decode(toBeEaten); Sptr<SipCommand> commandMsg; commandMsg.dynamicCast(mmsg); SipMsgContainer* statusMsg = new SipMsgContainer; statusMsg->msg.in = new StatusMsg((*commandMsg), 408); //statusMsg->msg.out = statusMsg->msg.in->encode(); recFifo->add(statusMsg); } } /// feed it to the GC... if(sipMsg->level3Ptr == 0) { SipTransactionGC::instance()-> collect(sipMsg, ORPHAN_CLEANUP_DELAY); } else if (sipMsg->msg.type != SIP_INVITE) { SipTransactionGC::instance()-> collect(sipMsg, MESSAGE_CLEANUP_DELAY); } delete retransmit; } }//if sipMsg }//if retransmit. }//end while}void SipUdp_impl::getHostPort(Sptr<SipMsg> sipMessage, Data* host, int* port){ if ( sipMessage->getType() == SIP_STATUS ) { assert( sipMessage->getNumVia() > 0 ); if ( sipMessage->getNumVia() > 0 ) { const SipVia& via = sipMessage->getVia( 0 ); // check for viaReceived parameter in the via header if ( via.isViaReceived() == true) { *host = via.getReceivedhost(); *port = via.getReceivedport().convertInt(); } else { *host = via.getMaddr(); if( host->length() == 0 ) { *host = via.getHost(); } *port = via.getPort(); cpLog( LOG_DEBUG_STACK,"got host from Via of %s",host->logData()); cpLog( LOG_DEBUG_STACK,"got port from Via of %d",*port); } } } else { Sptr<SipCommand> command; command.dynamicCast(sipMessage); if ( command != 0) { Sptr<SipUrl> dest = command->postProcessRouteAndGetNextHop(); if(dest != 0) { Data maddr = dest->getMaddrParam(); if(maddr.length() > 0) *host = maddr; else *host = dest->getHost(); *port = dest->getPort().convertInt(); cpLog( LOG_DEBUG_STACK, "got host from start line: %s:%d", host->logData(), *port); } else { cpLog(LOG_ERR, "attempting to send message to a non-sip URL, discarding"); assert(0); } } else { assert(0); } }//if sipCommand //If port is zero set the default port if(*port == 0) { *port = SIP_PORT; }} voidSipUdp_impl::send(SipMsgContainer* msg, const Data& host, const Data& port){ RetransmitContents* retransDetails = new RetransmitContents(msg, 0); if(!msg->msg.out.length()) { Data nhost; int nport; assert(msg->msg.in != 0); if(host.length()) { nhost = host; nport = port.convertInt(); } else getHostPort(msg->msg.in, &nhost, &nport); msg->msg.out = msg->msg.in->encode(); try { if(msg->msg.netAddr == 0 ) msg->msg.netAddr = new NetworkAddress(nhost.convertString(), nport); } catch(NetworkAddress::UnresolvedException& e) {// cpLog(LOG_ERR, "host: %s\n nhost: %s", host, nhost); cpLog(LOG_ERR, "Destination (%s) is not reachable, reason:%s.", nhost.logData(), e.getDescription().c_str()); } } // free the msg.in ptr if this is a status msg for a non-INVITE msg // or if it is an ACK message if((msg->msg.in != 0) && (((msg->msg.in->getType() == SIP_STATUS) && (msg->msg.in->getCSeq().getMethod() != "INVITE")) || (msg->msg.in->getType() == SIP_ACK))) { // clear msg.in msg->msg.in = 0; } //if this has to be retransmitted. if (msg->retransCount > 1) { cpLog(LOG_DEBUG_STACK, "Msg is for retransmission:\n %s", msg->msg.out.logData()); //////// will have to go after moving retrans count etc to stack!!! msg->retransCount = sipmaxRetrans; /////////////////////////////////////////////////////////////////// } cpLog(LOG_DEBUG_STACK, "$$$$$$$$$$$$$$$Msg is for retransmission:\n %s", msg->msg.out.logData()); //send immediately. sendFifo.addDelayMs( retransDetails , 0);}voidSipUdp_impl::reTransOn(){ Udpretransmitoff = false;}voidSipUdp_impl::reTransOff(){ Udpretransmitoff = true;}voidSipUdp_impl::setRetransTime(int initial, int max){ Udpretransmitimeinitial = initial; Udpretransmittimemax = max;}voidSipUdp_impl::setRandomLosePercent(int percent){ if((percent >=0) && (percent <= 100)) { randomLosePercent = percent; }}voidSipUdp_impl::printSize(){ cpLog(LOG_INFO, "recFifo: %d, sendFifo: %d", recFifo->size(),sendFifo.size());}DataSipUdp_impl::getDetails() const{ char buf[256]; sprintf(buf, "receive fifo: %d send fifo: %d", recFifo->size(),sendFifo.size()); sprintf(buf, "\npkts received: %d pkts sent: %d", udpStack.getPacketsReceived(),udpStack.getPacketsTransmitted()); return buf;}/* Local Variables: *//* c-file-style: "stroustrup" *//* indent-tabs-mode: nil *//* c-file-offsets: ((access-label . -) (inclass . ++)) *//* c-basic-offset: 4 *//* End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -