⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipmessage.cxx

📁 MiniSip Client with DomainKeys Authentication, Sip, Audio communications, Echo Cancel
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien    This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.  This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public  License along with this library; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * Authors: Erik Eliasson <eliasson@it.kth.se> *          Johan Bilien <jobi@via.ecp.fr>*//* Name * 	SipMessage.cxx * Author * 	Erik Eliasson, eliasson@it.kth.se * Purpose * */#include<config.h>#include<stdio.h>#include<libmsip/SipMessage.h>#include<errno.h>#include<ctype.h>#include<libmnetutil/Socket.h>#include<libmsip/SipMessageContentFactory.h>#include<libmsip/SipHeaderContentLength.h>#include<libmsip/SipHeaderVia.h>#include<libmsip/SipHeaderFrom.h>#include<libmsip/SipHeaderTo.h>#include<libmsip/SipHeaderCSeq.h>#include<libmsip/SipHeaderCallID.h>#include<libmsip/SipHeaderContentLength.h>#include<libmsip/SipHeaderContact.h>#include<libmsip/SipHeaderRecordRoute.h>#include<libmsip/SipHeaderRoute.h>#include<libmsip/SipHeaderRequire.h>#include<libmsip/SipHeaderSupported.h>#include<libmsip/SipHeaderContentType.h>#include<libmsip/SipHeaderWWWAuthenticate.h>#include<libmsip/SipHeaderWarning.h>#include<libmsip/SipRequest.h>#include<libmsip/SipResponse.h>#include<libmsip/SipUtils.h>#include<libmsip/SipMessageContentIM.h>#include<libmsip/SipException.h>#include<libmutil/trim.h>#include<libmutil/dbg.h>#include<libmutil/itoa.h>#include<libmutil/Timestamp.h>using namespace std;const string SipMessage::anyType="";#if defined(_MSC_VER) && !defined(_WIN32_WCE)	template class __declspec(dllexport) MRef<SipMessage*>;#endifMRef<SipMessageContent*> sipSipMessageContentFactory(const string & buf, const string &){	string tmp = buf;	return (*SipMessage::createMessage(tmp));}SMCFCollection SipMessage::contentFactories=SMCFCollection();string SipMessage::getDescription(){        string ret;	ret = getType();	if (ret=="RESPONSE")		ret +="_"+itoa(((SipResponse*)(this))->getStatusCode());	return ret;}SipMessage::~SipMessage(){}MRef<SipMessage*> SipMessage::createMessage(string &data){		size_t n = data.size();	if (n>3   &&    (data[0]=='S'||data[0]=='s') &&			(data[1]=='I'||data[1]=='i') &&			(data[2]=='P'||data[2]=='p' )){		return MRef<SipMessage*>(new SipResponse(data));	}else{		return new SipRequest(data);#if 0		if (n> 7 && data.substr(0, 7) == "MESSAGE"){			//return MRef<SipMessage*>(new SipIMMessage(data));			return new SipRequest(TYPE_SIP_MESSAGE_IMMESSAGE, data);		}		if (n> 6 && data.substr(0, 6) == "CANCEL"){			//return MRef<SipMessage*>(new SipCancel(data));			return new SipRequest(TYPE_SIP_MESSAGE_CANCEL, data);		}		if (n> 3 && data.substr(0, 3)=="BYE"){			//return MRef<SipMessage*>(new SipBye(data));			return new SipRequest(TYPE_SIP_MESSAGE_BYE, data);		}		if (n> 6 && data.substr(0, 6)=="INVITE"){			//return MRef<SipMessage*>(new SipInvite(data));			return new SipRequest(TYPE_SIP_MESSAGE_INVITE, data);		}		if (n> 3 && data.substr(0, 3)=="ACK"){			//return MRef<SipMessage*>(new SipAck(data));			return MRef<SipMessage*>(new SipRequest(TYPE_SIP_MESSAGE_ACK,data));		}		if (n> 9 && data.substr(0, 9)=="SUBSCRIBE"){			//return MRef<SipMessage*>(new SipSubscribe(data));			return  new SipRequest(TYPE_SIP_MESSAGE_SUBSCRIBE, data);		}		if (n> 6 && data.substr(0, 6)=="NOTIFY"){			//return MRef<SipMessage*>(new SipNotify(data));			return new SipRequest(TYPE_SIP_MESSAGE_NOTIFY, data);		}		if (n> 5 && data.substr(0, 5)=="REFER"){			//return MRef<SipMessage*>(new SipRefer(data));			return new SipRequest(TYPE_SIP_MESSAGE_REFER, data);		}		return MRef<SipMessage*>( new SipRequest( data ));#endif	}	return NULL;}ostream & operator<<(ostream &out, SipMessage &p){        out << p.getDescription();	return out;}SipMessage::SipMessage(string b):branch(b){	content=NULL;}void SipMessage::addHeader(MRef<SipHeader*> header){	if( header.isNull() ) {		merr << "ERROR: trying to add null header to message!"<<end;		return;	}	headers.push_back(header);}MRef<SipHeader*> SipMessage::getHeaderNo(int i){	if (i>=headers.size()){		MRef<SipHeader*> nullhdr;		return nullhdr;	}	return headers[i];}int SipMessage::getNoHeaders(){	return headers.size();}int32_t SipMessage::getContentLength(){	for (int32_t i=0; i< headers.size(); i++){		MRef<SipHeaderValueContentLength*> len;		if ((headers[i])->getType() == SIP_HEADER_TYPE_CONTENTLENGTH){			len = MRef<SipHeaderValueContentLength*>((SipHeaderValueContentLength*)*(headers[i]->getHeaderValue(0)));			return len->getContentLength();		}	}	return 0;}string SipMessage::getHeadersAndContent(){	string req="";	int32_t clen=-1;	for (int32_t i=0; i< headers.size(); i++){		req=req+headers[i]->getString()+"\r\n";		if ((headers[i])->getType() == SIP_HEADER_TYPE_CONTENTLENGTH){			clen=0;		}	}	if (clen<0){		if ( !content.isNull())			clen=(int)content->getString().length();		else			clen=0;		SipHeader content_length(new SipHeaderValueContentLength(clen));		req=req+content_length.getString()+"\r\n";	}	req=req+"\r\n";		if ( !content.isNull()){		req=req + content->getString();	}	return req;}/** * @return Index where the content of the message starts (if any) */int SipMessage::parseHeaders(const string &buf, int startIndex){	int i=startIndex;	int endBuf = (int)buf.size();	//This filters the sipfrag messages we receive ... like in NOTIFY ... which most of the times come without any header	if( startIndex + 4 >= endBuf ) {		#ifdef DEBUG_OUTPUT		mdbg << "SipMessage::parseHeaders: Info: SipMessage without headers ... only request line" << end;		#endif		return i;	}	do{		if (i+2<=endBuf && buf[i]=='\n' && buf[i+1]=='\n') {	// i points to first after header			return i+2;				// return pointer to start of content		}		if (i+4<=endBuf && buf[i]=='\r' && buf[i+1]=='\n' 				&& buf[i+2]=='\r' && buf[i+3]=='\n' ){	// i points to first after header			return i+4;				// return pointer to start of content		}		if (i+4<=endBuf && buf[i]=='\n' && buf[i+1]=='\r' 				&& buf[i+2]=='\n' && buf[i+3]=='\r' ){	// i points to first after header			return i+4;				// return pointer to start of content		}		int eoh = SipUtils::findEndOfHeader(buf, i);	// i will be adjusted to start of header		string header = buf.substr(i, eoh-i+1);// 		merr << "SipMessage::parseHeaders: parsing line = ##" << header // 			<< "## [end=" << endBuf << "; i="<< i // 			<< "; eoh=" << eoh << "; length=" // 			<< eoh-i+1 << "]" << end;		if( header == "" ) {			#ifdef DEBUG_OUTPUT			mdbg << "SipMessage::parseHeaders: Info: Could not copy line to new Message: (empty line)" << end;			#endif		} else if (!addLine(header)){			#ifdef DEBUG_OUTPUT			mdbg << "SipMessage::parseHeaders: Info: Could not copy line to new Message: " << header << " (unknown)" << end;			#endif		}		i=eoh+1;	}while (i<endBuf);		return i;}SipMessage::SipMessage(int, string &buildFrom){	uint32_t i;	//string header;	for (i=0; buildFrom[i]!='\r' && buildFrom[i]!='\n'; i++){		if(i==buildFrom.size()){#ifdef DEBUG_OUTPUT			cerr << "SipMessage::SipMessage: Size is too short - throwing exception"<< endl;#endif			throw SipExceptionInvalidMessage("SIP Message too short");		}		//header = header + buildFrom[i];	}		int contentStart = parseHeaders(buildFrom, i);	int clen = getContentLength();	if (clen>0){		string content=buildFrom.substr(contentStart, clen);		if ((int)content.length() != clen){			cerr << "WARNING: Length of content was shorter than expected (" << clen <<"!="<<(int)content.length()<<")"<<endl;		}		MRef<SipHeader*> h = getHeaderOfType(SIP_HEADER_TYPE_CONTENTTYPE);		if (h){				MRef<SipMessageContent*> smcref;			string contentType = ((SipHeaderValueString*)*(h->getHeaderValue(0) ))->getString();//			string b = (SipHeaderValueContentType*)*(h->getHeaderValue(0) )->getParameter("boundary");//cerr <<"boundary="<< b <<endl;			SipMessageContentFactoryFuncPtr contentFactory = contentFactories.getFactory( contentType );			if (contentFactory){				MRef<SipMessageContent*> smcref = contentFactory(content, contentType + "; boundary=boun=_dry");				setContent(smcref);			}else{ //TODO: Better error handling				merr << "WARNING: No SipMessageContentFactory found for content type "<<contentType <<end;			}					}else{ //TODO: Better error handling			merr << "WARNING: Sip message has content, but no content type! Content ignored."<< end;		}	}		branch = getLastViaBranch();}bool SipMessage::addLine(string line){	//ts.save("SipMessage-creating header start");	MRef<SipHeader*> hdr = SipHeader::parseHeader(line);	//ts.save("SipMessage-creating header end");	if( hdr.isNull() ) //do not add if null		return false;	addHeader(hdr);#if 0		string ln = line;	//Hack to get realm an nonce... FIXME	if (/*getType()==SipResponse::type &&*/ (SipUtils::startsWith(ln,"Proxy-Authenticate:") || SipUtils::startsWith(ln,"WWW-Authenticate")) ){		size_t r_pos = ln.find("realm=");		size_t n_pos = ln.find("nonce=");		if (r_pos == string::npos || n_pos ==string::npos){			merr << "ERROR: could not extract nonce and realm in line: " << ln << end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -