#include "samonitor_tag.h"
#include "eventlistener.h"
-namespace NetworkManager
+namespace communication
{
-Connection::Connection(Settings& deviceSettings, IRestService* restService)
+Connection::Connection(const std::string& duid, const std::chrono::milliseconds& timeout, IRestService* restService)
: active()
, listeners()
- , settings(deviceSettings)
- , state(SessionState::REGISTER)
+ , keepAliveTimeout(timeout)
, sinfo()
, rest(restService)
, locker()
, lastId(0)
, work(true)
{
- sinfo.duid = settings.getDeviceId();
-
- if (!sinfo.duid.empty())
- {
- state = SessionState::AUTHORIZE;
- }
+ sinfo.duid = duid;
}
std::chrono::steady_clock clock;
std::chrono::steady_clock::time_point next = clock.now();
- while(work)
+ while (work)
{
- switch(state)
- {
- case SessionState::REGISTER:
- if (reg()) {
- settings.setDeviceId(sinfo.duid);
- settings.save();
- state = SessionState::AUTHORIZE;
- }
- break;
- case SessionState::AUTHORIZE:
- if (authorize()) {
- state = SessionState::WORK;
- }
- break;
- case SessionState::WORK:
- {
- do {
- std::unique_lock<std::mutex> lock(locker);
-
- if (!reports.empty()) {
- ReportComposer composer;
-
- composer.addEvents(reports.begin(), reports.end());
- reports.clear();
-
- lock.unlock();
- try {
- rest->sendData(sinfo, composer.get());
- } catch (std::exception& e) {
- LOG_E(TAG, "Fail to send report: %s", e.what());
- }
- }
- } while(0);
-
- if (next <= clock.now()) {
- try {
- std::string updates = rest->getUpdates(sinfo);
- LOG_D(TAG, "Updates: %s", updates.c_str());
+ do {
+ std::unique_lock<std::mutex> lock(locker);
- if (updates.empty()) {
- break;
- }
-
- Json::Reader reader;
- Json::Value root;
+ if (!reports.empty()) {
+ ReportComposer composer;
- if (!reader.parse(updates, root)) {
- LOG_E(TAG, "Malformed JSON");
- } else {
- if (!root.isArray()) {
- LOG_D(TAG, "Update information must be an array.");
- break;
- }
+ composer.addEvents(reports.begin(), reports.end());
+ reports.clear();
- for (const auto& item: root) {
- Event event(item, *this);
-
- if (!event.isValid()) {
- LOG_E(TAG, "Update event is invalid");
- continue;
- }
-
- LOG_D(TAG, "Update type: %s", event.getType().c_str());
-
- try {
- auto found_listeners = listeners.find(event.getType());
-
- if (found_listeners != listeners.end()) {
- LOG_D(TAG, "Found listeners");
-
- for (auto it = found_listeners->second.begin(); it != found_listeners->second.end(); ++it) {
- (*it)->accept(event);
- }
- }
- } catch (std::exception& e) {
- LOG_E(TAG, "Failed to get update content \"%s\". Error: %s", event.getDescription().c_str(), e.what());
- }
- }
- }
+ lock.unlock();
+ try {
+ rest->sendData(sinfo, composer.get());
} catch (std::exception& e) {
- LOG_E(TAG, "Connection Work loop exception: %s", e.what());
+ LOG_E(TAG, "Fail to send report: %s", e.what());
}
}
- break;
- }
+ } while (0);
+
+ if (next <= clock.now()) {
+ checkUpdates();
}
if (next <= clock.now()) {
- next += settings.getKeepAliveTimeout();
+ next += keepAliveTimeout;
}
std::unique_lock<std::mutex> lock(locker);
rest->sendData(sinfo, data);
}
-bool Connection::reg()
+const std::string& Connection::registerDevice(const Json::Value& data)
{
- try {
- sinfo.duid = rest->registerDevice(sinfo);
- } catch (std::exception& e){
- LOG_E(TAG, "Register failed: %s", e.what());
- return false;
- }
+ sinfo.duid = rest->registerDevice(sinfo, data);
- return !sinfo.duid.empty();
+ return sinfo.duid;
}
-bool Connection::authorize()
+void Connection::checkUpdates()
{
- // TODO: Implement authorization
- return true;
+ try {
+ std::string updates = rest->getUpdates(sinfo);
+
+ if (updates.empty()) {
+ return;
+ }
+
+ LOG_D(TAG, "Updates: %.511s", updates.c_str());
+ Json::Reader reader;
+ Json::Value root;
+
+ if (reader.parse(updates, root) && root.isArray()) {
+ for (const auto& item: root) {
+ Event event(item, *this);
+
+ if (!event.isValid()) {
+ LOG_E(TAG, "Update event is invalid");
+ continue;
+ }
+
+ LOG_D(TAG, "Update type: %s", event.getType().c_str());
+
+ try {
+ auto found_listeners = listeners.find(event.getType());
+
+ if (found_listeners != listeners.end()) {
+ LOG_D(TAG, "Found listeners");
+
+ for (auto it = found_listeners->second.begin(); it != found_listeners->second.end(); ++it) {
+ (*it)->accept(event);
+ }
+ }
+ } catch (std::exception& e) {
+ LOG_E(TAG, "Failed to get update content \"%s\". Error: %s", event.getDescription().c_str(), e.what());
+ }
+ }
+ } else {
+ LOG_E(TAG, "Malformed JSON");
+ }
+ } catch (std::exception& e) {
+ LOG_E(TAG, "Connection Work loop exception: %s", e.what());
+ }
}
}