1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef SHILL_NET_ATTRIBUTE_LIST_H_ 18 #define SHILL_NET_ATTRIBUTE_LIST_H_ 19 20 #include <linux/nl80211.h> 21 22 #include <map> 23 #include <memory> 24 #include <string> 25 26 #include <base/bind.h> 27 28 #include "shill/net/netlink_message.h" 29 #include "shill/net/shill_export.h" 30 31 struct nlattr; 32 namespace shill { 33 34 class AttributeList; 35 typedef scoped_refptr<const AttributeList> AttributeListConstRefPtr; 36 typedef scoped_refptr<AttributeList> AttributeListRefPtr; 37 38 class ByteString; 39 class NetlinkAttribute; 40 class NetlinkRawAttribute; 41 42 class SHILL_EXPORT AttributeList : public base::RefCounted<AttributeList> { 43 public: 44 using AttributePointer = std::shared_ptr<NetlinkAttribute>; 45 using NewFromIdMethod = base::Callback<NetlinkAttribute*(int id)>; 46 using AttributeMethod = base::Callback<bool(int id, const ByteString& value)>; 47 AttributeList()48 AttributeList() {} 49 50 // Instantiates an NetlinkAttribute of the appropriate type from |id|, 51 // and adds it to |attributes_|. 52 bool CreateAttribute(int id, NewFromIdMethod factory); 53 54 // Helper function for creating control attribute. 55 bool CreateControlAttribute(int id); 56 57 // Helper function for creating nl80211 attribute. 58 bool CreateNl80211Attribute(int id, NetlinkMessage::MessageContext context); 59 60 // Instantiates an NetlinkAttribute of the appropriate type from |id| 61 // using |factory|, initializes it from |value|, and adds it to |attributes_|. 62 bool CreateAndInitAttribute(const NewFromIdMethod& factory, 63 int id, const ByteString& value); 64 65 // Initializes the attribute |id| from the data in |value|. 66 bool InitAttributeFromValue(int id, const ByteString& value); 67 68 // Prints the attribute list with each attribute using no less than 1 line. 69 // |indent| indicates the amout of leading spaces to be printed (useful for 70 // nested attributes). 71 void Print(int log_level, int indent) const; 72 73 // Visit each attribute in |payload| starting at |offset|. Call |method| 74 // for each attribute. If |method| returns false, the travesal is terminated 75 // and false is returned. If a malformed attribute entry is encountered, 76 // this method also returns false. 77 static bool IterateAttributes(const ByteString& payload, size_t offset, 78 const AttributeMethod& method); 79 80 // Decode an attribute list starting from |offset| within |payload|. Use 81 // |factory| to create each attribute object. 82 bool Decode(const ByteString& payload, 83 size_t offset, const NewFromIdMethod& factory); 84 85 // Returns the attributes as the payload portion of a netlink message 86 // suitable for Sockets::Send. Return value is empty on failure (or if no 87 // attributes exist). 88 ByteString Encode() const; 89 90 // Create, get, and set attributes of the given types. Attributes are 91 // accessed via an integer |id|. |id_string| is a string used to describe 92 // the attribute in debug output. 93 bool CreateU8Attribute(int id, const char* id_string); 94 bool SetU8AttributeValue(int id, uint8_t value); 95 bool GetU8AttributeValue(int id, uint8_t* value) const; 96 97 bool CreateU16Attribute(int id, const char* id_string); 98 bool SetU16AttributeValue(int id, uint16_t value); 99 bool GetU16AttributeValue(int id, uint16_t* value) const; 100 101 bool CreateU32Attribute(int id, const char* id_string); 102 bool SetU32AttributeValue(int id, uint32_t value); 103 bool GetU32AttributeValue(int id, uint32_t* value) const; 104 105 bool CreateU64Attribute(int id, const char* id_string); 106 bool SetU64AttributeValue(int id, uint64_t value); 107 bool GetU64AttributeValue(int id, uint64_t* value) const; 108 109 bool CreateFlagAttribute(int id, const char* id_string); 110 bool SetFlagAttributeValue(int id, bool value); 111 bool GetFlagAttributeValue(int id, bool* value) const; 112 // |IsFlagAttributeTrue| returns true if the flag attribute |id| is true. It 113 // retruns false if the attribute does not exist, is not of type kTypeFlag, 114 // or is not true. 115 bool IsFlagAttributeTrue(int id) const; 116 117 bool CreateStringAttribute(int id, const char* id_string); 118 // SSID attributes are derived from string attributes. 119 bool CreateSsidAttribute(int id, const char* id_string); 120 bool SetStringAttributeValue(int id, std::string value); 121 bool GetStringAttributeValue(int id, std::string* value) const; 122 123 bool CreateNestedAttribute(int id, const char* id_string); 124 bool SetNestedAttributeHasAValue(int id); 125 bool GetNestedAttributeList(int id, AttributeListRefPtr* value); 126 bool ConstGetNestedAttributeList(int id, 127 AttributeListConstRefPtr* value) const; 128 129 bool CreateRawAttribute(int id, const char* id_string); 130 // |value| should point to the data (after the |nlattr| header, if there is 131 // one). 132 bool SetRawAttributeValue(int id, ByteString value); 133 bool GetRawAttributeValue(int id, ByteString* output) const; 134 135 // This retrieves a string from any kind of attribute. 136 bool GetAttributeAsString(int id, std::string* value) const; 137 138 protected: 139 friend class base::RefCounted<AttributeList>; ~AttributeList()140 virtual ~AttributeList() {} 141 142 private: 143 typedef std::map<int, AttributePointer> AttributeMap; 144 friend class AttributeIdIterator; 145 friend class NetlinkNestedAttribute; 146 147 // Using this to get around issues with const and operator[]. 148 SHILL_PRIVATE NetlinkAttribute* GetAttribute(int id) const; 149 150 AttributeMap attributes_; 151 152 DISALLOW_COPY_AND_ASSIGN(AttributeList); 153 }; 154 155 // Provides a mechanism to iterate through the ids of all of the attributes 156 // in an |AttributeList|. This class is really only useful if the caller 157 // knows the type of each attribute in advance (such as with a nested array). 158 class AttributeIdIterator { 159 public: AttributeIdIterator(const AttributeList & list)160 explicit AttributeIdIterator(const AttributeList& list) 161 : iter_(list.attributes_.begin()), 162 end_(list.attributes_.end()) { 163 } Advance()164 void Advance() { ++iter_; } AtEnd()165 bool AtEnd() const { return iter_ == end_; } GetId()166 int GetId() const { return iter_->first; } 167 168 private: 169 AttributeList::AttributeMap::const_iterator iter_; 170 const AttributeList::AttributeMap::const_iterator end_; 171 172 DISALLOW_COPY_AND_ASSIGN(AttributeIdIterator); 173 }; 174 175 } // namespace shill 176 177 #endif // SHILL_NET_ATTRIBUTE_LIST_H_ 178