netlink_manager.h revision 0bb07ecdb74d6e9af6271cec1bdc6232d546a878
17397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang/* 27397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * Copyright (C) 2016 The Android Open Source Project 37397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * 47397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * Licensed under the Apache License, Version 2.0 (the "License"); 57397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * you may not use this file except in compliance with the License. 67397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * You may obtain a copy of the License at 77397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * 87397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * http://www.apache.org/licenses/LICENSE-2.0 97397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * 107397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * Unless required by applicable law or agreed to in writing, software 117397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * distributed under the License is distributed on an "AS IS" BASIS, 127397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * See the License for the specific language governing permissions and 147397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang * limitations under the License. 157397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang */ 167397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 177397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#ifndef WIFICOND_NET_NETLINK_MANAGER_H_ 187397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#define WIFICOND_NET_NETLINK_MANAGER_H_ 197397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 207397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include <functional> 217397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include <map> 227397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 230bb07ecdb74d6e9af6271cec1bdc6232d546a878Ningyuan Wang#include <android-base/macros.h> 247397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include <android-base/unique_fd.h> 257397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 267397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include "event_loop.h" 277397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 287397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangnamespace android { 297397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangnamespace wificond { 307397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 317397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangclass NL80211Packet; 327397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 337397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang// Encapsulates all the different things we know about a specific message 347397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang// type like its name, and its id. 357397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangstruct MessageType { 367397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This constructor is needed by map[key] operation. 377397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang MessageType() {}; 387397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang explicit MessageType(uint16_t id) { 397397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang family_id = id; 407397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang }; 417397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint16_t family_id; 427397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Multicast groups supported by the family. The string and mapping to 437397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // a group id are extracted from the CTRL_CMD_NEWFAMILY message. 447397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<std::string, uint32_t> groups; 457397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang}; 467397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 477397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangclass NetlinkManager { 487397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang public: 497397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang explicit NetlinkManager(EventLoop* event_loop); 50e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang virtual ~NetlinkManager(); 517397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Initialize netlink manager. 527397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This includes setting up socket and requesting nl80211 family id from kernel. 535ea9c07f01b5a7a617dbc99011a5d0952a7a87dbNingyuan Wang // Returns true on success. 54e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang bool Start(); 555ea9c07f01b5a7a617dbc99011a5d0952a7a87dbNingyuan Wang // Returns true if this netlink manager object is started. 565ea9c07f01b5a7a617dbc99011a5d0952a7a87dbNingyuan Wang bool IsStarted() const; 577397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Returns a sequence number available for use. 587397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t GetSequenceNumber(); 59e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Get NL80211 netlink family id, 60e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang uint16_t GetFamilyId(); 617397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Send |packet| to kernel. 627397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This works in an asynchronous way. 637397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // |handler| will be run when we receive a valid reply from kernel. 640c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Do not use this asynchronous interface to send a dump request. 657397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Returns true on success. 667397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang bool RegisterHandlerAndSendMessage(const NL80211Packet& packet, 677397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::function<void(NL80211Packet)> handler); 680c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Synchronous version of |RegisterHandlerAndSendMessage|. 690c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Returns true on successfully receiving an valid reply. 7047b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang // Reply packets will be stored in |response|. 7147b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang bool SendMessageAndGetResponses(const NL80211Packet& packet, 7247b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang std::vector<NL80211Packet>* response); 737397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 74e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Get the wiphy index from kernel. 75e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // |*out_wiphy_index| returns the wiphy index from kernel. 76e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Returns true on success. 77e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang virtual bool GetWiphyIndex(uint32_t* out_wiphy_index); 78e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang 7945a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang // Get wifi interface name from kernel. 8045a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang // |wiphy_index| is the wiphy index we get using GetWiphyIndex(). 8145a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang // Returns true on success. 8245a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang virtual bool GetInterfaceName(uint32_t wiphy_index, 8345a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang std::string* interface_name); 8445a655e6c6ba304c577ee098732ac176aaab311bNingyuan Wang 857397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang private: 860c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool SetupSocket(android::base::unique_fd* netlink_fd); 870c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool WatchSocket(android::base::unique_fd* netlink_fd); 880c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang void ReceivePacketAndRunHandler(int fd); 897397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang bool DiscoverFamilyId(); 900c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool SendMessageInternal(const NL80211Packet& packet, int fd); 917397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 927397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This handler revceives mapping from NL80211 family name to family id, 937397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // as well as mapping from group name to group id. 947397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // These mappings are allocated by kernel. 957397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang void OnNewFamily(NL80211Packet packet); 967397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 975ea9c07f01b5a7a617dbc99011a5d0952a7a87dbNingyuan Wang bool started_; 980c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // We use different sockets for synchronous and asynchronous interfaces. 990c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Kernel will reply error message when we start a new request in the 1000c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // middle of a dump request. 1010c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Using different sockets help us avoid the complexity of message 1020c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // rescheduling. 1030c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang android::base::unique_fd sync_netlink_fd_; 1040c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang android::base::unique_fd async_netlink_fd_; 1057397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang EventLoop* event_loop_; 1067397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1077397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This is a collection of message handlers, for each sequence number. 1087397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<uint32_t, std::function<void(NL80211Packet)>> message_handlers_; 1097397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1107397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Mapping from family name to family id, and group name to group id. 1117397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<std::string, MessageType> message_types_; 1127397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1137397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t sequence_number_; 1140bb07ecdb74d6e9af6271cec1bdc6232d546a878Ningyuan Wang 1150bb07ecdb74d6e9af6271cec1bdc6232d546a878Ningyuan Wang DISALLOW_COPY_AND_ASSIGN(NetlinkManager); 1167397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang}; 1177397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1187397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} // namespace wificond 1197397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} // namespace android 1207397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1217397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#endif // WIFICOND_NET_NETLINK_MANAGER_H_ 122