Welcome to mirror list, hosted at ThFree Co, Russian Federation.

wifi_location_service.cpp « platform - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 466d2145468a5b85a901412fd96efd8fc6ec4178 (plain)
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"

#define MWM_GEOLOCATION_SERVER "http://geolocation.server/"


namespace location
{
  class WiFiLocationService : public LocationService
  {
    WiFiInfo m_wifiInfo;

    void OnHttpPostFinished(downloader::HttpRequest & response)
    {
      if (response.Status() == downloader::HttpRequest::ECompleted)
      {
        // 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;
          my::Json root(response.Data().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.Data()));
        }
        catch (my::Json::Exception const & e)
        {
          LOG(LWARNING, ("Invalid reply from location server:", e.what(), response.Data()));
        }
      }
      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:
    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);
}