Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 5 | // This software provides an abstracted interface to the netlink socket |
| 6 | // interface. In its current implementation it is used, primarily, to |
| 7 | // communicate with the cfg80211 kernel module and mac80211 drivers: |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 8 | // |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 9 | // [shill]--[nl80211 library, libnl_genl/libnl libraries] |
| 10 | // | |
| 11 | // (netlink socket) |
| 12 | // | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 13 | // [cfg80211 kernel module] |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 14 | // | |
| 15 | // [mac80211 drivers] |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 16 | // |
| 17 | // In order to send a message and handle it's response, do the following: |
| 18 | // - Create a handler (it'll want to verify that it's the kind of message you |
| 19 | // want, cast it to the appropriate type, and get attributes from the cast |
| 20 | // message): |
| 21 | // |
| 22 | // #include "nl80211_message.h" |
| 23 | // class SomeClass { |
| 24 | // static void MyMessageHandler(const NetlinkMessage &raw) { |
| 25 | // if (raw.message_type() != ControlNetlinkMessage::kMessageType) |
| 26 | // return; |
| 27 | // const ControlNetlinkMessage *message = |
| 28 | // reinterpret_cast<const ControlNetlinkMessage *>(&raw); |
| 29 | // if (message.command() != NewFamilyMessage::kCommand) |
| 30 | // return; |
| 31 | // uint16_t my_attribute; |
| 32 | // message->const_attributes()->GetU16AttributeValue( |
| 33 | // CTRL_ATTR_FAMILY_ID, &my_attribute); |
| 34 | // } // MyMessageHandler. |
| 35 | // } // class SomeClass. |
| 36 | // |
| 37 | // - Instantiate a message: |
| 38 | // |
| 39 | // #include "nl80211_message.h" |
| 40 | // GetFamilyMessage msg; |
| 41 | // |
Wade Guthrie | 2623f1a | 2013-05-14 15:14:54 -0700 | [diff] [blame] | 42 | // - And set attributes: |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 43 | // |
Wade Guthrie | 2623f1a | 2013-05-14 15:14:54 -0700 | [diff] [blame] | 44 | // msg.attributes()->SetStringAttributeValue(CTRL_ATTR_FAMILY_NAME, "foo"); |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 45 | // |
| 46 | // - Then send the message, passing-in a closure to the handler you created: |
| 47 | // |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 48 | // NetlinkManager *netlink_manager = NetlinkManager::GetInstance(); |
| 49 | // netlink_manager->SendMessage(&msg, Bind(&SomeClass::MyMessageHandler)); |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 50 | // |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 51 | // NetlinkManager will then save your handler and send your message. When a |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 52 | // response to your message arrives, it'll call your handler. |
| 53 | // |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 54 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 55 | #ifndef SHILL_NETLINK_MANAGER_H_ |
| 56 | #define SHILL_NETLINK_MANAGER_H_ |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 57 | |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 58 | #include <list> |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 59 | #include <map> |
Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 60 | #include <set> |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 61 | #include <string> |
| 62 | |
| 63 | #include <base/basictypes.h> |
| 64 | #include <base/bind.h> |
| 65 | #include <base/lazy_instance.h> |
Wade Guthrie | b9c3feb | 2013-04-25 16:31:19 -0700 | [diff] [blame] | 66 | #include <base/memory/scoped_ptr.h> |
| 67 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 68 | |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 69 | #include "shill/generic_netlink_message.h" |
Wade Guthrie | b9c3feb | 2013-04-25 16:31:19 -0700 | [diff] [blame] | 70 | #include "shill/io_handler.h" |
Wade Guthrie | 0ae4b8e | 2013-04-10 16:49:15 -0700 | [diff] [blame] | 71 | #include "shill/netlink_message.h" |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 72 | #include "shill/shill_time.h" |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 73 | |
Wade Guthrie | 89e6cb3 | 2013-03-07 08:03:45 -0800 | [diff] [blame] | 74 | struct nlmsghdr; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 75 | |
| 76 | namespace shill { |
| 77 | |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 78 | class ControlNetlinkMessage; |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 79 | class Error; |
Wade Guthrie | 89e6cb3 | 2013-03-07 08:03:45 -0800 | [diff] [blame] | 80 | class EventDispatcher; |
Liam McLoughlin | f4baef2 | 2012-08-01 19:08:25 -0700 | [diff] [blame] | 81 | struct InputData; |
Wade Guthrie | 89e6cb3 | 2013-03-07 08:03:45 -0800 | [diff] [blame] | 82 | class NetlinkSocket; |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 83 | class Nl80211Message; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 84 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 85 | // NetlinkManager is a singleton that coordinates sending netlink messages to, |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 86 | // and receiving netlink messages from, the kernel. The first use of this is |
| 87 | // to communicate between user-space and the cfg80211 module that manages wifi |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 88 | // drivers. Bring NetlinkManager up as follows: |
| 89 | // NetlinkManager *netlink_manager_ = NetlinkManager::GetInstance(); |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 90 | // EventDispatcher dispatcher_; |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 91 | // netlink_manager_->Init(); // Initialize the socket. |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 92 | // // Get message types for all dynamic message types. |
| 93 | // Nl80211Message::SetMessageType( |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 94 | // netlink_manager_->GetFamily(Nl80211Message::kMessageTypeString, |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 95 | // Bind(&Nl80211Message::CreateMessage))); |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 96 | // netlink_manager_->Start(&dispatcher_); |
| 97 | class NetlinkManager { |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 98 | public: |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 99 | enum AuxilliaryMessageType { |
| 100 | kErrorFromKernel, |
| 101 | kUnexpectedResponseType, |
| 102 | kTimeoutWaitingForResponse |
| 103 | }; |
Wade Guthrie | f48a195 | 2013-03-04 17:33:47 -0800 | [diff] [blame] | 104 | typedef base::Callback<void(const NetlinkMessage &)> NetlinkMessageHandler; |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 105 | typedef base::Callback<void(const ControlNetlinkMessage &)> |
| 106 | ControlNetlinkMessageHandler; |
| 107 | typedef base::Callback<void(const Nl80211Message &)> Nl80211MessageHandler; |
| 108 | // NetlinkAuxilliaryMessageHandler handles netlink error messages, things |
| 109 | // like the DoneMessage at the end of a multi-part message, and any errors |
| 110 | // discovered by |NetlinkManager| (which are passed as NULL pointers because |
| 111 | // there is no way to reserve a part of the ErrorAckMessage space for |
| 112 | // non-netlink errors). |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 113 | typedef base::Callback<void(AuxilliaryMessageType type, |
| 114 | const NetlinkMessage *)> |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 115 | NetlinkAuxilliaryMessageHandler; |
| 116 | |
| 117 | // ResponseHandlers provide a polymorphic context for the base::Callback |
| 118 | // message handlers so that handlers for different types of messages can be |
| 119 | // kept in the same container (namely, |message_handlers_|). |
| 120 | class NetlinkResponseHandler : |
| 121 | public base::RefCounted<NetlinkResponseHandler> { |
| 122 | public: |
| 123 | explicit NetlinkResponseHandler( |
| 124 | const NetlinkAuxilliaryMessageHandler &error_handler); |
| 125 | virtual ~NetlinkResponseHandler(); |
| 126 | // Calls wrapper-type-specific callback for |netlink_message|. Returns |
| 127 | // false if |netlink_message| is not the correct type. Calls callback |
| 128 | // (which is declared in the private area of derived classes) with |
| 129 | // properly cast version of |netlink_message|. |
| 130 | virtual bool HandleMessage(const NetlinkMessage &netlink_message) const = 0; |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 131 | void HandleError(AuxilliaryMessageType type, |
| 132 | const NetlinkMessage *netlink_message) const; |
| 133 | void set_delete_after(const timeval &time) { delete_after_ = time; } |
| 134 | const struct timeval &delete_after() const { return delete_after_; } |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 135 | |
| 136 | protected: |
| 137 | NetlinkResponseHandler(); |
| 138 | |
| 139 | private: |
| 140 | NetlinkAuxilliaryMessageHandler error_handler_; |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 141 | struct timeval delete_after_; |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 142 | |
| 143 | DISALLOW_COPY_AND_ASSIGN(NetlinkResponseHandler); |
| 144 | }; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 145 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 146 | // Encapsulates all the different things we know about a specific message |
Wade Guthrie | 0ae4b8e | 2013-04-10 16:49:15 -0700 | [diff] [blame] | 147 | // type like its name, and its id. |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 148 | struct MessageType { |
| 149 | MessageType(); |
| 150 | |
| 151 | uint16_t family_id; |
| 152 | |
| 153 | // Multicast groups supported by the family. The string and mapping to |
| 154 | // a group id are extracted from the CTRL_CMD_NEWFAMILY message. |
| 155 | std::map<std::string, uint32_t> groups; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 156 | }; |
| 157 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 158 | // Various kinds of events to which we can subscribe (and receive) from |
| 159 | // cfg80211. |
| 160 | static const char kEventTypeConfig[]; |
| 161 | static const char kEventTypeScan[]; |
| 162 | static const char kEventTypeRegulatory[]; |
| 163 | static const char kEventTypeMlme[]; |
| 164 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 165 | // NetlinkManager is a singleton and this is the way to access it. |
| 166 | static NetlinkManager *GetInstance(); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 167 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 168 | // Performs non-trivial object initialization of the NetlinkManager singleton. |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 169 | bool Init(); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 170 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 171 | // Passes the job of waiting for, and the subsequent reading from, the |
| 172 | // netlink socket to |dispatcher|. |
| 173 | void Start(EventDispatcher *dispatcher); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 174 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 175 | // The following methods deal with the network family table. This table |
| 176 | // associates netlink family names with family_ids (also called message |
| 177 | // types). Note that some families have static ids assigned to them but |
| 178 | // others require the kernel to resolve a string describing the family into |
| 179 | // a dynamically-determined id. |
| 180 | |
| 181 | // Returns the family_id (message type) associated with |family_name|, |
| 182 | // calling the kernel if needed. Returns |
| 183 | // |NetlinkMessage::kIllegalMessageType| if the message type could not be |
| 184 | // determined. May block so |GetFamily| should be called before entering the |
| 185 | // event loop. |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 186 | virtual uint16_t GetFamily(const std::string &family_name, |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 187 | const NetlinkMessageFactory::FactoryMethod &message_factory); |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 188 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 189 | // Install a NetlinkManager NetlinkMessageHandler. The handler is a |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 190 | // user-supplied object to be called by the system for user-bound messages |
| 191 | // that do not have a corresponding messaage-specific callback. |
| 192 | // |AddBroadcastHandler| should be called before |SubscribeToEvents| since |
| 193 | // the result of this call are used for that call. |
Wade Guthrie | 5a4e2ef | 2013-04-30 12:51:39 -0700 | [diff] [blame] | 194 | virtual bool AddBroadcastHandler( |
| 195 | const NetlinkMessageHandler &message_handler); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 196 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 197 | // Uninstall a NetlinkMessage Handler. |
Wade Guthrie | 5a4e2ef | 2013-04-30 12:51:39 -0700 | [diff] [blame] | 198 | virtual bool RemoveBroadcastHandler( |
| 199 | const NetlinkMessageHandler &message_handler); |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 200 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 201 | // Determines whether a handler is in the list of broadcast handlers. |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 202 | bool FindBroadcastHandler(const NetlinkMessageHandler &message_handler) const; |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 203 | |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 204 | // Uninstall all broadcast netlink message handlers. |
| 205 | void ClearBroadcastHandlers(); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 206 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 207 | // Sends a netlink message to the kernel using the NetlinkManager socket after |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 208 | // installing a handler to deal with the kernel's response to the message. |
Wade Guthrie | 5d53d49 | 2012-11-07 09:53:31 -0800 | [diff] [blame] | 209 | // TODO(wdg): Eventually, this should also include a timeout and a callback |
| 210 | // to call in case of timeout. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 211 | virtual bool SendControlMessage( |
| 212 | ControlNetlinkMessage *message, |
| 213 | const ControlNetlinkMessageHandler &message_handler, |
| 214 | const NetlinkAuxilliaryMessageHandler &error_handler); |
| 215 | virtual bool SendNl80211Message( |
| 216 | Nl80211Message *message, |
| 217 | const Nl80211MessageHandler &message_handler, |
| 218 | const NetlinkAuxilliaryMessageHandler &error_handler); |
| 219 | |
| 220 | // Generic erroneous message handler everyone can use. |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 221 | static void OnNetlinkMessageError(AuxilliaryMessageType type, |
| 222 | const NetlinkMessage *raw_message); |
Wade Guthrie | 5d53d49 | 2012-11-07 09:53:31 -0800 | [diff] [blame] | 223 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 224 | // Uninstall the handler for a specific netlink message. |
Wade Guthrie | f48a195 | 2013-03-04 17:33:47 -0800 | [diff] [blame] | 225 | bool RemoveMessageHandler(const NetlinkMessage &message); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 226 | |
Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 227 | // Sign-up to receive and log multicast events of a specific type (once wifi |
| 228 | // is up). |
Wade Guthrie | 5a4e2ef | 2013-04-30 12:51:39 -0700 | [diff] [blame] | 229 | virtual bool SubscribeToEvents(const std::string &family, |
| 230 | const std::string &group); |
Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 231 | |
Wade Guthrie | bdcdaa7 | 2013-03-04 12:47:12 -0800 | [diff] [blame] | 232 | // Gets the next sequence number for a NetlinkMessage to be sent over |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 233 | // NetlinkManager's netlink socket. |
Wade Guthrie | bdcdaa7 | 2013-03-04 12:47:12 -0800 | [diff] [blame] | 234 | uint32_t GetSequenceNumber(); |
| 235 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 236 | protected: |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 237 | friend struct base::DefaultLazyInstanceTraits<NetlinkManager>; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 238 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 239 | explicit NetlinkManager(); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 240 | |
| 241 | private: |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 242 | friend class NetlinkManagerTest; |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 243 | friend class NetlinkMessageTest; |
Darin Petkov | d581838 | 2013-01-28 16:27:07 +0100 | [diff] [blame] | 244 | friend class ShillDaemonTest; |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 245 | FRIEND_TEST(NetlinkManagerTest, AddLinkTest); |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 246 | FRIEND_TEST(NetlinkManagerTest, BroadcastHandler); |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 247 | FRIEND_TEST(NetlinkManagerTest, GetFamilyOneInterstitialMessage); |
| 248 | FRIEND_TEST(NetlinkManagerTest, GetFamilyTimeout); |
Wade Guthrie | bbe59f7 | 2013-05-21 08:45:39 -0700 | [diff] [blame] | 249 | FRIEND_TEST(NetlinkManagerTest, MessageHandler); |
| 250 | FRIEND_TEST(NetlinkManagerTest, MultipartMessageHandler); |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 251 | FRIEND_TEST(NetlinkManagerTest, TimeoutResponseHandlers); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 252 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_ASSOCIATE); |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 253 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_AUTHENTICATE); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 254 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_CONNECT); |
| 255 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DEAUTHENTICATE); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 256 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DISASSOCIATE); |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 257 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DISCONNECT); |
| 258 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NEW_SCAN_RESULTS); |
| 259 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NEW_STATION); |
| 260 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NOTIFY_CQM); |
| 261 | FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_TRIGGER_SCAN); |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 262 | |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 263 | typedef scoped_refptr<NetlinkResponseHandler> NetlinkResponseHandlerRefPtr; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 264 | |
Wade Guthrie | 84db7ce | 2013-06-12 11:40:49 -0700 | [diff] [blame] | 265 | // These need to be member variables, even though they're only used once in |
| 266 | // the code, since they're needed for unittests. |
| 267 | static const long kMaximumNewFamilyWaitSeconds; // NOLINT |
| 268 | static const long kMaximumNewFamilyWaitMicroSeconds; // NOLINT |
| 269 | static const long kResponseTimeoutSeconds; // NOLINT |
| 270 | static const long kResponseTimeoutMicroSeconds; // NOLINT |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 271 | |
| 272 | // Returns the file descriptor of socket used to read wifi data. |
Wade Guthrie | 89e6cb3 | 2013-03-07 08:03:45 -0800 | [diff] [blame] | 273 | int file_descriptor() const; |
Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 274 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 275 | // EventDispatcher calls this when data is available on our socket. This |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 276 | // method passes each, individual, message in the input to |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 277 | // |OnNlMessageReceived|. Each part of a multipart message gets handled, |
| 278 | // individually, by this method. |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 279 | void OnRawNlMessageReceived(InputData *data); |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 280 | |
| 281 | // This method processes a message from |OnRawNlMessageReceived| by passing |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 282 | // the message to either the NetlinkManager callback that matches the sequence |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 283 | // number of the message or, if there isn't one, to all of the default |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 284 | // NetlinkManager callbacks in |broadcast_handlers_|. |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 285 | void OnNlMessageReceived(nlmsghdr *msg); |
| 286 | |
| 287 | // Called by InputHandler on exceptional events. |
| 288 | void OnReadError(const Error &error); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 289 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 290 | // Just for tests, this method turns off WiFi and clears the subscribed |
| 291 | // events list. If |full| is true, also clears state set by Init. |
Darin Petkov | d581838 | 2013-01-28 16:27:07 +0100 | [diff] [blame] | 292 | void Reset(bool full); |
Wade Guthrie | d615361 | 2012-08-23 11:36:14 -0700 | [diff] [blame] | 293 | |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 294 | // Handles a CTRL_CMD_NEWFAMILY message from the kernel. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 295 | void OnNewFamilyMessage(const ControlNetlinkMessage &message); |
| 296 | |
| 297 | // Sends a netlink message to the kernel using the NetlinkManager socket after |
| 298 | // installing a handler to deal with the kernel's response to the message. |
| 299 | // Adds a serial number to |message| before it is sent. |
| 300 | bool SendMessageInternal( |
| 301 | NetlinkMessage *message, |
| 302 | NetlinkResponseHandler *message_wrapper); // Passes ownership. |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 303 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 304 | // NetlinkManager Handlers, OnRawNlMessageReceived invokes each of these |
Wade Guthrie | b1ec860 | 2012-10-18 17:26:14 -0700 | [diff] [blame] | 305 | // User-supplied callback object when _it_ gets called to read libnl data. |
Wade Guthrie | 71cb0a7 | 2013-02-27 10:27:18 -0800 | [diff] [blame] | 306 | std::list<NetlinkMessageHandler> broadcast_handlers_; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 307 | |
Wade Guthrie | 5d3d6de | 2012-11-02 11:08:34 -0700 | [diff] [blame] | 308 | // Message-specific callbacks, mapped by message ID. |
Wade Guthrie | 7347bf2 | 2013-04-30 11:21:51 -0700 | [diff] [blame] | 309 | std::map<uint32_t, NetlinkResponseHandlerRefPtr> message_handlers_; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 310 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 311 | // Hooks needed to be called by shill's EventDispatcher. |
| 312 | EventDispatcher *dispatcher_; |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 313 | base::WeakPtrFactory<NetlinkManager> weak_ptr_factory_; |
repo sync | bcaa694 | 2013-01-02 15:38:21 -0800 | [diff] [blame] | 314 | base::Callback<void(InputData *)> dispatcher_callback_; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 315 | scoped_ptr<IOHandler> dispatcher_handler_; |
| 316 | |
Wade Guthrie | cc53f23 | 2013-03-05 13:22:23 -0800 | [diff] [blame] | 317 | NetlinkSocket *sock_; |
Wade Guthrie | bee87c2 | 2013-03-06 11:00:46 -0800 | [diff] [blame] | 318 | std::map<const std::string, MessageType> message_types_; |
Wade Guthrie | 12f113a | 2013-03-12 17:15:46 -0700 | [diff] [blame] | 319 | NetlinkMessageFactory message_factory_; |
Wade Guthrie | fa2100e | 2013-05-15 10:11:22 -0700 | [diff] [blame] | 320 | Time *time_; |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 321 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 322 | DISALLOW_COPY_AND_ASSIGN(NetlinkManager); |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 323 | }; |
| 324 | |
Wade Guthrie | 0d43853 | 2012-05-18 14:18:50 -0700 | [diff] [blame] | 325 | } // namespace shill |
| 326 | |
Wade Guthrie | bb9fca2 | 2013-04-10 17:21:42 -0700 | [diff] [blame] | 327 | #endif // SHILL_NETLINK_MANAGER_H_ |