std::vector<boost::asio::const_buffer> Message::toBuffers( const Header& overrideHeader) const { // buffers to return std::vector<boost::asio::const_buffer> buffers ; // call subclass to append first line appendFirstLineBuffers(buffers) ; buffers.push_back(boost::asio::buffer(CrLf)) ; // copy override header (for stable storage) overrideHeader_ = overrideHeader; // headers for (Headers::const_iterator it = headers_.begin(); it != headers_.end(); ++it) { // add the header if it isn't being overriden if (it->name != overrideHeader_.name) appendHeader(*it, &buffers); } // add override header if (!overrideHeader_.empty()) appendHeader(overrideHeader_, &buffers); // empty line buffers.push_back(boost::asio::buffer(CrLf)) ; // body buffers.push_back(boost::asio::buffer(body_)) ; // return the buffers return buffers ; }
// Generate the string representing this sip message. string SipMessage::smGenerate(string userAgent) { string result; result.reserve(1000); char buf[200]; // First line. if (msmCode == 0) { // It is a request string uri = this->msmReqUri; // This includes the URI params and headers, if any. snprintf(buf,200,"%s %s SIP/2.0\r\n", this->msmReqMethod.c_str(), uri.c_str()); } else { // It is a reply. snprintf(buf,200,"SIP/2.0 %u %s\r\n", msmCode, msmReason.c_str()); } result.append(buf); appendHeader(&result,"To",this->msmTo.value()); appendHeader(&result,"From",this->msmFrom.value()); appendHeader(&result,"Via",this->msmVias); appendHeader(&result,"Route",this->msmRoutes); appendHeader(&result,"Call-ID",this->msmCallId); snprintf(buf,200,"%d %s",msmCSeqNum,msmCSeqMethod.c_str()); appendHeader(&result,"CSeq",buf); if (! msmContactValue.empty()) { appendHeader(&result,"Contact",msmContactValue); } if (! msmAuthorizationValue.empty()) { appendHeader(&result,"Authorization",msmAuthorizationValue); } // The WWW-Authenticate header occurs only in inbound replies from the Registrar, so we ignore it here. if (! msmMaxForwards.empty()) { appendHeader(&result,"Max-Forwards",msmMaxForwards); } // These are other headers we dont otherwise process. for (SipParamList::iterator it = msmHeaders.begin(); it != msmHeaders.end(); it++) { // Take out the headers we are going to add below. const char *name = it->mName.c_str(); if (strcasecmp(name,"User-Agent") && /*strcasecmp(name,"Max-Forwards") &&*/ strcasecmp(name,"Content-Type") && strcasecmp(name,"Content-Length")) { appendHeader(&result,it->mName.c_str(),it->mValue); } } appendHeader(&result,"User-Agent",userAgent); // Append termination cause text see examples below // Reason: SIP ;cause=580 ;text="Precondition Failure" // Reason: Q.850 ;cause=16 ;text="Terminated" // SVG Added 4/21/14 for Lynx SIPCallTermination //LOG(INFO) << "SIP term info copy SIP call termination reasons to SIP message, count: " << SIPMsgCallTerminationList.size(); // SVGDBG //string sTemp = SIPMsgCallTerminationList.getTextForAllMsgs();; //LOG(INFO) << "SIP term info in smGenerate text: " << sTemp.c_str(); // SVGDBG //result.append(sTemp.c_str()); if (msmReasonHeader.size()) { appendHeader(&result,"Reason",msmReasonHeader); } // Create the body, if any. appendHeader(&result,"Content-Type",msmContentType); appendHeader(&result,"Content-Length",msmBody.size()); result.append("\r\n"); result.append(msmBody); msmContent = result; LOG(INFO) << "SIP term info generated SIP msg: \r\n" << result.c_str(); //SVGDBG return msmContent; }
static void appendHeader(string *result,const char *name,int val) { char buf[30]; snprintf(buf,30,"%d",val); appendHeader(result,name,buf); }
// Generate the string representing this sip message. string SipMessage::smGenerate() { string result; result.reserve(1000); char buf[200]; // First line. if (msmCode == 0) { // It is a request string uri = this->msmReqUri; // This includes the URI params and headers, if any. snprintf(buf,200,"%s %s SIP/2.0\r\n", this->msmReqMethod.c_str(), uri.c_str()); } else { // It is a reply. snprintf(buf,200,"SIP/2.0 %u %s\r\n", msmCode, msmReason.c_str()); } result.append(buf); appendHeader(&result,"To",this->msmTo.value()); appendHeader(&result,"From",this->msmFrom.value()); appendHeader(&result,"Via",this->msmVias); appendHeader(&result,"Route",this->msmRoutes); appendHeader(&result,"Call-ID",this->msmCallId); snprintf(buf,200,"%d %s",msmCSeqNum,msmCSeqMethod.c_str()); appendHeader(&result,"CSeq",buf); if (! msmContactValue.empty()) { appendHeader(&result,"Contact",msmContactValue); } if (! msmAuthorizationValue.empty()) { appendHeader(&result,"Authorization",msmAuthorizationValue); } // The WWW-Authenticate header occurs only in inbound replies from the Registrar, so we ignore it here. // These are other headers we dont otherwise process. for (SipParamList::iterator it = msmHeaders.begin(); it != msmHeaders.end(); it++) { appendHeader(&result,it->mName.c_str(),it->mValue); } static const char* userAgent1 = "OpenBTS " VERSION " Build Date " __DATE__; const char *userAgent = userAgent1; appendHeader(&result,"User-Agent",userAgent); appendHeader(&result,"Max-Forwards",gConfig.getNum("SIP.MaxForwards")); // Create the body, if any. appendHeader(&result,"Content-Type",msmContentType); appendHeader(&result,"Content-Length",msmBody.size()); result.append("\r\n"); result.append(msmBody); msmContent = result; return msmContent; }