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