shill: instruct wpa_supplicant to use directed probes

In order to find APs that are configured to hide their
SSIDs, we need to send directed probe messages (which
contain the SSID of interest), rather than broadcast
probes. So instruct supplicant to do so.

Note that we follow flimflam's practice of sending
this instruction unconditionally (whether we're
connecting to a hidden SSID or not).

BUG=chromium-os:23612
TEST=unittests, subset of autotests (below)

autotests run:
PASS WiFiMatFunc.003CheckBcastSSID
PASS WiFiMatFunc.004CheckHiddenSSID
PASS WiFiSecMat.030CheckHidden_WEP
FAIL WiFiSecMat.031CheckHidden_WPA
FAIL WiFiSecMat.032CheckHidden_RSN

Change-Id: I8cb61d2a5a9b56984c27dfffe1d0852ba8c0e9e7
Reviewed-on: https://gerrit.chromium.org/gerrit/12300
Commit-Ready: mukesh agrawal <quiche@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
diff --git a/mock_wifi.h b/mock_wifi.h
index fb3c428..b1bfa42 100644
--- a/mock_wifi.h
+++ b/mock_wifi.h
@@ -37,8 +37,8 @@
   MOCK_METHOD2(GetService,
                WiFiServiceRefPtr(const KeyValueStore &args, Error *error));
   MOCK_METHOD2(ConnectTo,
-               void(WiFiService *,
-                    const std::map<std::string, ::DBus::Variant> &));
+               void(WiFiService *service,
+                    std::map<std::string, ::DBus::Variant> service_params));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockWiFi);
diff --git a/wifi.cc b/wifi.cc
index b0f1c41..f1323c7 100644
--- a/wifi.cc
+++ b/wifi.cc
@@ -264,7 +264,7 @@
 }
 
 void WiFi::ConnectTo(WiFiService *service,
-                     const map<string, DBus::Variant> &service_params) {
+                     map<string, DBus::Variant> service_params) {
   CHECK(service);
   DBus::Path network_path;
 
@@ -272,12 +272,14 @@
   // TODO(quiche): Handle case where there's already a pending
   // connection attempt.
 
-  // TODO(quiche): Set scan_ssid=1 in service_params, like flimflam does?
   try {
     // TODO(quiche): Set a timeout here. In the normal case, we expect
     // that, if wpa_supplicant fails to connect, it will eventually send
     // a signal that its CurrentBSS has changed. But there may be cases
     // where the signal is not sent. (crosbug.com/23206)
+    const uint32_t scan_ssid = 1;  // "True": Use directed probe.
+    service_params[wpa_supplicant::kNetworkPropertyScanSSID].writer().
+        append_uint32(scan_ssid);
     network_path =
         supplicant_interface_proxy_->AddNetwork(service_params);
     // TODO(quiche): Figure out when to remove services from this map.
diff --git a/wifi.h b/wifi.h
index b804282..94877aa 100644
--- a/wifi.h
+++ b/wifi.h
@@ -54,7 +54,7 @@
   // Called by WiFiService.
   virtual void ConnectTo(
       WiFiService *service,
-      const std::map<std::string, ::DBus::Variant> &service_params);
+      std::map<std::string, ::DBus::Variant> service_params);
 
   // Called by Manager.
   virtual WiFiServiceRefPtr GetService(const KeyValueStore &args, Error *error);
diff --git a/wpa_supplicant.cc b/wpa_supplicant.cc
index a0fe09d..37c04d5 100644
--- a/wpa_supplicant.cc
+++ b/wpa_supplicant.cc
@@ -34,6 +34,7 @@
 const char kNetworkModeAdHoc[]       = "ad-hoc";
 const char kNetworkModeAccessPoint[] = "ap";
 const char kNetworkPropertyMode[]   = "mode";
+const char kNetworkPropertyScanSSID[] = "scan_ssid";
 const char kNetworkPropertySSID[]   = "ssid";
 const char kPropertyAuthAlg[]       = "auth_alg";
 const char kPropertyKeyManagement[] = "key_mgmt";
diff --git a/wpa_supplicant.h b/wpa_supplicant.h
index 8b9345c..8240f9a 100644
--- a/wpa_supplicant.h
+++ b/wpa_supplicant.h
@@ -38,6 +38,9 @@
 extern const char kNetworkModeAccessPoint[];
 extern const char kNetworkPropertyMode[];
 extern const char kNetworkPropertySSID[];
+extern const char kNetworkPropertyScanSSID[];
+// TODO(quiche): Make the naming scheme more consistent, by adding the
+// object type to the property names below. (crosbug.com/23656)
 extern const char kPropertyAuthAlg[];
 extern const char kPropertyBSSID[];
 extern const char kPropertyKeyManagement[];