1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include "platform/location_service.hpp"
#include "platform/wifi_info.hpp"
#include "platform/http_request.hpp"
#include "base/logging.hpp"
#include "std/bind.hpp"
#include "std/ctime.hpp"
#include "3party/jansson/myjansson.hpp"
#include "private.h"
namespace location
{
class WiFiLocationService : public LocationService
{
WiFiInfo m_wifiInfo;
void OnHttpPostFinished(downloader::HttpRequest & response)
{
if (response.GetStatus() == downloader::HttpRequest::Status::Completed)
{
// stop requesting wifi updates if reply from server is received
m_wifiInfo.Stop();
// here we should receive json reply with coordinates and accuracy
try
{
bool success = false;
base::Json root(response.GetData().c_str());
if (json_is_object(root.get()))
{
json_t * location = json_object_get(root.get(), "location");
if (json_is_object(location))
{
json_t * lat = json_object_get(location, "latitude");
json_t * lon = json_object_get(location, "longitude");
json_t * acc = json_object_get(location, "accuracy");
if (json_is_real(lat) && json_is_real(lon) && json_is_real(acc))
{
GpsInfo info;
info.m_latitude = json_real_value(lat);
info.m_longitude = json_real_value(lon);
if (IsLatValid(info.m_latitude) && IsLonValid(info.m_latitude))
{
info.m_horizontalAccuracy = json_real_value(acc);
// @TODO introduce flags to mark valid values
info.m_timestamp = static_cast<double>(time(NULL));
info.m_source = location::EGoogle;
m_observer.OnLocationUpdated(info);
success = true;
}
}
}
}
if (!success)
LOG(LWARNING, ("Invalid reply from location server:", response.GetData()));
}
catch (base::Json::Exception const & e)
{
LOG(LWARNING, ("Invalid reply from location server:", e.what(), response.GetData()));
}
}
else
LOG(LWARNING, ("Location server is not available"));
// free memory
delete &response;
}
void OnWifiScanCompleted(vector<WiFiInfo::AccessPoint> const & accessPoints)
{
string jsonRequest("{\"version\":\"1.1.0\"");
if (accessPoints.size())
jsonRequest += ",\"wifi_towers\":[";
for (size_t i = 0; i < accessPoints.size(); ++i)
{
jsonRequest += "{\"mac_address\":\"";
jsonRequest += accessPoints[i].m_bssid;
jsonRequest += "\",\"ssid\":\"";
jsonRequest += accessPoints[i].m_ssid;
jsonRequest += "\",\"signal_strength\":";
jsonRequest += accessPoints[i].m_signalStrength;
jsonRequest += "},";
}
if (accessPoints.size())
jsonRequest[jsonRequest.size() - 1] = ']';
jsonRequest += "}";
// memory will be freed in callback
downloader::HttpRequest::PostJson(MWM_GEOLOCATION_SERVER,
jsonRequest,
bind(&WiFiLocationService::OnHttpPostFinished, this, _1));
}
public:
explicit WiFiLocationService(LocationObserver & observer) : LocationService(observer)
{
}
virtual void Start()
{
m_wifiInfo.RequestWiFiBSSIDs(bind(&WiFiLocationService::OnWifiScanCompleted, this, _1));
}
virtual void Stop()
{
m_wifiInfo.Stop();
}
};
}
extern "C" location::LocationService * CreateWiFiLocationService(location::LocationObserver & observer)
{
return new location::WiFiLocationService(observer);
}
|