4 * @brief Connman technology request handling.
6 * @author Ossama Othman @<ossama.othman@@intel.com@>
9 * Copyright 2013 Intel Corporation All Rights Reserved.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation;
14 * version 2.1 of the License.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
27 #include "technology.hpp"
28 #include "connman_manager.hpp"
30 #include <settingsd/response_callback.hpp>
31 #include <settingsd/glib_traits.hpp>
32 #include <settingsd/json_glib_traits.hpp>
33 #include <settingsd/unique_ptr.hpp>
37 ivi::settings::technology::technology(char const * path,
38 GDBusConnection * connection,
39 connman_manager & manager)
40 : connman_("net.connman.Technology", // Interface
48 ivi::settings::technology::handle_request(char const * name,
50 response_callback & response)
52 if (name != nullptr) {
53 if (strcmp(name, "is_enabled") == 0)
54 get_powered(reader, response);
55 else if (strcmp(name, "enable") == 0)
56 set_powered(reader, response);
57 else if (strcmp(name, "scan") == 0)
58 scan(reader, response);
59 else if (strcmp(name, "tethering") == 0)
60 set_tethering(reader, response);
63 std::string("Unrecognized connman technology request name: ")
70 ivi::settings::technology::get_powered(JsonReader * reader,
71 response_callback & response)
74 // The value is the second array element.
75 if (json_reader_read_element(reader, 1)) {
76 null = json_reader_get_null_value(reader);
78 json_reader_end_element(reader);
82 "connman::technology is_enabled parameter is not null.");
86 unique_ptr<GVariant> const property(
87 get_property("Powered", G_VARIANT_TYPE_BOOLEAN, response));
89 if (property != nullptr) {
90 bool const powered = g_variant_get_boolean(property.get());
92 response.send_response(
93 [powered](JsonBuilder * builder)
95 json_builder_set_member_name(builder, "value");
96 json_builder_add_boolean_value(builder, powered);
100 // Error responses handled in get_property() method.
104 ivi::settings::technology::set_powered(JsonReader * reader,
105 response_callback & response)
108 // The value is the second array element.
109 if (json_reader_read_element(reader, 1)) {
110 enable = json_reader_get_boolean_value(reader);
112 json_reader_end_element(reader);
114 constexpr char const name[] = "Powered";
116 GError * error = nullptr;
118 unique_ptr<GVariant> ret(
119 connman_.set_property(name,
120 g_variant_new_boolean(enable),
123 unique_ptr<GError> safe_error(error);
125 if (ret != nullptr) {
126 // Nothing to add to successful response.
127 response.send_response(
128 [](JsonBuilder * /* builder */) {});
129 } else if (error != nullptr) {
131 std::string("Unable to set connman::technology powered state: ")
135 "Malformed connman::technology enable request value.");
140 ivi::settings::technology::set_tethering(JsonReader * reader,
141 response_callback & response)
143 bool const have_enabled = json_reader_read_member(reader, "enabled");
144 bool enabled = false;
146 enabled = json_reader_get_boolean_value(reader);
147 json_reader_end_element(reader);
150 "connman::technology tether \"enabled\" parameter is null.");
151 // We have to call json_reader_end_element() before we return
152 json_reader_end_element(reader);
156 unique_ptr<GError> identifier_error;
157 unique_ptr<GError> passphrase_error;
158 bool identifier_res = true; // Identifier not always needed.
159 bool passphrase_res = true; // Passphrase not always needed.
161 // Check if we have a tethering identifier and passphrase if we are
162 // enabling tethering.
164 // --------------------
165 // Tethering identifier
166 // --------------------
167 char const * ssid = nullptr;
168 if (json_reader_read_member(reader, "ssid")) {
169 ssid = json_reader_get_string_value(reader);
171 json_reader_end_element(reader);
173 if (ssid != nullptr) {
174 constexpr char const identifier[] = "TetheringIdentifier";
175 GError * error = nullptr;
176 identifier_res = this->set_property(identifier,
177 g_variant_new_string(ssid),
180 identifier_error.reset(error);
183 // --------------------
184 // Tethering passphrase
185 // --------------------
186 char const * password = nullptr;
187 if (json_reader_read_member(reader, "password")) {
188 password = json_reader_get_string_value(reader);
190 json_reader_end_element(reader);
192 if (password != nullptr) {
193 constexpr char const passphrase[] = "TetheringPassphrase";
194 GError * error = nullptr;
195 passphrase_res = this->set_property(passphrase,
196 g_variant_new_string(password),
199 passphrase_error.reset(error);
206 // Set "enabled" after passphrase and SSID have been set.
207 // Otherwise Connman may issue an invalid argument error.
208 constexpr char const tethering[] = "Tethering";
209 bool enabled_res = false;
210 GError * error = nullptr;
211 enabled_res = this->set_property(tethering,
212 g_variant_new_boolean(enabled),
215 unique_ptr<GError> enabled_error(error);
217 // ----------------------------
218 // Send final response or error
219 // ----------------------------
220 if (enabled_res && identifier_res && passphrase_res) {
221 response.send_response(
222 [enabled](JsonBuilder * builder) {
223 json_builder_set_member_name(builder, "value");
224 json_builder_add_boolean_value(builder, enabled);
227 char const * failed_part = nullptr;
231 error = enabled_error.get();
232 failed_part = "status";
233 } else if (!identifier_res) {
234 error = identifier_error.get();
235 failed_part = "identifier";
236 } else if (!passphrase_res) {
237 error = passphrase_error.get();
238 failed_part = "passphrase";
241 if (error != nullptr) {
243 std::string("Unable to set connman::technology tethering ")
249 std::string("Malformed connman::technology tethering ")
256 ivi::settings::technology::set_property(char const * name,
258 response_callback /* response */,
261 unique_ptr<GVariant> const ret(
262 connman_.set_property(name, value, error));
264 return ret != nullptr;
268 ivi::settings::technology::scan(JsonReader * reader,
269 response_callback & response)
272 // The value is the second array element.
273 if (json_reader_read_element(reader, 1)) {
274 null = json_reader_get_null_value(reader);
276 json_reader_end_element(reader);
280 "connman::technology scan parameter is not null.");
284 // The scan could take a while.
285 constexpr gint const timeout = 10000; // milliseconds
286 GError * error = nullptr;
288 unique_ptr<GVariant> const ret(
289 g_dbus_proxy_call_sync(connman_.proxy(),
291 nullptr, // No parameters
292 G_DBUS_CALL_FLAGS_NONE,
294 nullptr, // Not cancellable
297 unique_ptr<GError> safe_error(error);
299 if (ret != nullptr) {
300 manager_.get_services(response);
301 } else if (error != nullptr) {
303 std::string("Unable to scan connman::technology: ")
307 "Malformed connman::technology scan request value.");
312 ivi::settings::technology::get_property(char const * name,
313 GVariantType const * type,
314 response_callback & response)
316 GError * error = nullptr;
318 std::string tech(connman_.object_path());
319 auto const n = tech.rfind('/');
320 if (n == std::string::npos) {
322 "Unable to determine Connman technology. Malformed object path.");
327 tech = tech.substr(n + 1);
329 unique_ptr<GVariant> const properties(
330 manager_.get_properties(tech.c_str(), error));
332 unique_ptr<GError> safe_error(error);
334 unique_ptr<GVariant> property;
335 if (properties != nullptr) {
337 g_variant_lookup_value(properties.get(), name, type));
339 if (property == nullptr) {
342 + "error: \"" + name + "\" property lookup failed.");
344 } else if (error != nullptr) {
346 "Unable to get " + tech + "properties: "
349 // This scenario will occur if the technology doesn't exist on
350 // the platform. For example, attempting to retrieve the wifi
351 // "Powered" property on a platform without supported hardware
352 // will result in this error.
354 "Connman technology properties are not available.");
357 return property.release();
364 // indent-tabs-mode: nil