shill: track the CurrentBSS property reported by wpa_supplicant,
and use it to update WiFiService state.

BUG=chromium-os:22850
TEST=new unit tests, autotests (details below)

Ran the WiFiRoaming suite, and noted the following changes:
- 000ChannelHopBSS regressed. This is due to the fact that we
  now call RemoveNetwork when supplicant gives up on connecting
  to a network. With this in place, we need other mechansism
  to retry the connection. (They will come in later commits.)
- 006BeaconLoss now passes.
- 008Prefer5GHz regressed. This failed because we don't group
  Endpoints into Services. I suspect the previous pass was a
  fluke.
- 009ConnectOnResume passes, even though it should fail until
  we provide retry mechanisms. Logs indicate that supplicant's
  AP scan didn't time out as soon as it should have.

Bonus changes:
- Updated some TESTING and HACKING info.
- Added some comments TODOs about timing out connection
  attempts. These aren't strictly part of CurrentBSS
  tracking, but they fit along the theme of getting our
  wpa_supplicant interactions sorted out.

Change-Id: Iba3495cae89ca835523dbf4d9ebfab5da4a8cc2d
Reviewed-on: https://gerrit.chromium.org/gerrit/11822
Tested-by: mukesh agrawal <quiche@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: mukesh agrawal <quiche@chromium.org>
diff --git a/wifi.h b/wifi.h
index 1dcc110..31c20dc 100644
--- a/wifi.h
+++ b/wifi.h
@@ -43,7 +43,7 @@
   virtual bool TechnologyIs(const Technology::Identifier type) const;
   virtual void LinkEvent(unsigned int flags, unsigned int change);
 
-  // called by SupplicantInterfaceProxy, in response to events from
+  // Called by SupplicantInterfaceProxy, in response to events from
   // wpa_supplicant.
   void BSSAdded(const ::DBus::Path &BSS,
                 const std::map<std::string, ::DBus::Variant> &properties);
@@ -51,12 +51,12 @@
       const std::map<std::string, ::DBus::Variant> &properties);
   void ScanDone();
 
-  // called by WiFiService
+  // Called by WiFiService.
   virtual void ConnectTo(
       WiFiService *service,
       const std::map<std::string, ::DBus::Variant> &service_params);
 
-  // called by Manager
+  // Called by Manager.
   virtual WiFiServiceRefPtr GetService(const KeyValueStore &args, Error *error);
 
  private:
@@ -65,6 +65,7 @@
 
   typedef std::map<const std::string, WiFiEndpointRefPtr> EndpointMap;
   typedef std::map<const std::string, WiFiServiceRefPtr> ServiceMap;
+  typedef std::map<WiFiService *, std::string> ReverseServiceMap;
 
   static const char kManagerErrorPassphraseRequired[];
   static const char kManagerErrorSSIDTooLong[];
@@ -76,15 +77,23 @@
   static const char kManagerErrorUnsupportedServiceMode[];
   static const char kInterfaceStateUnknown[];
 
+  WiFiServiceRefPtr CreateServiceForEndpoint(
+      const WiFiEndpoint &endpoint, bool hidden_ssid);
+  void CurrentBSSChanged(const ::DBus::Path &new_bss);
   WiFiServiceRefPtr FindService(const std::vector<uint8_t> &ssid,
                                 const std::string &mode,
                                 const std::string &security) const;
   ByteArrays GetHiddenSSIDList();
+  void HandleDisconnect();
+  void HandleRoam(const ::DBus::Path &new_bssid);
   // Create services for hidden networks stored in |storage|.  Returns true
   // if any were found, otherwise returns false.
   bool LoadHiddenServices(StoreInterface *storage);
+  void PropertiesChangedTask(
+      const std::map<std::string, ::DBus::Variant> &properties);
   void ScanDoneTask();
   void ScanTask();
+  WiFiServiceRefPtr GetServiceForEndpoint(const WiFiEndpoint &endpoint);
   void StateChanged(const std::string &new_state);
 
   // Store cached copies of singletons for speed/ease of testing.
@@ -94,7 +103,25 @@
   scoped_ptr<SupplicantProcessProxyInterface> supplicant_process_proxy_;
   scoped_ptr<SupplicantInterfaceProxyInterface> supplicant_interface_proxy_;
   EndpointMap endpoint_by_bssid_;
+  // The rpcid used as the key is wpa_supplicant's D-Bus path for the
+  // Endpoint (BSS, in supplicant parlance).
+  EndpointMap endpoint_by_rpcid_;
   ServiceMap service_by_private_id_;
+  // Map from Services to the D-Bus path for the corresponding wpa_supplicant
+  // Network.
+  ReverseServiceMap rpcid_by_service_;
+  bool link_up_;
+  std::vector<WiFiServiceRefPtr> services_;
+  // The Service we are presently connected to. May be NULL is we're not
+  // not connected to any Service.
+  WiFiServiceRefPtr current_service_;
+  // The Service we're attempting to connect to. May be NULL if we're
+  // not attempting to connect to a new Service. If non-NULL, should
+  // be distinct from |current_service_|. (A service should not
+  // simultaneously be both pending, and current.)
+  WiFiServiceRefPtr pending_service_;
+  std::string supplicant_state_;
+  std::string supplicant_bss_;
 
   // Properties
   std::string bgscan_method_;
@@ -102,10 +129,6 @@
   int32 bgscan_signal_threshold_;
   bool scan_pending_;
   uint16 scan_interval_;
-  bool link_up_;
-  std::vector<WiFiServiceRefPtr> services_;
-  WiFiServiceRefPtr pending_service_;
-  std::string supplicant_state_;
 
   DISALLOW_COPY_AND_ASSIGN(WiFi);
 };