-// ANNA - Anna is Not Nothingness Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// http://redmine.teslayout.com/projects/anna-suite
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: eduardo.ramos.testillano@gmail.com
-// cisco.tierra@gmail.com
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
#ifndef anna_diameter_codec_Message_hpp
/**
* Default constructor
+ * @param engine Codec engine used
*/
- Message();
+ Message(Engine *engine = NULL);
/**
* Identified constructor
* @param id Command identifier as pair (code,request-indicator).
+ * @param engine Codec engine used
*/
- Message(CommandId id);
+ Message(CommandId id, Engine *engine = NULL);
+
+
+ /**
+ * Sets the codec engine.
+ *
+ * Once assigned (here or at constructor), this method SHALL NOT be used anymore.
+ * Also, the associated dictionary SHOULD NOT BE CHANGED through the engine,
+ * unless you know what are you doing. If you want to reconfigure the engine,
+ * first #clear the message and then you could reuse the same object with
+ * different configurations (execution contexts).
+ *
+ * Setting a new different engine with different stack, even same engine where the
+ * stack has been dynamically changed, could cause a bad behaviour depending on the
+ * changes: in general, if the dictionary grows, nothing bad will happen, but if
+ * you remove or modified some elements which were processed with a certain format,
+ * will be interpreted as 'unknown' with the new dictionary, and then some problems
+ * may occur. If you add elements (vendors, avps, messages) is not a problem.
+ */
+ void setEngine(Engine *engine) throw();
// Length references
Sets the command identifier and clear the former content.
@param id Command identifier as pair (code,request-indicator).
- @param _clear Message will be cleared when updating the command identifier (default behaviour).
*/
- void setId(CommandId id, bool _clear = true) throw(anna::RuntimeException);
+ void setId(CommandId id) throw(anna::RuntimeException);
/**
Same as #setId but providing dictionary logical name for Avp searched
/**
Sets/unsets E bit activation.
Application should not have to use this because dictionary information is used in order to configure flags when Message identifier is stored.
+ This flag MUST NOT be set in request messages (in this case, it will be ignored).
@param activate Activates/deactivates the bit. True by default.
*/
- void setErrorBit(bool activate = true) throw() { if(activate) a_flags |= EBitMask; else a_flags &= (~EBitMask); }
+ void setErrorBit(bool activate = true) throw() { if(isRequest()) return; if(activate) a_flags |= EBitMask; else a_flags &= (~EBitMask); }
/**
Sets/unsets T bit activation.
Application should not have to use this because dictionary information is used in order to configure flags when Message identifier is stored.
+ This flag MUST NOT be set in answer messages (in this case, it will be ignored).
@param activate Activates/deactivates the bit. True by default.
*/
- void setPotentiallyReTransmittedMessageBit(bool activate = true) throw() { if(activate) a_flags |= TBitMask; else a_flags &= (~TBitMask); }
+ void setPotentiallyReTransmittedMessageBit(bool activate = true) throw() { if(isAnswer()) return; if(activate) a_flags |= TBitMask; else a_flags &= (~TBitMask); }
/**
- Sets the message application id
+ Sets the message application id.
+
+ The codec engine could be configured to force a stack selection based in this field value: see #selectStackWithApplicationId.
+ In multistack applications (in case of being monothread), you only have to take care about how to apply this method: the thing
+ is that you must not interleave message builds which belongs to different stacks. For example, you could think about setting the
+ message header for message A using stack A. Then, start to add the message header fields for a second message B using another stack B.
+ Following you would add the message A avps, but then, the stack is not going to be automatically changed (this is only done through this
+ method). The result could be unexpected when adding/encoding messages with a dictionary which does not correspond.
+
+ @warning do not interleave build/encode operations between different messages which uses different stacks over the same codec engine.
+ It seems common sense, but it is not bad to advice about this.
+
@param aid Application-id.
*/
- void setApplicationId(U32 aid) throw() { a_applicationId = aid; }
+ void setApplicationId(U32 aid) throw(anna::RuntimeException);
/**
Sets the message hop-by-hop
@warning Request provided must be a request, in other case method do nothing.
*/
- void setHeaderToAnswer(const Message &request) throw() {
+ void setHeaderToAnswer(const Message &request) throw(anna::RuntimeException) {
if(!request.getId().second) return;
- setId(CommandId(request.getId().first, !request.getId().second), false /* don't clear */);
+ a_engine = request.getEngine(); // we know this will be
+
+ setId(CommandId(request.getId().first, !request.getId().second));
setVersion(request.getVersion());
setApplicationId(request.getApplicationId());
setHopByHop(request.getHopByHop()); // The same Hop-by-Hop Identifier in the request is used in the answer (RFC 6733 Section 6.2).
@warning Request provided must be a request, in other case method do nothing.
*/
- void setStandardToAnswer(const Message &request, const std::string &originHost, const std::string &originRealm, int resultCode = helpers::base::AVPVALUES__Result_Code::DIAMETER_SUCCESS) throw();
+ void setStandardToAnswer(const Message &request, const std::string &originHost, const std::string &originRealm, int resultCode = helpers::base::AVPVALUES__Result_Code::DIAMETER_SUCCESS) throw(anna::RuntimeException);
/**
/**
Adds an avp child providing a persistent pointer (must be maintained by application).
+ It is not allowed to add an avp with no codec engine configured, neither if the engine
+ is not the same.
@param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
+ Also NULL returned for bad engine configuration.
@return Pointer to the added avp (again).
*/
- Avp * addAvp(Avp * avp) throw() { if(!avp) return NULL; addChild(avp); return avp; }
+ Avp * addAvp(Avp * avp) throw();
/**
/**
* Clears and initializes Message class information.
- * Application must clear auxiliary message objects before adding Avps in a new context.
+ * Application must clear auxiliary message objects before adding Avps in a new context if the same object is reused.
* Application don't need to clear a message object before decode operation (decode invokes #clear before any other task).
* Any reimplementation must first invoke base class method.
*/
*/
bool valid(Message *ptrAnswer = NULL) const throw(anna::RuntimeException);
-
/**
Interpret xml data in order to dump over the class content.
- \param messageNode Message root node
+ \param messageNode Message root node obtained from @functions::xmlFileTo
*/
void fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeException);
/**
- Interpret xml string representation in order to dump over the class content.
- DTD validation is used in the same way that #loadXML does.
- \param xmlString XML string representation with relevant information for this instance
- */
- void fromXMLString(const std::string &xmlString) throw(anna::RuntimeException);
-
- /**
- Loads an xml file based on this message DTD (could be accumulative, no initialization will be performed by this method).
-
- <pre>
- <!ELEMENT message (avp*)>
- <!ELEMENT avp (avp*)>
-
- <!ATTLIST message version CDATA #IMPLIED name CDATA #IMPLIED code CDATA #IMPLIED flags CDATA #IMPLIED application-id CDATA #REQUIRED hop-by-hop-id CDATA #IMPLIED end-by-end-id CDATA #IMPLIED>
- <!--
- version: Diameter version. Sets '1' by default
- name: Command name within working stack (dictionary identifier)
-
- In order to get more coding capabilities, command code and flags could be established instead of former command name,
- but neither of them are allowed if 'name' is provided (and vice versa):
-
- code: Command code
- flags: Command flags byte value (0-255) where standard bit set for flags is 'RPET rrrr': (R)equest, (P)roxiable, (E)rror, Potentially re-(T)ransmitted message and (r)eserved
-
-
- application-id: Message application id
- hop-by-hop-id: Message hop by hop id. Sets '0' by default
- end-by-end-id: Message end by end id. Sets '0' by default
- -->
-
- <!ATTLIST avp name CDATA #IMPLIED code CDATA #IMPLIED vendor-code CDATA #IMPLIED flags CDATA #IMPLIED data CDATA #IMPLIED hex-data CDATA #IMPLIED>
- <!--
- name: Avp name within working stack (dictionary identifier)
-
- In order to get more coding capabilities, avp code, vendor-id and flags could be established instead of former avp name,
- but neither of them are allowed if 'name' is provided (and vice versa):
-
- code: Avp code
- vendor-code: Avp vendor code
- flags: Avp flags byte value (0-255) where standard bit set for flags is 'VMPr rrrr': (V)endor-specific, (M)andatory, end to end encry(P)tion and r(eserved)
-
-
- data: Natural string representation for avp data. Specially applicable with numbers and printable strings, but also
- useful for certain formats which could be easily understandable in such friendly/smart representation. We will
- achieve different human-readable strings depending on data format:
-
- [ OctetString ] (if printable, but not recommended)
- [ Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64 ] (normal number representation)
- [ Time ] (NTP timestamp, normal number representation)
- [ Address ] (auto detects IPv4 or IPv6 address version, then only ip address is specified: IPv4 with dots, IPv6 with colons)
- [ UTF8String, DiameterIdentity, DiameterURI ] (printable)
- [ IPFilterRule, QoSFilterRule ] (uses ASCII charset, printable)
-
- New application formats must define specific natural representation for internal raw data
-
- hex-data: Hexadecimal octet sequence representation (i.e. 'af012fb3', with even number of digits). Suitable for whatever kind
- of diameter format, but mandatory for non printable information. OctetString usually transport non human-readable
- data and should better be encoded within this field although being printable. Unknown avps (which fails identifying
- provided name or code/vendor-code) must always use this representation.
-
- Xml representation for decoded messages shows natural content except for 'OctetString' format and unknown avps. Anyway, when printable,
- OctetString could show such information at data field apart from hex-data, because many implementations use this format to transport
- readable-string data. In general, one of the data fields is mandatory except for 'Grouped' type (its data is another level of avps).
- Application-specific formats must decide the way to represent its contents, being recommended to use a natural representation if possible,
- because xml is read by humans with testing and monitoring purposes.
- -->
- </pre>
-
- @param xmlPathFile Complete path file to the xml document which represents the diameter message
- @see fromXMLString
- */
- void loadXML(const std::string & xmlPathFile) throw(anna::RuntimeException);
-
+ * Interpret a xml file in order to create a diameter message
+ *
+ * @see functions::messageXmlDocumentFromXmlFile
+ * @see fromXML
+ *
+ * @param xmlPathFile Complete path file to the xml document which represents the diameter message
+ */
+ void loadXML(const std::string &xmlPathFile) throw(anna::RuntimeException);
// getters