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:
authorSergey Yershov <yershov@corp.mail.ru>2016-10-21 19:54:02 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-10-25 17:33:35 +0300
commit1f1d0a58713f4f4817827aa108f75e0657014813 (patch)
treeeff7e58b59addf80982788177617215f4f840622 /tracking
parent8314310c0e8a63bed40abf95b7741b10c24521eb (diff)
[tracking] Made tracking work
Diffstat (limited to 'tracking')
-rw-r--r--tracking/connection.cpp31
-rw-r--r--tracking/connection.hpp1
-rw-r--r--tracking/protocol.cpp62
-rw-r--r--tracking/protocol.hpp38
-rw-r--r--tracking/reporter.cpp26
-rw-r--r--tracking/reporter.hpp11
-rw-r--r--tracking/tracking.pro2
-rw-r--r--tracking/tracking_tests/protocol_test.cpp34
-rw-r--r--tracking/tracking_tests/reporter_test.cpp34
-rw-r--r--tracking/tracking_tests/tracking_tests.pro3
10 files changed, 213 insertions, 29 deletions
diff --git a/tracking/connection.cpp b/tracking/connection.cpp
index 550a797afc..26cbfadba3 100644
--- a/tracking/connection.cpp
+++ b/tracking/connection.cpp
@@ -1,5 +1,8 @@
-#include "connection.hpp"
+#include "tracking/connection.hpp"
+#include "tracking/protocol.hpp"
+
+#include "platform/platform.hpp"
#include "platform/socket.hpp"
namespace
@@ -22,19 +25,27 @@ Connection::Connection(unique_ptr<platform::Socket> socket, string const & host,
bool Connection::Reconnect()
{
m_socket->Close();
- return m_socket->Open(m_host, m_port);
+
+ if (!m_socket->Open(m_host, m_port))
+ return false;
+
+ auto packet = Protocol::CreateAuthPacket(GetPlatform().UniqueClientId());
+ if (!m_socket->Write(packet.data(), static_cast<uint32_t>(packet.size())))
+ return false;
+
+ string check(begin(Protocol::kFail), end(Protocol::kFail));
+ bool const isSuccess =
+ m_socket->Read(reinterpret_cast<uint8_t *>(&check[0]), static_cast<uint32_t>(check.size()));
+ if (!isSuccess || check != string(begin(Protocol::kOk), end(Protocol::kOk)))
+ return false;
+
+ return true;
}
// TODO: implement historical
bool Connection::Send(boost::circular_buffer<DataPoint> const & points)
{
- ASSERT(m_buffer.empty(), ());
-
- MemWriter<decltype(m_buffer)> writer(m_buffer);
- using coding::TrafficGPSEncoder;
- TrafficGPSEncoder::SerializeDataPoints(TrafficGPSEncoder::kLatestVersion, writer, points);
- bool const isSuccess = m_socket->Write(m_buffer.data(), m_buffer.size());
- m_buffer.clear();
- return isSuccess;
+ auto packet = Protocol::CreateDataPacket(points);
+ return m_socket->Write(packet.data(), static_cast<uint32_t>(packet.size()));
}
} // namespace tracking
diff --git a/tracking/connection.hpp b/tracking/connection.hpp
index a87f3dbbf1..48445444bd 100644
--- a/tracking/connection.hpp
+++ b/tracking/connection.hpp
@@ -31,6 +31,5 @@ private:
string const m_host;
uint16_t const m_port;
bool const m_isHistorical;
- vector<uint8_t> m_buffer;
};
} // namespace tracking
diff --git a/tracking/protocol.cpp b/tracking/protocol.cpp
new file mode 100644
index 0000000000..ada9a49842
--- /dev/null
+++ b/tracking/protocol.cpp
@@ -0,0 +1,62 @@
+#include "tracking/protocol.hpp"
+
+#include "coding/endianness.hpp"
+
+#include "base/assert.hpp"
+
+#include "std/cstdint.hpp"
+
+namespace tracking
+{
+uint8_t const Protocol::kOk[4] = {'O', 'K', '\n', '\n'};
+uint8_t const Protocol::kFail[4] = {'F', 'A', 'I', 'L'};
+
+static_assert(sizeof(Protocol::kFail) >= sizeof(Protocol::kOk), "");
+
+vector<uint8_t> Protocol::CreateAuthPacket(string const & clientId)
+{
+ vector<uint8_t> packet;
+
+ InitHeader(packet, PacketType::CurrentAuth, static_cast<uint32_t>(clientId.size()));
+ packet.insert(packet.end(), begin(clientId), end(clientId));
+
+ return packet;
+}
+
+vector<uint8_t> Protocol::CreateDataPacket(DataElements const & points)
+{
+ vector<uint8_t> buffer;
+ MemWriter<decltype(buffer)> writer(buffer);
+ Encoder::SerializeDataPoints(Encoder::kLatestVersion, writer, points);
+
+ vector<uint8_t> packet;
+ InitHeader(packet, PacketType::CurrentData, static_cast<uint32_t>(buffer.size()));
+ packet.insert(packet.end(), begin(buffer), end(buffer));
+
+ return packet;
+}
+
+void Protocol::InitHeader(vector<uint8_t> & packet, PacketType type, uint32_t payloadSize)
+{
+ packet.resize(sizeof(uint32_t));
+ uint32_t & size = *reinterpret_cast<uint32_t *>(packet.data());
+ size = payloadSize;
+
+ ASSERT_LESS(size, 0x00FFFFFF, ());
+
+ if (!IsBigEndian())
+ size = ReverseByteOrder(size);
+
+ packet[0] = static_cast<uint8_t>(type);
+}
+
+string DebugPrint(Protocol::PacketType type)
+{
+ switch (type)
+ {
+ case Protocol::PacketType::AuthV0: return "AuthV0";
+ case Protocol::PacketType::DataV0: return "DataV0";
+ default: return "Unknown";
+ }
+}
+} // namespace tracking
diff --git a/tracking/protocol.hpp b/tracking/protocol.hpp
new file mode 100644
index 0000000000..6b15b7bdeb
--- /dev/null
+++ b/tracking/protocol.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "coding/traffic.hpp"
+
+#include "std/string.hpp"
+#include "std/vector.hpp"
+
+#include "boost/circular_buffer.hpp"
+
+namespace tracking
+{
+class Protocol
+{
+public:
+ using Encoder = coding::TrafficGPSEncoder;
+ using DataElements = boost::circular_buffer<Encoder::DataPoint>;
+
+ static uint8_t const kOk[4];
+ static uint8_t const kFail[4];
+
+ enum class PacketType
+ {
+ AuthV0 = 0x81,
+ DataV0 = 0x82,
+
+ CurrentAuth = AuthV0,
+ CurrentData = DataV0
+ };
+
+ static vector<uint8_t> CreateAuthPacket(string const & clientId);
+ static vector<uint8_t> CreateDataPacket(DataElements const & points);
+
+private:
+ static void InitHeader(vector<uint8_t> & packet, PacketType type, uint32_t payloadSize);
+};
+
+string DebugPrint(Protocol::PacketType type);
+} // namespace tracking
diff --git a/tracking/reporter.cpp b/tracking/reporter.cpp
index b161b4e3d6..35b59c65ae 100644
--- a/tracking/reporter.cpp
+++ b/tracking/reporter.cpp
@@ -8,8 +8,6 @@
#include "std/target_os.hpp"
-#include "private.h"
-
namespace
{
double constexpr kRequiredHorizontalAccuracy = 10.0;
@@ -25,21 +23,22 @@ namespace tracking
// Keys saved for existing users, so can' fix it easy, need migration.
// Use this hack until change to special traffic key.
#if defined(OMIM_OS_IPHONE)
-const char Reporter::kEnabledSettingsKey[] = "StatisticsEnabled";
+const char Reporter::kEnableTrackingKey[] = "StatisticsEnabled";
#elif defined(OMIM_OS_ANDROID)
-const char Reporter::kEnabledSettingsKey[] = "AllowStat";
+const char Reporter::kEnableTrackingKey[] = "AllowStat";
#else
-const char Reporter::kEnabledSettingsKey[] = "AllowStat";
+const char Reporter::kEnableTrackingKey[] = "AllowStat";
#endif
// static
milliseconds const Reporter::kPushDelayMs = milliseconds(10000);
-Reporter::Reporter(unique_ptr<platform::Socket> socket, milliseconds pushDelay)
- : m_realtimeSender(move(socket), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, false)
+Reporter::Reporter(unique_ptr<platform::Socket> socket, string const & host, uint16_t port,
+ milliseconds pushDelay)
+ : m_realtimeSender(move(socket), host, port, false)
, m_pushDelay(pushDelay)
, m_points(kRealTimeBufferSize)
- , m_thread([this]{Run();})
+ , m_thread([this] { Run(); })
{
}
@@ -82,8 +81,15 @@ void Reporter::Run()
m_input.clear();
lock.unlock();
- if (SendPoints())
- m_points.clear();
+ if (m_points.empty() && m_idleFn)
+ {
+ m_idleFn();
+ }
+ else
+ {
+ if (SendPoints())
+ m_points.clear();
+ }
lock.lock();
auto const passedMs = duration_cast<milliseconds>(steady_clock::now() - startTime);
diff --git a/tracking/reporter.hpp b/tracking/reporter.hpp
index 2c85b69969..380a3cd460 100644
--- a/tracking/reporter.hpp
+++ b/tracking/reporter.hpp
@@ -7,6 +7,7 @@
#include "std/chrono.hpp"
#include "std/condition_variable.hpp"
#include "std/mutex.hpp"
+#include "std/string.hpp"
#include "std/unique_ptr.hpp"
#include "std/vector.hpp"
@@ -28,13 +29,16 @@ class Reporter final
{
public:
static milliseconds const kPushDelayMs;
- static const char kEnabledSettingsKey[];
+ static const char kEnableTrackingKey[];
- Reporter(unique_ptr<platform::Socket> socket, milliseconds pushDelay);
+ Reporter(unique_ptr<platform::Socket> socket, string const & host, uint16_t port,
+ milliseconds pushDelay);
~Reporter();
void AddLocation(location::GpsInfo const & info);
+ inline void SetIdleFunc(function<void()> fn) { m_idleFn = fn; }
+
private:
void Run();
bool SendPoints();
@@ -43,6 +47,9 @@ private:
milliseconds m_pushDelay;
bool m_wasConnected = false;
double m_lastConnectionAttempt = 0.0;
+ // Function to be called every |kPushDelayMs| in
+ // case no points were sent.
+ function<void()> m_idleFn;
// Input buffer for incoming points. Worker thread steals it contents.
vector<DataPoint> m_input;
// Last collected points, sends periodically to server.
diff --git a/tracking/tracking.pro b/tracking/tracking.pro
index 2418e67637..42e7d13953 100644
--- a/tracking/tracking.pro
+++ b/tracking/tracking.pro
@@ -8,8 +8,10 @@ include($$ROOT_DIR/common.pri)
SOURCES += \
connection.cpp \
+ protocol.cpp \
reporter.cpp \
HEADERS += \
connection.hpp \
+ protocol.hpp \
reporter.hpp \
diff --git a/tracking/tracking_tests/protocol_test.cpp b/tracking/tracking_tests/protocol_test.cpp
new file mode 100644
index 0000000000..f3b72d6160
--- /dev/null
+++ b/tracking/tracking_tests/protocol_test.cpp
@@ -0,0 +1,34 @@
+#include "testing/testing.hpp"
+
+#include "tracking/protocol.hpp"
+
+using namespace tracking;
+
+UNIT_TEST(Protocol_CreateAuthPacket)
+{
+ auto packet = Protocol::CreateAuthPacket("AAA");
+ TEST_EQUAL(packet.size(), 7, ());
+ TEST_EQUAL(Protocol::PacketType(packet[0]), Protocol::PacketType::CurrentAuth, ());
+ TEST_EQUAL(packet[1], 0x00, ());
+ TEST_EQUAL(packet[2], 0x00, ());
+ TEST_EQUAL(packet[3], 0x03, ());
+ TEST_EQUAL(packet[4], 'A', ());
+ TEST_EQUAL(packet[5], 'A', ());
+ TEST_EQUAL(packet[6], 'A', ());
+}
+
+UNIT_TEST(Protocol_CreateDataPacket)
+{
+ Protocol::DataElements buffer(5);
+ buffer.push_back(Protocol::DataElements::value_type(1, ms::LatLon(10, 10)));
+ buffer.push_back(Protocol::DataElements::value_type(2, ms::LatLon(15, 15)));
+ auto packet = Protocol::CreateDataPacket(buffer);
+ TEST_EQUAL(packet.size(), 26, ());
+ TEST_EQUAL(Protocol::PacketType(packet[0]), Protocol::PacketType::CurrentData, ());
+ TEST_EQUAL(packet[1], 0x00, ());
+ TEST_EQUAL(packet[2], 0x00, ());
+ TEST_EQUAL(packet[3], 22, ());
+ TEST_EQUAL(packet[4], 1, ());
+ TEST_EQUAL(packet[5], 227, ());
+ TEST_EQUAL(packet[6], 241, ());
+}
diff --git a/tracking/tracking_tests/reporter_test.cpp b/tracking/tracking_tests/reporter_test.cpp
index 685b4f19f7..bdd47a60a5 100644
--- a/tracking/tracking_tests/reporter_test.cpp
+++ b/tracking/tracking_tests/reporter_test.cpp
@@ -1,4 +1,7 @@
+#include "testing/testing.hpp"
+
#include "tracking/reporter.hpp"
+#include "tracking/protocol.hpp"
#include "coding/traffic.hpp"
@@ -6,8 +9,6 @@
#include "platform/platform_tests_support/test_socket.hpp"
#include "platform/socket.hpp"
-#include "testing/testing.hpp"
-
#include "base/math.hpp"
#include "base/thread.hpp"
@@ -28,13 +29,36 @@ void TransferLocation(Reporter & reporter, TestSocket & testSocket, double times
gpsInfo.m_horizontalAccuracy = 1.0;
reporter.AddLocation(gpsInfo);
+ using Packet = tracking::Protocol::PacketType;
vector<uint8_t> buffer;
- size_t const readSize = testSocket.ReadServer(buffer);
- TEST_GREATER(readSize, 0, ());
+ size_t readSize = 0;
+ size_t attempts = 3;
+ do
+ {
+ readSize = testSocket.ReadServer(buffer);
+ if (attempts-- && readSize == 0)
+ continue;
+ switch (Packet(buffer[0]))
+ {
+ case Packet::CurrentAuth:
+ {
+ buffer.clear();
+ testSocket.WriteServer(tracking::Protocol::kOk);
+ break;
+ }
+ case Packet::CurrentData:
+ {
+ readSize = 0;
+ break;
+ }
+ }
+ } while (readSize);
+ TEST(!buffer.empty(), ());
vector<coding::TrafficGPSEncoder::DataPoint> points;
MemReader memReader(buffer.data(), buffer.size());
ReaderSource<MemReader> src(memReader);
+ src.Skip(sizeof(uint32_t /* header */));
coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, src,
points);
@@ -51,7 +75,7 @@ UNIT_TEST(Reporter_TransferLocations)
auto socket = make_unique<TestSocket>();
TestSocket & testSocket = *socket.get();
- Reporter reporter(move(socket), milliseconds(10) /* pushDelay */);
+ Reporter reporter(move(socket), "localhost", 0, milliseconds(10) /* pushDelay */);
TransferLocation(reporter, testSocket, 1.0, 2.0, 3.0);
TransferLocation(reporter, testSocket, 4.0, 5.0, 6.0);
TransferLocation(reporter, testSocket, 7.0, 8.0, 9.0);
diff --git a/tracking/tracking_tests/tracking_tests.pro b/tracking/tracking_tests/tracking_tests.pro
index 81465b60aa..6009b5ffda 100644
--- a/tracking/tracking_tests/tracking_tests.pro
+++ b/tracking/tracking_tests/tracking_tests.pro
@@ -26,4 +26,5 @@ win*|linux* {
SOURCES += \
$$ROOT_DIR/testing/testingmain.cpp \
- reporter_test.cpp
+ protocol_test.cpp \
+ reporter_test.cpp \