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

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Zolotarev <deathbaba@gmail.com>2011-05-03 18:03:58 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:16:56 +0300
commit1c052fd1e5474b2ebf80636a75a8baa5a3a92bce (patch)
tree348ee748c5b6bbac35a9fbbc9bfe557a5c6b3b5f /platform
parentf91561f65cf2dd54cfafd636c13d0aac567c935c (diff)
Introduced LocationManager with multiple location services support
Added WiFi location service for Mac @TODO filter location events from different sources
Diffstat (limited to 'platform')
-rw-r--r--platform/apple_location_service.mm5
-rw-r--r--platform/location.hpp6
-rw-r--r--platform/location_manager.cpp75
-rw-r--r--platform/platform.pro22
-rw-r--r--platform/platform_tests/platform_tests.pro2
-rw-r--r--platform/qt_location_service.cpp23
-rw-r--r--platform/wifi_info.hpp26
-rw-r--r--platform/wifi_info_mac.mm101
-rw-r--r--platform/wifi_info_windows.cpp34
-rw-r--r--platform/wifi_location_service.cpp96
10 files changed, 359 insertions, 31 deletions
diff --git a/platform/apple_location_service.mm b/platform/apple_location_service.mm
index 216436daec..64d89d7a61 100644
--- a/platform/apple_location_service.mm
+++ b/platform/apple_location_service.mm
@@ -179,8 +179,7 @@ public:
@end
-extern "C" location::LocationService & GetLocationService()
+location::LocationService * CreateAppleLocationService()
{
- static AppleLocationService ls;
- return ls;
+ return new AppleLocationService();
}
diff --git a/platform/location.hpp b/platform/location.hpp
index 45a38bcde7..839475eedf 100644
--- a/platform/location.hpp
+++ b/platform/location.hpp
@@ -67,6 +67,8 @@ namespace location
}
public:
+ virtual ~LocationService() {}
+
void SetGpsObserver(TGpsCallback observer)
{
m_gpsObserver = observer;
@@ -85,4 +87,6 @@ namespace location
}
-extern "C" location::LocationService & GetLocationService();
+extern "C" location::LocationService & GetLocationManager();
+extern "C" location::LocationService * CreateAppleLocationService();
+extern "C" location::LocationService * CreateWiFiLocationService();
diff --git a/platform/location_manager.cpp b/platform/location_manager.cpp
new file mode 100644
index 0000000000..b84c09c7d1
--- /dev/null
+++ b/platform/location_manager.cpp
@@ -0,0 +1,75 @@
+#include "location.hpp"
+
+#include "../std/target_os.hpp"
+#include "../std/vector.hpp"
+#include "../std/bind.hpp"
+
+/// Chooses most accurate data from different position services
+class PositionFilter
+{
+public:
+ GpsInfo const & MostNewAndAccuratePosition()
+ {
+ }
+};
+
+namespace location
+{
+ class LocationManager : public LocationService
+ {
+ vector<LocationService *> m_services;
+
+ void OnGpsUpdate(GpsInfo const & info)
+ {
+ NotifyGpsObserver(info);
+ }
+
+ void OnCompassUpdate(CompassInfo const & info)
+ {
+ NotifyCompassObserver(info);
+ }
+
+ public:
+ LocationManager()
+ {
+ LocationService * service;
+
+#if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_MAC)
+ service = CreateAppleLocationService();
+ service->SetGpsObserver(bind(&LocationManager::OnGpsUpdate, this, _1));
+ service->SetCompassObserver(bind(&LocationManager::OnCompassUpdate, this, _1));
+ m_services.push_back(service);
+#endif
+
+#if defined(OMIM_OS_WINDOWS) || defined(OMIM_OS_MAC)
+ service = CreateWiFiLocationService();
+ service->SetGpsObserver(bind(&LocationManager::OnGpsUpdate, this, _1));
+ m_services.push_back(service);
+#endif
+ }
+
+ virtual ~LocationManager()
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ delete m_services[i];
+ }
+
+ virtual void StartUpdate(bool useAccurateMode)
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ m_services[i]->StartUpdate(useAccurateMode);
+ }
+
+ virtual void StopUpdate()
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ m_services[i]->StopUpdate();
+ }
+ };
+}
+
+location::LocationService & GetLocationManager()
+{
+ static location::LocationManager mgr;
+ return mgr;
+}
diff --git a/platform/platform.pro b/platform/platform.pro
index a0c5d08022..7339bd2b1e 100644
--- a/platform/platform.pro
+++ b/platform/platform.pro
@@ -5,17 +5,20 @@ TEMPLATE = lib
CONFIG += staticlib
ROOT_DIR = ..
-DEPENDENCIES = coding base
+DEPENDENCIES = coding base jansson
include($$ROOT_DIR/common.pri)
QT *= core network
!iphone* {
+ INCLUDEPATH += $$ROOT_DIR/3party/jansson/src
+
SOURCES += \
qtplatform.cpp \
+ wifi_location_service.cpp \
qt_download_manager.cpp \
- qt_download.cpp
+ qt_download.cpp \
HEADERS += \
qt_download_manager.hpp \
@@ -26,10 +29,23 @@ HEADERS += \
platform.hpp \
download_manager.hpp \
location.hpp \
+ wifi_info.hpp
macx|iphone* {
OBJECTIVE_SOURCES += apple_location_service.mm
LIBS += -framework CoreLocation -framework Foundation
} else {
- SOURCES += qt_location_service.cpp
+ SOURCES +=
+}
+
+macx:!iphone* {
+ OBJECTIVE_SOURCES += wifi_info_mac.mm
+ LIBS += -framework CoreWLAN
}
+win32 {
+ SOURCES += wifi_info_windows.cpp
+}
+
+# common sources for all platforms
+SOURCES += \
+ location_manager.cpp \
diff --git a/platform/platform_tests/platform_tests.pro b/platform/platform_tests/platform_tests.pro
index 97c629a0ec..ccb68adc87 100644
--- a/platform/platform_tests/platform_tests.pro
+++ b/platform/platform_tests/platform_tests.pro
@@ -8,7 +8,7 @@ DEPENDENCIES = platform coding base tomcrypt jansson
include($$ROOT_DIR/common.pri)
-INCLUDEPATH += $$ROOT_DIR/3party/jansson $$ROOT_DIR/3party/jansson/src
+INCLUDEPATH += $$ROOT_DIR/3party/jansson/src
QT *= core network
diff --git a/platform/qt_location_service.cpp b/platform/qt_location_service.cpp
deleted file mode 100644
index 35b29875af..0000000000
--- a/platform/qt_location_service.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "location.hpp"
-
-using namespace location;
-
-class QtLocationService : public LocationService
-{
-public:
- virtual void StartUpdate(bool /*useAccurateMode*/)
- {
- // @TODO
- }
-
- virtual void StopUpdate()
- {
- // @TODO
- }
-};
-
-extern "C" location::LocationService & GetLocationService()
-{
- static QtLocationService ls;
- return ls;
-}
diff --git a/platform/wifi_info.hpp b/platform/wifi_info.hpp
new file mode 100644
index 0000000000..7584031f1e
--- /dev/null
+++ b/platform/wifi_info.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "../std/function.hpp"
+
+#include "../std/vector.hpp"
+#include "../std/string.hpp"
+
+class WiFiInfo
+{
+ class Impl;
+ Impl * m_pImpl;
+
+public:
+ struct AccessPoint
+ {
+ string m_bssid; //!< for example, "33-12-03-5b-44-9a"
+ string m_ssid; //!< name for APN
+ string m_signalStrength; //!< for example, "-54"
+ };
+
+ WiFiInfo();
+ ~WiFiInfo();
+
+ typedef boost::function<void (vector<WiFiInfo::AccessPoint> const &)> WifiRequestCallbackT;
+ void RequestWiFiBSSIDs(WifiRequestCallbackT callback);
+};
diff --git a/platform/wifi_info_mac.mm b/platform/wifi_info_mac.mm
new file mode 100644
index 0000000000..2b904c4d18
--- /dev/null
+++ b/platform/wifi_info_mac.mm
@@ -0,0 +1,101 @@
+#include "../std/target_os.hpp"
+#ifdef OMIM_OS_MAC
+
+#include "wifi_info.hpp"
+
+#include "../base/string_utils.hpp"
+
+#import <Foundation/Foundation.h>
+#import <CoreWLAN/CWInterface.h>
+#import <CoreWLAN/CWNetwork.h>
+
+static string AppendZeroIfNeeded(string const & macAddrPart)
+{
+ string res(macAddrPart);
+ if (res.size() == 1)
+ res.insert(0, "0");
+ return res;
+}
+
+@interface WiFiInfoMac : NSObject {
+@private
+ WiFiInfo::WifiRequestCallbackT m_callback;
+ vector<WiFiInfo::AccessPoint> m_accessPoints;
+}
+@end
+//- (id)InitWithCallback:(WiFiInfo::WifiRequestCallbackT)callback;
+@implementation WiFiInfoMac
+
+- (id)InitWithCallback:(WiFiInfo::WifiRequestCallbackT)callback
+{
+ self = [super init];
+ m_callback = callback;
+ [self performSelectorInBackground:@selector(WifiScanThread) withObject:nil];
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+ NSLog(@"Mac OS WiFiInfo selfdestructed successfully");
+}
+
+/// Executed on main thread
+- (void)NotifyGUI
+{
+ m_callback(m_accessPoints);
+ // selfdestruct
+ [self release];
+}
+
+/// new background thread
+- (void)WifiScanThread
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ m_accessPoints.clear();
+
+ CWInterface * iFace = [CWInterface interface];
+ NSArray * nets = [iFace scanForNetworksWithParameters:nil error:nil];
+ for (NSUInteger i = 0; i < [nets count]; ++i)
+ {
+ CWNetwork * net = (CWNetwork *)[nets objectAtIndex:i];
+ WiFiInfo::AccessPoint apn;
+ apn.m_ssid = [net.ssid UTF8String];
+ apn.m_signalStrength = utils::to_string([net.rssi intValue]);
+ // fix formatting for wifi address
+ string const rawBssid = [net.bssid UTF8String];
+ if (!rawBssid.empty())
+ {
+ utils::TokenizeIterator tokIt(rawBssid, ":");
+ apn.m_bssid = AppendZeroIfNeeded(*tokIt);
+ while (!(++tokIt).is_last())
+ {
+ apn.m_bssid += "-";
+ apn.m_bssid += AppendZeroIfNeeded(*tokIt);
+ }
+ }
+ m_accessPoints.push_back(apn);
+ }
+
+ [pool drain];
+
+ [self performSelectorOnMainThread:@selector(NotifyGUI) withObject:nil waitUntilDone:NO];
+}
+@end
+/////////////////////////////////////////////////////////////////////////////
+WiFiInfo::WiFiInfo()
+{
+}
+
+WiFiInfo::~WiFiInfo()
+{
+}
+
+void WiFiInfo::RequestWiFiBSSIDs(WifiRequestCallbackT callback)
+{
+ // it will be self-destroyed when finished
+ [[WiFiInfoMac alloc] InitWithCallback:callback];
+}
+
+#endif
diff --git a/platform/wifi_info_windows.cpp b/platform/wifi_info_windows.cpp
new file mode 100644
index 0000000000..cebaddf390
--- /dev/null
+++ b/platform/wifi_info_windows.cpp
@@ -0,0 +1,34 @@
+#include "wifi_info.hpp"
+
+#if defined(OMIM_OS_WINDOWS)
+ #include "internal/wifi_impl_windows.hpp"
+#elif defined(OMIM_OS_MAC)
+ #include "internal/wifi_impl_mac.hpp"
+#else
+ #error "Please add your OS implementation"
+#endif
+
+class WiFiInfo::Impl
+{
+ WiFiInfo::WifiRequestCallbackT m_callback;
+
+public:
+ void RequestWiFiBSSIDs(WifiRequestCallbackT callback)
+ {
+ }
+};
+
+
+WiFiInfo::WiFiInfo() : m_pImpl(new WiFiInfo::Impl)
+{
+}
+
+WiFiInfo::~WiFiInfo()
+{
+ delete m_pImpl;
+}
+
+void WiFiInfo::RequestWiFiBSSIDs(WifiRequestCallbackT callback)
+{
+ m_pImpl->RequestWiFiBSSIDs(callback);
+}
diff --git a/platform/wifi_location_service.cpp b/platform/wifi_location_service.cpp
new file mode 100644
index 0000000000..a3f9a3803c
--- /dev/null
+++ b/platform/wifi_location_service.cpp
@@ -0,0 +1,96 @@
+#include "location.hpp"
+#include "wifi_info.hpp"
+#include "download_manager.hpp"
+
+#include "../base/logging.hpp"
+
+#include "../std/bind.hpp"
+
+#include "../3party/jansson/myjansson.hpp"
+
+#define MWM_GEOLOCATION_SERVER "http://geolocation.server/"
+
+namespace location
+{
+ class WiFiLocationService : public LocationService
+ {
+ WiFiInfo m_wifiInfo;
+
+ void OnHttpPostFinished(HttpFinishedParams const & result)
+ {
+ // here we should receive json reply with coordinates and accuracy
+ try
+ {
+ my::Json root(result.m_data.c_str());
+ if (json_is_object(root))
+ {
+ json_t * location = json_object_get(root, "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);
+ info.m_horizontalAccuracy = json_real_value(acc);
+ // @TODO introduce flags to mark valid values
+ info.m_status = ERoughMode;
+ NotifyGpsObserver(info);
+ }
+ }
+ }
+ }
+ catch (my::Json::Exception const & e)
+ {
+ LOG(LWARNING, ("Invalid reply from location server:", e.what(), result.m_data));
+ }
+ LOG(LWARNING, ("Invalid reply from location server:", result.m_data));
+ }
+
+ 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 += "}";
+
+ HttpStartParams params;
+ params.m_finish = bind(&WiFiLocationService::OnHttpPostFinished, this, _1);
+ params.m_contentType = "application/json";
+ params.m_postData = jsonRequest;
+ params.m_url = MWM_GEOLOCATION_SERVER;
+ GetDownloadManager().HttpRequest(params);
+ }
+
+ public:
+ virtual void StartUpdate(bool)
+ {
+ m_wifiInfo.RequestWiFiBSSIDs(bind(&WiFiLocationService::OnWifiScanCompleted, this, _1));
+ }
+
+ virtual void StopUpdate()
+ {
+ }
+ };
+}
+
+location::LocationService * CreateWiFiLocationService()
+{
+ return new location::WiFiLocationService();
+}