namespace senf {
struct MIHTLVLengthException : public senf::Exception
- {
- MIHTLVLengthException()
- : senf::Exception("MIHTLVLengthException") {}
+ {
+ MIHTLVLengthException()
+ : senf::Exception("MIHTLVLengthException") {}
};
-
- class MIHTLVLengthParser
+
+ class MIHTLVLengthParser
: public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
public PacketParserBase
{
value_type value() const;
void value(value_type const & v);
-
+
MIHTLVLengthParser const & operator= (value_type other);
size_type bytes() const;
void init() const;
SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 6, unsigned );
void finalize();
- void maxValue(value_type v);
- value_type maxValue() const;
-
+ void capacity(value_type v);
+ value_type capacity() const;
+
private:
void resize_(size_type size);
- };
-
+ };
+
/** \brief Base class for MIH TLV parsers
-
+
MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
- \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
- MIHTLVLengthParser. The length field is read-only.
-
- To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
- forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
- the value is a vector of MacAddresses:
+ \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
+ MIHTLVLengthParser. The length field is read-only.
+
+ To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
+ forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
+ the value is a vector of MacAddresses:
\code
struct MacAddressesTLVParser : public MIHBaseTLVParser {
- # include SENF_PARSER()
+ # include SENF_PARSER()
SENF_PARSER_INHERIT ( MIHBaseTLVParser );
SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
SENF_PARSER_FINALIZE( MacAddressesTLVParser );
};
\endcode
-
- You have to adjust the maximum length value with the \ref maxLengthValue function
- before the length value is set. The default maximum value is 127. So, in the above
+
+ You have to adjust the maximum length value with the \ref maxLength function
+ before the length value is set. The default maximum value is 128. So, in the above
example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
- if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
-
+ if you don't call \c maxLength( \e some_value) before.
+
\see MIHTLVLengthParser \n
MIHGenericTLVParser \n
*/
SENF_PARSER_FIELD ( type, UInt8Parser );
SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
SENF_PARSER_FINALIZE ( MIHBaseTLVParser );
-
- /** \brief set maximum value of length field
-
- The size of the length field will be increased if necessary.
- \param v maximum value of length field
- */
- void maxLengthValue(MIHTLVLengthParser::value_type v) const {
- protect(), length_().maxValue(v);
- }
-
- /** \brief shrink size of length field to minimum
-
+
+ /** \brief shrink size of the TLV length field to minimum
+
The size of the length field will be decreased to minimum necessary to hold
the current length value.
*/
- void finalizeLength() {
- protect(), length_().finalize();
- };
-
- typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
-
+ void finalize();
+
+ typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
+
protected:
- /// resize the packet after the length field to given size
- senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
+ /** \brief set maximum value of TLV length field
+
+ The size of the length field will be increased if necessary.
+ \param v maximum value of length field
+ */
+ void maxLength(MIHTLVLengthParser::value_type maxl) const;
};
-
+
+
/** \brief Parser for a generic TLV packet
*/
struct MIHGenericTLVParser
void init() const {
defaultInit();
- maxLengthValue( MIHTLVLengthParser::max_value);
+ maxLength( MIHTLVLengthParser::max_value);
}
-
+
using base::init;
+ using base::maxLength;
};
-
+
+
+ /** \brief Base class for list TLV parser
+ */
+ struct MIHBaseListTLVParser
+ : public MIHBaseTLVParser
+ {
+ # include SENF_PARSER()
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
+ SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
+ SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
+
+ void maxListSize(MIHTLVLengthParser::value_type maxl) const;
+ };
+
+ template <class Self>
+ struct MIHListTLVParserMixin
+ {
+ void finalize();
+ };
+
+
/** \brief Parse a MIHF_ID
- the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
- we could set maxLengthValue in init(), but for the most MIHF_IDs the default
- maximum length of 127 should be enough.
-
- \note you must call mihfIdPacket.maxLengthValue( 253) *before*
- setting longer MIHF_IDs values.
+ Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
+ We could set maxLength in init(), but for the most MIHF_IDs the default
+ maximum length of 128 should be enough.
+
+ \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
+ than 128.
+
+ \see MIHFId
*/
class MIHFIdTLVParser : public MIHBaseTLVParser
{
# include SENF_PARSER()
SENF_PARSER_INHERIT ( MIHBaseTLVParser );
- SENF_PARSER_SKIP ( length(), 0 );
+ SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
+ SENF_PARSER_LABEL ( idValue );
+ SENF_PARSER_SKIP ( idLength(), 0 );
SENF_PARSER_FINALIZE ( MIHFIdTLVParser );
-
+
public:
- std::string asString() const;
- void setString(std::string const &id);
+ ///\name Value setters
+ ///@{
+ void value( MIHFId const & id);
+
+ void value( std::string const & id );
+ void value( senf::MACAddress const & addr);
+ void value( senf::INet4Address const & addr);
+ void value( senf::INet6Address const & addr);
+ void value( senf::EUI64 const & addr);
+ ///@}
- senf::MACAddress asMACAddress() const;
- void setMACAddress(senf::MACAddress const &mac);
+ ///\name Value getters
+ ///@{
+ MIHFId valueAs( MIHFId::Type type) const;
- senf::INet4Address asINet4Address() const;
- void setINet4Address(senf::INet4Address const &addr);
+ std::string valueAsString() const;
+ senf::MACAddress valueAsMACAddress() const;
+ senf::INet4Address valueAsINet4Address() const;
+ senf::INet6Address valueAsINet6Address() const;
+ senf::EUI64 valueAsEUI64() const;
+ ///@}
- senf::INet6Address asINet6Address() const;
- void setINet6Address(senf::INet6Address const &addr);
-
- senf::EUI64 asEUI64() const;
- void setEUI64(senf::EUI64 const &addr);
+ ///\name Value comparisons
+ ///@{
+ bool valueEquals( MIHFId const & id) const;
+
+ bool valueEquals( std::string const & id ) const;
+ bool valueEquals( senf::MACAddress const & addr) const;
+ bool valueEquals( senf::INet4Address const & addr) const;
+ bool valueEquals( senf::INet6Address const & addr) const;
+ bool valueEquals( senf::EUI64 const & addr) const;
+ ///@}
- MIHFId valueAs(MIHFId::Type type) const;
-
void dump(std::ostream & os) const;
+ void maxIdLength(boost::uint8_t maxl) const;
+ void finalize();
private:
+ /// resize the packet after the length field to given size
+ senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
+
+ data_iterator valueBegin() const;
+ data_iterator valueEnd() const;
+
template <class OutputIterator>
struct binaryNAIEncoder {
- binaryNAIEncoder(OutputIterator &i) : i_(i) {}
- void operator()(const boost::uint8_t &v) const {
- *i_++ = '\\';
- *i_++ = v;
- }
- OutputIterator &i_;
+ binaryNAIEncoder(OutputIterator & i);
+ void operator()(boost::uint8_t v);
+ OutputIterator & i_;
};
+
template <class OutputIterator>
- static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
- return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
- }
+ static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
+ getNAIEncodedOutputIterator(OutputIterator i);
struct binaryNAIDecoder {
- binaryNAIDecoder() : readNextByte_(true) {}
- bool operator()(const boost::uint8_t &v) {
- readNextByte_ = readNextByte_ ? false : true;
- return readNextByte_;
- }
+ binaryNAIDecoder();
+ bool operator()(boost::uint8_t v);
bool readNextByte_;
};
+
template <class Iterator>
- static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
- return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
- }
+ static boost::filter_iterator<binaryNAIDecoder, Iterator>
+ getNAIDecodedIterator(Iterator begin, Iterator end);
+
+ struct ValueSetterVisitor : public boost::static_visitor<> {
+ MIHFIdTLVParser & parser;
+ ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
+ void operator()( boost::blank ) const {
+ parser.value( std::string());
+ }
+ template <typename MIHFIdType>
+ void operator()( MIHFIdType const & id ) const {
+ parser.value( id);
+ }
+ };
+
+ struct ValueEqualsVisitor : public boost::static_visitor<bool> {
+ MIHFIdTLVParser const & parser;
+ ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
+ bool operator()( boost::blank ) const {
+ return parser.idLength() == 0;
+ }
+ template <typename MIHFIdType>
+ bool operator()( MIHFIdType const & id ) const {
+ return parser.valueEquals( id);
+ }
+ };
};
+ /** \brief Parser for 802.21 source MIHF_ID TLV
+ */
struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
{
MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
-
+
void init() const {
defaultInit();
type() << typeId+0;
}
static type_t::value_type const typeId = 1;
-
void dump(std::ostream & os) const;
};
-
+
+ /** \brief Parser for 802.21 destination MIHF_ID TLV
+ */
struct MIHFDstIdTLVParser : public MIHFIdTLVParser
{
MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
-
+
void init() const {
defaultInit();
type() << typeId+0;
}
static type_t::value_type const typeId = 2;
-
void dump(std::ostream & os) const;
};
+
+ /** \brief Parser for 802.21 Status TLV
+ */
+ struct MIHStatusTLVParser : public MIHBaseTLVParser
+ {
+ # include SENF_PARSER()
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
+ SENF_PARSER_FIELD ( value, UInt8Parser );
+ SENF_PARSER_FINALIZE( MIHStatusTLVParser );
+
+ SENF_PARSER_INIT() {
+ defaultInit();
+ type() << typeId+0;
+ length_() = 1;
+ }
+ static type_t::value_type const typeId = 3;
+ void dump(std::ostream & os) const; ///< dump string representation to given stream
+
+ enum StatusCode {
+ Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
+ };
+
+ struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
+ {
+ # include SENF_PARSER()
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
+ SENF_PARSER_FIELD ( value, UInt8Parser );
+ SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
+
+ SENF_PARSER_INIT() {
+ defaultInit();
+ type() = typeId+0;
+ length_() = 1;
+ }
+ static type_t::value_type const typeId = 11;
+ void dump(std::ostream & os) const; ///< dump string representation to given stream
+
+ enum RequestCode { Registration, ReRegistration };
+ };
+
+ struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
+ {
+ # include SENF_PARSER()
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
+ SENF_PARSER_FIELD ( value, UInt32Parser );
+ SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
+
+ SENF_PARSER_INIT() {
+ defaultInit();
+ type() = typeId+0;
+ length_() = 4;
+ }
+ static type_t::value_type const typeId = 12;
+ void dump(std::ostream & os) const; ///< dump string representation to given stream
+ };
+
}
///////////////////////////////hh.e////////////////////////////////////////
#include "TLVParser.cci"
-//#include "TLVParser.ct"
-//#include "TLVParser.cti"
+#include "TLVParser.ct"
+#include "TLVParser.cti"
#endif
\f