26
28
#include <core/net/http/response.h>
27
29
#include <core/net/http/status.h>
29
#include <json/json.h>
33
namespace json = Json;
35
Object Object::parse_from_string(const std::string& s)
37
return Object{json_tokener_parse(s.c_str())};
40
Object Object::create_array()
42
return Object{json_object_new_array()};
45
Object Object::create_object()
47
return Object{json_object_new_object()};
50
Object::Object(json_object* object) : object(object)
54
Object::Object(const Object& rhs) : object(json_object_get(rhs.object))
60
json_object_put(object);
63
Object& Object::operator=(const Object& rhs)
65
json_object_put(object);
66
object = json_object_get(rhs.object);
71
std::string Object::to_plain_string()
75
json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN)
79
Object Object::get(const std::string& name) const
81
json_object* result{nullptr};
83
json_object_object_get_ex(object, name.c_str(), &result);
85
if (not result) throw std::out_of_range
90
return Object{result};
95
template<json_type type> void throw_if_type_mismatch(json_object* object)
97
if (not json_object_is_type(object, type)) throw std::logic_error
103
// Attempts to resolve the object to a boolean value.
104
// Throws std::logic_error in case of type mismatches.
105
bool Object::to_bool() const
107
throw_if_type_mismatch<json_type_boolean>(object);
108
return json_object_get_boolean(object);
111
std::int32_t Object::to_int32() const
113
throw_if_type_mismatch<json_type_int>(object);
114
return json_object_get_int(object);
117
std::int64_t Object::to_int64() const
119
throw_if_type_mismatch<json_type_int>(object);
120
return json_object_get_int64(object);
123
double Object::to_double() const
125
throw_if_type_mismatch<json_type_double>(object);
126
return json_object_get_double(object);
129
std::string Object::to_string() const
131
throw_if_type_mismatch<json_type_string>(object);
132
return std::string{json_object_get_string(object)};
135
void Object::put_array(const std::string& name, Object array)
137
json_object_object_add(object, name.c_str(), json_object_get(array.object));
140
void Object::put_object(const std::string& name, Object other)
142
json_object_object_add(object, name.c_str(), json_object_get(other.object));
145
void Object::put_boolean(const std::string& name, bool value)
147
json_object_object_add(object, name.c_str(), json_object_new_boolean(value));
150
void Object::put_int32(const std::string& name, std::int32_t value)
152
json_object_object_add(object, name.c_str(), json_object_new_int(value));
155
void Object::put_int64(const std::string& name, std::int64_t value)
157
json_object_object_add(object, name.c_str(), json_object_new_int64(value));
160
void Object::put_double(const std::string& name, double value)
162
json_object_object_add(object, name.c_str(), json_object_new_double(value));
165
void Object::put_string(const std::string& name, const std::string& value)
167
json_object_object_add(object, name.c_str(), json_object_new_string_len(value.c_str(), value.size()));
170
std::size_t Object::array_size() const
172
throw_if_type_mismatch<json_type_array>(object);
173
return json_object_array_length(object);
176
void Object::append(Object other)
178
throw_if_type_mismatch<json_type_array>(object);
179
json_object_array_add(object, json_object_get(other.object));
182
void Object::put_object_for_index(std::size_t index, Object other)
184
throw_if_type_mismatch<json_type_array>(object);
185
json_object_array_put_idx(object, index, json_object_get(other.object));
188
// Queries the object at index 'index'.
189
// Throws std::logic_error if the object does not represent an array.
190
// Throws std::out_of_range if the index exceeds the bounds of the array.
191
Object Object::get_object_for_index(std::size_t index)
193
throw_if_type_mismatch<json_type_array>(object);
196
json_object_get(json_object_array_get_idx(object, index))
34
201
namespace location = com::ubuntu::location;
36
203
location::service::ichnaea::Reporter::Reporter(
79
246
const std::vector<location::connectivity::WirelessNetwork::Ptr>& wifis,
80
247
const std::vector<location::connectivity::RadioCell::Ptr>& cells)
249
json::Object submit = json::Object::create_object();
250
json::Object items = json::Object::create_array();
251
json::Object item = json::Object::create_object();
85
item[Json::radio] = "gsm"; // We currently only support gsm radio types.
86
item[Json::lat] = update.value.latitude.value.value();
87
item[Json::lon] = update.value.longitude.value.value();
253
item.put_string(Json::radio, "gsm"); // We currently only support gsm radio types.
254
item.put_double(Json::lat, update.value.latitude.value.value());
255
item.put_double(Json::lon, update.value.longitude.value.value());
89
257
if (update.value.accuracy.horizontal)
90
item[Json::accuracy] = (*update.value.accuracy.horizontal).value();
258
item.put_double(Json::accuracy, (*update.value.accuracy.horizontal).value());
91
259
if (update.value.altitude)
92
item[Json::altitude] = (*update.value.altitude).value.value();
260
item.put_double(Json::altitude, (*update.value.altitude).value.value());
93
261
if (update.value.accuracy.vertical)
94
item[Json::altitude_accuracy] = (*update.value.accuracy.vertical).value();
262
item.put_double(Json::altitude_accuracy, (*update.value.accuracy.vertical).value());
96
264
if (!wifis.empty())
97
ichnaea::Reporter::convert_wifis_to_json(wifis, item[Json::wifi]);
266
json::Object w = json::Object::create_array();
267
ichnaea::Reporter::convert_wifis_to_json(wifis, w);
268
item.put_array(Json::wifi, w);
99
271
if (!cells.empty())
100
ichnaea::Reporter::convert_cells_to_json(cells, item[Json::cell]);
102
submit[Json::items].append(item);
104
json::FastWriter writer;
106
VLOG(10) << "Submitting: " << writer.write(submit);
273
json::Object c = json::Object::create_array();
274
ichnaea::Reporter::convert_cells_to_json(cells, c);
275
item.put_array(Json::cell, c);
279
submit.put_array(Json::items, items);
281
auto string_representation = submit.to_plain_string();
283
VLOG(10) << "Submitting: " << string_representation;
108
285
auto request = http_client->post(
109
286
submit_request_config,
110
writer.write(submit),
287
string_representation,
111
288
core::net::http::ContentType::json);
113
290
request->async_execute(
152
329
void location::service::ichnaea::Reporter::convert_cells_to_json(
153
330
const std::vector<location::connectivity::RadioCell::Ptr>& cells,
154
json::Value& destination)
331
json::Object& destination)
156
333
for (const auto& cell : cells)
335
json::Object c = json::Object::create_object();
160
337
switch (cell->type())
162
339
case connectivity::RadioCell::Type::gsm:
164
c[Json::Cell::radio] = "gsm";
341
c.put_string(Json::Cell::radio, "gsm");
166
343
const auto& details = cell->gsm();
168
345
if (details.mobile_country_code.is_valid())
169
c[Json::Cell::mcc] = details.mobile_country_code.get();
346
c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
170
347
if (details.mobile_network_code.is_valid())
171
c[Json::Cell::mnc] = details.mobile_network_code.get();
348
c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
172
349
if (details.location_area_code.is_valid())
173
c[Json::Cell::lac] = details.location_area_code.get();
350
c.put_int32(Json::Cell::lac, details.location_area_code.get());
174
351
if (details.id.is_valid())
175
c[Json::Cell::cid] = details.id.get();
352
c.put_int32(Json::Cell::cid, details.id.get());
176
353
if (details.strength.is_valid())
177
c[Json::Cell::asu] = details.strength.get();
354
c.put_int32(Json::Cell::asu, details.strength.get());
181
358
case connectivity::RadioCell::Type::umts:
183
c[Json::Cell::radio] = "umts";
360
c.put_string(Json::Cell::radio, "umts");
185
362
const auto& details = cell->umts();
187
364
if (details.mobile_country_code.is_valid())
188
c[Json::Cell::mcc] = details.mobile_country_code.get();
365
c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
189
366
if (details.mobile_network_code.is_valid())
190
c[Json::Cell::mnc] = details.mobile_network_code.get();
367
c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
191
368
if (details.location_area_code.is_valid())
192
c[Json::Cell::lac] = details.location_area_code.get();
369
c.put_int32(Json::Cell::lac, details.location_area_code.get());
193
370
if (details.id.is_valid())
194
c[Json::Cell::cid] = details.id.get();
371
c.put_int32(Json::Cell::cid, details.id.get());
195
372
if (details.strength.is_valid())
196
c[Json::Cell::asu] = details.strength.get();
373
c.put_int32(Json::Cell::asu, details.strength.get());
200
377
case connectivity::RadioCell::Type::lte:
202
c[Json::Cell::radio] = "lte";
379
c.put_string(Json::Cell::radio, "lte");
204
381
const auto& details = cell->lte();
206
383
if (details.mobile_country_code.is_valid())
207
c[Json::Cell::mcc] = details.mobile_country_code.get();
384
c.put_int32(Json::Cell::mcc, details.mobile_country_code.get());
208
385
if (details.mobile_network_code.is_valid())
209
c[Json::Cell::mnc] = details.mobile_network_code.get();
386
c.put_int32(Json::Cell::mnc, details.mobile_network_code.get());
210
387
if (details.tracking_area_code.is_valid())
211
c[Json::Cell::lac] = details.tracking_area_code.get();
388
c.put_int32(Json::Cell::lac, details.tracking_area_code.get());
212
389
if (details.id.is_valid())
213
c[Json::Cell::cid] = details.id.get();
390
c.put_int32(Json::Cell::cid, details.id.get());
214
391
if (details.physical_id.is_valid())
215
c[Json::Cell::psc] = details.physical_id.get();
392
c.put_int32(Json::Cell::psc, details.physical_id.get());
216
393
if (details.strength.is_valid())
217
c[Json::Cell::asu] = details.strength.get();
394
c.put_int32(Json::Cell::asu, details.strength.get());