reSIProcate/stack  9694
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | Friends
resip::SipMessage Class Reference

Represents a SIP message. More...

#include <SipMessage.hxx>

Inheritance diagram for resip::SipMessage:
Inheritance graph
[legend]
Collaboration diagram for resip::SipMessage:
Collaboration graph
[legend]

List of all members.

Classes

class  Exception
 Base exception for SipMessage related exceptions. More...

Public Types

typedef std::list< std::pair
< Data, HeaderFieldValueList * >
, StlPoolAllocator< std::pair
< Data, HeaderFieldValueList * >
, PoolBase > > 
UnknownHeaders

Public Member Functions

 RESIP_HeapCount (SipMessage)
 SipMessage (const Transport *fromWire=0)
 SipMessage (const SipMessage &message)
virtual Messageclone () const
SipMessageoperator= (const SipMessage &rhs)
virtual const DatagetTransactionId () const
 Returns the transaction id from the branch or if 2543, the computed hash.
const DatagetRFC2543TransactionId () const
 Calculates an MD5 hash over the Request-URI, To tag (for non-INVITE transactions), From tag, Call-ID, CSeq (including the method), and top Via header.
void setRFC2543TransactionId (const Data &tid)
virtual ~SipMessage ()
void parseAllHeaders ()
void setFromTU ()
 Mark message as internally generated.
void setFromExternal ()
 Mark message as externally generated.
bool isExternal () const
 Check if SipMessage came off the wire.
virtual bool isClientTransaction () const
 Check if SipMessage is a client transaction.
virtual EncodeStreamencode (EncodeStream &str) const
 Generate a string from the SipMessage object.
virtual EncodeStreamencodeSipFrag (EncodeStream &str) const
EncodeStreamencodeEmbedded (EncodeStream &str) const
virtual EncodeStreamencodeBrief (EncodeStream &str) const
 output a brief description to stream
EncodeStreamencodeSingleHeader (Headers::Type type, EncodeStream &str) const
bool isRequest () const
 Returns true if message is a request, false otherwise.
bool isResponse () const
 Returns true if message is a response, false otherwise.
bool isInvalid () const
 Returns true if message failed to parse, false otherwise.
resip::MethodTypes method () const
 returns the method type of the message
const DatamethodStr () const
 Returns a string containing the SIP method for the message.
const resip::DatagetReason () const
 Returns a string containing the response reason text.
const RequestLineheader (const RequestLineType &l) const
 Returns the RequestLine. This is only valid for request messages.
RequestLineheader (const RequestLineType &l)
 Returns the RequestLine. This is only valid for request messages.
const RequestLineconst_header (const RequestLineType &l) const
const StatusLineheader (const StatusLineType &l) const
 Returns the StatusLine. This is only valid for response messages.
StatusLineheader (const StatusLineType &l)
 Returns the StatusLine. This is only valid for response messages.
const StatusLineconst_header (const StatusLineType &l) const
bool exists (const HeaderBase &headerType) const
 Returns true if the given header field is present, false otherwise.
bool empty (const HeaderBase &headerType) const
 Returns true if the header field is present and non-empty, false otherwise.
void remove (const HeaderBase &headerType)
 Prevents a header field from being present when the message is prepared for sending to a transport.
void remove (Headers::Type type)
 defineHeader (ContentDisposition,"Content-Disposition", Token,"RFC 3261")
 defineHeader (ContentEncoding,"Content-Encoding", Token,"RFC 3261")
 defineHeader (MIMEVersion,"Mime-Version", Token,"RFC 3261")
 defineHeader (Priority,"Priority", Token,"RFC 3261")
 defineHeader (Event,"Event", Token,"RFC 3265")
 defineHeader (SubscriptionState,"Subscription-State", Token,"RFC 3265")
 defineHeader (SIPETag,"SIP-ETag", Token,"RFC 3903")
 defineHeader (SIPIfMatch,"SIP-If-Match", Token,"RFC 3903")
 defineHeader (ContentId,"Content-ID", Token,"RFC 2045")
 defineMultiHeader (AllowEvents,"Allow-Events", Token,"RFC 3265")
 defineHeader (Identity,"Identity", StringCategory,"RFC 4474")
 defineMultiHeader (AcceptEncoding,"Accept-Encoding", Token,"RFC 3261")
 defineMultiHeader (AcceptLanguage,"Accept-Language", Token,"RFC 3261")
 defineMultiHeader (Allow,"Allow", Token,"RFC 3261")
 defineMultiHeader (ContentLanguage,"Content-Language", Token,"RFC 3261")
 defineMultiHeader (ProxyRequire,"Proxy-Require", Token,"RFC 3261")
 defineMultiHeader (Require,"Require", Token,"RFC 3261")
 defineMultiHeader (Supported,"Supported", Token,"RFC 3261")
 defineMultiHeader (Unsupported,"Unsupported", Token,"RFC 3261")
 defineMultiHeader (SecurityClient,"Security-Client", Token,"RFC 3329")
 defineMultiHeader (SecurityServer,"Security-Server", Token,"RFC 3329")
 defineMultiHeader (SecurityVerify,"Security-Verify", Token,"RFC 3329")
 defineMultiHeader (RequestDisposition,"Request-Disposition", Token,"RFC 3841")
 defineMultiHeader (Reason,"Reason", Token,"RFC 3326")
 defineMultiHeader (Privacy,"Privacy", PrivacyCategory,"RFC 3323")
 defineMultiHeader (PMediaAuthorization,"P-Media-Authorization", Token,"RFC 3313")
 defineHeader (ReferSub,"Refer-Sub", Token,"RFC 4488")
 defineHeader (AnswerMode,"Answer-Mode", Token,"draft-ietf-answermode-04")
 defineHeader (PrivAnswerMode,"Priv-Answer-Mode", Token,"draft-ietf-answermode-04")
 defineMultiHeader (Accept,"Accept", Mime,"RFC 3261")
 defineHeader (ContentType,"Content-Type", Mime,"RFC 3261")
 defineMultiHeader (CallInfo,"Call-Info", GenericUri,"RFC 3261")
 defineMultiHeader (AlertInfo,"Alert-Info", GenericUri,"RFC 3261")
 defineMultiHeader (ErrorInfo,"Error-Info", GenericUri,"RFC 3261")
 defineHeader (IdentityInfo,"Identity-Info", GenericUri,"RFC 4474")
 defineMultiHeader (RecordRoute,"Record-Route", NameAddr,"RFC 3261")
 defineMultiHeader (Route,"Route", NameAddr,"RFC 3261")
 defineMultiHeader (Contact,"Contact", NameAddr,"RFC 3261")
 defineHeader (From,"From", NameAddr,"RFC 3261")
 defineHeader (To,"To", NameAddr,"RFC 3261")
 defineHeader (ReplyTo,"Reply-To", NameAddr,"RFC 3261")
 defineHeader (ReferTo,"Refer-To", NameAddr,"RFC 3515")
 defineHeader (ReferredBy,"Referred-By", NameAddr,"RFC 3892")
 defineMultiHeader (Path,"Path", NameAddr,"RFC 3327")
 defineMultiHeader (AcceptContact,"Accept-Contact", NameAddr,"RFC 3841")
 defineMultiHeader (RejectContact,"Reject-Contact", NameAddr,"RFC 3841")
 defineMultiHeader (PAssertedIdentity,"P-Asserted-Identity", NameAddr,"RFC 3325")
 defineMultiHeader (PPreferredIdentity,"P-Preferred-Identity", NameAddr,"RFC 3325")
 defineHeader (PCalledPartyId,"P-Called-Party-ID", NameAddr,"RFC 3455")
 defineMultiHeader (PAssociatedUri,"P-Associated-URI", NameAddr,"RFC 3455")
 defineMultiHeader (ServiceRoute,"Service-Route", NameAddr,"RFC 3608")
 defineMultiHeader (RemotePartyId,"Remote-Party-ID", NameAddr,"draft-ietf-sip-privacy-04")
 defineMultiHeader (HistoryInfo,"History-Info", NameAddr,"RFC 4244")
 defineHeader (ContentTransferEncoding,"Content-Transfer-Encoding", StringCategory,"RFC 1521")
 defineHeader (Organization,"Organization", StringCategory,"RFC 3261")
 defineHeader (Server,"Server", StringCategory,"RFC 3261")
 defineHeader (Subject,"Subject", StringCategory,"RFC 3261")
 defineHeader (UserAgent,"User-Agent", StringCategory,"RFC 3261")
 defineHeader (Timestamp,"Timestamp", StringCategory,"RFC 3261")
 defineHeader (ContentLength,"Content-Length", UInt32Category,"RFC 3261")
 defineHeader (MaxForwards,"Max-Forwards", UInt32Category,"RFC 3261")
 defineHeader (MinExpires,"Min-Expires", UInt32Category,"RFC 3261")
 defineHeader (RSeq,"RSeq", UInt32Category,"RFC 3261")
 defineHeader (RetryAfter,"Retry-After", UInt32Category,"RFC 3261")
 defineHeader (FlowTimer,"Flow-Timer", UInt32Category,"RFC 5626")
 defineHeader (Expires,"Expires", ExpiresCategory,"RFC 3261")
 defineHeader (SessionExpires,"Session-Expires", ExpiresCategory,"RFC 4028")
 defineHeader (MinSE,"Min-SE", ExpiresCategory,"RFC 4028")
 defineHeader (CallID,"Call-ID", CallID,"RFC 3261")
 defineHeader (Replaces,"Replaces", CallID,"RFC 3891")
 defineHeader (InReplyTo,"In-Reply-To", CallID,"RFC 3261")
 defineHeader (Join,"Join", CallId,"RFC 3911")
 defineHeader (TargetDialog,"Target-Dialog", CallId,"RFC 4538")
 defineHeader (AuthenticationInfo,"Authentication-Info", Auth,"RFC 3261")
 defineMultiHeader (Authorization,"Authorization", Auth,"RFC 3261")
 defineMultiHeader (ProxyAuthenticate,"Proxy-Authenticate", Auth,"RFC 3261")
 defineMultiHeader (ProxyAuthorization,"Proxy-Authorization", Auth,"RFC 3261")
 defineMultiHeader (WWWAuthenticate,"Www-Authenticate", Auth,"RFC 3261")
 defineHeader (CSeq,"CSeq", CSeqCategory,"RFC 3261")
 defineHeader (Date,"Date", DateCategory,"RFC 3261")
 defineMultiHeader (Warning,"Warning", WarningCategory,"RFC 3261")
 defineMultiHeader (Via,"Via", Via,"RFC 3261")
 defineHeader (RAck,"RAck", RAckCategory,"RFC 3262")
const StringCategoriesheader (const ExtensionHeader &symbol) const
 unknown header interface
StringCategoriesheader (const ExtensionHeader &symbol)
bool exists (const ExtensionHeader &symbol) const
void remove (const ExtensionHeader &symbol)
const HeaderFieldValueListgetRawHeader (Headers::Type headerType) const
 typeless header interface
void setRawHeader (const HeaderFieldValueList *hfvs, Headers::Type headerType)
const UnknownHeadersgetRawUnknownHeaders () const
const HeaderFieldValuegetRawBody () const
 Return the raw body string (if it exists).
void setRawBody (const HeaderFieldValue &body)
 Remove any existing body/contents, and (if non-empty) set the body to {body}.
ContentsgetContents () const
 Retrieves the body of a SIP message.
std::auto_ptr< ContentsreleaseContents ()
 Removes the contents from the message.
void setContents (const Contents *contents)
 Set the contents of the message.
void setContents (std::auto_ptr< Contents > contents)
 Set the contents of the message.
void setStartLine (const char *start, int len)
void setBody (const char *start, UInt32 len)
void addHeader (Headers::Type header, const char *headerName, int headerLen, const char *start, int len)
 Add HeaderFieldValue given enum, header name, pointer start, content length.
const TransportgetReceivedTransport () const
 Interface used to determine which Transport was used to receive a particular SipMessage.
void setSource (const Tuple &tuple)
const TuplegetSource () const
 Returns the source tuple that the message was received from only makes sense for messages received from the wire.
void setDestination (const Tuple &tuple)
 Used by the stateless interface to specify where to send a request/response.
TuplegetDestination ()
void addBuffer (char *buf)
UInt64 getCreatedTimeMicroSec ()
void setForceTarget (const Uri &uri)
 deal with a notion of an "out-of-band" forced target for SIP routing
void clearForceTarget ()
const UrigetForceTarget () const
bool hasForceTarget () const
const DatagetTlsDomain () const
void setTlsDomain (const Data &domain)
const std::list< Data > & getTlsPeerNames () const
void setTlsPeerNames (const std::list< Data > &tlsPeerNames)
Data getCanonicalIdentityString () const
SipMessagemergeUri (const Uri &source)
void setSecurityAttributes (std::auto_ptr< SecurityAttributes >)
const SecurityAttributesgetSecurityAttributes () const
void addOutboundDecorator (std::auto_ptr< MessageDecorator > md)
 Call a MessageDecorator to process the message before it is sent to the transport.
void clearOutboundDecorators ()
void callOutboundDecorators (const Tuple &src, const Tuple &dest, const Data &sigcompId)
void rollbackOutboundDecorators ()
void copyOutboundDecoratorsToStackCancel (SipMessage &cancel)
void copyOutboundDecoratorsToStackFailureAck (SipMessage &ack)

Static Public Member Functions

static SipMessagemake (const Data &buffer, bool isExternal=false)
 Construct a SipMessage object from a string containing a SIP request or response.

Public Attributes

bool mIsDecorated
bool mIsBadAck200

Static Public Attributes

static bool checkContentLength = true

Protected Member Functions

void clear (bool leaveResponseStuff=false)
void freeMem (bool leaveResponseStuff=false)
void init (const SipMessage &rhs)

Private Types

typedef std::vector
< HeaderFieldValueList
*, StlPoolAllocator
< HeaderFieldValueList
*, PoolBase > > 
TypedHeaders

Private Member Functions

void compute2543TransactionHash () const
EncodeStreamencode (EncodeStream &str, bool isSipFrag) const
void copyFrom (const SipMessage &message)
HeaderFieldValueListensureHeaders (Headers::Type type)
HeaderFieldValueListensureHeaders (Headers::Type type) const
HeaderFieldValueListensureHeader (Headers::Type type)
HeaderFieldValueListensureHeader (Headers::Type type) const
void throwHeaderMissing (Headers::Type type) const
HeaderFieldValueListgetEmptyHfvl ()
HeaderFieldValueListgetCopyHfvl (const HeaderFieldValueList &hfvl)
void freeHfvl (HeaderFieldValueList *hfvl)
template<class T >
ParserContainer< T > * makeParserContainer ()
template<class T >
ParserContainer< T > * makeParserContainer (HeaderFieldValueList *hfvs, Headers::Type type=Headers::UNKNOWN)

Private Attributes

bool mIsExternal
DinkyPool< 2968 > mPool
TypedHeaders mHeaders
short mHeaderIndices [Headers::MAX_HEADERS]
UnknownHeaders mUnknownHeaders
const TransportmTransport
Tuple mSource
Tuple mDestination
std::vector< char * > mBufferList
StartLinemStartLine
char mStartLineMem [sizeof(RequestLine) > sizeof(StatusLine)?sizeof(RequestLine):sizeof(StatusLine)]
HeaderFieldValue mContentsHfv
ContentsmContents
Data mRFC2543TransactionId
bool mRequest
bool mResponse
bool mInvalid
resip::DatamReason
UInt64 mCreatedTime
UrimForceTarget
Data mTlsDomain
std::list< DatamTlsPeerNames
std::auto_ptr< SecurityAttributesmSecurityAttributes
std::vector< MessageDecorator * > mOutboundDecorators

Friends

class TransportSelector

Detailed Description

Represents a SIP message.

This is the class that your app will spend the most time working with. This is because, in the UA core/Transaction User architecture, the vast majority of interaction is carried out through SIP messaging.

When you get a SipMessage, generally the first thing you want to know is whether it is a request or a response. This is done by calling SipMessage::isRequest() or SipMessage::isResponse().

Next, it is usually important to determine what the SIP method of the message is. This is done by calling SipMessage::method() (this is a convenience function that checks the method of the Request-Line if the message is a request, or the method of the CSeq if a response).

At this point, it may become useful to examine the start-line of the message.

If the message is a request, you can get the Request-Line (represented by a RequestLine&) by calling SipMessage::header(const RequestLineType&)

      RequestLine& rLine = sip.header(h_RequestLine);

If the message is a response, you can get the Status-Line (represented by a StatusLine&) by calling SipMessage::header(const StatusLineType&)

      StatusLine& sLine = sip.header(h_StatusLine);

From here, examination of the various headers is in order. The way the underlying code works is very complicated, but fortunately relatively painless to use. For each header type, there is a subclass of HeaderBase, and a SipMessage::header() function that takes a reference to this subclass. On top of this, there is a static instance of each of these subclasses. Examples include h_To, h_From, h_CSeq, h_CallId, h_Routes, h_Contacts, h_RecordRoutes, etc.

      NameAddr& to = sip.header(h_To);
      NameAddr& from = sip.header(h_From);
      CSeqCategory& cseq = sip.header(h_CSeq);
      CallId& callId = sip.header(h_CallId);
      ParserContainer<NameAddr>& routes = sip.header(h_Routes);
      ParserContainer<NameAddr>& contacts = sip.header(h_Contacts);
      ParserContainer<NameAddr>& rRoutes = sip.header(h_RecordRoutes);

Generally speaking, the access token is named in a predictable fashion; all non-alphanumeric characters are omitted, the first letter of each word is capitalized, and the name is pluralized if the header is multi-valued (since this stuff is all macro-generated, sometimes this pluralization isn't quite right; h_AllowEventss, h_PAssertedIdentitys).

When accessing a single-value header, you need to check whether it exists first (unless you want it to be created implicitly). Also, since all header field values are lazily parsed (see LazyParser), you'll want to make sure it is well-formed before attempting to access any portion of it.

      if(sip.exists(h_Event))
      {
         Token& event = sip.header(h_Event);
         if(event.isWellFormed())
         {
            // do stuff with event.
         }
         else
         {
            // complain bitterly
         }
      }

When accessing a multi-value header, it is important to keep in mind that it can be empty, even if it exists (for example, "Supported: " has a meaning that is distinct from the lack of a Supported header).

      if(sip.exists(h_Contacts))
      {
         ParserContainer<NameAddr>& contacts = sip.header(h_Contacts);
         if(!contacts.empty())
         {
            NameAddr& frontContact = contacts.front();
            if(frontContact.isWellFormed())
            {
               // do stuff with frontContact
            }
            else
            {
               // complain bitterly
            }
         }
         else
         {
            // complain bitterly
         }
      }

In some cases, you will need to access header-types that are not natively supported by the stack (ie, don't have an access-token). ExtensionHeader will allow you to construct an access-token at runtime that will retrieve the header field value as a ParserContainer<StringCategory>. Here's an example:

      // We need to access the FooBar header field value here.
      static ExtensionHeader h_FooBar("FooBar");
      if(sip.exists(h_FooBar))
      {
         ParserContainer<StringCategory>& fooBars = sip.header(h_FooBar);
      }

Definition at line 152 of file SipMessage.hxx.


Member Typedef Documentation

Definition at line 624 of file SipMessage.hxx.

Definition at line 157 of file SipMessage.hxx.


Constructor & Destructor Documentation

SipMessage::SipMessage ( const Transport fromWire = 0) [explicit]

Definition at line 30 of file SipMessage.cxx.

References clear(), and mHeaders.

Referenced by clone(), and make().

   : mIsDecorated(false),
     mIsBadAck200(false),     
     mIsExternal(fromWire != 0),
     mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
#ifndef __SUNPRO_CC
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
#else
     mUnknownHeaders(),
#endif
     mTransport(fromWire),
     mRFC2543TransactionId(),
     mRequest(false),
     mResponse(false),
     mInvalid(false),
     mCreatedTime(Timer::getTimeMicroSec()),
     mTlsDomain(Data::Empty)
{
   // !bwc! TODO make this tunable
   mHeaders.reserve(16);
   clear();
}

Here is the call graph for this function:

SipMessage::SipMessage ( const SipMessage message)
Todo:
.dlb. public, allows pass by value to compile.

Definition at line 53 of file SipMessage.cxx.

References init().

   : mHeaders(StlPoolAllocator<HeaderFieldValueList*, PoolBase >(&mPool)),
#ifndef __SUNPRO_CC
     mUnknownHeaders(StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase >(&mPool)),
#else
     mUnknownHeaders(),
#endif
     mCreatedTime(Timer::getTimeMicroSec())
{
   init(from);
}

Here is the call graph for this function:

SipMessage::~SipMessage ( ) [virtual]

Definition at line 82 of file SipMessage.cxx.

References freeMem().

{
   freeMem();
}

Here is the call graph for this function:


Member Function Documentation

void SipMessage::addBuffer ( char *  buf)

Definition at line 842 of file SipMessage.cxx.

References mBufferList.

Referenced by make(), resip::ConnectionBase::preparseNewBytes(), and resip::UdpTransport::processRxParse().

{
   mBufferList.push_back(buf);
}
void SipMessage::addHeader ( Headers::Type  header,
const char *  headerName,
int  headerLen,
const char *  start,
int  len 
)

Add HeaderFieldValue given enum, header name, pointer start, content length.

Definition at line 1179 of file SipMessage.cxx.

References resip::Data::append(), resip::Data::Empty, getEmptyHfvl(), resip::Headers::getHeaderName(), header(), resip::Headers::isMulti(), mHeaderIndices, mHeaders, mInvalid, mReason, mUnknownHeaders, resip::HeaderFieldValueList::push_back(), resip::HeaderFieldValueList::size(), strncasecmp(), and resip::Headers::UNKNOWN.

{
   if (header != Headers::UNKNOWN)
   {
      HeaderFieldValueList* hfvl=0;
      if (mHeaderIndices[header] == 0)
      {
         mHeaderIndices[header] = mHeaders.size();
         mHeaders.push_back(getEmptyHfvl());
         hfvl=mHeaders.back();
      }
      else
      {
         if(mHeaderIndices[header]<0)
         {
            // Adding to a previously removed header type; there is already an 
            // empty HeaderFieldValueList in mHeaders for this type, all we 
            // need to do is flip the sign to re-enable it.
            mHeaderIndices[header] *= -1;
         }
         hfvl=mHeaders[mHeaderIndices[header]];
      }

      if(Headers::isMulti(header))
      {
         if (len)
         {
            hfvl->push_back(start, len, false);
         }
      }
      else
      {
         if(hfvl->size()==1)
         {
            if(!mReason)
            {
               mReason=new Data;
            }
            
            if(mInvalid)
            {
               mReason->append(",",1);
            }
            mInvalid=true;
            mReason->append("Multiple values in single-value header ",39);
            (*mReason)+=Headers::getHeaderName(header);
            return;
         }
         hfvl->push_back(start ? start : Data::Empty.data(), len, false);
      }

   }
   else
   {
      assert(headerLen >= 0);
      for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
           i != mUnknownHeaders.end(); i++)
      {
         if (i->first.size() == (unsigned int)headerLen &&
             strncasecmp(i->first.data(), headerName, headerLen) == 0)
         {
            // add to end of list
            if (len)
            {
               i->second->push_back(start, len, false);
            }
            return;
         }
      }

      // didn't find it, add an entry
      HeaderFieldValueList *hfvs = getEmptyHfvl();
      if (len)
      {
         hfvs->push_back(start, len, false);
      }
      mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(Data(headerName, headerLen),
                                                                  hfvs));
   }
}

Here is the call graph for this function:

void resip::SipMessage::addOutboundDecorator ( std::auto_ptr< MessageDecorator md) [inline]

Call a MessageDecorator to process the message before it is sent to the transport.

Definition at line 524 of file SipMessage.hxx.

References mOutboundDecorators.

Referenced by copyOutboundDecoratorsToStackCancel(), and copyOutboundDecoratorsToStackFailureAck().

{mOutboundDecorators.push_back(md.release());}
void SipMessage::callOutboundDecorators ( const Tuple src,
const Tuple dest,
const Data sigcompId 
)

Definition at line 1701 of file SipMessage.cxx.

References mIsDecorated, mOutboundDecorators, and rollbackOutboundDecorators().

Referenced by resip::TransportSelector::transmit().

{
   if(mIsDecorated)
   {
      rollbackOutboundDecorators();
   }

  std::vector<MessageDecorator*>::iterator i;
  for (i = mOutboundDecorators.begin();
       i != mOutboundDecorators.end(); i++)
  {
    (*i)->decorateMessage(*this, src, dest, sigcompId);
  }
  mIsDecorated = true;
}

Here is the call graph for this function:

void SipMessage::clear ( bool  leaveResponseStuff = false) [protected]

Definition at line 88 of file SipMessage.cxx.

References resip::HeaderFieldValue::clear(), getEmptyHfvl(), mBufferList, mContents, mContentsHfv, mForceTarget, mHeaderIndices, mHeaders, mOutboundDecorators, mReason, mStartLine, and mUnknownHeaders.

Referenced by init(), and SipMessage().

{
   if(!leaveResponseStuff)
   {
      memset(mHeaderIndices,0,sizeof(mHeaderIndices));
      mHeaders.clear();
      
      // !bwc! The "invalid" 0 index.
      mHeaders.push_back(getEmptyHfvl());
      mBufferList.clear();
   }

   mUnknownHeaders.clear();

   mStartLine = 0;
   mContents = 0;
   mContentsHfv.clear();
   mForceTarget = 0;
   mReason=0;
   mOutboundDecorators.clear();
}

Here is the call graph for this function:

void SipMessage::clearForceTarget ( )

Definition at line 1602 of file SipMessage.cxx.

References mForceTarget.

Referenced by resip::DeprecatedDialog::updateRequest().

{
   delete mForceTarget;
   mForceTarget = 0;
}
void SipMessage::clearOutboundDecorators ( )

Definition at line 1720 of file SipMessage.cxx.

References mOutboundDecorators.

{
   while(!mOutboundDecorators.empty())
   {
      delete mOutboundDecorators.back();
      mOutboundDecorators.pop_back();
   }
}
Message * SipMessage::clone ( ) const [virtual]
Todo:
.dlb. sure would be nice to have overloaded return value here..

Reimplemented from resip::TransactionMessage.

Reimplemented in resip::KeepAliveMessage.

Definition at line 66 of file SipMessage.cxx.

References SipMessage().

Referenced by resip::SipStack::send(), and resip::SipStack::sendTo().

{
   return new SipMessage(*this);
}

Here is the call graph for this function:

void SipMessage::compute2543TransactionHash ( ) const [private]

Definition at line 364 of file SipMessage.cxx.

References resip::ParserCategory::commutativeParameterHash(), DebugLog, resip::Data::empty(), empty(), exists(), resip::MD5Stream::getHex(), header(), resip::Uri::host(), InfoLog, isRequest(), resip::RequestLine::method(), mRFC2543TransactionId, resip::Uri::password(), resip::Uri::port(), resip::Uri::scheme(), resip::RequestLine::uri(), and resip::Uri::user().

Referenced by getRFC2543TransactionId(), and getTransactionId().

{
   assert (mRFC2543TransactionId.empty());
   
   /*  From rfc3261, 17.2.3
       The INVITE request matches a transaction if the Request-URI, To tag,
       From tag, Call-ID, CSeq, and top Via header field match those of the
       INVITE request which created the transaction.  In this case, the
       INVITE is a retransmission of the original one that created the
       transaction.  

       The ACK request matches a transaction if the Request-URI, From tag,
       Call-ID, CSeq number (not the method), and top Via header field match
       those of the INVITE request which created the transaction, and the To
       tag of the ACK matches the To tag of the response sent by the server
       transaction.  

       Matching is done based on the matching rules defined for each of those
       header fields.  Inclusion of the tag in the To header field in the ACK
       matching process helps disambiguate ACK for 2xx from ACK for other
       responses at a proxy, which may have forwarded both responses (This
       can occur in unusual conditions.  Specifically, when a proxy forked a
       request, and then crashes, the responses may be delivered to another
       proxy, which might end up forwarding multiple responses upstream).  An
       ACK request that matches an INVITE transaction matched by a previous
       ACK is considered a retransmission of that previous ACK.

       For all other request methods, a request is matched to a transaction
       if the Request-URI, To tag, From tag, Call-ID, CSeq (including the
       method), and top Via header field match those of the request that
       created the transaction.  Matching is done based on the matching
   */

   // If it is here and isn't a request, leave the transactionId empty, this
   // will cause the Transaction to send it statelessly

   if (isRequest())
   {
      MD5Stream strm;
      // See section 17.2.3 Matching Requests to Server Transactions in rfc 3261

//#define VONAGE_FIX
#ifndef VONAGE_FIX         
      strm << header(h_RequestLine).uri().scheme();
      strm << header(h_RequestLine).uri().user();
      strm << header(h_RequestLine).uri().host();
      strm << header(h_RequestLine).uri().port();
      strm << header(h_RequestLine).uri().password();
      strm << header(h_RequestLine).uri().commutativeParameterHash();
#endif
      if (!empty(h_Vias))
      {
         strm << header(h_Vias).front().protocolName();
         strm << header(h_Vias).front().protocolVersion();
         strm << header(h_Vias).front().transport();
         strm << header(h_Vias).front().sentHost();
         strm << header(h_Vias).front().sentPort();
         strm << header(h_Vias).front().commutativeParameterHash();
      }
         
      if (header(h_From).exists(p_tag))
      {
         strm << header(h_From).param(p_tag);
      }

      // Only include the totag for non-invite requests
      if (header(h_RequestLine).getMethod() != INVITE && 
          header(h_RequestLine).getMethod() != ACK && 
          header(h_RequestLine).getMethod() != CANCEL &&
          header(h_To).exists(p_tag))
      {
         strm << header(h_To).param(p_tag);
      }

      strm << header(h_CallID).value();

      if (header(h_RequestLine).getMethod() == ACK || 
          header(h_RequestLine).getMethod() == CANCEL)
      {
         strm << INVITE;
         strm << header(h_CSeq).sequence();
      }
      else
      {
         strm << header(h_CSeq).method();
         strm << header(h_CSeq).sequence();
      }
           
      mRFC2543TransactionId = strm.getHex();
   }
   else
   {
      InfoLog (<< "Trying to compute a transaction id on a 2543 response. Drop the response");
      DebugLog (<< *this);
      throw Exception("Drop invalid 2543 response", __FILE__, __LINE__);
   }
}

Here is the call graph for this function:

const RequestLine& resip::SipMessage::const_header ( const RequestLineType l) const [inline]

Definition at line 280 of file SipMessage.hxx.

References header().

Referenced by resip::TransportSelector::dnsResolve(), resip::TransportSelector::findTransportByVia(), getContents(), resip::Helper::getPortForReply(), resip::TransactionState::handleInternalCancel(), resip::TransactionState::isResponse(), resip::Helper::makeChallengeResponseAuthWithA1(), resip::DeprecatedDialog::makeInitialInvite(), resip::DeprecatedDialog::makeInitialMessage(), resip::DeprecatedDialog::makeInitialPublish(), resip::DeprecatedDialog::makeInitialRegister(), resip::DeprecatedDialog::makeInitialSubscribe(), resip::DeprecatedDialog::makeResponse(), resip::Helper::makeResponse(), resip::ConnectionBase::preparseNewBytes(), resip::StatelessHandler::process(), resip::TransactionState::process(), resip::TransactionState::processClientInvite(), resip::TransactionState::processClientNonInvite(), resip::TransactionState::processServerInvite(), resip::TransactionState::processServerNonInvite(), resip::Helper::processStrictRoute(), resip::StatisticsManager::received(), resip::StatelessMessage::rewriteRequest(), resip::TransactionState::rewriteRequest(), resip::TransactionState::saveOriginalContactAndVia(), resip::TransactionState::sendCurrentToWire(), resip::TransactionState::sendToTU(), resip::StatisticsManager::sent(), setBody(), resip::Transport::setRemoteSigcompId(), resip::Transport::stampReceived(), and resip::TransportSelector::transmit().

      {
         return header(l);
      }

Here is the call graph for this function:

const StatusLine& resip::SipMessage::const_header ( const StatusLineType l) const [inline]

Definition at line 294 of file SipMessage.hxx.

References header().

      {
         return header(l);
      }

Here is the call graph for this function:

void resip::SipMessage::copyFrom ( const SipMessage message) [private]
void SipMessage::copyOutboundDecoratorsToStackCancel ( SipMessage cancel)

Definition at line 1741 of file SipMessage.cxx.

References addOutboundDecorator(), and mOutboundDecorators.

Referenced by resip::TransactionState::processClientInvite().

{
  std::vector<MessageDecorator*>::iterator i;
  for (i = mOutboundDecorators.begin();
       i != mOutboundDecorators.end(); i++)
  {
     if((*i)->copyToStackCancels())
     {
        cancel.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone())));
     }    
  }
}

Here is the call graph for this function:

void SipMessage::copyOutboundDecoratorsToStackFailureAck ( SipMessage ack)

Definition at line 1755 of file SipMessage.cxx.

References addOutboundDecorator(), and mOutboundDecorators.

Referenced by resip::TransactionState::processClientInvite().

{
  std::vector<MessageDecorator*>::iterator i;
  for (i = mOutboundDecorators.begin();
       i != mOutboundDecorators.end(); i++)
  {
     if((*i)->copyToStackFailureAcks())
     {
        ack.addOutboundDecorator(*(new auto_ptr<MessageDecorator>((*i)->clone())));
     }    
  }
}

Here is the call graph for this function:

resip::SipMessage::defineHeader ( ContentDisposition  ,
"Content-Disposition"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( ContentEncoding  ,
"Content-Encoding"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( MIMEVersion  ,
"Mime-Version"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Priority  ,
"Priority"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Event  ,
"Event"  ,
Token  ,
"RFC 3265"   
)
resip::SipMessage::defineHeader ( SubscriptionState  ,
"Subscription-State"  ,
Token  ,
"RFC 3265"   
)
resip::SipMessage::defineHeader ( SIPETag  ,
"SIP-ETag"  ,
Token  ,
"RFC 3903"   
)
resip::SipMessage::defineHeader ( SIPIfMatch  ,
"SIP-If-Match"  ,
Token  ,
"RFC 3903"   
)
resip::SipMessage::defineHeader ( ContentId  ,
"Content-ID"  ,
Token  ,
"RFC 2045"   
)
resip::SipMessage::defineHeader ( Identity  ,
"Identity"  ,
StringCategory  ,
"RFC 4474"   
)
resip::SipMessage::defineHeader ( ReferSub  ,
"Refer-Sub"  ,
Token  ,
"RFC 4488"   
)
resip::SipMessage::defineHeader ( AnswerMode  ,
"Answer-Mode"  ,
Token  ,
"draft-ietf-answermode-04"   
)
resip::SipMessage::defineHeader ( PrivAnswerMode  ,
"Priv-Answer-Mode"  ,
Token  ,
"draft-ietf-answermode-04"   
)
resip::SipMessage::defineHeader ( ContentType  ,
"Content-Type"  ,
Mime  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( IdentityInfo  ,
"Identity-Info"  ,
GenericUri  ,
"RFC 4474"   
)
resip::SipMessage::defineHeader ( From  ,
"From"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( To  ,
"To"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( ReplyTo  ,
"Reply-To"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( ReferTo  ,
"Refer-To"  ,
NameAddr  ,
"RFC 3515"   
)
resip::SipMessage::defineHeader ( ReferredBy  ,
"Referred-By"  ,
NameAddr  ,
"RFC 3892"   
)
resip::SipMessage::defineHeader ( PCalledPartyId  ,
"P-Called-Party-ID"  ,
NameAddr  ,
"RFC 3455"   
)
resip::SipMessage::defineHeader ( ContentTransferEncoding  ,
"Content-Transfer-Encoding"  ,
StringCategory  ,
"RFC 1521"   
)
resip::SipMessage::defineHeader ( Organization  ,
"Organization"  ,
StringCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Server  ,
"Server"  ,
StringCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Subject  ,
"Subject"  ,
StringCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( UserAgent  ,
"User-Agent"  ,
StringCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Timestamp  ,
"Timestamp"  ,
StringCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( ContentLength  ,
"Content-Length"  ,
UInt32Category  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( MaxForwards  ,
"Max-Forwards"  ,
UInt32Category  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( MinExpires  ,
"Min-Expires"  ,
UInt32Category  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( RSeq  ,
"RSeq"  ,
UInt32Category  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( RetryAfter  ,
"Retry-After"  ,
UInt32Category  ,
"RFC 3261"   
)
Todo:
!dlb! this one is not quite right -- can have (comment) after field value
resip::SipMessage::defineHeader ( FlowTimer  ,
"Flow-Timer ,
UInt32Category  ,
"RFC 5626"   
)
resip::SipMessage::defineHeader ( Expires  ,
"Expires"  ,
ExpiresCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( SessionExpires  ,
"Session-Expires"  ,
ExpiresCategory  ,
"RFC 4028"   
)
resip::SipMessage::defineHeader ( MinSE  ,
"Min-SE"  ,
ExpiresCategory  ,
"RFC 4028"   
)
resip::SipMessage::defineHeader ( CallID  ,
"Call-ID"  ,
CallID  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Replaces  ,
"Replaces"  ,
CallID  ,
"RFC 3891"   
)
resip::SipMessage::defineHeader ( InReplyTo  ,
"In-Reply-To"  ,
CallID  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Join  ,
"Join"  ,
CallId  ,
"RFC 3911"   
)
resip::SipMessage::defineHeader ( TargetDialog  ,
"Target-Dialog"  ,
CallId  ,
"RFC 4538"   
)
resip::SipMessage::defineHeader ( AuthenticationInfo  ,
"Authentication-Info"  ,
Auth  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( CSeq  ,
"CSeq"  ,
CSeqCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( Date  ,
"Date"  ,
DateCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineHeader ( RAck  ,
"RAck"  ,
RAckCategory  ,
"RFC 3262"   
)
resip::SipMessage::defineMultiHeader ( AllowEvents  ,
"Allow-Events"  ,
Token  ,
"RFC 3265"   
)
resip::SipMessage::defineMultiHeader ( AcceptEncoding  ,
"Accept-Encoding"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( AcceptLanguage  ,
"Accept-Language"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Allow  ,
"Allow"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( ContentLanguage  ,
"Content-Language"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( ProxyRequire  ,
"Proxy-Require"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Require  ,
"Require"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Supported  ,
"Supported"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Unsupported  ,
"Unsupported"  ,
Token  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( SecurityClient  ,
"Security-Client ,
Token  ,
"RFC 3329"   
)
resip::SipMessage::defineMultiHeader ( SecurityServer  ,
"Security-Server ,
Token  ,
"RFC 3329"   
)
resip::SipMessage::defineMultiHeader ( SecurityVerify  ,
"Security-Verify"  ,
Token  ,
"RFC 3329"   
)
resip::SipMessage::defineMultiHeader ( RequestDisposition  ,
"Request-Disposition"  ,
Token  ,
"RFC 3841"   
)
resip::SipMessage::defineMultiHeader ( Reason  ,
"Reason"  ,
Token  ,
"RFC 3326"   
)
resip::SipMessage::defineMultiHeader ( Privacy  ,
"Privacy"  ,
PrivacyCategory  ,
"RFC 3323"   
)
resip::SipMessage::defineMultiHeader ( PMediaAuthorization  ,
"P-Media-Authorization"  ,
Token  ,
"RFC 3313"   
)
resip::SipMessage::defineMultiHeader ( Accept  ,
"Accept"  ,
Mime  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( CallInfo  ,
"Call-Info"  ,
GenericUri  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( AlertInfo  ,
"Alert-Info"  ,
GenericUri  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( ErrorInfo  ,
"Error-Info"  ,
GenericUri  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( RecordRoute  ,
"Record-Route"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Route  ,
"Route"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Contact  ,
"Contact"  ,
NameAddr  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Path  ,
"Path"  ,
NameAddr  ,
"RFC 3327"   
)
resip::SipMessage::defineMultiHeader ( AcceptContact  ,
"Accept-Contact"  ,
NameAddr  ,
"RFC 3841"   
)
resip::SipMessage::defineMultiHeader ( RejectContact  ,
"Reject-Contact"  ,
NameAddr  ,
"RFC 3841"   
)
resip::SipMessage::defineMultiHeader ( PAssertedIdentity  ,
"P-Asserted-Identity"  ,
NameAddr  ,
"RFC 3325"   
)
resip::SipMessage::defineMultiHeader ( PPreferredIdentity  ,
"P-Preferred-Identity"  ,
NameAddr  ,
"RFC 3325"   
)
resip::SipMessage::defineMultiHeader ( PAssociatedUri  ,
"P-Associated-URI"  ,
NameAddr  ,
"RFC 3455"   
)
resip::SipMessage::defineMultiHeader ( ServiceRoute  ,
"Service-Route"  ,
NameAddr  ,
"RFC 3608"   
)
resip::SipMessage::defineMultiHeader ( RemotePartyId  ,
"Remote-Party-ID"  ,
NameAddr  ,
"draft-ietf-sip-privacy-04"   
)
resip::SipMessage::defineMultiHeader ( HistoryInfo  ,
"History-Info"  ,
NameAddr  ,
"RFC 4244"   
)
resip::SipMessage::defineMultiHeader ( Authorization  ,
"Authorization"  ,
Auth  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( ProxyAuthenticate  ,
"Proxy-Authenticate"  ,
Auth  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( ProxyAuthorization  ,
"Proxy-Authorization"  ,
Auth  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( WWWAuthenticate  ,
"Www-Authenticate"  ,
Auth  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Warning  ,
"Warning"  ,
WarningCategory  ,
"RFC 3261"   
)
resip::SipMessage::defineMultiHeader ( Via  ,
"Via"  ,
Via  ,
"RFC 3261"   
)
bool SipMessage::empty ( const HeaderBase headerType) const

Returns true if the header field is present and non-empty, false otherwise.

Definition at line 1382 of file SipMessage.cxx.

References resip::HeaderBase::getTypeNum(), mHeaderIndices, and mHeaders.

Referenced by compute2543TransactionHash(), encodeBrief(), getCanonicalIdentityString(), getContents(), getRFC2543TransactionId(), getTransactionId(), resip::Helper::massageRoute(), and resip::Helper::validateMessage().

{
   return (mHeaderIndices[headerType.getTypeNum()] <= 0) || mHeaders[mHeaderIndices[headerType.getTypeNum()]]->parsedEmpty();
}

Here is the call graph for this function:

EncodeStream & SipMessage::encode ( EncodeStream str) const [virtual]
EncodeStream & SipMessage::encode ( EncodeStream str,
bool  isSipFrag 
) const [private]

Definition at line 704 of file SipMessage.cxx.

References resip::Data::append(), CRLF, resip::Data::empty(), resip::LazyParser::encode(), resip::HeaderFieldValue::getBuffer(), resip::HeaderFieldValue::getLength(), resip::Headers::MAX_HEADERS, mContents, mContentsHfv, mHeaderIndices, mHeaders, mStartLine, mUnknownHeaders, resip::Data::size(), and resip::HeaderFieldValue::toShareData().

{
   if (mStartLine != 0)
   {
      mStartLine->encode(str);
      str << "\r\n";
   }

   Data contents;
   if (mContents != 0)
   {
      oDataStream temp(contents);
      mContents->encode(temp);
   }
   else if (mContentsHfv.getBuffer() != 0)
   {
#if 0
      // !bwc! This causes an additional copy; sure would be nice to have a way
      // to get a data to take on a buffer with Data::Share _after_ construction
      contents.append(mContentsHfv.getBuffer(), mContentsHfv.getLength());
#else
      // .kw. Your wish is granted
      mContentsHfv.toShareData(contents);
#endif
   }

   for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++)
   {
      if (i != Headers::ContentLength) // !dlb! hack...
      {
         if (mHeaderIndices[i] > 0)
         {
            mHeaders[mHeaderIndices[i]]->encode(i, str);
         }
      }
   }

   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
        i != mUnknownHeaders.end(); i++)
   {
      i->second->encode(i->first, str);
   }

   if(!isSipFrag || !contents.empty())
   {
      str << "Content-Length: " << contents.size() << "\r\n";
   }

   str << Symbols::CRLF;
   
   str << contents;
   return str;
}

Here is the call graph for this function:

EncodeStream & SipMessage::encodeBrief ( EncodeStream str) const [virtual]

output a brief description to stream

Implements resip::Message.

Definition at line 615 of file SipMessage.cxx.

References contactEB(), cseqEB(), resip::Data::empty(), empty(), ftuEB, resip::Uri::getAor(), resip::RequestLine::getMethod(), getTransactionId(), header(), isRequest(), isResponse(), mIsExternal, mTlsDomain, requestEB, responseEB, slashEB, resip::Symbols::SPACE, tidEB(), tlsdEB(), resip::RequestLine::unknownMethodName(), resip::RequestLine::uri(), and wireEB.

{
   if (isRequest()) 
   {
      str << requestEB;
      MethodTypes meth = header(h_RequestLine).getMethod();
      if (meth != UNKNOWN)
      {
         str << getMethodName(meth);
      }
      else
      {
         str << header(h_RequestLine).unknownMethodName();
      }
      
      str << Symbols::SPACE;
      str << header(h_RequestLine).uri().getAor();
   }
   else if (isResponse())
   {
      str << responseEB;
      str << header(h_StatusLine).responseCode();
   }
   if (!empty(h_Vias))
   {
      str << tidEB;
      try
      {
         str << getTransactionId();
      }
      catch(SipMessage::Exception&)
      {
         str << "BAD-VIA";
      }
   }
   else
   {
      str << " NO-VIAS ";
   }

   str << cseqEB;
   str << header(h_CSeq);

   try
   {
      if (!empty(h_Contacts))
      {
         str << contactEB;
         str << header(h_Contacts).front().uri().getAor();
      }
   }
   catch(resip::ParseException&)
   {
      str << " MALFORMED CONTACT ";
   }
   
   str << slashEB;
   str << header(h_CSeq).sequence();
   str << (mIsExternal ? wireEB : ftuEB);
   if (!mTlsDomain.empty())
   {
      str << tlsdEB << mTlsDomain;
   }
   
   return str;
}

Here is the call graph for this function:

EncodeStream & SipMessage::encodeEmbedded ( EncodeStream str) const

Definition at line 769 of file SipMessage.cxx.

References resip::Symbols::AMPERSAND, resip::LazyParser::encode(), encode(), resip::HeaderFieldValue::getBuffer(), resip::Headers::getHeaderName(), resip::Headers::MAX_HEADERS, mContents, mContentsHfv, mHeaderIndices, mHeaders, mUnknownHeaders, resip::Symbols::QUESTION, and resip::HeaderFieldValue::toShareData().

{
   bool first = true;
   for (UInt8 i = 0; i < Headers::MAX_HEADERS; i++)
   {
      if (i != Headers::ContentLength)
      {
         if (mHeaderIndices[i] > 0)
         {
            if (first)
            {
               str << Symbols::QUESTION;
               first = false;
            }
            else
            {
               str << Symbols::AMPERSAND;
            }
            mHeaders[mHeaderIndices[i]]->encodeEmbedded(Headers::getHeaderName(i), str);
         }
      }
   }

   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin(); 
        i != mUnknownHeaders.end(); i++)
   {
      if (first)
      {
         str << Symbols::QUESTION;
         first = false;
      }
      else
      {
         str << Symbols::AMPERSAND;
      }
      i->second->encodeEmbedded(i->first, str);
   }

   if (mContents != 0 || mContentsHfv.getBuffer() != 0)
   {
      if (first)
      {
         str << Symbols::QUESTION;
      }
      else
      {
         str << Symbols::AMPERSAND;
      }
      str << "body=";
      Data contents;
      // !dlb! encode escaped for characters
      // .kw. what does that mean? what needs to be escaped?
      if(mContents != 0)
      {
         DataStream s(contents);
         mContents->encode(s);
      }
      else
      {
         // .kw. Early code did:
         // DataStream s(contents);
         // mContentsHfv->encode(str);
         // str << Embedded::encode(contents);
         // .kw. which I think is buggy b/c Hfv was written directly
         // to str and skipped the encode step via contents
         mContentsHfv.toShareData(contents);
      }
      str << Embedded::encode(contents);
   }
   return str;
}

Here is the call graph for this function:

EncodeStream & SipMessage::encodeSingleHeader ( Headers::Type  type,
EncodeStream str 
) const

Definition at line 759 of file SipMessage.cxx.

References mHeaderIndices, mHeaders, and type.

Referenced by resip::Helper::makeRawResponse().

{
   if (mHeaderIndices[type] > 0)
   {
      mHeaders[mHeaderIndices[type]]->encode(type, str);
   }
   return str;
}
EncodeStream & SipMessage::encodeSipFrag ( EncodeStream str) const [virtual]

Definition at line 696 of file SipMessage.cxx.

References encode().

Referenced by resip::SipFrag::encodeParsed(), and main().

{
   return encode(str, true);
}

Here is the call graph for this function:

HeaderFieldValueList * SipMessage::ensureHeader ( Headers::Type  type) [private]

Definition at line 1336 of file SipMessage.cxx.

References getEmptyHfvl(), mHeaderIndices, mHeaders, resip::HeaderFieldValueList::push_back(), and type.

{
   HeaderFieldValueList* hfvl=0;
   if(mHeaderIndices[type]!=0)
   {
      if(mHeaderIndices[type]<0)
      {
         // Accessing a previously removed header type; there is already an 
         // empty HeaderFieldValueList in mHeaders for this type, all we 
         // need to do is flip the sign to re-enable it.
         mHeaderIndices[type] *= -1;
         hfvl = mHeaders[mHeaderIndices[type]];
         hfvl->push_back(0,0,false);
      }
      hfvl = mHeaders[mHeaderIndices[type]];
   }
   else
   {
      // create the list with a new component
      mHeaders.push_back(getEmptyHfvl());
      hfvl=mHeaders.back();
      mHeaderIndices[type]=mHeaders.size()-1;
      mHeaders.back()->push_back(0,0,false);
   }

   return hfvl;
}

Here is the call graph for this function:

HeaderFieldValueList* resip::SipMessage::ensureHeader ( Headers::Type  type) const [inline, private]

Definition at line 567 of file SipMessage.hxx.

References mHeaderIndices, mHeaders, throwHeaderMissing(), and type.

      {
         if(mHeaderIndices[type]>0)
         {
            return mHeaders[mHeaderIndices[type]];
         }
         throwHeaderMissing(type);
         return 0;
      }

Here is the call graph for this function:

HeaderFieldValueList * SipMessage::ensureHeaders ( Headers::Type  type) [private]

Definition at line 1310 of file SipMessage.cxx.

References getEmptyHfvl(), mHeaderIndices, mHeaders, and type.

Referenced by parseAllHeaders().

{
   HeaderFieldValueList* hfvl=0;
   if(mHeaderIndices[type]!=0)
   {
      if(mHeaderIndices[type]<0)
      {
         // Accessing a previously removed header type; there is already an 
         // empty HeaderFieldValueList in mHeaders for this type, all we 
         // need to do is flip the sign to re-enable it.
         mHeaderIndices[type] *= -1;
      }
      hfvl = mHeaders[mHeaderIndices[type]];
   }
   else
   {
      // create the list with a new component
      mHeaders.push_back(getEmptyHfvl());
      hfvl=mHeaders.back();
      mHeaderIndices[type]=mHeaders.size()-1;
   }

   return hfvl;
}

Here is the call graph for this function:

HeaderFieldValueList* resip::SipMessage::ensureHeaders ( Headers::Type  type) const [inline, private]

Definition at line 556 of file SipMessage.hxx.

References mHeaderIndices, mHeaders, throwHeaderMissing(), and type.

      {
         if(mHeaderIndices[type]>0)
         {
            return mHeaders[mHeaderIndices[type]];
         }
         throwHeaderMissing(type);
         return 0;
      }

Here is the call graph for this function:

bool SipMessage::exists ( const HeaderBase headerType) const

Returns true if the given header field is present, false otherwise.

Definition at line 1376 of file SipMessage.cxx.

References resip::HeaderBase::getTypeNum(), and mHeaderIndices.

Referenced by resip::Helper::addAuthorization(), resip::Helper::advancedAuthenticateRequest(), resip::Helper::authenticateRequest(), resip::Helper::authenticateRequestWithA1(), badbranch(), compute2543TransactionHash(), resip::DeprecatedDialog::createDialogAsUAC(), dblreq(), resip::Helper::determineFailureMessageEffect(), resip::TransportSelector::determineSourceInterface(), resip::TransportSelector::dnsResolve(), esc01(), esc02(), escnull(), resip::MessageFilterRule::eventIsInList(), resip::TransportSelector::findTransportByVia(), getRFC2543TransactionId(), getTransactionId(), intmeth(), longreq(), lwsdisp(), main(), resip::DeprecatedDialog::makeAck(), resip::Helper::makeCancel(), resip::Helper::makeFailureAck(), resip::DeprecatedDialog::makeResponse(), resip::Helper::makeResponse(), mpart01(), noreason(), resip::SipFrag::parse(), resip::TransactionState::process(), resip::TuIM::processRegisterRequest(), resip::TuIM::processRegisterResponse(), resip::TuIM::processResponse(), resip::Helper::processStrictRoute(), resip::TuIM::processSubscribeRequest(), resip::TuIM::processSubscribeResponse(), resip::TransactionState::saveOriginalContactAndVia(), semiuri(), resip::TransactionState::sendCurrentToWire(), resip::TransactionState::sendToTU(), setBody(), resip::Transport::stampReceived(), resip::DeprecatedDialog::targetRefreshRequest(), resip::DeprecatedDialog::targetRefreshResponse(), resip::TransportSelector::transmit(), transports(), unreason(), and wsinv().

{
   return mHeaderIndices[headerType.getTypeNum()] > 0;
};

Here is the call graph for this function:

bool SipMessage::exists ( const ExtensionHeader symbol) const

Definition at line 1150 of file SipMessage.cxx.

References resip::ExtensionHeader::getName(), resip::isEqualNoCase(), and mUnknownHeaders.

{
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {
      if (isEqualNoCase(i->first, symbol.getName()))
      {
         return true;
      }
   }
   return false;
}

Here is the call graph for this function:

void resip::SipMessage::freeHfvl ( HeaderFieldValueList hfvl) [inline, private]

Definition at line 591 of file SipMessage.hxx.

References resip::DinkyPool< S >::deallocate(), mPool, and resip::HeaderFieldValueList::~HeaderFieldValueList().

Referenced by freeMem(), and remove().

      {
         if(hfvl)
         {
            hfvl->~HeaderFieldValueList();
            mPool.deallocate(hfvl);
         }
      }

Here is the call graph for this function:

void SipMessage::freeMem ( bool  leaveResponseStuff = false) [protected]

Definition at line 208 of file SipMessage.cxx.

References freeHfvl(), mBufferList, mContents, mForceTarget, mHeaders, mOutboundDecorators, mReason, mStartLine, mUnknownHeaders, and resip::StartLine::~StartLine().

Referenced by operator=(), and ~SipMessage().

{
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {
      freeHfvl(i->second);
   }

   if(!leaveResponseStuff)
   {
      for (TypedHeaders::iterator i = mHeaders.begin();
           i != mHeaders.end(); i++)
      {
         freeHfvl(*i);
      }
      mHeaders.clear();

      for (vector<char*>::iterator i = mBufferList.begin();
           i != mBufferList.end(); i++)
      {
         delete [] *i;
      }
   }

   if(mStartLine)
   {
      mStartLine->~StartLine();
      mStartLine=0;
   }

   delete mContents;
   delete mForceTarget;
   delete mReason;

   for(std::vector<MessageDecorator*>::iterator i=mOutboundDecorators.begin();
         i!=mOutboundDecorators.end();++i)
   {
      delete *i;
   }
}

Here is the call graph for this function:

Data SipMessage::getCanonicalIdentityString ( ) const

Definition at line 480 of file SipMessage.cxx.

References resip::Symbols::BAR, DebugLog, empty(), resip::HeaderFieldValue::encode(), resip::LazyParser::encode(), resip::RequestLine::encodeParsed(), resip::HeaderFieldValue::getBuffer(), header(), mContents, mContentsHfv, resip::Symbols::STAR, resip::RequestLine::uri(), and WarningLog.

Referenced by resip::TransportSelector::transmit().

{
   Data result;
   DataStream strm(result);
   
   // digest-string = addr-spec ":" addr-spec ":" callid ":" 1*DIGIT SP method ":"
   //             SIP-Date ":" [ addr-spec ] ":" message-body
  
   strm << header(h_From).uri();
   strm << Symbols::BAR;
   
   strm << header(h_To).uri();
   strm << Symbols::BAR;
   
   strm << header(h_CallId).value();
   strm << Symbols::BAR;
   
   header(h_CSeq).sequence(); // force parsed
   header(h_CSeq).encodeParsed( strm );
   strm << Symbols::BAR;
   
   // if there is no date, it will throw 
   if ( empty(h_Date) )
   {
      WarningLog( << "Computing Identity on message with no Date header" );
      // TODO FIX - should it have a throw here ???? Help ???
   }
   header(h_Date).dayOfMonth(); // force it to be parsed 
   header(h_Date).encodeParsed( strm );
   strm << Symbols::BAR;
   
   if ( !empty(h_Contacts) )
   { 
      if ( header(h_Contacts).front().isAllContacts() )
      {
         strm << Symbols::STAR;
      }
      else
      {
         strm << header(h_Contacts).front().uri();
      }
   }
   strm << Symbols::BAR;
   
   // bodies 
   if (mContents != 0)
   {
      mContents->encode(strm);
   }
   else if (mContentsHfv.getBuffer() != 0)
   {
      mContentsHfv.encode(strm);
   }

   strm.flush();

   DebugLog( << "Indentity Canonical String is: " << result );
   
   return result;
}

Here is the call graph for this function:

Contents * SipMessage::getContents ( ) const

Retrieves the body of a SIP message.

In the case of an INVITE request containing SDP, the body would be an SdpContents. For a MESSAGE request, the body may be PlainContents, CpimContents, or another subclass of Contents.

Returns:
pointer to the contents of the SIP message

Definition at line 1032 of file SipMessage.cxx.

References const_header(), DebugLog, empty(), resip::HeaderFieldValue::getBuffer(), resip::ContentsFactoryBase::getFactoryMap(), resip::OctetContents::getStaticType(), resip::Contents::header(), InfoLog, resip::LazyParser::isWellFormed(), mContents, mContentsHfv, StackLog, and type.

Referenced by resip::Helper::advancedAuthenticateRequest(), resip::Helper::authenticateRequest(), resip::Helper::authenticateRequestWithA1(), resip::Helper::extractFromPkcs7(), main(), resip::Helper::makeChallengeResponseAuth(), resip::Helper::makeChallengeResponseAuthWithA1(), parseAllHeaders(), resip::TuIM::processMessageRequest(), resip::TuIM::processNotifyRequest(), resip::TuIM::processSipFrag(), and releaseContents().

{
   if (mContents == 0 && mContentsHfv.getBuffer() != 0)
   {
      if (empty(h_ContentType) ||
            !const_header(h_ContentType).isWellFormed())
      {
         StackLog(<< "SipMessage::getContents: ContentType header does not exist - implies no contents");
         return 0;
      }
      DebugLog(<< "SipMessage::getContents: " 
               << const_header(h_ContentType).type()
               << "/"
               << const_header(h_ContentType).subType());

      if ( ContentsFactoryBase::getFactoryMap().find(const_header(h_ContentType)) == ContentsFactoryBase::getFactoryMap().end() )
      {
         InfoLog(<< "SipMessage::getContents: got content type ("
                 << const_header(h_ContentType).type()
                 << "/"
                 << const_header(h_ContentType).subType()
                 << ") that is not known, "
                 << "returning as opaque application/octet-stream");
         mContents = ContentsFactoryBase::getFactoryMap()[OctetContents::getStaticType()]->create(mContentsHfv, OctetContents::getStaticType());
      }
      else
      {
         mContents = ContentsFactoryBase::getFactoryMap()[const_header(h_ContentType)]->create(mContentsHfv, const_header(h_ContentType));
      }
      assert( mContents );
      
      // copy contents headers into the contents
      if (!empty(h_ContentDisposition))
      {
         mContents->header(h_ContentDisposition) = const_header(h_ContentDisposition);
      }
      if (!empty(h_ContentTransferEncoding))
      {
         mContents->header(h_ContentTransferEncoding) = const_header(h_ContentTransferEncoding);
      }
      if (!empty(h_ContentLanguages))
      {
         mContents->header(h_ContentLanguages) = const_header(h_ContentLanguages);
      }
      if (!empty(h_ContentType))
      {
         mContents->header(h_ContentType) = const_header(h_ContentType);
      }
      // !dlb! Content-Transfer-Encoding?
   }
   return mContents;
}

Here is the call graph for this function:

HeaderFieldValueList* resip::SipMessage::getCopyHfvl ( const HeaderFieldValueList hfvl) [inline, private]

Definition at line 585 of file SipMessage.hxx.

References resip::DinkyPool< S >::allocate(), and mPool.

Referenced by init(), and setRawHeader().

      {
         void* ptr(mPool.allocate(sizeof(HeaderFieldValueList)));
         return new (ptr) HeaderFieldValueList(hfvl, mPool);
      }

Here is the call graph for this function:

UInt64 resip::SipMessage::getCreatedTimeMicroSec ( ) [inline]

Definition at line 501 of file SipMessage.hxx.

References mCreatedTime.

{return mCreatedTime;}
Tuple& resip::SipMessage::getDestination ( ) [inline]
HeaderFieldValueList* resip::SipMessage::getEmptyHfvl ( ) [inline, private]

Definition at line 579 of file SipMessage.hxx.

References resip::DinkyPool< S >::allocate(), and mPool.

Referenced by addHeader(), clear(), ensureHeader(), ensureHeaders(), and header().

      {
         void* ptr(mPool.allocate(sizeof(HeaderFieldValueList)));
         return new (ptr) HeaderFieldValueList(mPool);
      }

Here is the call graph for this function:

const Uri & SipMessage::getForceTarget ( ) const
const HeaderFieldValue& resip::SipMessage::getRawBody ( ) const [inline]

Return the raw body string (if it exists).

The returned HFV and its underlying memory is owned by the SipMessage, and may be released when this SipMessage is manipulated.

This is a low-level interface; see getContents() for higher level.

Definition at line 442 of file SipMessage.hxx.

References mContentsHfv.

{return mContentsHfv;}
const HeaderFieldValueList * SipMessage::getRawHeader ( Headers::Type  headerType) const

typeless header interface

Definition at line 1550 of file SipMessage.cxx.

References mHeaderIndices, and mHeaders.

{
   if(mHeaderIndices[headerType]>0)
   {
      return mHeaders[mHeaderIndices[headerType]];
   }
   
   return 0;
}
const UnknownHeaders& resip::SipMessage::getRawUnknownHeaders ( ) const [inline]

Definition at line 434 of file SipMessage.hxx.

References mUnknownHeaders.

{return mUnknownHeaders;}
const resip::Data* resip::SipMessage::getReason ( ) const [inline]

Returns a string containing the response reason text.

Definition at line 269 of file SipMessage.hxx.

References mReason.

Referenced by resip::TransactionState::handleBadRequest().

{return mReason;}
const Transport* resip::SipMessage::getReceivedTransport ( ) const [inline]

Interface used to determine which Transport was used to receive a particular SipMessage.

If the SipMessage was not received from the wire, getReceivedTransport() returns 0. Set in constructor

Definition at line 486 of file SipMessage.hxx.

References mTransport.

Referenced by resip::TransactionState::sendToTU().

{ return mTransport; }
const Data & SipMessage::getRFC2543TransactionId ( ) const

Calculates an MD5 hash over the Request-URI, To tag (for non-INVITE transactions), From tag, Call-ID, CSeq (including the method), and top Via header.

The hash is used for transaction matching.

Definition at line 463 of file SipMessage.cxx.

References compute2543TransactionHash(), resip::Data::empty(), empty(), exists(), getTransactionId(), header(), and mRFC2543TransactionId.

Referenced by resip::Helper::makeResponse().

{
   if(empty(h_Vias) ||
      !header(h_Vias).front().exists(p_branch) ||
      !header(h_Vias).front().param(p_branch).hasMagicCookie() ||
      header(h_Vias).front().param(p_branch).getTransactionId().empty())
   {
      if (mRFC2543TransactionId.empty())
      {
         compute2543TransactionHash();
      }
   }
   return mRFC2543TransactionId;
}

Here is the call graph for this function:

const SecurityAttributes* resip::SipMessage::getSecurityAttributes ( ) const [inline]

Definition at line 520 of file SipMessage.hxx.

References mSecurityAttributes.

{ return mSecurityAttributes.get(); }
const Tuple& resip::SipMessage::getSource ( ) const [inline]
const Data& resip::SipMessage::getTlsDomain ( ) const [inline]
const std::list<Data>& resip::SipMessage::getTlsPeerNames ( ) const [inline]

Definition at line 512 of file SipMessage.hxx.

References mTlsPeerNames.

{ return mTlsPeerNames; }
const Data & SipMessage::getTransactionId ( ) const [virtual]

Returns the transaction id from the branch or if 2543, the computed hash.

Implements resip::TransactionMessage.

Definition at line 337 of file SipMessage.cxx.

References compute2543TransactionHash(), resip::Data::empty(), empty(), exists(), header(), InfoLog, and mRFC2543TransactionId.

Referenced by encodeBrief(), getRFC2543TransactionId(), resip::TransactionState::processSipMessageAsNew(), resip::TransactionState::sendCurrentToWire(), resip::TransactionState::tid(), and resip::TransportSelector::transmit().

{
   if (empty(h_Vias))
   {
      InfoLog (<< "Bad message with no Vias: " << *this);
      throw Exception("No Via in message", __FILE__,__LINE__);
   }
   
   assert(exists(h_Vias) && !header(h_Vias).empty());
   if( exists(h_Vias) && header(h_Vias).front().exists(p_branch) 
       && header(h_Vias).front().param(p_branch).hasMagicCookie() 
       && (!header(h_Vias).front().param(p_branch).getTransactionId().empty())
     )
   {
      return header(h_Vias).front().param(p_branch).getTransactionId();
   }
   else
   {
      if (mRFC2543TransactionId.empty())
      {
         compute2543TransactionHash();
      }
      return mRFC2543TransactionId;
   }
}

Here is the call graph for this function:

bool SipMessage::hasForceTarget ( ) const
const RequestLine & SipMessage::header ( const RequestLineType l) const

Returns the RequestLine. This is only valid for request messages.

Definition at line 1274 of file SipMessage.cxx.

References isResponse(), and mStartLine.

Referenced by resip::Helper::addAuthorization(), addHeader(), resip::Helper::advancedAuthenticateRequest(), resip::Helper::authenticateRequest(), resip::Helper::authenticateRequestWithA1(), badbranch(), compute2543TransactionHash(), const_header(), resip::DeprecatedDialog::copyCSeq(), resip::DeprecatedDialog::createDialogAsUAC(), dblreq(), resip::Helper::determineFailureMessageEffect(), resip::TransportSelector::determineSourceInterface(), resip::DeprecatedDialog::dialogId(), encodeBrief(), esc01(), esc02(), escnull(), resip::MessageFilterRule::eventIsInList(), resip::Helper::extractFromPkcs7(), resip::TransportSelector::findTransportByVia(), getCanonicalIdentityString(), resip::Helper::getClientPublicAddress(), getRFC2543TransactionId(), getTransactionId(), Loadgen::Registrar::go(), resip::TransactionState::handleBadRequest(), resip::TransactionState::handleInternalCancel(), resip::DeprecatedDialog::incrementCSeq(), intmeth(), resip::Helper::isClientBehindNAT(), resip::KeepAliveMessage::KeepAliveMessage(), longreq(), lwsdisp(), main(), resip::Helper::make405(), resip::DeprecatedDialog::makeAck(), resip::DeprecatedDialog::makeCancel(), resip::Helper::makeCancel(), resip::Helper::makeChallenge(), resip::Helper::makeChallengeResponseAuth(), resip::Helper::makeChallengeResponseAuthWithA1(), resip::Helper::makeFailureAck(), resip::BasicNonceHelper::makeNonce(), resip::DeprecatedDialog::makeRefer(), resip::DeprecatedDialog::makeRequestInternal(), resip::DeprecatedDialog::makeResponse(), resip::Helper::makeResponse(), resip::Helper::massageRoute(), resip::MessageFilterRule::matches(), mergeUri(), method(), methodStr(), mpart01(), noreason(), performTest(), resip::StatelessHandler::process(), resip::TransactionState::process(), Client::process(), resip::TuIM::processMessageRequest(), resip::TransactionState::processNoDnsResults(), resip::TuIM::processNotifyRequest(), resip::TuIM::processNotifyResponse(), resip::TuIM::processPageResponse(), resip::TuIM::processPublishResponse(), resip::TuIM::processRegisterRequest(), resip::TuIM::processRegisterResponse(), resip::TuIM::processRequest(), resip::TuIM::processResponse(), resip::UdpTransport::processRxParse(), resip::TransactionState::processServerInvite(), resip::Helper::processStrictRoute(), resip::TuIM::processSubscribeRequest(), resip::TuIM::processSubscribeResponse(), processTimeouts(), resip::TransactionState::processTransportFailure(), resip::StatisticsManager::received(), resip::TransactionState::restoreOriginalContactAndVia(), resip::StatelessMessage::rewriteRequest(), resip::TransactionState::rewriteRequest(), resip::TransactionState::saveOriginalContactAndVia(), semiuri(), Loadgen::Transceiver::send(), resip::TransactionController::send(), resip::TransactionState::sendToTU(), setBody(), resip::TuIM::setOutbound(), resip::Transport::stampReceived(), resip::DeprecatedDialog::targetRefreshRequest(), resip::DeprecatedDialog::targetRefreshResponse(), Client::thread(), Server::thread(), resip::TransportSelector::transmit(), transports(), unreason(), resip::DeprecatedDialog::updateRequest(), resip::Helper::validateMessage(), Loadgen::InviteServer::waitForRequest(), Loadgen::InviteServer::waitForResponse(), Loadgen::InviteClient::waitForResponse(), and wsinv().

{
   assert (!isResponse());
   if (mStartLine == 0 )
   { 
      // request line missing
      assert(false);
   }
   return *static_cast<RequestLine*>(mStartLine);
}

Here is the call graph for this function:

RequestLine & SipMessage::header ( const RequestLineType l)

Returns the RequestLine. This is only valid for request messages.

Definition at line 1262 of file SipMessage.cxx.

References isResponse(), mRequest, mStartLine, and mStartLineMem.

{
   assert (!isResponse());
   if (mStartLine == 0 )
   { 
      mStartLine = new (mStartLineMem) RequestLine;
      mRequest = true;
   }
   return *static_cast<RequestLine*>(mStartLine);
}

Here is the call graph for this function:

const StatusLine & SipMessage::header ( const StatusLineType l) const

Returns the StatusLine. This is only valid for response messages.

Definition at line 1298 of file SipMessage.cxx.

References isRequest(), and mStartLine.

{
   assert (!isRequest());
   if (mStartLine == 0 )
   { 
      // status line missing
      assert(false);
   }
   return *static_cast<StatusLine*>(mStartLine);
}

Here is the call graph for this function:

StatusLine & SipMessage::header ( const StatusLineType l)

Returns the StatusLine. This is only valid for response messages.

Definition at line 1286 of file SipMessage.cxx.

References isRequest(), mResponse, mStartLine, and mStartLineMem.

{
   assert (!isRequest());
   if (mStartLine == 0 )
   { 
      mStartLine = new (mStartLineMem) StatusLine;
      mResponse = true;
   }
   return *static_cast<StatusLine*>(mStartLine);
}

Here is the call graph for this function:

const StringCategories & SipMessage::header ( const ExtensionHeader symbol) const

unknown header interface

Definition at line 1103 of file SipMessage.cxx.

References resip::ExtensionHeader::getName(), resip::HeaderFieldValueList::getParserContainer(), resip::isEqualNoCase(), makeParserContainer(), mUnknownHeaders, and resip::HeaderFieldValueList::setParserContainer().

{
   for (UnknownHeaders::const_iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {      
      if (isEqualNoCase(i->first, headerName.getName()))
      {
         HeaderFieldValueList* hfvs = i->second;
         if (hfvs->getParserContainer() == 0)
         {
            SipMessage* nc_this(const_cast<SipMessage*>(this));
            hfvs->setParserContainer(nc_this->makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
         }
         return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
      }
   }
   // missing extension header
   assert(false);

   return *(StringCategories*)0;
}

Here is the call graph for this function:

StringCategories & SipMessage::header ( const ExtensionHeader symbol)

Definition at line 1126 of file SipMessage.cxx.

References getEmptyHfvl(), resip::ExtensionHeader::getName(), resip::HeaderFieldValueList::getParserContainer(), resip::isEqualNoCase(), mUnknownHeaders, and resip::HeaderFieldValueList::setParserContainer().

{
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {
      if (isEqualNoCase(i->first, headerName.getName()))
      {
         HeaderFieldValueList* hfvs = i->second;
         if (hfvs->getParserContainer() == 0)
         {
            hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
         }
         return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
      }
   }

   // create the list empty
   HeaderFieldValueList* hfvs = getEmptyHfvl();
   hfvs->setParserContainer(makeParserContainer<StringCategory>(hfvs, Headers::RESIP_DO_NOT_USE));
   mUnknownHeaders.push_back(make_pair(headerName.getName(), hfvs));
   return *dynamic_cast<ParserContainer<StringCategory>*>(hfvs->getParserContainer());
}

Here is the call graph for this function:

void SipMessage::init ( const SipMessage rhs) [protected]

Definition at line 111 of file SipMessage.cxx.

References clear(), resip::StartLine::clone(), resip::Contents::clone(), resip::HeaderFieldValue::copyWithPadding(), resip::HeaderFieldValue::getBuffer(), getCopyHfvl(), mContents, mContentsHfv, mDestination, mForceTarget, mHeaderIndices, mHeaders, mInvalid, mIsBadAck200, mIsDecorated, mIsExternal, mOutboundDecorators, mReason, mRequest, mResponse, mRFC2543TransactionId, mSecurityAttributes, mSource, mStartLine, mStartLineMem, mTlsDomain, mTransport, and mUnknownHeaders.

Referenced by operator=(), and SipMessage().

{
   clear();
   mIsDecorated = rhs.mIsDecorated;
   mIsBadAck200 = rhs.mIsBadAck200;
   mIsExternal = rhs.mIsExternal;
   mTransport = rhs.mTransport;
   mSource = rhs.mSource;
   mDestination = rhs.mDestination;
   mRFC2543TransactionId = rhs.mRFC2543TransactionId;
   mRequest = rhs.mRequest;
   mResponse = rhs.mResponse;
   mInvalid = rhs.mInvalid;
   if(!rhs.mReason)
   {
      mReason=0;
   }
   else
   {
      mReason = new Data(*rhs.mReason);
   }
   mTlsDomain = rhs.mTlsDomain;

   memcpy(&mHeaderIndices,&rhs.mHeaderIndices,sizeof(mHeaderIndices));

   // .bwc. Clear out the pesky invalid 0 index.
   mHeaders.clear();
   mHeaders.reserve(rhs.mHeaders.size());
   for (TypedHeaders::const_iterator i = rhs.mHeaders.begin();
        i != rhs.mHeaders.end(); i++)
   {
      mHeaders.push_back(getCopyHfvl(**i));
   }

   for (UnknownHeaders::const_iterator i = rhs.mUnknownHeaders.begin();
        i != rhs.mUnknownHeaders.end(); i++)
   {
      mUnknownHeaders.push_back(pair<Data, HeaderFieldValueList*>(
                                   i->first,
                                   getCopyHfvl(*i->second)));
   }
   if (rhs.mStartLine != 0)
   {
      mStartLine = rhs.mStartLine->clone(mStartLineMem);
   }
   if (rhs.mContents != 0)
   {
      mContents = rhs.mContents->clone();
   }
   else if (rhs.mContentsHfv.getBuffer() != 0)
   {
      mContentsHfv.copyWithPadding(rhs.mContentsHfv);
   }
   else
   {
      // no body to copy
   }
   if (rhs.mForceTarget != 0)
   {
      mForceTarget = new Uri(*rhs.mForceTarget);
   }

   if (rhs.mSecurityAttributes.get())
   {

      if (!mSecurityAttributes.get())
      {
         SecurityAttributes* attr = new SecurityAttributes();
         mSecurityAttributes.reset(attr);
      }

      if (rhs.mSecurityAttributes->isEncrypted())
      {
         mSecurityAttributes->setEncrypted();
      }
      mSecurityAttributes->setSignatureStatus(rhs.mSecurityAttributes->getSignatureStatus());
      mSecurityAttributes->setIdentity(rhs.mSecurityAttributes->getIdentity());
      mSecurityAttributes->setIdentityStrength(rhs.mSecurityAttributes->getIdentityStrength());
      mSecurityAttributes->setSigner(rhs.mSecurityAttributes->getSigner());
      mSecurityAttributes->setOutgoingEncryptionLevel(rhs.mSecurityAttributes->getOutgoingEncryptionLevel());
      mSecurityAttributes->setEncryptionPerformed(rhs.mSecurityAttributes->encryptionPerformed());
   }
   else
   {
      if (mSecurityAttributes.get())
      {
         mSecurityAttributes.reset();
      }
   }

   for(std::vector<MessageDecorator*>::const_iterator i=rhs.mOutboundDecorators.begin(); i!=rhs.mOutboundDecorators.end();++i)
   {
      mOutboundDecorators.push_back((*i)->clone());
   }
}

Here is the call graph for this function:

bool SipMessage::isClientTransaction ( ) const [virtual]

Check if SipMessage is a client transaction.

Returns:
true if the message is external and is a response or an internally-generated request.

Implements resip::TransactionMessage.

Definition at line 683 of file SipMessage.cxx.

References mIsExternal, mRequest, and mResponse.

{
   assert(mRequest || mResponse);
   return ((mIsExternal && mResponse) || (!mIsExternal && mRequest));
}
bool resip::SipMessage::isExternal ( ) const [inline]
bool resip::SipMessage::isInvalid ( ) const [inline]

Returns true if message failed to parse, false otherwise.

Definition at line 260 of file SipMessage.hxx.

References mInvalid.

Referenced by resip::TransactionState::process().

{return mInvalid;}
bool resip::SipMessage::isRequest ( ) const [inline]

Returns true if message is a request, false otherwise.

Definition at line 256 of file SipMessage.hxx.

References mRequest.

Referenced by resip::Transport::basicCheck(), compute2543TransactionHash(), resip::DeprecatedDialog::createDialogAsUAC(), resip::TransportSelector::determineSourceInterface(), resip::DeprecatedDialog::dialogId(), resip::TransportSelector::dnsResolve(), encodeBrief(), resip::Helper::extractFromPkcs7(), resip::Helper::getClientPublicAddress(), resip::Helper::getPortForReply(), resip::TransactionState::handleBadRequest(), header(), resip::Helper::isClientBehindNAT(), resip::TransactionState::isRequest(), main(), resip::Helper::makeCancel(), resip::DeprecatedDialog::makeResponse(), resip::Helper::massageRoute(), method(), methodStr(), performTest(), resip::ConnectionBase::preparseNewBytes(), resip::StatelessHandler::process(), resip::TransactionState::process(), resip::TransactionState::processClientInvite(), resip::UdpTransport::processRxParse(), resip::TransactionState::processSipMessageAsNew(), processTimeouts(), resip::TransactionState::processTransportFailure(), resip::StatisticsManager::received(), resip::StatelessMessage::rewriteRequest(), resip::TransactionState::rewriteRequest(), Loadgen::Transceiver::send(), resip::TransactionController::send(), resip::TransactionState::sendCurrentToWire(), resip::TransactionState::sendToTU(), resip::StatisticsManager::sent(), resip::Transport::stampReceived(), resip::TransportSelector::transmit(), resip::DeprecatedDialog::updateRequest(), resip::Helper::validateMessage(), and Loadgen::InviteServer::waitForRequest().

{return mRequest;}
bool resip::SipMessage::isResponse ( ) const [inline]
SipMessage * SipMessage::make ( const Data buffer,
bool  isExternal = false 
) [static]

Construct a SipMessage object from a string containing a SIP request or response.

Parameters:
buffera buffer containing a SIP message
isExternaltrue for a message generated externally, false otherwise.
Returns:
constructed SipMessage object

Definition at line 250 of file SipMessage.cxx.

References addBuffer(), resip::Data::data(), DebugLog, len, resip::MsgHeaderScanner::prepareForMessage(), resip::MsgHeaderScanner::scrEnd, setBody(), SipMessage(), and resip::Data::size().

Referenced by badaspec(), badbranch(), baddate(), baddn(), badinv01(), badvers(), bcast(), bext01(), bigcode(), clerr(), cparam01(), cparam02(), dblreq(), esc01(), esc02(), escnull(), escruri(), insuf(), intmeth(), inv2543(), invut(), longreq(), ltgtruri(), lwsdisp(), lwsruri(), lwsstart(), main(), mcl01(), mismatch01(), mismatch02(), mpart01(), multi01(), ncl(), noreason(), novelsc(), quotbal(), regaut01(), regbadct(), regescrt(), scalar02(), scalarlg(), sdp01(), semiuri(), transports(), trws(), unkscm(), unksm2(), unreason(), wsinv(), and zeromf().

{
   Transport* external = (Transport*)(0xFFFF);
   SipMessage* msg = new SipMessage(isExternal ? external : 0);

   size_t len = data.size();
   char *buffer = new char[len + 5];

   msg->addBuffer(buffer);
   memcpy(buffer,data.data(), len);
   MsgHeaderScanner msgHeaderScanner;
   msgHeaderScanner.prepareForMessage(msg);
   
   char *unprocessedCharPtr;
   if (msgHeaderScanner.scanChunk(buffer, (unsigned int)len, &unprocessedCharPtr) != MsgHeaderScanner::scrEnd)
   {
      DebugLog(<<"Scanner rejecting buffer as unparsable / fragmented.");
      DebugLog(<< data);
      delete msg; 
      msg = 0; 
      return 0;
   }

   // no pp error
   unsigned int used = (unsigned int)(unprocessedCharPtr - buffer);

   if (used < len)
   {
      // body is present .. add it up.
      // NB. The Sip Message uses an overlay (again)
      // for the body. It ALSO expects that the body
      // will be contiguous (of course).
      // it doesn't need a new buffer in UDP b/c there
      // will only be one datagram per buffer. (1:1 strict)

      msg->setBody(buffer+used,UInt32(len-used));
      //DebugLog(<<"added " << len-used << " byte body");
   }

   return msg;
}

Here is the call graph for this function:

template<class T >
ParserContainer<T>* resip::SipMessage::makeParserContainer ( ) [inline, private]

Definition at line 601 of file SipMessage.hxx.

References resip::DinkyPool< S >::allocate(), and mPool.

Referenced by header().

      {
         void* ptr(mPool.allocate(sizeof(ParserContainer<T>)));
         return new (ptr) ParserContainer<T>(mPool);
      }

Here is the call graph for this function:

template<class T >
ParserContainer<T>* resip::SipMessage::makeParserContainer ( HeaderFieldValueList hfvs,
Headers::Type  type = Headers::UNKNOWN 
) [inline, private]

Definition at line 608 of file SipMessage.hxx.

References resip::DinkyPool< S >::allocate(), mPool, and type.

      {
         void* ptr(mPool.allocate(sizeof(ParserContainer<T>)));
         return new (ptr) ParserContainer<T>(hfvs, type, mPool);
      }

Here is the call graph for this function:

SipMessage & SipMessage::mergeUri ( const Uri source)

Definition at line 1622 of file SipMessage.cxx.

References resip::Uri::embedded(), resip::Uri::exists(), resip::Uri::hasEmbedded(), header(), resip::RequestLine::method(), resip::ParserCategory::param(), resip::Uri::remove(), resip::Uri::removeEmbedded(), and resip::RequestLine::uri().

{
   header(h_RequestLine).uri() = source;
   header(h_RequestLine).uri().removeEmbedded();

   if (source.exists(p_method))
   {
      header(h_RequestLine).method() = getMethodType(source.param(p_method));
      header(h_RequestLine).uri().remove(p_method);      
   }           
   
   //19.1.5
   //dangerous headers not included in merge:
   // From, Call-ID, Cseq, Via, Record Route, Route, Accept, Accept-Encoding,
   // Accept-Langauge, Allow, Contact, Organization, Supported, User-Agent

   //from the should-verify section, remove for now, some never seem to make
   //sense:  
   // Content-Encoding, Content-Language, Content-Length, Content-Type, Date,
   // Mime-Version, and TimeStamp

   if (source.hasEmbedded())
   {
      h_AuthenticationInfo.merge(*this, source.embedded());
      h_ContentTransferEncoding.merge(*this, source.embedded());
      h_Event.merge(*this, source.embedded());
      h_Expires.merge(*this, source.embedded());
      h_SessionExpires.merge(*this, source.embedded());
      h_MinSE.merge(*this, source.embedded());
      h_InReplyTo.merge(*this, source.embedded());
      h_MaxForwards.merge(*this, source.embedded());
      h_MinExpires.merge(*this, source.embedded());
      h_Priority.merge(*this, source.embedded());
      h_ReferTo.merge(*this, source.embedded());
      h_ReferredBy.merge(*this, source.embedded());
      h_Replaces.merge(*this, source.embedded());
      h_ReplyTo.merge(*this, source.embedded());
      h_RetryAfter.merge(*this, source.embedded());
      h_Server.merge(*this, source.embedded());
      h_SIPETag.merge(*this, source.embedded());
      h_SIPIfMatch.merge(*this, source.embedded());
      h_Subject.merge(*this, source.embedded());
      h_SubscriptionState.merge(*this, source.embedded());
      h_To.merge(*this, source.embedded());
      h_Warnings.merge(*this, source.embedded());

      h_SecurityClients.merge(*this, source.embedded());
      h_SecurityServers.merge(*this, source.embedded());
      h_SecurityVerifys.merge(*this, source.embedded());

      h_Authorizations.merge(*this, source.embedded());
      h_ProxyAuthenticates.merge(*this, source.embedded());
      h_WWWAuthenticates.merge(*this, source.embedded());
      h_ProxyAuthorizations.merge(*this, source.embedded());

      h_AlertInfos.merge(*this, source.embedded());
      h_AllowEvents.merge(*this, source.embedded());
      h_CallInfos.merge(*this, source.embedded());
      h_ErrorInfos.merge(*this, source.embedded());
      h_ProxyRequires.merge(*this, source.embedded());
      h_Requires.merge(*this, source.embedded());
      h_Unsupporteds.merge(*this, source.embedded());
      h_AnswerMode.merge(*this, source.embedded());
      h_PrivAnswerMode.merge(*this, source.embedded());

      h_RSeq.merge(*this, source.embedded());
      h_RAck.merge(*this, source.embedded());
   }   
   //unknown header merge
   return *this;   
}

Here is the call graph for this function:

resip::MethodTypes SipMessage::method ( ) const
const Data & SipMessage::methodStr ( ) const

Returns a string containing the SIP method for the message.

Definition at line 575 of file SipMessage.cxx.

References resip::Data::Empty, header(), isRequest(), isResponse(), method(), and resip::RequestLine::unknownMethodName().

Referenced by resip::TransactionState::process(), and resip::TransactionState::processSipMessageAsNew().

{
   if(method()!=UNKNOWN)
   {
      return getMethodName(method());
   }
   else
   {
      try
      {
         if(isRequest())
         {
            return header(h_RequestLine).unknownMethodName();
         }
         else if(isResponse())
         {
            return header(h_CSeq).unknownMethodName();
         }
         else
         {
            assert(0);
         }
      }
      catch(resip::ParseException&)
      {
      }
   }
   return Data::Empty;
}

Here is the call graph for this function:

SipMessage & SipMessage::operator= ( const SipMessage rhs)

Definition at line 72 of file SipMessage.cxx.

References freeMem(), and init().

{
   if (this != &rhs)
   {
      freeMem();
      init(rhs);
   }
   return *this;
}

Here is the call graph for this function:

void SipMessage::parseAllHeaders ( )

Definition at line 293 of file SipMessage.cxx.

References resip::LazyParser::checkParsed(), ensureHeaders(), getContents(), resip::HeaderBase::getInstance(), resip::HeaderFieldValueList::getParserContainer(), resip::Headers::isMulti(), resip::HeaderBase::makeContainer(), resip::Headers::MAX_HEADERS, mHeaderIndices, mStartLine, mUnknownHeaders, resip::ParserContainerBase::parseAll(), resip::HeaderFieldValueList::parsedEmpty(), resip::HeaderFieldValueList::push_back(), and resip::HeaderFieldValueList::setParserContainer().

Referenced by badaspec(), badbranch(), baddate(), baddn(), badinv01(), badvers(), bcast(), bext01(), bigcode(), clerr(), cparam01(), cparam02(), dblreq(), esc01(), esc02(), escnull(), escruri(), insuf(), intmeth(), inv2543(), invut(), longreq(), ltgtruri(), lwsdisp(), lwsruri(), lwsstart(), mcl01(), mismatch01(), mismatch02(), mpart01(), multi01(), ncl(), noreason(), novelsc(), resip::TransactionState::process(), quotbal(), regaut01(), regbadct(), regescrt(), scalar02(), scalarlg(), sdp01(), semiuri(), transports(), trws(), unkscm(), unksm2(), unreason(), wsinv(), and zeromf().

{
   for (int i = 0; i < Headers::MAX_HEADERS; i++)
   {
      ParserContainerBase* pc=0;
      if(mHeaderIndices[i]>0)
      {
         HeaderFieldValueList* hfvl = ensureHeaders((Headers::Type)i);
         if(!Headers::isMulti((Headers::Type)i) && hfvl->parsedEmpty())
         {
            hfvl->push_back(0,0,false);
         }

         if(!(pc=hfvl->getParserContainer()))
         {
            pc = HeaderBase::getInstance((Headers::Type)i)->makeContainer(hfvl);
            hfvl->setParserContainer(pc);
         }
      
         pc->parseAll();
      }
   }

   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {
      ParserContainerBase* scs=0;
      if(!(scs=i->second->getParserContainer()))
      {
         scs=makeParserContainer<StringCategory>(i->second,Headers::RESIP_DO_NOT_USE);
         i->second->setParserContainer(scs);
      }
      
      scs->parseAll();
   }
   
   assert(mStartLine);

   mStartLine->checkParsed();
   
   getContents();
}

Here is the call graph for this function:

auto_ptr< Contents > SipMessage::releaseContents ( )

Removes the contents from the message.

Definition at line 1086 of file SipMessage.cxx.

References resip::Contents::clone(), getContents(), and setContents().

Referenced by main().

{
   Contents* c=getContents();
   // .bwc. auto_ptr owns the Contents. No other references allowed!
   auto_ptr<Contents> ret(c ? c->clone() : 0);
   setContents(std::auto_ptr<Contents>(0));

   if (ret.get() != 0 && !ret->isWellFormed())
   {
      ret.reset(0);
   }

   return ret;
}

Here is the call graph for this function:

void resip::SipMessage::remove ( const HeaderBase headerType) [inline]

Prevents a header field from being present when the message is prepared for sending to a transport.

This does not free the memory that was used by the header.

Definition at line 306 of file SipMessage.hxx.

Referenced by resip::TuIM::processRegisterRequest(), and resip::TransportSelector::transmit().

      {
         remove(headerType.getTypeNum());
      }
void SipMessage::remove ( Headers::Type  type)

Definition at line 1388 of file SipMessage.cxx.

References mHeaderIndices, mHeaders, and type.

{
   if(mHeaderIndices[type] > 0)
   {
      // .bwc. The entry in mHeaders still remains after we do this; we retain 
      // our index (as a negative number, indicating that this header should 
      // not be encoded), in case this header type needs to be used later.
      mHeaders[mHeaderIndices[type]]->clear();
      mHeaderIndices[type] *= -1;
   }
};
void SipMessage::remove ( const ExtensionHeader symbol)

Definition at line 1164 of file SipMessage.cxx.

References freeHfvl(), resip::ExtensionHeader::getName(), resip::isEqualNoCase(), and mUnknownHeaders.

{
   for (UnknownHeaders::iterator i = mUnknownHeaders.begin();
        i != mUnknownHeaders.end(); i++)
   {
      if (isEqualNoCase(i->first, headerName.getName()))
      {
         freeHfvl(i->second);
         mUnknownHeaders.erase(i);
         return;
      }
   }
}

Here is the call graph for this function:

resip::SipMessage::RESIP_HeapCount ( SipMessage  )
void SipMessage::rollbackOutboundDecorators ( )

Definition at line 1730 of file SipMessage.cxx.

References mIsDecorated, and mOutboundDecorators.

Referenced by callOutboundDecorators(), and resip::TransportSelector::transmit().

{
   std::vector<MessageDecorator*>::reverse_iterator r;
   for(r=mOutboundDecorators.rbegin(); r!=mOutboundDecorators.rend(); ++r)
   {
      (*r)->rollbackMessage(*this);
   }
   mIsDecorated = false;
}
void SipMessage::setBody ( const char *  start,
UInt32  len 
)

Definition at line 893 of file SipMessage.cxx.

References resip::Data::append(), checkContentLength, resip::LazyParser::checkParsed(), const_header(), exists(), header(), InfoLog, resip::HeaderFieldValue::init(), len, mContentsHfv, mInvalid, and mReason.

Referenced by make(), resip::SipFrag::parse(), resip::ConnectionBase::preparseNewBytes(), and resip::UdpTransport::processRxParse().

{
   if(checkContentLength)
   {
      if(exists(h_ContentLength))
      {
         try
         {
            const_header(h_ContentLength).checkParsed();
         }
         catch(resip::ParseException& e)
         {
            if(!mReason)
            {
               mReason=new Data;
            }
            
            if(mInvalid)
            {
               mReason->append(",",1);
            }

            mInvalid=true; 
            mReason->append("Malformed Content-Length",24);
            InfoLog(<< "Malformed Content-Length. Ignoring. " << e);
            header(h_ContentLength).value()=len;
         }
         
         UInt32 contentLength=const_header(h_ContentLength).value();
         
         if(len > contentLength)
         {
            InfoLog(<< (len-contentLength) << " extra bytes after body. Ignoring these bytes.");
         }
         else if(len < contentLength)
         {
            InfoLog(<< "Content Length (" << contentLength << ") is "
                    << (contentLength-len) << " bytes larger than body (" << len << ")!"
                    << " (We are supposed to 400 this) ");

            if(!mReason)
            {
               mReason=new Data;
            }

            if(mInvalid)
            {
               mReason->append(",",1);
            }

            mInvalid=true; 
            mReason->append("Bad Content-Length (larger than datagram)",41);
            header(h_ContentLength).value()=len;
            contentLength=len;
                     
         }
         
         mContentsHfv.init(start,contentLength, false);
      }
      else
      {
         InfoLog(<< "Message has a body, but no Content-Length header.");
         mContentsHfv.init(start,len, false);
      }
   }
   else
   {
      mContentsHfv.init(start,len, false);
   }
}

Here is the call graph for this function:

void SipMessage::setContents ( const Contents contents)

Set the contents of the message.

Parameters:
contentsto store in the message

Definition at line 1019 of file SipMessage.cxx.

References resip::Contents::clone().

Referenced by main(), releaseContents(), and setRawBody().

{ 
   if (contents)
   {
      setContents(auto_ptr<Contents>(contents->clone()));
   }
   else
   {
      setContents(auto_ptr<Contents>(0));
   }
}

Here is the call graph for this function:

void resip::SipMessage::setContents ( std::auto_ptr< Contents contents)

Set the contents of the message.

Parameters:
contentsto store in the message
void resip::SipMessage::setDestination ( const Tuple tuple) [inline]

Used by the stateless interface to specify where to send a request/response.

Definition at line 496 of file SipMessage.hxx.

References mDestination.

Referenced by resip::SipStack::sendTo().

{ mDestination = tuple; }
void SipMessage::setForceTarget ( const Uri uri)

deal with a notion of an "out-of-band" forced target for SIP routing

Definition at line 1589 of file SipMessage.cxx.

References mForceTarget.

Referenced by resip::TransportSelector::dnsResolve(), resip::Helper::processStrictRoute(), and resip::SipStack::sendTo().

{
   if (mForceTarget)
   {
      *mForceTarget = uri;
   }
   else
   {
      mForceTarget = new Uri(uri);
   }
}
void resip::SipMessage::setFromExternal ( ) [inline]

Mark message as externally generated.

Definition at line 223 of file SipMessage.hxx.

References mIsExternal.

Referenced by resip::Helper::makeResponse().

      {
         mIsExternal = true;
      }
void resip::SipMessage::setFromTU ( ) [inline]

Mark message as internally generated.

Definition at line 217 of file SipMessage.hxx.

References mIsExternal.

Referenced by resip::Helper::makeResponse(), resip::SipStack::sendTo(), and resip::TransactionState::sendToTU().

      {
         mIsExternal = false;
      }
void SipMessage::setRawBody ( const HeaderFieldValue body)

Remove any existing body/contents, and (if non-empty) set the body to {body}.

It makes full copy of the body to stored within the SipMessage (since lifetime of the message is unpredictable).

This is a low-level interface; see setContents() for higher level.

Definition at line 965 of file SipMessage.cxx.

References mContentsHfv, and setContents().

{
   setContents(0);
   mContentsHfv = body;
}

Here is the call graph for this function:

void SipMessage::setRawHeader ( const HeaderFieldValueList hfvs,
Headers::Type  headerType 
)

Definition at line 1561 of file SipMessage.cxx.

References getCopyHfvl(), resip::Headers::isMulti(), mHeaderIndices, mHeaders, resip::HeaderFieldValueList::parsedEmpty(), and resip::HeaderFieldValueList::push_back().

{
   HeaderFieldValueList* copy=0;
   if (mHeaderIndices[headerType] == 0)
   {
      mHeaderIndices[headerType]=mHeaders.size();
      copy=getCopyHfvl(*hfvs);
      mHeaders.push_back(copy);
   }
   else
   {
      if(mHeaderIndices[headerType]<0)
      {
         // Setting a previously removed header type; there is already an 
         // empty HeaderFieldValueList in mHeaders for this type, all we 
         // need to do is flip the sign to re-enable it.
         mHeaderIndices[headerType]=-mHeaderIndices[headerType];
      }
      copy = mHeaders[mHeaderIndices[headerType]];
      *copy=*hfvs;
   }
   if(!Headers::isMulti(headerType) && copy->parsedEmpty())
   {
      copy->push_back(0,0,false);
   }
}

Here is the call graph for this function:

void SipMessage::setRFC2543TransactionId ( const Data tid)

Definition at line 543 of file SipMessage.cxx.

References mRFC2543TransactionId.

Referenced by resip::Helper::makeResponse().

void SipMessage::setSecurityAttributes ( std::auto_ptr< SecurityAttributes )

Definition at line 1695 of file SipMessage.cxx.

References mSecurityAttributes.

void resip::SipMessage::setSource ( const Tuple tuple) [inline]

Definition at line 490 of file SipMessage.hxx.

References mSource.

Referenced by resip::ConnectionBase::preparseNewBytes(), and resip::UdpTransport::processRxParse().

{ mSource = tuple; }
void SipMessage::setStartLine ( const char *  start,
int  len 
)

transport interface

dcm! should invoke the statusline parser here once it does limited validation

dcm! should invoke the responseline parser here once it does limited validation

Definition at line 848 of file SipMessage.cxx.

References mRequest, mResponse, mStartLine, mStartLineMem, and strncasecmp().

{
   if(len >= 4 && !strncasecmp(st,"SIP/",4))
   {
      // Response
      mStartLine = new (mStartLineMem) StatusLine(st, len);
      mResponse = true;
   }
   else
   {
      // Request
      mStartLine = new (mStartLineMem) RequestLine(st, len);
      mRequest = true;
   }


// .bwc. This stuff is so needlessly complicated. Much, much simpler, faster,
// and more robust code above.
//   ParseBuffer pb(st, len);
//   const char* start;
//   start = pb.skipWhitespace();
//   pb.skipNonWhitespace();
//   MethodTypes method = getMethodType(start, pb.position() - start);
//   if (method == UNKNOWN) //probably a status line
//   {
//      start = pb.skipChar(Symbols::SPACE[0]);
//      pb.skipNonWhitespace();
//      if ((pb.position() - start) == 3)
//      {
//         mStartLine = new (mStartLineMem) StatusLine(st, len ,Headers::NONE);
//         //!dcm! should invoke the statusline parser here once it does limited validation
//         mResponse = true;
//      }
//   }
//   if (!mResponse)
//   {
//      mStartLine = new (mStartLineMem) RequestLine(st, len, Headers::NONE);
//      //!dcm! should invoke the responseline parser here once it does limited validation
//      mRequest = true;
//   }
}

Here is the call graph for this function:

void resip::SipMessage::setTlsDomain ( const Data domain) [inline]

Definition at line 510 of file SipMessage.hxx.

References mTlsDomain.

Referenced by resip::ConnectionBase::preparseNewBytes().

{ mTlsDomain = domain; }
void resip::SipMessage::setTlsPeerNames ( const std::list< Data > &  tlsPeerNames) [inline]

Definition at line 513 of file SipMessage.hxx.

References mTlsPeerNames.

Referenced by resip::ConnectionBase::preparseNewBytes().

{ mTlsPeerNames = tlsPeerNames; }
void SipMessage::throwHeaderMissing ( Headers::Type  type) const [private]

Definition at line 1365 of file SipMessage.cxx.

References DebugLog, resip::Headers::getHeaderName(), and InfoLog.

Referenced by ensureHeader(), and ensureHeaders().

{
   // header missing
   // assert(false);
   InfoLog( << "Missing Header [" << Headers::getHeaderName(type) << "]");      
   DebugLog (<< *this);
   throw Exception("Missing header " + Headers::getHeaderName(type), __FILE__, __LINE__);
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class TransportSelector [friend]

Definition at line 684 of file SipMessage.hxx.


Member Data Documentation

bool SipMessage::checkContentLength = true [static]

Definition at line 195 of file SipMessage.hxx.

Referenced by main(), setBody(), and resip::SipStack::setContentLengthChecking().

std::vector<char*> resip::SipMessage::mBufferList [private]

Definition at line 645 of file SipMessage.hxx.

Referenced by addBuffer(), clear(), and freeMem().

Definition at line 668 of file SipMessage.hxx.

Referenced by getCreatedTimeMicroSec().

Definition at line 642 of file SipMessage.hxx.

Referenced by getDestination(), init(), and setDestination().

short resip::SipMessage::mHeaderIndices[Headers::MAX_HEADERS] [private]

Definition at line 665 of file SipMessage.hxx.

Referenced by addHeader(), init(), isInvalid(), and setBody().

Definition at line 534 of file SipMessage.hxx.

Referenced by init(), and resip::TransactionState::process().

Definition at line 620 of file SipMessage.hxx.

Referenced by freeHfvl(), getCopyHfvl(), getEmptyHfvl(), and makeParserContainer().

Definition at line 666 of file SipMessage.hxx.

Referenced by addHeader(), clear(), freeMem(), getReason(), init(), and setBody().

Definition at line 662 of file SipMessage.hxx.

Referenced by header(), init(), isClientTransaction(), isRequest(), and setStartLine().

Definition at line 663 of file SipMessage.hxx.

Referenced by header(), init(), isClientTransaction(), isResponse(), and setStartLine().

Definition at line 680 of file SipMessage.hxx.

Referenced by getSecurityAttributes(), init(), and setSecurityAttributes().

Definition at line 639 of file SipMessage.hxx.

Referenced by getSource(), init(), and setSource().

Definition at line 648 of file SipMessage.hxx.

Referenced by clear(), encode(), freeMem(), header(), init(), parseAllHeaders(), and setStartLine().

char resip::SipMessage::mStartLineMem[sizeof(RequestLine) > sizeof(StatusLine)?sizeof(RequestLine):sizeof(StatusLine)] [private]

Definition at line 649 of file SipMessage.hxx.

Referenced by header(), init(), and setStartLine().

Definition at line 675 of file SipMessage.hxx.

Referenced by encodeBrief(), getTlsDomain(), init(), and setTlsDomain().

std::list<Data> resip::SipMessage::mTlsPeerNames [private]

Definition at line 678 of file SipMessage.hxx.

Referenced by getTlsPeerNames(), and setTlsPeerNames().

Definition at line 635 of file SipMessage.hxx.

Referenced by getReceivedTransport(), and init().


The documentation for this class was generated from the following files: