1 //
2 // Copyright (C) 2015 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 #include <sysexits.h>
18 
19 #include <map>
20 #include <memory>
21 #include <string>
22 
23 #include <base/command_line.h>
24 #include <base/logging.h>
25 #include <brillo/any.h>
26 #include <brillo/daemons/dbus_daemon.h>
27 #if defined(__ANDROID__)
28 #include <dbus/service_constants.h>
29 #else
30 #include <chromeos/dbus/service_constants.h>
31 #endif  // __ANDROID__
32 #include <shill/dbus-proxies.h>
33 
34 namespace {
35 
36 namespace switches {
37 static const char kHelp[] = "help";
38 static const char kPassphrase[] = "passphrase";
39 static const char kHexSsid[] = "hex-ssid";
40 static const char kSSID[] = "ssid";
41 static const char kHelpMessage[] = "\n"
42     "Available Switches: \n"
43     "  --ssid=<ssid>\n"
44     "    Set the SSID to configure (mandatory).\n"
45     "  --hex-ssid\n"
46     "    SSID is provided in hexadecimal\n"
47     "  --passphrase=<passprhase>\n"
48     "    Set the passphrase for PSK networks\n";
49 }  // namespace switches
50 
51 }  // namespace
52 
53 class MyClient : public brillo::DBusDaemon {
54  public:
MyClient(std::string ssid,bool is_hex_ssid,std::string psk)55   MyClient(std::string ssid, bool is_hex_ssid, std::string psk)
56       : ssid_(ssid), is_hex_ssid_(is_hex_ssid), psk_(psk) {}
57   ~MyClient() override = default;
58 
59  protected:
OnInit()60   int OnInit() override {
61     int ret = DBusDaemon::OnInit();
62     if (ret != EX_OK) {
63       return ret;
64     }
65     ConfigureAndConnect();
66     Quit();
67     return EX_OK;
68   }
69 
ConfigureAndConnect()70   bool ConfigureAndConnect() {
71     std::unique_ptr<org::chromium::flimflam::ManagerProxy> shill_manager_proxy(
72         new org::chromium::flimflam::ManagerProxy(bus_));
73 
74     dbus::ObjectPath created_service;
75     brillo::ErrorPtr configure_error;
76     if (!shill_manager_proxy->ConfigureService(
77             GetServiceConfig(), &created_service, &configure_error)) {
78       LOG(ERROR) << "Configure service failed";
79       return false;
80     }
81 
82     brillo::ErrorPtr connect_error;
83     std::unique_ptr<org::chromium::flimflam::ServiceProxy> shill_service_proxy(
84         new org::chromium::flimflam::ServiceProxy(bus_,
85                                                   created_service));
86     if (!shill_service_proxy->Connect(&connect_error)) {
87       LOG(ERROR) << "Connect service failed";
88       return false;
89     }
90 
91     // TODO(pstew): Monitor service as it attempts to connect.
92 
93     return true;
94   }
95 
GetServiceConfig()96   std::map<std::string, brillo::Any> GetServiceConfig() {
97     std::map<std::string, brillo::Any> configure_dict;
98     configure_dict[shill::kTypeProperty] = shill::kTypeWifi;
99     if (is_hex_ssid_) {
100       configure_dict[shill::kWifiHexSsid] = ssid_;
101     } else {
102       configure_dict[shill::kSSIDProperty] = ssid_;
103     }
104     if (!psk_.empty()) {
105       configure_dict[shill::kPassphraseProperty] = psk_;
106       configure_dict[shill::kSecurityProperty] = shill::kSecurityPsk;
107     }
108     return configure_dict;
109   }
110 
111   std::string ssid_;
112   bool is_hex_ssid_;
113   std::string psk_;
114 };
115 
main(int argc,char ** argv)116 int main(int argc, char** argv) {
117   base::CommandLine::Init(argc, argv);
118   base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
119 
120   if (cl->HasSwitch(switches::kHelp)) {
121     LOG(INFO) << switches::kHelpMessage;
122     return EXIT_SUCCESS;
123   }
124 
125   if (!cl->HasSwitch(switches::kSSID)) {
126     LOG(ERROR) << "ssid switch is mandatory.";
127     LOG(ERROR) << switches::kHelpMessage;
128     return EXIT_FAILURE;
129   }
130 
131   std::string ssid = cl->GetSwitchValueASCII(switches::kSSID);
132   std::string psk;
133   if (cl->HasSwitch(switches::kPassphrase)) {
134     psk = cl->GetSwitchValueASCII(switches::kPassphrase);
135   }
136   bool hex_ssid = cl->HasSwitch(switches::kHexSsid);
137 
138   MyClient client(ssid, hex_ssid, psk);
139   client.Run();
140   LOG(INFO) << "Process exiting.";
141 
142   return EXIT_SUCCESS;
143 }
144 
145