netlink_manager.h revision 47b3d35354ee70c78e1c2d6df3320f43fd2b2c24
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 237397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include <android-base/unique_fd.h> 247397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 257397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#include "event_loop.h" 267397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 277397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangnamespace android { 287397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangnamespace wificond { 297397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 307397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangclass NL80211Packet; 317397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 327397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang// Encapsulates all the different things we know about a specific message 337397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang// type like its name, and its id. 347397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangstruct MessageType { 357397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This constructor is needed by map[key] operation. 367397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang MessageType() {}; 377397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang explicit MessageType(uint16_t id) { 387397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang family_id = id; 397397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang }; 407397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint16_t family_id; 417397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Multicast groups supported by the family. The string and mapping to 427397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // a group id are extracted from the CTRL_CMD_NEWFAMILY message. 437397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<std::string, uint32_t> groups; 447397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang}; 457397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 467397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wangclass NetlinkManager { 477397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang public: 487397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang explicit NetlinkManager(EventLoop* event_loop); 49e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang virtual ~NetlinkManager(); 507397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Initialize netlink manager. 517397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This includes setting up socket and requesting nl80211 family id from kernel. 52e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang bool Start(); 537397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Returns a sequence number available for use. 547397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t GetSequenceNumber(); 55e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Get NL80211 netlink family id, 56e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang uint16_t GetFamilyId(); 577397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Send |packet| to kernel. 587397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This works in an asynchronous way. 597397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // |handler| will be run when we receive a valid reply from kernel. 600c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Do not use this asynchronous interface to send a dump request. 617397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Returns true on success. 627397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang bool RegisterHandlerAndSendMessage(const NL80211Packet& packet, 637397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::function<void(NL80211Packet)> handler); 640c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Synchronous version of |RegisterHandlerAndSendMessage|. 650c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Returns true on successfully receiving an valid reply. 6647b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang // Reply packets will be stored in |response|. 6747b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang bool SendMessageAndGetResponses(const NL80211Packet& packet, 6847b3d35354ee70c78e1c2d6df3320f43fd2b2c24Ningyuan Wang std::vector<NL80211Packet>* response); 697397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 70e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Get the wiphy index from kernel. 71e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // |*out_wiphy_index| returns the wiphy index from kernel. 72e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang // Returns true on success. 73e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang virtual bool GetWiphyIndex(uint32_t* out_wiphy_index); 74e6dce59eaa5f1fcbdfb4b3fc6a60d5cd3b522b06Ningyuan Wang 757397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang private: 760c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool SetupSocket(android::base::unique_fd* netlink_fd); 770c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool WatchSocket(android::base::unique_fd* netlink_fd); 780c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang void ReceivePacketAndRunHandler(int fd); 797397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang bool DiscoverFamilyId(); 800c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang bool SendMessageInternal(const NL80211Packet& packet, int fd); 817397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 827397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This handler revceives mapping from NL80211 family name to family id, 837397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // as well as mapping from group name to group id. 847397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // These mappings are allocated by kernel. 857397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang void OnNewFamily(NL80211Packet packet); 867397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 870c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // We use different sockets for synchronous and asynchronous interfaces. 880c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Kernel will reply error message when we start a new request in the 890c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // middle of a dump request. 900c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // Using different sockets help us avoid the complexity of message 910c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang // rescheduling. 920c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang android::base::unique_fd sync_netlink_fd_; 930c2afe0b1381efea4a2821a51b65fb2a255364d3Ningyuan Wang android::base::unique_fd async_netlink_fd_; 947397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang EventLoop* event_loop_; 957397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 967397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // This is a collection of message handlers, for each sequence number. 977397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<uint32_t, std::function<void(NL80211Packet)>> message_handlers_; 987397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 997397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang // Mapping from family name to family id, and group name to group id. 1007397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang std::map<std::string, MessageType> message_types_; 1017397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1027397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang uint32_t sequence_number_; 1037397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang}; 1047397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1057397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} // namespace wificond 1067397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang} // namespace android 1077397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang 1087397e6b7c3635e2121f6d2229557e684bc4756cfNingyuan Wang#endif // WIFICOND_NET_NETLINK_MANAGER_H_ 109