4 * @brief Connman-based clock settings.
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
29 #include <settingsd/response_callback.hpp>
30 #include <settingsd/glib_traits.hpp>
31 #include <settingsd/json_glib_traits.hpp>
32 #include <settingsd/smart_ptr.hpp>
35 #include <boost/lexical_cast.hpp>
38 ivi::settings::clock::clock(event_callback const & e)
39 : connman_("net.connman.Clock", "/", e)
43 ivi::settings::clock::~clock()
48 ivi::settings::clock::id() const
50 static std::string const the_id("clock");
56 ivi::settings::clock::handle_request(std::string request,
57 response_callback response)
59 smart_ptr<JsonParser> const parser(json_parser_new());
60 json_parser_load_from_data(parser.get(), request.c_str(), -1, nullptr);
62 JsonReader * const reader =
63 json_reader_new(json_parser_get_root(parser.get()));
65 smart_ptr<JsonReader> safe_reader(reader);
67 char const * name = nullptr;
68 if (json_reader_read_member(reader, "name")) {
69 name = json_reader_get_string_value(reader);
71 json_reader_end_member(reader);
73 if (name != nullptr) {
74 GError * error = nullptr;
77 if (strcmp(name, "time") == 0)
78 success = set_time(reader, response, error);
79 else if (strcmp(name, "time_updates") == 0)
80 success = set_updates("TimeUpdates", reader, response, error);
81 else if (strcmp(name, "timezone") == 0)
82 success = set_timezone(reader, response, error);
83 else if (strcmp(name, "timezone_updates") == 0)
84 success = set_updates("TimezoneUpdates", reader, response, error);
85 else if (strcmp(name, "is_time_updates_auto") == 0)
86 is_updates_auto("TimeUpdates", reader, response, error);
87 else if (strcmp(name, "is_timezone_updates_auto") == 0)
88 is_updates_auto("TimezoneUpdates", reader, response, error);
91 "Unrecognized " + id() + " request name: " + name);
94 smart_ptr<GError> safe_error(error);
98 // Nothing to add to successful response.
99 response.send_response(
100 [](JsonBuilder * /* builder */) {});
102 } else if (error != nullptr) {
104 std::string("Unable to set ") + name + ": " + error->message);
107 // If success is false and error == nullptr a succesful response
108 // was sent by one of the functions above, e.g. is_update_auto().
112 "Malformed " + id() + " request: \"name\" is missing.");
117 ivi::settings::clock::set_time(JsonReader * reader,
118 response_callback response,
122 if (json_reader_read_member(reader, "value")) {
124 * @bug @c json_read_get_int_value() returns a signed 64 bit
125 * integer. However, the connman clock API expects an
126 * unsigned 64 bit integer. This means we cannot set time
127 * values before the Unix epoch (< 0) or greater than
128 * (2^63)-1, i.e the largest signed 64 bit integer.
130 time = json_reader_get_int_value(reader);
133 json_reader_end_member(reader);
135 bool success = false;
138 // Note that the connman clock API expects an unsigned 64 bit
139 // integer containing seconds since the Unix epoch. We cast the
140 // positive int64_t value to an uint64_t value. There is no
141 // chance of overflow in this case.
144 g_variant_new_uint64(static_cast<uint64_t>(time)),
148 response.send_error("Time value is earlier than epoch (negative): "
149 + boost::lexical_cast<std::string>(time));
156 ivi::settings::clock::set_timezone(JsonReader * reader,
157 response_callback response,
160 bool success = false;
162 if (json_reader_read_member(reader, "value")) {
163 char const * const timezone = json_reader_get_string_value(reader);
164 success = this->set_property("Timezone",
165 g_variant_new_string(timezone),
170 json_reader_end_member(reader);
176 ivi::settings::clock::set_updates(char const * name,
178 response_callback response,
181 bool success = false;
183 char const * updates = nullptr;
184 if (json_reader_read_member(reader, "value")) {
185 updates = json_reader_get_string_value(reader);
187 json_reader_end_member(reader);
189 if (updates == nullptr
190 || (strcmp(updates, "manual") != 0
191 && strcmp(updates, "auto") != 0)) {
192 response.send_error(id()
193 + ": updates value not \"manual\" "
195 + (updates == nullptr
199 smart_ptr<GVariant> const current_value(get_property(name, error));
201 if (current_value != nullptr) {
203 g_variant_get_string(current_value.get(), nullptr);
205 if (strcmp(value, updates) == 0) {
206 // Already set. Just return success, otherwise we'll timeout
207 // waiting for a PropertyChanged signal that'll never come.
212 success = set_property(name,
213 g_variant_new_string(updates),
222 ivi::settings::clock::is_updates_auto(char const * name,
224 response_callback response,
228 if (json_reader_read_member(reader, "value")) {
229 null = json_reader_get_null_value(reader);
231 json_reader_end_member(reader);
234 response.send_error(std::string(name) + " query parameter is not null.");
238 smart_ptr<GVariant> const current_value(get_property(name, error));
240 if (current_value != nullptr) {
242 g_variant_get_string(current_value.get(), nullptr);
244 bool const is_auto = (strcmp(value, "auto") == 0);
246 response.send_response(
247 [is_auto](JsonBuilder * builder)
249 json_builder_set_member_name(builder, "value");
250 json_builder_add_boolean_value(builder, is_auto);
256 ivi::settings::clock::set_property(char const * name,
258 response_callback /* response */,
261 smart_ptr<GVariant> const ret(
262 connman_.set_property(name, value, error));
264 return ret.get() != nullptr;
268 ivi::settings::clock::get_property(char const * property,
269 GError *& error) const
271 constexpr gint const timeout = 5000; // milliseconds
273 smart_ptr<GVariant> const dictionary(
274 g_dbus_proxy_call_sync(connman_.proxy(),
276 nullptr, // No parameters
277 G_DBUS_CALL_FLAGS_NONE,
279 nullptr, // Not cancellable
282 smart_ptr<GVariant> value;
284 if (dictionary != nullptr) {
285 GVariantIter * i = nullptr;
286 g_variant_get(dictionary.get(), "(a{sv})", &i);
287 smart_ptr<GVariantIter> const iter(i);
289 gchar * pname = nullptr;
290 GVariant * pvalue = nullptr;
292 while (g_variant_iter_next(i, "{sv}", &pname, &pvalue)) {
293 smart_ptr<gchar> const name(pname);
296 // Check if this is the property we want.
297 if (strcmp(name.get(), property) == 0)
302 return value.release();
309 // indent-tabs-mode: nil