Loading automotive/can/1.0/default/libnl++/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ cc_library_static { "protocols/generic/Generic.cpp", "protocols/generic/GenericMessageBase.cpp", "protocols/generic/Unknown.cpp", "protocols/generic/families/Nl80211.cpp", "protocols/route/Link.cpp", "protocols/route/Route.cpp", "protocols/route/structs.cpp", Loading automotive/can/1.0/default/libnl++/printer.cpp +31 −9 Original line number Diff line number Diff line Loading @@ -51,24 +51,24 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::M printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED"); switch (genre) { case protocols::MessageGenre::UNKNOWN: case protocols::MessageGenre::Unknown: break; case protocols::MessageGenre::GET: case protocols::MessageGenre::Get: printFlag(NLM_F_DUMP, "DUMP"); // ROOT | MATCH printFlag(NLM_F_ROOT, "ROOT"); printFlag(NLM_F_MATCH, "MATCH"); printFlag(NLM_F_ATOMIC, "ATOMIC"); break; case protocols::MessageGenre::NEW: case protocols::MessageGenre::New: printFlag(NLM_F_REPLACE, "REPLACE"); printFlag(NLM_F_EXCL, "EXCL"); printFlag(NLM_F_CREATE, "CREATE"); printFlag(NLM_F_APPEND, "APPEND"); break; case protocols::MessageGenre::DELETE: case protocols::MessageGenre::Delete: printFlag(NLM_F_NONREC, "NONREC"); break; case protocols::MessageGenre::ACK: case protocols::MessageGenre::Ack: printFlag(NLM_F_CAPPED, "CAPPED"); printFlag(NLM_F_ACK_TLVS, "ACK_TLVS"); break; Loading Loading @@ -99,11 +99,25 @@ static void toStream(std::stringstream& ss, const Buffer<uint8_t> data) { static void toStream(std::stringstream& ss, const Buffer<nlattr> attr, const protocols::AttributeMap& attrMap) { using DataType = protocols::AttributeDefinition::DataType; using Flags = protocols::AttributeDefinition::Flags; const auto attrtype = attrMap[attr->nla_type]; ss << attrtype.name << ": "; ss << attrtype.name; if (attrtype.dataType == DataType::Flag && attr.data<uint8_t>().getRaw().len() == 0) return; ss << ": "; if (attrtype.flags == Flags::Verbose) { const auto raw = attr.data<uint8_t>(); ss << "{len=" << raw.getRaw().len(); ss << ", crc=" << std::hex << std::setw(4) << crc16(raw) << std::dec; ss << "}"; return; } switch (attrtype.dataType) { case DataType::Raw: case DataType::Flag: toStream(ss, attr.data<uint8_t>()); break; case DataType::Nested: { Loading @@ -117,13 +131,19 @@ static void toStream(std::stringstream& ss, const Buffer<nlattr> attr, ss << '}'; break; } case DataType::StringNul: case DataType::String: { const auto str = attr.data<char>().getRaw(); ss << '"' << printableOnly({str.ptr(), str.len()}) << '"'; auto len = str.len(); if (attrtype.dataType == DataType::StringNul && len > 0 && str.ptr()[len - 1] == '\0') { len--; } ss << '"' << printableOnly({str.ptr(), len}) << '"'; break; } case DataType::Uint: ss << attr.data<uint32_t>().copyFirst(); ss << attr.data<uint64_t>().copyFirst(); break; case DataType::Struct: { const auto structToStream = Loading @@ -147,10 +167,12 @@ std::string toString(const Buffer<nlmsghdr> hdr, int protocol, bool printPayload } protocols::NetlinkProtocol& protocolDescr = *protocolMaybe; const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); const auto msgDetails = protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type); if (msgDescMaybe.has_value()) msgDescMaybe->get().track(hdr); ss << "nlmsg{" << protocolDescr.getName() << " "; ss << "hdr={"; Loading automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -56,15 +56,17 @@ const AttributeMap& MessageDescriptor::getAttributeMap() const { MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const { const auto it = mMessageDetails.find(msgtype); if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN}; if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::Unknown}; return it->second; } MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails( const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe, const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe, nlmsgtype_t msgtype) { if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype); return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN}; return {std::to_string(msgtype), protocols::MessageGenre::Unknown}; } void MessageDescriptor::track(const Buffer<nlmsghdr> /* hdr */) {} } // namespace android::nl::protocols automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +60 −6 Original line number Diff line number Diff line Loading @@ -54,17 +54,64 @@ class AttributeMap : private std::map<std::optional<nlattrtype_t>, AttributeDefi */ struct AttributeDefinition { enum class DataType : uint8_t { /** * Binary blob (or attribute of unknown type). */ Raw, /** * Nested attribute (with or without NLA_F_NESTED). */ Nested, /** * Non-null terminated string. * * The length of the string is determined by the size of an attribute. */ String, /** * Null terminated string. */ StringNul, /** * Unsigned integer of size 8, 16, 32 or 64 bits. */ Uint, /** * Structure which printer is defined in ops ToStream variant. */ Struct, /** * Flag attribute. * * The attribute doesn't have any contents. The flag is set when the attribute is present, * it's not when it's absent from attribute list. */ Flag, }; enum class Flags : uint8_t { Verbose = (1 << 0), }; using ToStream = std::function<void(std::stringstream& ss, const Buffer<nlattr> attr)>; std::string name; DataType dataType = DataType::Raw; std::variant<AttributeMap, ToStream> ops = AttributeMap{}; /** * Attribute flags. * * It's not really a bitmask flag set (since you are not supposed to compare enum class by * bitmask), but std::set<Flags> bumps compile time from 16s to 3m. Let's leave it as-is for * now and revisit if we get some flags that can be used in pairs. When it happens, review all * uses of the flags field to include the "&" operator and not "==". */ Flags flags = {}; }; /** Loading @@ -74,11 +121,11 @@ struct AttributeDefinition { * section in linux/netlink.h. */ enum class MessageGenre { UNKNOWN, GET, NEW, DELETE, ACK, Unknown, Get, New, Delete, Ack, }; /** Loading @@ -103,8 +150,15 @@ class MessageDescriptor { MessageDetails getMessageDetails(nlmsgtype_t msgtype) const; virtual void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const = 0; /** * Message tracking for stateful protocols (such as NETLINK_GENERIC). * * \param hdr Message to track */ virtual void track(const Buffer<nlmsghdr> hdr); static MessageDetails getMessageDetails( const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe, const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe, nlmsgtype_t msgtype); protected: Loading automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ const std::string& NetlinkProtocol::getName() const { return mName; } const std::optional<std::reference_wrapper<const MessageDescriptor>> const std::optional<std::reference_wrapper<MessageDescriptor>> NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt; return *mMessageDescrs.find(nlmsg_type)->second; Loading @@ -41,7 +41,7 @@ NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) { MessageDescriptorMap map; for (const auto& descr : descrs) { for (auto& descr : descrs) { for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) { map.emplace(mtype, descr); } Loading Loading
automotive/can/1.0/default/libnl++/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ cc_library_static { "protocols/generic/Generic.cpp", "protocols/generic/GenericMessageBase.cpp", "protocols/generic/Unknown.cpp", "protocols/generic/families/Nl80211.cpp", "protocols/route/Link.cpp", "protocols/route/Route.cpp", "protocols/route/structs.cpp", Loading
automotive/can/1.0/default/libnl++/printer.cpp +31 −9 Original line number Diff line number Diff line Loading @@ -51,24 +51,24 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::M printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED"); switch (genre) { case protocols::MessageGenre::UNKNOWN: case protocols::MessageGenre::Unknown: break; case protocols::MessageGenre::GET: case protocols::MessageGenre::Get: printFlag(NLM_F_DUMP, "DUMP"); // ROOT | MATCH printFlag(NLM_F_ROOT, "ROOT"); printFlag(NLM_F_MATCH, "MATCH"); printFlag(NLM_F_ATOMIC, "ATOMIC"); break; case protocols::MessageGenre::NEW: case protocols::MessageGenre::New: printFlag(NLM_F_REPLACE, "REPLACE"); printFlag(NLM_F_EXCL, "EXCL"); printFlag(NLM_F_CREATE, "CREATE"); printFlag(NLM_F_APPEND, "APPEND"); break; case protocols::MessageGenre::DELETE: case protocols::MessageGenre::Delete: printFlag(NLM_F_NONREC, "NONREC"); break; case protocols::MessageGenre::ACK: case protocols::MessageGenre::Ack: printFlag(NLM_F_CAPPED, "CAPPED"); printFlag(NLM_F_ACK_TLVS, "ACK_TLVS"); break; Loading Loading @@ -99,11 +99,25 @@ static void toStream(std::stringstream& ss, const Buffer<uint8_t> data) { static void toStream(std::stringstream& ss, const Buffer<nlattr> attr, const protocols::AttributeMap& attrMap) { using DataType = protocols::AttributeDefinition::DataType; using Flags = protocols::AttributeDefinition::Flags; const auto attrtype = attrMap[attr->nla_type]; ss << attrtype.name << ": "; ss << attrtype.name; if (attrtype.dataType == DataType::Flag && attr.data<uint8_t>().getRaw().len() == 0) return; ss << ": "; if (attrtype.flags == Flags::Verbose) { const auto raw = attr.data<uint8_t>(); ss << "{len=" << raw.getRaw().len(); ss << ", crc=" << std::hex << std::setw(4) << crc16(raw) << std::dec; ss << "}"; return; } switch (attrtype.dataType) { case DataType::Raw: case DataType::Flag: toStream(ss, attr.data<uint8_t>()); break; case DataType::Nested: { Loading @@ -117,13 +131,19 @@ static void toStream(std::stringstream& ss, const Buffer<nlattr> attr, ss << '}'; break; } case DataType::StringNul: case DataType::String: { const auto str = attr.data<char>().getRaw(); ss << '"' << printableOnly({str.ptr(), str.len()}) << '"'; auto len = str.len(); if (attrtype.dataType == DataType::StringNul && len > 0 && str.ptr()[len - 1] == '\0') { len--; } ss << '"' << printableOnly({str.ptr(), len}) << '"'; break; } case DataType::Uint: ss << attr.data<uint32_t>().copyFirst(); ss << attr.data<uint64_t>().copyFirst(); break; case DataType::Struct: { const auto structToStream = Loading @@ -147,10 +167,12 @@ std::string toString(const Buffer<nlmsghdr> hdr, int protocol, bool printPayload } protocols::NetlinkProtocol& protocolDescr = *protocolMaybe; const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); const auto msgDetails = protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type); if (msgDescMaybe.has_value()) msgDescMaybe->get().track(hdr); ss << "nlmsg{" << protocolDescr.getName() << " "; ss << "hdr={"; Loading
automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -56,15 +56,17 @@ const AttributeMap& MessageDescriptor::getAttributeMap() const { MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const { const auto it = mMessageDetails.find(msgtype); if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN}; if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::Unknown}; return it->second; } MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails( const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe, const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe, nlmsgtype_t msgtype) { if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype); return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN}; return {std::to_string(msgtype), protocols::MessageGenre::Unknown}; } void MessageDescriptor::track(const Buffer<nlmsghdr> /* hdr */) {} } // namespace android::nl::protocols
automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +60 −6 Original line number Diff line number Diff line Loading @@ -54,17 +54,64 @@ class AttributeMap : private std::map<std::optional<nlattrtype_t>, AttributeDefi */ struct AttributeDefinition { enum class DataType : uint8_t { /** * Binary blob (or attribute of unknown type). */ Raw, /** * Nested attribute (with or without NLA_F_NESTED). */ Nested, /** * Non-null terminated string. * * The length of the string is determined by the size of an attribute. */ String, /** * Null terminated string. */ StringNul, /** * Unsigned integer of size 8, 16, 32 or 64 bits. */ Uint, /** * Structure which printer is defined in ops ToStream variant. */ Struct, /** * Flag attribute. * * The attribute doesn't have any contents. The flag is set when the attribute is present, * it's not when it's absent from attribute list. */ Flag, }; enum class Flags : uint8_t { Verbose = (1 << 0), }; using ToStream = std::function<void(std::stringstream& ss, const Buffer<nlattr> attr)>; std::string name; DataType dataType = DataType::Raw; std::variant<AttributeMap, ToStream> ops = AttributeMap{}; /** * Attribute flags. * * It's not really a bitmask flag set (since you are not supposed to compare enum class by * bitmask), but std::set<Flags> bumps compile time from 16s to 3m. Let's leave it as-is for * now and revisit if we get some flags that can be used in pairs. When it happens, review all * uses of the flags field to include the "&" operator and not "==". */ Flags flags = {}; }; /** Loading @@ -74,11 +121,11 @@ struct AttributeDefinition { * section in linux/netlink.h. */ enum class MessageGenre { UNKNOWN, GET, NEW, DELETE, ACK, Unknown, Get, New, Delete, Ack, }; /** Loading @@ -103,8 +150,15 @@ class MessageDescriptor { MessageDetails getMessageDetails(nlmsgtype_t msgtype) const; virtual void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const = 0; /** * Message tracking for stateful protocols (such as NETLINK_GENERIC). * * \param hdr Message to track */ virtual void track(const Buffer<nlmsghdr> hdr); static MessageDetails getMessageDetails( const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe, const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe, nlmsgtype_t msgtype); protected: Loading
automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ const std::string& NetlinkProtocol::getName() const { return mName; } const std::optional<std::reference_wrapper<const MessageDescriptor>> const std::optional<std::reference_wrapper<MessageDescriptor>> NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt; return *mMessageDescrs.find(nlmsg_type)->second; Loading @@ -41,7 +41,7 @@ NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) { MessageDescriptorMap map; for (const auto& descr : descrs) { for (auto& descr : descrs) { for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) { map.emplace(mtype, descr); } Loading