Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2016 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 WIFICOND_NET_NETLINK_MANAGER_H_
     18 #define WIFICOND_NET_NETLINK_MANAGER_H_
     19 
     20 #include <functional>
     21 #include <map>
     22 #include <memory>
     23 
     24 #include <android-base/macros.h>
     25 #include <android-base/unique_fd.h>
     26 
     27 #include "event_loop.h"
     28 
     29 namespace android {
     30 namespace wificond {
     31 
     32 class MlmeEventHandler;
     33 class NL80211Packet;
     34 
     35 // Encapsulates all the different things we know about a specific message
     36 // type like its name, and its id.
     37 struct MessageType {
     38    // This constructor is needed by map[key] operation.
     39    MessageType() {};
     40    explicit MessageType(uint16_t id) {
     41      family_id = id;
     42    };
     43    uint16_t family_id;
     44    // Multicast groups supported by the family.  The string and mapping to
     45    // a group id are extracted from the CTRL_CMD_NEWFAMILY message.
     46    std::map<std::string, uint32_t> groups;
     47 };
     48 
     49 // This describes a type of function handling scan results ready notification.
     50 // |interface_index| is the index of interface which the scan results
     51 // are from.
     52 // |aborted| is a boolean indicating if this scan was aborted or not.
     53 // According to nl80211.h document, part of the scan result might still be
     54 // available even when the scan was aborted.
     55 // |ssids| is a vector of scan ssids associated with the corresponding
     56 // scan request.
     57 // |frequencies| is a vector of scan frequencies associated with the
     58 // corresponding scan request.
     59 typedef std::function<void(
     60     uint32_t interface_index,
     61     bool aborted,
     62     std::vector<std::vector<uint8_t>>& ssids,
     63     std::vector<uint32_t>& frequencies)> OnScanResultsReadyHandler;
     64 
     65 // This describes a type of function handling scheduled scan results ready
     66 // notification. This can also be used for notificating the stopping of a
     67 // scheduled scan.
     68 // |interface_index| is the index of interface which the scan results
     69 // are from.
     70 // |scan_stopped| is a boolean indicating if this scheduled scan was stopped
     71 // or not.
     72 typedef std::function<void(
     73     uint32_t interface_index,
     74     bool scan_stopped)> OnSchedScanResultsReadyHandler;
     75 
     76 // This describes a type of function handling regulatory domain change
     77 // notification.
     78 // If the regulatory domain set is one that pertains to a specific country,
     79 // |country_code| will be set accordingly.
     80 // If the regulatory domain set does not pertain to a specific country,
     81 // |country_code| will be an empty string. This could be a world regulatory
     82 // domain or a intersection regulatory domain.
     83 // See details in defination of |nl80211_reg_type| from nl80211.h.
     84 typedef std::function<void(
     85     std::string& country_code)> OnRegDomainChangedHandler;
     86 
     87 // Enum used for identifying channel bandwidth.
     88 // This is used by function |OnChannelSwitchEventHandler|.
     89 enum ChannelBandwidth {
     90     BW_INVALID,
     91     BW_20_NOHT,
     92     BW_20,
     93     BW_40,
     94     BW_80,
     95     BW_80P80,
     96     BW_160,
     97 };
     98 
     99 // This describes a type of function handling channel switch notification.
    100 // |frequency| represents the frequence of the channel in MHz.
    101 typedef std::function<void(
    102     uint32_t frequency, ChannelBandwidth bandwidth)> OnChannelSwitchEventHandler;
    103 
    104 // Enum used for identifying the type of a station event.
    105 // This is used by function |OnStationEventHandler|.
    106 enum StationEvent {
    107     NEW_STATION,
    108     DEL_STATION
    109 };
    110 
    111 // This describes a type of function handling station events.
    112 // |event| specifies the type of this event.
    113 // |mac_address| is the station mac address associated with this event.
    114 typedef std::function<void(
    115     StationEvent event,
    116     const std::vector<uint8_t>& mac_address)> OnStationEventHandler;
    117 
    118 class NetlinkManager {
    119  public:
    120   explicit NetlinkManager(EventLoop* event_loop);
    121   virtual ~NetlinkManager();
    122   // Initialize netlink manager.
    123   // This includes setting up socket and requesting nl80211 family id from kernel.
    124   // Returns true on success.
    125   virtual bool Start();
    126   // Returns true if this netlink manager object is started.
    127   virtual bool IsStarted() const;
    128   // Returns a sequence number available for use.
    129   virtual uint32_t GetSequenceNumber();
    130   // Get NL80211 netlink family id,
    131   virtual uint16_t GetFamilyId();
    132 
    133   // Send |packet| to kernel.
    134   // This works in an asynchronous way.
    135   // |handler| will be run when we receive a valid reply from kernel.
    136   // Do not use this asynchronous interface to send a dump request.
    137   // Returns true on success.
    138   virtual bool RegisterHandlerAndSendMessage(const NL80211Packet& packet,
    139       std::function<void(std::unique_ptr<const NL80211Packet>)> handler);
    140   // Synchronous version of |RegisterHandlerAndSendMessage|.
    141   // Returns true on successfully receiving an valid reply.
    142   // Reply packets will be stored in |*response|.
    143   virtual bool SendMessageAndGetResponses(
    144       const NL80211Packet& packet,
    145       std::vector<std::unique_ptr<const NL80211Packet>>* response);
    146   // Wrapper of |SendMessageAndGetResponses| for messages with a single
    147   // response.
    148   // Returns true on successfully receiving an valid reply.
    149   // This will returns false if a NLMSG_ERROR is received.
    150   // Reply packet will be stored in |*response|.
    151   virtual bool SendMessageAndGetSingleResponse(
    152       const NL80211Packet& packet,
    153       std::unique_ptr<const NL80211Packet>* response);
    154 
    155   // Wrapper of |SendMessageAndGetResponses| for messages with a single
    156   // response.
    157   // Returns true on successfully receiving an valid reply.
    158   // This will returns true if a NLMSG_ERROR is received.
    159   // This is useful when the caller needs the error code from kernel.
    160   // Reply packet will be stored in |*response|.
    161   virtual bool SendMessageAndGetSingleResponseOrError(
    162       const NL80211Packet& packet,
    163       std::unique_ptr<const NL80211Packet>* response);
    164 
    165   // Wrapper of |SendMessageAndGetResponses| for messages that trigger
    166   // only a NLMSG_ERROR response
    167   // Returns true if the message is successfully sent and a NLMSG_ERROR response
    168   // comes back, regardless of the error code.
    169   // Error code will be stored in |*error_code|
    170   virtual bool SendMessageAndGetAckOrError(const NL80211Packet& packet,
    171                                            int* error_code);
    172   // Wrapper of |SendMessageAndGetResponses| that returns true iff the response
    173   // is an ACK.
    174   virtual bool SendMessageAndGetAck(const NL80211Packet& packet);
    175 
    176   // Sign up to receive and log multicast events of a specific type.
    177   // |group| is one of the string NL80211_MULTICAST_GROUP_* in nl80211.h.
    178   virtual bool SubscribeToEvents(const std::string& group);
    179 
    180   // Sign up to be notified when new scan results are available.
    181   // |handler| will be called when the kernel signals to wificond that a scan
    182   // has been completed on the given |interface_index|.  See the declaration of
    183   // OnScanResultsReadyHandler for documentation on the semantics of this
    184   // callback.
    185   // Only one handler can be registered per interface index.
    186   // New handler will replace the registered handler if they are for the
    187   // same interface index.
    188   virtual void SubscribeScanResultNotification(
    189       uint32_t interface_index,
    190       OnScanResultsReadyHandler handler);
    191 
    192   // Cancel the sign-up of receiving new scan result notification from
    193   // interface with index |interface_index|.
    194   virtual void UnsubscribeScanResultNotification(uint32_t interface_index);
    195 
    196   // Sign up to be notified when there is MLME event.
    197   // Only one handler can be registered per interface index.
    198   // New handler will replace the registered handler if they are for the
    199   // same interface index.
    200   // NetlinkManager is not going to take ownership of this pointer, and that it
    201   // is the caller's responsibility to make sure that the object exists for the
    202   // duration of the subscription.
    203   virtual void SubscribeMlmeEvent(uint32_t interface_index,
    204                                   MlmeEventHandler* handler);
    205 
    206   // Cancel the sign-up of receiving MLME event notification
    207   // from interface with index |interface_index|.
    208   virtual void UnsubscribeMlmeEvent(uint32_t interface_index);
    209 
    210   // Sign up to be notified when new scan results are available.
    211   // |handler| will be called when the kernel signals to wificond that a
    212   // scheduled scan has been completed on the given |interface_index|.
    213   // See the declaration of OnSchedScanResultsReadyHandler for documentation
    214   // on the semantics of this callback.
    215   // Only one handler can be registered per interface index.
    216   // New handler will replace the registered handler if they are for the
    217   // same interface index.
    218   virtual void SubscribeSchedScanResultNotification(
    219       uint32_t interface_index,
    220       OnSchedScanResultsReadyHandler handler);
    221 
    222   // Cancel the sign-up of receiving new scheduled scan result notification from
    223   // interface with index |interface_index|.
    224   virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index);
    225 
    226   // Sign up to be notified when there is an regulatory domain change.
    227   // Only one handler can be registered per wiphy index.
    228   // New handler will replace the registered handler if they are for the
    229   // same wiphy index.
    230   virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
    231                                         OnRegDomainChangedHandler handler);
    232 
    233   // Cancel the sign-up of receiving regulatory domain change notification
    234   // from wiphy with index |wiphy_index|.
    235   virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);
    236 
    237   // Sign up to be notified when there is a station event.
    238   // Only one handler can be registered per interface index.
    239   // New handler will replace the registered handler if they are for the
    240   // same interface index.
    241   virtual void SubscribeStationEvent(uint32_t interface_index,
    242                                      OnStationEventHandler handler);
    243 
    244   // Cancel the sign-up of receiving station events.
    245   virtual void UnsubscribeStationEvent(uint32_t interface_index);
    246 
    247   // Sign up to be notified when there is a channel switch event.
    248   // Only one handler can be registered per interface index.
    249   // New handler will replace the registered handler if they are for the
    250   // same interface index.
    251   virtual void SubscribeChannelSwitchEvent(
    252       uint32_t interface_index,
    253       OnChannelSwitchEventHandler handler);
    254 
    255   // Cancel the sign-up of receiving channel events.
    256   virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
    257 
    258  private:
    259   bool SetupSocket(android::base::unique_fd* netlink_fd);
    260   bool WatchSocket(android::base::unique_fd* netlink_fd);
    261   void ReceivePacketAndRunHandler(int fd);
    262   bool DiscoverFamilyId();
    263   bool SendMessageInternal(const NL80211Packet& packet, int fd);
    264   void BroadcastHandler(std::unique_ptr<const NL80211Packet> packet);
    265   void OnRegChangeEvent(std::unique_ptr<const NL80211Packet> packet);
    266   void OnMlmeEvent(std::unique_ptr<const NL80211Packet> packet);
    267   void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
    268   void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
    269   void OnChannelSwitchEvent(std::unique_ptr<const NL80211Packet> packet);
    270 
    271   // This handler revceives mapping from NL80211 family name to family id,
    272   // as well as mapping from group name to group id.
    273   // These mappings are allocated by kernel.
    274   void OnNewFamily(std::unique_ptr<const NL80211Packet> packet);
    275 
    276   bool started_;
    277   // We use different sockets for synchronous and asynchronous interfaces.
    278   // Kernel will reply error message when we start a new request in the
    279   // middle of a dump request.
    280   // Using different sockets help us avoid the complexity of message
    281   // rescheduling.
    282   android::base::unique_fd sync_netlink_fd_;
    283   android::base::unique_fd async_netlink_fd_;
    284   EventLoop* event_loop_;
    285 
    286   // This is a collection of message handlers, for each sequence number.
    287   std::map<uint32_t,
    288       std::function<void(std::unique_ptr<const NL80211Packet>)>> message_handlers_;
    289 
    290   // A mapping from interface index to the handler registered to receive
    291   // scan results notifications.
    292   std::map<uint32_t, OnScanResultsReadyHandler> on_scan_result_ready_handler_;
    293   // A mapping from interface index to the handler registered to receive
    294   // scheduled scan results notifications.
    295   std::map<uint32_t, OnSchedScanResultsReadyHandler>
    296       on_sched_scan_result_ready_handler_;
    297 
    298   std::map<uint32_t, MlmeEventHandler*> on_mlme_event_handler_;
    299 
    300   // A mapping from wiphy index to the handler registered to receive
    301   // regulatory domain change notifications.
    302   std::map<uint32_t, OnRegDomainChangedHandler> on_reg_domain_changed_handler_;
    303   std::map<uint32_t, OnStationEventHandler> on_station_event_handler_;
    304   std::map<uint32_t, OnChannelSwitchEventHandler> on_channel_switch_event_handler_;
    305 
    306   // Mapping from family name to family id, and group name to group id.
    307   std::map<std::string, MessageType> message_types_;
    308 
    309   uint32_t sequence_number_;
    310 
    311   DISALLOW_COPY_AND_ASSIGN(NetlinkManager);
    312 };
    313 
    314 }  // namespace wificond
    315 }  // namespace android
    316 
    317 #endif  // WIFICOND_NET_NETLINK_MANAGER_H_
    318