// // Copyright (C) 2012 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef SHILL_NET_ATTRIBUTE_LIST_H_ #define SHILL_NET_ATTRIBUTE_LIST_H_ #include #include #include #include #include #include "shill/net/netlink_message.h" #include "shill/net/shill_export.h" struct nlattr; namespace shill { class AttributeList; typedef scoped_refptr AttributeListConstRefPtr; typedef scoped_refptr AttributeListRefPtr; class ByteString; class NetlinkAttribute; class NetlinkRawAttribute; class SHILL_EXPORT AttributeList : public base::RefCounted { public: using AttributePointer = std::shared_ptr; using NewFromIdMethod = base::Callback; using AttributeMethod = base::Callback; AttributeList() {} // Instantiates an NetlinkAttribute of the appropriate type from |id|, // and adds it to |attributes_|. bool CreateAttribute(int id, const NewFromIdMethod& factory); // Helper function for creating control attribute. bool CreateControlAttribute(int id); // Helper function for creating nl80211 attribute. bool CreateNl80211Attribute(int id, NetlinkMessage::MessageContext context); // Instantiates an NetlinkAttribute of the appropriate type from |id| // using |factory|, initializes it from |value|, and adds it to |attributes_|. bool CreateAndInitAttribute(const NewFromIdMethod& factory, int id, const ByteString& value); // Initializes the attribute |id| from the data in |value|. bool InitAttributeFromValue(int id, const ByteString& value); // Prints the attribute list with each attribute using no less than 1 line. // |indent| indicates the amout of leading spaces to be printed (useful for // nested attributes). void Print(int log_level, int indent) const; // Visit each attribute in |payload| starting at |offset|. Call |method| // for each attribute. If |method| returns false, the travesal is terminated // and false is returned. If a malformed attribute entry is encountered, // this method also returns false. static bool IterateAttributes(const ByteString& payload, size_t offset, const AttributeMethod& method); // Decode an attribute list starting from |offset| within |payload|. Use // |factory| to create each attribute object. bool Decode(const ByteString& payload, size_t offset, const NewFromIdMethod& factory); // Returns the attributes as the payload portion of a netlink message // suitable for Sockets::Send. Return value is empty on failure (or if no // attributes exist). ByteString Encode() const; // Create, get, and set attributes of the given types. Attributes are // accessed via an integer |id|. |id_string| is a string used to describe // the attribute in debug output. bool CreateU8Attribute(int id, const char* id_string); bool SetU8AttributeValue(int id, uint8_t value); bool GetU8AttributeValue(int id, uint8_t* value) const; bool CreateU16Attribute(int id, const char* id_string); bool SetU16AttributeValue(int id, uint16_t value); bool GetU16AttributeValue(int id, uint16_t* value) const; bool CreateU32Attribute(int id, const char* id_string); bool SetU32AttributeValue(int id, uint32_t value); bool GetU32AttributeValue(int id, uint32_t* value) const; bool CreateU64Attribute(int id, const char* id_string); bool SetU64AttributeValue(int id, uint64_t value); bool GetU64AttributeValue(int id, uint64_t* value) const; bool CreateFlagAttribute(int id, const char* id_string); bool SetFlagAttributeValue(int id, bool value); bool GetFlagAttributeValue(int id, bool* value) const; // |IsFlagAttributeTrue| returns true if the flag attribute |id| is true. It // retruns false if the attribute does not exist, is not of type kTypeFlag, // or is not true. bool IsFlagAttributeTrue(int id) const; bool CreateStringAttribute(int id, const char* id_string); // SSID attributes are derived from string attributes. bool CreateSsidAttribute(int id, const char* id_string); bool SetStringAttributeValue(int id, const std::string& value); bool GetStringAttributeValue(int id, std::string* value) const; bool CreateNestedAttribute(int id, const char* id_string); bool SetNestedAttributeHasAValue(int id); bool GetNestedAttributeList(int id, AttributeListRefPtr* value); bool ConstGetNestedAttributeList(int id, AttributeListConstRefPtr* value) const; bool CreateRawAttribute(int id, const char* id_string); // |value| should point to the data (after the |nlattr| header, if there is // one). bool SetRawAttributeValue(int id, const ByteString& value); bool GetRawAttributeValue(int id, ByteString* output) const; // This retrieves a string from any kind of attribute. bool GetAttributeAsString(int id, std::string* value) const; protected: friend class base::RefCounted; virtual ~AttributeList() {} private: typedef std::map AttributeMap; friend class AttributeIdIterator; friend class NetlinkNestedAttribute; // Using this to get around issues with const and operator[]. SHILL_PRIVATE NetlinkAttribute* GetAttribute(int id) const; AttributeMap attributes_; DISALLOW_COPY_AND_ASSIGN(AttributeList); }; // Provides a mechanism to iterate through the ids of all of the attributes // in an |AttributeList|. This class is really only useful if the caller // knows the type of each attribute in advance (such as with a nested array). class AttributeIdIterator { public: explicit AttributeIdIterator(const AttributeList& list) : iter_(list.attributes_.begin()), end_(list.attributes_.end()) { } void Advance() { ++iter_; } bool AtEnd() const { return iter_ == end_; } int GetId() const { return iter_->first; } private: AttributeList::AttributeMap::const_iterator iter_; const AttributeList::AttributeMap::const_iterator end_; DISALLOW_COPY_AND_ASSIGN(AttributeIdIterator); }; } // namespace shill #endif // SHILL_NET_ATTRIBUTE_LIST_H_