diff options
author | Ningyuan Wang | 2016-12-02 17:09:53 -0600 |
---|---|---|
committer | Ningyuan Wang | 2017-02-16 16:12:26 -0600 |
commit | 495e5b35c9b7231574658f273f2aa061e46d0a08 (patch) | |
tree | ed1876f32bc21179953da0618dd7251c2ee0b565 /net | |
parent | b516002a75893408d9089c9443856968a84610fb (diff) | |
download | system-connectivity-wificond-495e5b35c9b7231574658f273f2aa061e46d0a08.tar.gz system-connectivity-wificond-495e5b35c9b7231574658f273f2aa061e46d0a08.tar.xz system-connectivity-wificond-495e5b35c9b7231574658f273f2aa061e46d0a08.zip |
Monitor regulatory domain change
This adds the function of regulatory domain change monitoring
on wificond.
This also allows wificond to print the supported bands/channels
upon regulatory domain change.
This also adds the corresponding unit tests.
Bug: 35150708
Test: compile, unit tests, manual tests
Change-Id: Idbcf9ebf25f4e7be3b371ec3531b6b52303476e8
Diffstat (limited to 'net')
-rw-r--r-- | net/netlink_manager.cpp | 65 | ||||
-rw-r--r-- | net/netlink_manager.h | 27 | ||||
-rw-r--r-- | net/netlink_utils.cpp | 11 | ||||
-rw-r--r-- | net/netlink_utils.h | 13 |
4 files changed, 115 insertions, 1 deletions
diff --git a/net/netlink_manager.cpp b/net/netlink_manager.cpp index 45ecc18..11d2cab 100644 --- a/net/netlink_manager.cpp +++ b/net/netlink_manager.cpp | |||
@@ -216,9 +216,15 @@ bool NetlinkManager::Start() { | |||
216 | if (!WatchSocket(&async_netlink_fd_)) { | 216 | if (!WatchSocket(&async_netlink_fd_)) { |
217 | return false; | 217 | return false; |
218 | } | 218 | } |
219 | // Subscribe kernel NL80211 broadcast of regulatory changes. | ||
220 | if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_REG)) { | ||
221 | return false; | ||
222 | } | ||
223 | // Subscribe kernel NL80211 broadcast of scanning events. | ||
219 | if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_SCAN)) { | 224 | if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_SCAN)) { |
220 | return false; | 225 | return false; |
221 | } | 226 | } |
227 | // Subscribe kernel NL80211 broadcast of MLME events. | ||
222 | if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) { | 228 | if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) { |
223 | return false; | 229 | return false; |
224 | } | 230 | } |
@@ -490,6 +496,55 @@ void NetlinkManager::BroadcastHandler(unique_ptr<const NL80211Packet> packet) { | |||
490 | OnMlmeEvent(std::move(packet)); | 496 | OnMlmeEvent(std::move(packet)); |
491 | return; | 497 | return; |
492 | } | 498 | } |
499 | if (command == NL80211_CMD_REG_CHANGE) { | ||
500 | OnRegChangeEvent(std::move(packet)); | ||
501 | return; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | void NetlinkManager::OnRegChangeEvent(unique_ptr<const NL80211Packet> packet) { | ||
506 | uint32_t wiphy_index; | ||
507 | if (!packet->GetAttributeValue(NL80211_ATTR_WIPHY, &wiphy_index)) { | ||
508 | LOG(ERROR) << "Failed to get wiphy index from reg changed message"; | ||
509 | return; | ||
510 | } | ||
511 | |||
512 | uint8_t reg_type; | ||
513 | if (!packet->GetAttributeValue(NL80211_ATTR_REG_TYPE, ®_type)) { | ||
514 | LOG(ERROR) << "Failed to get NL80211_ATTR_REG_TYPE"; | ||
515 | } | ||
516 | |||
517 | string country_code; | ||
518 | // NL80211_REGDOM_TYPE_COUNTRY means the regulatory domain set is one that | ||
519 | // pertains to a specific country | ||
520 | if (reg_type == NL80211_REGDOM_TYPE_COUNTRY) { | ||
521 | if (!packet->GetAttributeValue(NL80211_ATTR_REG_ALPHA2, &country_code)) { | ||
522 | LOG(ERROR) << "Failed to get NL80211_ATTR_REG_ALPHA2"; | ||
523 | return; | ||
524 | } | ||
525 | } else if (reg_type == NL80211_REGDOM_TYPE_WORLD || | ||
526 | reg_type == NL80211_REGDOM_TYPE_CUSTOM_WORLD || | ||
527 | reg_type == NL80211_REGDOM_TYPE_INTERSECTION) { | ||
528 | // NL80211_REGDOM_TYPE_WORLD refers to the world regulartory domain. | ||
529 | // NL80211_REGDOM_TYPE_CUSTOM_WORLD refers to the driver specific world | ||
530 | // regulartory domain. | ||
531 | // NL80211_REGDOM_TYPE_INTERSECTION refers to an intersection between two | ||
532 | // regulatory domains: | ||
533 | // The previously set regulatory domain on the system and the last accepted | ||
534 | // regulatory domain request to be processed. | ||
535 | country_code = ""; | ||
536 | } else { | ||
537 | LOG(ERROR) << "Unknown type of regulatory domain change: " << (int)reg_type; | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | auto handler = on_reg_domain_changed_handler_.find(wiphy_index); | ||
542 | if (handler == on_reg_domain_changed_handler_.end()) { | ||
543 | LOG(DEBUG) << "No handler for country code changed event from wiphy" | ||
544 | << "with index: " << wiphy_index; | ||
545 | return; | ||
546 | } | ||
547 | handler->second(country_code); | ||
493 | } | 548 | } |
494 | 549 | ||
495 | void NetlinkManager::OnMlmeEvent(unique_ptr<const NL80211Packet> packet) { | 550 | void NetlinkManager::OnMlmeEvent(unique_ptr<const NL80211Packet> packet) { |
@@ -590,6 +645,16 @@ void NetlinkManager::OnScanResultsReady(unique_ptr<const NL80211Packet> packet) | |||
590 | handler->second(if_index, aborted, ssids, freqs); | 645 | handler->second(if_index, aborted, ssids, freqs); |
591 | } | 646 | } |
592 | 647 | ||
648 | void NetlinkManager::SubscribeRegDomainChange( | ||
649 | uint32_t wiphy_index, | ||
650 | OnRegDomainChangedHandler handler) { | ||
651 | on_reg_domain_changed_handler_[wiphy_index] = handler; | ||
652 | } | ||
653 | |||
654 | void NetlinkManager::UnsubscribeRegDomainChange(uint32_t wiphy_index) { | ||
655 | on_reg_domain_changed_handler_.erase(wiphy_index); | ||
656 | } | ||
657 | |||
593 | void NetlinkManager::SubscribeScanResultNotification( | 658 | void NetlinkManager::SubscribeScanResultNotification( |
594 | uint32_t interface_index, | 659 | uint32_t interface_index, |
595 | OnScanResultsReadyHandler handler) { | 660 | OnScanResultsReadyHandler handler) { |
diff --git a/net/netlink_manager.h b/net/netlink_manager.h index 9d29128..72b7d31 100644 --- a/net/netlink_manager.h +++ b/net/netlink_manager.h | |||
@@ -73,6 +73,17 @@ typedef std::function<void( | |||
73 | uint32_t interface_index, | 73 | uint32_t interface_index, |
74 | bool scan_stopped)> OnSchedScanResultsReadyHandler; | 74 | bool scan_stopped)> OnSchedScanResultsReadyHandler; |
75 | 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 | |||
76 | class NetlinkManager { | 87 | class NetlinkManager { |
77 | public: | 88 | public: |
78 | explicit NetlinkManager(EventLoop* event_loop); | 89 | explicit NetlinkManager(EventLoop* event_loop); |
@@ -181,6 +192,17 @@ class NetlinkManager { | |||
181 | // interface with index |interface_index|. | 192 | // interface with index |interface_index|. |
182 | virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index); | 193 | virtual void UnsubscribeSchedScanResultNotification(uint32_t interface_index); |
183 | 194 | ||
195 | // Sign up to be notified when there is an regulatory domain change. | ||
196 | // Only one handler can be registered per wiphy index. | ||
197 | // New handler will replace the registered handler if they are for the | ||
198 | // same wiphy index. | ||
199 | virtual void SubscribeRegDomainChange(uint32_t wiphy_index, | ||
200 | OnRegDomainChangedHandler handler); | ||
201 | |||
202 | // Cancel the sign-up of receiving regulatory domain change notification | ||
203 | // from wiphy with index |wiphy_index|. | ||
204 | virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index); | ||
205 | |||
184 | private: | 206 | private: |
185 | bool SetupSocket(android::base::unique_fd* netlink_fd); | 207 | bool SetupSocket(android::base::unique_fd* netlink_fd); |
186 | bool WatchSocket(android::base::unique_fd* netlink_fd); | 208 | bool WatchSocket(android::base::unique_fd* netlink_fd); |
@@ -188,6 +210,7 @@ class NetlinkManager { | |||
188 | bool DiscoverFamilyId(); | 210 | bool DiscoverFamilyId(); |
189 | bool SendMessageInternal(const NL80211Packet& packet, int fd); | 211 | bool SendMessageInternal(const NL80211Packet& packet, int fd); |
190 | void BroadcastHandler(std::unique_ptr<const NL80211Packet> packet); | 212 | void BroadcastHandler(std::unique_ptr<const NL80211Packet> packet); |
213 | void OnRegChangeEvent(std::unique_ptr<const NL80211Packet> packet); | ||
191 | void OnMlmeEvent(std::unique_ptr<const NL80211Packet> packet); | 214 | void OnMlmeEvent(std::unique_ptr<const NL80211Packet> packet); |
192 | void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet); | 215 | void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet); |
193 | void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet); | 216 | void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet); |
@@ -221,6 +244,10 @@ class NetlinkManager { | |||
221 | 244 | ||
222 | std::map<uint32_t, MlmeEventHandler*> on_mlme_event_handler_; | 245 | std::map<uint32_t, MlmeEventHandler*> on_mlme_event_handler_; |
223 | 246 | ||
247 | // A mapping from wiphy index to the handler registered to receive | ||
248 | // regulatory domain change notifications. | ||
249 | std::map<uint32_t, OnRegDomainChangedHandler> on_reg_domain_changed_handler_; | ||
250 | |||
224 | // Mapping from family name to family id, and group name to group id. | 251 | // Mapping from family name to family id, and group name to group id. |
225 | std::map<std::string, MessageType> message_types_; | 252 | std::map<std::string, MessageType> message_types_; |
226 | 253 | ||
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp index bcd369a..1b8d2a3 100644 --- a/net/netlink_utils.cpp +++ b/net/netlink_utils.cpp | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <android-base/logging.h> | 25 | #include <android-base/logging.h> |
26 | 26 | ||
27 | #include "wificond/net/mlme_event_handler.h" | 27 | #include "wificond/net/mlme_event_handler.h" |
28 | #include "wificond/net/netlink_manager.h" | ||
29 | #include "wificond/net/nl80211_packet.h" | 28 | #include "wificond/net/nl80211_packet.h" |
30 | 29 | ||
31 | using std::string; | 30 | using std::string; |
@@ -372,5 +371,15 @@ void NetlinkUtils::UnsubscribeMlmeEvent(uint32_t interface_index) { | |||
372 | netlink_manager_->UnsubscribeMlmeEvent(interface_index); | 371 | netlink_manager_->UnsubscribeMlmeEvent(interface_index); |
373 | } | 372 | } |
374 | 373 | ||
374 | void NetlinkUtils::SubscribeRegDomainChange( | ||
375 | uint32_t wiphy_index, | ||
376 | OnRegDomainChangedHandler handler) { | ||
377 | netlink_manager_->SubscribeRegDomainChange(wiphy_index, handler); | ||
378 | } | ||
379 | |||
380 | void NetlinkUtils::UnsubscribeRegDomainChange(uint32_t wiphy_index) { | ||
381 | netlink_manager_->UnsubscribeRegDomainChange(wiphy_index); | ||
382 | } | ||
383 | |||
375 | } // namespace wificond | 384 | } // namespace wificond |
376 | } // namespace android | 385 | } // namespace android |
diff --git a/net/netlink_utils.h b/net/netlink_utils.h index 7fb2a2e..dbdb00a 100644 --- a/net/netlink_utils.h +++ b/net/netlink_utils.h | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #include <android-base/macros.h> | 25 | #include <android-base/macros.h> |
26 | 26 | ||
27 | #include "wificond/net/netlink_manager.h" | ||
28 | |||
27 | namespace android { | 29 | namespace android { |
28 | namespace wificond { | 30 | namespace wificond { |
29 | 31 | ||
@@ -151,6 +153,17 @@ class NetlinkUtils { | |||
151 | // from interface with index |interface_index|. | 153 | // from interface with index |interface_index|. |
152 | virtual void UnsubscribeMlmeEvent(uint32_t interface_index); | 154 | virtual void UnsubscribeMlmeEvent(uint32_t interface_index); |
153 | 155 | ||
156 | // Sign up to be notified when there is an regulatory domain change. | ||
157 | // Only one handler can be registered per wiphy index. | ||
158 | // New handler will replace the registered handler if they are for the | ||
159 | // same wiphy index. | ||
160 | virtual void SubscribeRegDomainChange(uint32_t wiphy_index, | ||
161 | OnRegDomainChangedHandler handler); | ||
162 | |||
163 | // Cancel the sign-up of receiving regulatory domain change notification | ||
164 | // from wiphy with index |wiphy_index|. | ||
165 | virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index); | ||
166 | |||
154 | private: | 167 | private: |
155 | bool ParseBandInfo(const NL80211Packet* const packet, | 168 | bool ParseBandInfo(const NL80211Packet* const packet, |
156 | BandInfo* out_band_info); | 169 | BandInfo* out_band_info); |