[place_recognition] initial commit 32/50432/4
authorTomasz Toczyski <t.toczyski@samsung.com>
Tue, 3 Nov 2015 16:54:58 +0000 (17:54 +0100)
committerTomasz Toczyski <t.toczyski@samsung.com>
Tue, 3 Nov 2015 16:54:58 +0000 (17:54 +0100)
- wifi_logger
- visit_listener_iface
- visit_detector stub

Change-Id: I4bdeccac0d3d580d987f2f6f133dc276167baea5
Signed-off-by: Tomasz Toczyski <t.toczyski@samsung.com>
20 files changed:
AUTHORS
CMakeLists.txt
packaging/place-context-provider.spec
src/place_context_provider.cpp
src/place_recognition/place_recognition.cpp [new file with mode: 0644]
src/place_recognition/place_recognition.h [new file with mode: 0644]
src/place_recognition/place_recognition_types.h [new file with mode: 0644]
src/place_recognition/user_places/debug_utils.cpp [new file with mode: 0644]
src/place_recognition/user_places/debug_utils.h [new file with mode: 0644]
src/place_recognition/user_places/user_places.cpp [new file with mode: 0644]
src/place_recognition/user_places/user_places.h [new file with mode: 0644]
src/place_recognition/user_places/user_places_params.h [new file with mode: 0644]
src/place_recognition/user_places/user_places_types.cpp [new file with mode: 0644]
src/place_recognition/user_places/user_places_types.h [new file with mode: 0644]
src/place_recognition/user_places/visit_detector.cpp [new file with mode: 0644]
src/place_recognition/user_places/visit_detector.h [new file with mode: 0644]
src/place_recognition/user_places/visit_listener_iface.h [new file with mode: 0644]
src/place_recognition/user_places/wifi_listener_iface.h [new file with mode: 0644]
src/place_recognition/user_places/wifi_logger.cpp [new file with mode: 0644]
src/place_recognition/user_places/wifi_logger.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index a86e881..4c123d9 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,7 @@
-Andrei Glushkov <a.glushkov@samsung.com>
-Mu-Woong Lee    <muwoong.lee@samsung.com>
+Andrei Glushkov                <a.glushkov@samsung.com>
+Mu-Woong Lee           <muwoong.lee@samsung.com>
+Bozena Lukasiak                <b.lukasiak@samsung.com>
+Marcin Masternak       <m.masternak@samsung.com>
+Piotr Czarnecki                <p.czarnecki@samsung.com>
+Tomasz Toczyski                <t.toczyski@samsung.com>
+Witold Chmielowiec     <w.chmielowie@samsung.com>
index e5efb63..e9b98a2 100644 (file)
@@ -15,7 +15,11 @@ SET(provider_deps "context-common")
 IF("${PROFILE}" STREQUAL "mobile")
        ADD_DEFINITIONS("-D_MOBILE_")
        FILE(GLOB SRCS ${SRCS} src/geofence/*.cpp)
+       FILE(GLOB SRCS ${SRCS} src/place_recognition/*.cpp)
+       FILE(GLOB SRCS ${SRCS} src/place_recognition/user_places/*.cpp)
        SET(provider_deps "${provider_deps} capi-geofence-manager")
+       SET(provider_deps "${provider_deps} capi-network-wifi")
+       SET(provider_deps "${provider_deps} capi-location-manager")
 ENDIF("${PROFILE}" STREQUAL "mobile")
 
 IF("${PROFILE}" STREQUAL "wearable")
index 4849a71..ad99c7f 100644 (file)
@@ -13,6 +13,8 @@ BuildRequires: pkgconfig(context-common)
 
 %if "%{?BUILD_PROFILE}" == "mobile"
 BuildRequires: pkgconfig(capi-geofence-manager)
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-location-manager)
 %endif
 
 %description
@@ -29,7 +31,7 @@ export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Ws
 
 export   CFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
 export CXXFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
-#export CXXFLAGS+=" -std=c++0x"
+export CXXFLAGS+=" -std=c++0x"
 
 export   CFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow -fno-common"
 export CXXFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
index a0205b6..1b43ac7 100644 (file)
@@ -21,6 +21,7 @@
 
 #ifdef _MOBILE_
 #include "geofence/place_geofence.h"
+#include "place_recognition/place_recognition.h"
 #endif
 
 template<typename provider>
@@ -31,13 +32,16 @@ void register_provider(const char *subject, const char *privilege)
 
        ctx::context_provider_info provider_info(provider::create, provider::destroy, NULL, privilege);
        ctx::context_manager::register_provider(subject, provider_info);
-       provider::submit_trigger_item();
 }
 
 EXTAPI bool ctx::init_place_context_provider()
 {
 #ifdef _MOBILE_
        register_provider<place_geofence_provider>(PLACE_SUBJ_GEOFENCE, PLACE_PRIV_GEOFENCE);
+       place_geofence_provider::submit_trigger_item();
+
+       place_recognition_provider::create(NULL);
+       register_provider<place_recognition_provider>(PLACE_SUBJ_RECOGNITION, PLACE_PRIV_RECOGNITION);
 #endif
        return true;
 }
diff --git a/src/place_recognition/place_recognition.cpp b/src/place_recognition/place_recognition.cpp
new file mode 100644 (file)
index 0000000..97517a4
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <types_internal.h>
+#include <context_mgr.h>
+#include "place_recognition.h"
+
+ctx::place_recognition_provider *ctx::place_recognition_provider::__instance = NULL;
+
+ctx::place_recognition_provider::place_recognition_provider()
+{
+       engine.start();
+}
+
+ctx::place_recognition_provider::~place_recognition_provider()
+{
+       engine.stop();
+}
+
+ctx::context_provider_iface *ctx::place_recognition_provider::create(void *data)
+{
+       IF_FAIL_RETURN(!__instance, __instance);
+       __instance = new(std::nothrow) place_recognition_provider();
+       IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed");
+       _I(BLUE("Created"));
+       return __instance;
+}
+
+void ctx::place_recognition_provider::destroy(void *data)
+{
+       IF_FAIL_VOID(__instance);
+       delete __instance;
+       __instance = NULL;
+       _I(BLUE("Destroyed"));
+}
+
+int ctx::place_recognition_provider::subscribe(const char *subject, ctx::json option, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::place_recognition_provider::unsubscribe(const char *subject, ctx::json option)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::place_recognition_provider::read(const char *subject, ctx::json option, ctx::json* request_result)
+{
+       _I(BLUE("Read"));
+       _J("Option", option);
+
+       json data_read; // @to_be_added get detected places
+
+       // The below function needs to be called once.
+       // It does not need to be called within this read() function.
+       // In can be called later, in another scope.
+       // Please just be sure that, the 2nd input parameter "option" should be the same to the
+       // "option" parameter received via ctx::place_recognition_provider::read().
+       ctx::context_manager::reply_to_read(PLACE_SUBJ_RECOGNITION, option, ERR_NONE, data_read);
+
+       return ERR_NONE;
+}
+
+int ctx::place_recognition_provider::write(const char *subject, ctx::json data, ctx::json* request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+bool ctx::place_recognition_provider::is_supported()
+{
+       return true;
+}
diff --git a/src/place_recognition/place_recognition.h b/src/place_recognition/place_recognition.h
new file mode 100644 (file)
index 0000000..3fdbbbc
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_RECOGNITION_H__
+#define __CONTEXT_PLACE_RECOGNITION_H__
+
+#include <provider_iface.h>
+#include "place_recognition_types.h"
+#include "user_places/user_places.h"
+
+namespace ctx {
+
+       class place_recognition_provider : public context_provider_iface
+       {
+       public:
+               static context_provider_iface *create(void *data);
+               static void destroy(void *data);
+               static bool is_supported();
+
+               int subscribe(const char *subject, ctx::json option, ctx::json *request_result);
+               int unsubscribe(const char *subject, ctx::json option);
+               int read(const char *subject, ctx::json option, ctx::json *request_result);
+               int write(const char *subject, ctx::json data, ctx::json *request_result);
+
+       private:
+               static place_recognition_provider *__instance;
+               user_places engine;
+
+               place_recognition_provider();
+               ~place_recognition_provider();
+
+       };      /* class place_recognition_provider */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_RECOGNITION_H__ */
diff --git a/src/place_recognition/place_recognition_types.h b/src/place_recognition/place_recognition_types.h
new file mode 100644 (file)
index 0000000..f255b6c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_RECOGNITION_TYPES__
+#define __CONTEXT_PLACE_RECOGNITION_TYPES__
+
+// Context Items
+#define PLACE_SUBJ_RECOGNITION                              "place/pattern/personal_poi"
+
+#define PLACE_PRIV_RECOGNITION                              "location"
+
+// Database
+
+#define PLACE_STATUS_WIFI_TABLE_NAME                        "place_status_user_place_wifi"
+#define PLACE_STATUS_WIFI_COLUMN_TIMESTAMP                  "timestamp"
+#define PLACE_STATUS_WIFI_COLUMN_BSSID                      "bssid"
+
+#endif
diff --git a/src/place_recognition/user_places/debug_utils.cpp b/src/place_recognition/user_places/debug_utils.cpp
new file mode 100644 (file)
index 0000000..0a2557b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "debug_utils.h"
+#include <types_internal.h>
+
+std::string ctx::debug_utils::human_readable_date_time(time_t timestamp, std::string format, size_t size, bool utc)
+{
+       struct tm * timeinfo;
+       if (utc) {
+               format += " UTC";
+               size += 4;
+               timeinfo = gmtime(&timestamp);
+       } else {
+               timeinfo = localtime(&timestamp);
+       }
+       char buffer[size];
+       if (timeinfo) {
+               strftime(buffer, size, format.c_str(), timeinfo);
+       } else {
+               snprintf(buffer, size, "NULL");
+       }
+       return std::string(buffer);
+}
diff --git a/src/place_recognition/user_places/debug_utils.h b/src/place_recognition/user_places/debug_utils.h
new file mode 100644 (file)
index 0000000..d6a0754
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_DEBUG_UTILS_H__
+#define __CONTEXT_PLACE_STATUS_DEBUG_UTILS_H__
+
+#include <string>
+#include <ctime>
+
+namespace ctx {
+
+       class debug_utils
+       {
+       public:
+               static std::string human_readable_date_time(time_t timestamp, std::string format, size_t size, bool utc = false);
+       };      /* class debug_utils */
+
+}      /* namespace ctx */
+
+#endif /*__CONTEXT_PLACE_STATUS_DEBUG_UTILS_H__*/
diff --git a/src/place_recognition/user_places/user_places.cpp b/src/place_recognition/user_places/user_places.cpp
new file mode 100644 (file)
index 0000000..d91d745
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctime>
+#include <memory>
+#include <types_internal.h>
+#include "user_places.h"
+#include "timer_mgr.h"
+#include "../place_recognition_types.h"
+#include "db_mgr.h"
+
+int ctx::user_places::start()
+{
+       running = true;
+       time_t now = std::time(nullptr);
+       visit_detector = new(std::nothrow) visit_detector_t(now);
+       if (visit_detector == nullptr) {
+               _E("Cannot initialize visit_detector");
+               return ERR_OUT_OF_MEMORY;
+       }
+
+       return ERR_NONE;
+}
+
+int ctx::user_places::stop()
+{
+       running = false;
+
+       if (visit_detector == nullptr) {
+               _E("No visit_detector to destroy");
+       } else {
+               delete visit_detector;
+       }
+
+       return ERR_NONE;
+}
+
+
+bool ctx::user_places::is_running()
+{
+       return running;
+}
diff --git a/src/place_recognition/user_places/user_places.h b/src/place_recognition/user_places/user_places.h
new file mode 100644 (file)
index 0000000..f36d340
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_USER_PLACES_ENGINE_H__
+#define __CONTEXT_PLACE_STATUS_USER_PLACES_ENGINE_H__
+
+#include "visit_detector.h"
+#include <vector>
+#include "user_places_types.h"
+#include <json.h>
+
+namespace ctx {
+
+       class user_places
+       {
+       private:
+               bool running;
+               visit_detector_t *visit_detector;
+               int places_detector_timer_id;
+       public:
+               user_places() : running(false) {}
+               ~user_places() {};
+
+               int start();
+               int stop();
+               bool is_running();
+
+       };      /* class user_places */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_STATUS_USER_PLACES_ENGINE_H__ */
+
diff --git a/src/place_recognition/user_places/user_places_params.h b/src/place_recognition/user_places/user_places_params.h
new file mode 100644 (file)
index 0000000..4f1cae5
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_USER_PLACES_PARAMS_H__
+#define __CONTEXT_PLACE_STATUS_USER_PLACES_PARAMS_H__
+
+/*
+ * WiFi scanning frequency (in minutes).
+ */
+#define PLACE_STATUS_WIFI_LOGGER_INTERVAL_MINUTES 3
+
+
+#endif /* __CONTEXT_PLACE_STATUS_USER_PLACES_PARAMS_H__ */
diff --git a/src/place_recognition/user_places/user_places_types.cpp b/src/place_recognition/user_places/user_places_types.cpp
new file mode 100644 (file)
index 0000000..0495381
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <algorithm>
+#include <types_internal.h>
+#include "user_places_types.h"
+#include "debug_utils.h"
+
+#define MAC_SET_STRING_DELIMITER ','
+
+ctx::mac_t::mac_t(const std::string& str)
+{
+       std::stringstream ss(str);
+       ss >> *this;
+}
+
+ctx::mac_t::mac_t(const char *str)
+{
+       std::stringstream ss(str);
+       ss >> *this;
+}
+
+std::istream& ctx::operator>>(std::istream &input, ctx::mac_t &mac)
+{
+       int h;
+       char colon;
+       size_t i = 0;
+       while (true) {
+               input >> std::hex;
+               input >> h;
+               mac.c[i] = h;
+               i++;
+               if (i >= ctx::mac_t::MAC_SIZE)
+                       break;
+               input >> colon;
+               if (colon != ':') {
+                       throw std::runtime_error("Invalid mac format");
+               }
+       }
+       input >> std::dec;
+       return input;
+}
+
+std::ostream& ctx::operator<<(std::ostream &output, const ctx::mac_t &mac)
+{
+       size_t i = 0;
+       while (true) {
+               output << std::hex << std::setfill('0') << std::setw(2);
+               output << static_cast<int>(mac.c[i]);
+               i++;
+               if (i >= mac_t::MAC_SIZE)
+                       break;
+               output << ":";
+       }
+       output << std::dec;
+       return output;
+}
+
+ctx::mac_t::operator std::string() const
+{
+       std::stringstream ss;
+       ss << *this;
+       return ss.str();
+}
+
+bool ctx::operator==(const mac_t &m1, const mac_t &m2)
+{
+       for (size_t i = 0; i < mac_t::MAC_SIZE; i++) {
+               if (m1.c[i] != m2.c[i]) {
+                       return false;
+               }
+       }
+       return true;
+}
+
+bool ctx::operator!=(const mac_t &m1, const mac_t &m2)
+{
+       return !(m1 == m2);
+}
+
+bool ctx::operator<(const mac_t &m1, const mac_t &m2)
+{
+       unsigned char c1, c2;
+       for (size_t i = 0; i < mac_t::MAC_SIZE; i++) {
+               c1 = m1.c[i];
+               c2 = m2.c[i];
+               if (c1 < c2) {
+                       return true;
+               }
+               if (c1 > c2) {
+                       return false;
+               }
+       }
+       return false; // they are equal
+}
diff --git a/src/place_recognition/user_places/user_places_types.h b/src/place_recognition/user_places/user_places_types.h
new file mode 100644 (file)
index 0000000..8b8af3e
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_USER_PLACES_TYPES_H__
+#define __CONTEXT_PLACE_STATUS_USER_PLACES_TYPES_H__
+
+#include <memory>
+#include <vector>
+#include <map>
+#include <unordered_map>
+#include <unordered_set>
+#include "../place_recognition_types.h"
+#include <string>
+#include <ctime>
+
+namespace ctx {
+
+       /*
+        * type for numerical computations
+        */
+       typedef double num_t;
+
+       /*
+        * mac address
+        */
+       class mac_t
+       {
+       public:
+               const static size_t MAC_SIZE = 6;  // number of bytes for mac address.
+               unsigned char c[MAC_SIZE];
+
+               mac_t() {};
+               mac_t(const std::string &str);
+               mac_t(const char *str);
+               operator std::string() const;
+
+       };      /* class mac_t */
+
+       std::istream &operator>>(std::istream &input, ctx::mac_t &mac);
+       std::ostream &operator<<(std::ostream &output, const ctx::mac_t &mac);
+       bool operator==(const ctx::mac_t &m1, const ctx::mac_t &m2);
+       bool operator!=(const ctx::mac_t &m1, const ctx::mac_t &m2);
+       bool operator<(const ctx::mac_t &m1, const ctx::mac_t &m2);
+       bool operator>(const ctx::mac_t &m1, const ctx::mac_t &m2);
+
+}      /* namespace ctx */
+
+namespace std {
+
+       template <> struct hash<ctx::mac_t> {
+               size_t operator()(const ctx::mac_t & m) const {
+                       size_t h = 1;
+                       for (size_t i = 0; i < ctx::mac_t::MAC_SIZE; i++) {
+                               h = h * 37 + m.c[i];
+                       }
+                       return h;
+               }
+       };
+
+}      /* namespace std */
+
+namespace ctx {
+
+
+       /*
+        * mac address + its timestamp
+        */
+       struct mac_event_t
+       {
+               time_t timestamp;
+               mac_t mac;
+
+               mac_event_t(time_t timestamp_, mac_t mac_) : timestamp(timestamp_), mac(mac_) {}
+       };
+}      /* namespace ctx */
+
+#endif /*__CONTEXT_PLACE_STATUS_USER_PLACES_TYPES_H__*/
diff --git a/src/place_recognition/user_places/visit_detector.cpp b/src/place_recognition/user_places/visit_detector.cpp
new file mode 100644 (file)
index 0000000..b9ce2ab
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <types_internal.h>
+#include <db_mgr.h>
+#include <json.h>
+#include "../place_recognition_types.h"
+#include "visit_detector.h"
+#include "debug_utils.h"
+
+ctx::visit_detector_t::visit_detector_t(time_t t_start_scan, bool test_mode_)
+       : test_mode(test_mode_)
+       , wifi_logger(this, test_mode_)
+{
+       // @to_be_added visit detecor logic
+
+       wifi_logger.start_logging();
+}
+
+ctx::visit_detector_t::~visit_detector_t()
+{
+}
+
+void ctx::visit_detector_t::on_wifi_scan(ctx::mac_event_t e)
+{
+       // @to_be_added visit detecor logic
+}
+
diff --git a/src/place_recognition/user_places/visit_detector.h b/src/place_recognition/user_places/visit_detector.h
new file mode 100644 (file)
index 0000000..22db2b3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_VISIT_DETECTOR_H__
+#define __CONTEXT_PLACE_STATUS_VISIT_DETECTOR_H__
+
+#include <memory>
+#include <vector>
+#include <map>
+#include <unordered_map>
+#include <unordered_set>
+#include "user_places_types.h"
+#include <json.h>
+#include "visit_listener_iface.h"
+#include "wifi_listener_iface.h"
+#include "wifi_logger.h"
+
+namespace ctx {
+
+       class visit_detector_t : public wifi_listener_iface
+       {
+       private:
+               bool test_mode;
+               wifi_logger_t wifi_logger;
+
+               // @to_be_added visit detector logic methods
+
+       public:
+               visit_detector_t(time_t _t_start_scan, bool test_mode_ = false);
+               ~visit_detector_t();
+               void on_wifi_scan(mac_event_t event);
+
+               // @to_be_added visit detector logic methods
+
+       };      /* class visit_detector_t */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_STATUS_VISIT_DETECTOR_H__ */
diff --git a/src/place_recognition/user_places/visit_listener_iface.h b/src/place_recognition/user_places/visit_listener_iface.h
new file mode 100644 (file)
index 0000000..c1d7605
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_VISIT_LISTENER_IFACE_H__
+#define __CONTEXT_PLACE_STATUS_VISIT_LISTENER_IFACE_H__
+
+namespace ctx {
+
+       class visit_listener_iface
+       {
+       public:
+               virtual ~visit_listener_iface() {};
+               virtual void on_visit_start() = 0;
+               virtual void on_visit_end() = 0;
+
+       };      /* class visit_listener_iface */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_STATUS_VISIT_LISTENER_IFACE_H__ */
diff --git a/src/place_recognition/user_places/wifi_listener_iface.h b/src/place_recognition/user_places/wifi_listener_iface.h
new file mode 100644 (file)
index 0000000..b947513
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_WIFI_LISTENER_IFACE_H__
+#define __CONTEXT_PLACE_STATUS_WIFI_LISTENER_IFACE_H__
+
+#include "user_places_types.h"
+
+namespace ctx {
+
+       class wifi_listener_iface
+       {
+       public:
+               virtual ~wifi_listener_iface() {};
+               virtual void on_wifi_scan(ctx::mac_event_t e) = 0;
+
+       };      /* wifi_listener_iface */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_STATUS_WIFI_LISTENER_IFACE_H__ */
diff --git a/src/place_recognition/user_places/wifi_logger.cpp b/src/place_recognition/user_places/wifi_logger.cpp
new file mode 100644 (file)
index 0000000..d6f10c3
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_logger.h"
+#include <types_internal.h>
+#include "../place_recognition_types.h"
+#include <db_mgr.h>
+#include <sstream>
+#include "debug_utils.h"
+
+#define PLACE_STATUS_WIFI_CREATE_TABLE_COLUMNS \
+       PLACE_STATUS_WIFI_COLUMN_TIMESTAMP " timestamp NOT NULL, "\
+       PLACE_STATUS_WIFI_COLUMN_BSSID " TEXT NOT NULL"
+
+int ctx::wifi_logger_t::create_table()
+{
+       bool ret = db_manager::create_table(0, PLACE_STATUS_WIFI_TABLE_NAME, PLACE_STATUS_WIFI_CREATE_TABLE_COLUMNS, NULL, NULL);
+       _D("Table Creation Request: %s", ret ? "SUCCESS" : "FAIL");
+       return ret;
+}
+
+int ctx::wifi_logger_t::db_insert_logs()
+{
+       if (logs.size() > 0) {
+               std::stringstream query;
+               const char* separator = " ";
+               query << "BEGIN TRANSACTION; \
+                               INSERT INTO " PLACE_STATUS_WIFI_TABLE_NAME " \
+                               ( " PLACE_STATUS_WIFI_COLUMN_BSSID ", " PLACE_STATUS_WIFI_COLUMN_TIMESTAMP " ) \
+                               VALUES";
+               for (mac_event_t mac_event : logs) {
+                       query << separator << "( '" << mac_event.mac << "', '" << mac_event.timestamp << "' )";
+                       separator = ", ";
+               }
+               logs.clear();
+               query << "; \
+                               END TRANSACTION;";
+               bool ret = ctx::db_manager::execute(0, query.str().c_str(), NULL);
+               _D("DB insert request: %s", ret ? "SUCCESS" : "FAIL");
+               return ret;
+       }
+       _D("logs vector empty -> nothing to insert");
+       return 0;
+}
+
+ctx::wifi_logger_t::wifi_logger_t(wifi_listener_iface * listener_, bool test_mode_, int interval_minutes_)
+       : test_mode(test_mode_)
+       , listener(listener_)
+       , last_scan_time(time_t(0))
+       , last_timer_callback_time(time_t(0))
+       , timer_on(false)
+       , interval_minutes(interval_minutes_)
+       , during_visit(false)
+       , started(false)
+       , running(false)
+{
+       _D("CONSTRUCTOR");
+
+       if (interval_minutes <= 0) {
+               _E("interval_minutes should be greater than zero");
+       }
+
+       if (test_mode) return;
+
+       if (PLACE_STATUS_WIFI_LOGGER_DATABASE) {
+               create_table();
+       }
+
+       logs = std::vector<mac_event_t>();
+
+       wifi_initialize_request();
+       wifi_set_device_state_changed_cb_request();
+       if (PLACE_STATUS_WIFI_LOGGER_LOW_POWER_MODE) {
+               wifi_set_connection_state_changed_cb_request();
+       }
+       wifi_connection_state_e state = wifi_get_connection_state_request();
+       connected_to_wifi_ap = (state == WIFI_CONNECTION_STATE_CONNECTED);
+       _D("connected_to_wifi_ap = %d, during_visit = %d IN CONSTRUCTOR",
+                               static_cast<int>(connected_to_wifi_ap),
+                               static_cast<int>(during_visit));
+}
+
+ctx::wifi_logger_t::~wifi_logger_t()
+{
+       _D("DESTRUCTOR");
+       stop_logging();
+       wifi_deinitialize_request();
+}
+
+void ctx::wifi_logger_t::wifi_device_state_changed_cb(wifi_device_state_e state, void *user_data)
+{
+       ctx::wifi_logger_t* wifi_logger_p = (ctx::wifi_logger_t *)user_data;
+       switch (state) {
+       case WIFI_DEVICE_STATE_DEACTIVATED:
+               _D("WIFI setting OFF");
+               if (wifi_logger_p->started) {
+                       wifi_logger_p->_stop_logging();
+               }
+               break;
+       case WIFI_DEVICE_STATE_ACTIVATED:
+               _D("WIFI setting ON");
+               if (wifi_logger_p->started) {
+                       wifi_logger_p->_start_logging();
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+void ctx::wifi_logger_t::wifi_connection_state_changed_cb(wifi_connection_state_e state, wifi_ap_h ap, void *user_data)
+{
+       ctx::wifi_logger_t* wifi_logger_p = (ctx::wifi_logger_t *)user_data;
+       switch (state) {
+       case WIFI_CONNECTION_STATE_CONNECTED:
+               _D("connected to AP");
+               wifi_logger_p->connected_to_wifi_ap = true;
+               break;
+       default:
+               _D("disconnected from AP -> last_scans_pool.clear()");
+               wifi_logger_p->connected_to_wifi_ap = false;
+               wifi_logger_p->last_scans_pool.clear();
+               break;
+       }
+       // TODO: Check if AP bssid (MAC Address) will be helpful somehow
+}
+
+bool ctx::wifi_logger_t::wifi_found_ap_cb(wifi_ap_h ap, void *user_data)
+{
+       ctx::wifi_logger_t* wifi_logger_p = (ctx::wifi_logger_t *)user_data;
+
+       char *bssid = NULL;
+       int ret = wifi_ap_get_bssid_request(ap, &bssid);
+       if (ret != WIFI_ERROR_NONE) {
+               return false;
+       }
+
+       mac_t mac;
+       try {
+               mac = mac_t(bssid);
+       } catch (std::runtime_error &e) {
+               _E("Cannot create mac_event. Exception: %s", e.what());
+               return false;
+       }
+
+       mac_event_t log(wifi_logger_p->last_scan_time, mac);
+       if (wifi_logger_p->listener) {
+               wifi_logger_p->listener->on_wifi_scan(log);
+               if (PLACE_STATUS_WIFI_LOGGER_LOW_POWER_MODE
+                               && (wifi_logger_p->connected_to_wifi_ap || wifi_logger_p->during_visit) ) {
+                       // Add to last scans AP's set
+                       wifi_logger_p->last_scans_pool.insert(std::string(bssid));
+               }
+       }
+       if (PLACE_STATUS_WIFI_LOGGER_DATABASE) {
+               wifi_logger_p->logs.push_back(log);
+       }
+
+       return true;
+}
+
+void ctx::wifi_logger_t::log(int error)
+{
+       switch (error) {
+       case WIFI_ERROR_INVALID_PARAMETER: // Invalid parameter
+               _D("ERROR == WIFI_ERROR_INVALID_PARAMETER");
+               break;
+       case WIFI_ERROR_OUT_OF_MEMORY: // Out of memory error
+               _D("ERROR == WIFI_ERROR_OUT_OF_MEMORY");
+               break;
+       case WIFI_ERROR_INVALID_OPERATION: // Invalid operation
+               _D("ERROR == WIFI_ERROR_INVALID_OPERATION");
+               break;
+       case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED: // Address family not supported
+               _D("ERROR == WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED");
+               break;
+       case WIFI_ERROR_OPERATION_FAILED: // Operation failed
+               _D("ERROR == WIFI_ERROR_OPERATION_FAILED");
+               break;
+       case WIFI_ERROR_NO_CONNECTION: // There is no connected AP
+               _D("ERROR == WIFI_ERROR_NO_CONNECTION");
+               break;
+       case WIFI_ERROR_NOW_IN_PROGRESS: // Now in progress
+               _D("ERROR == WIFI_ERROR_NOW_IN_PROGRESS");
+               break;
+       case WIFI_ERROR_ALREADY_EXISTS: // Already exists
+               _D("ERROR == WIFI_ERROR_ALREADY_EXISTS");
+               break;
+       case WIFI_ERROR_OPERATION_ABORTED: // Operation is aborted
+               _D("ERROR == WIFI_ERROR_OPERATION_ABORTED");
+               break;
+       case WIFI_ERROR_DHCP_FAILED: // DHCP failed
+               _D("ERROR == WIFI_ERROR_DHCP_FAILED");
+               break;
+       case WIFI_ERROR_INVALID_KEY: // Invalid key
+               _D("ERROR == WIFI_ERROR_INVALID_KEY");
+               break;
+       case WIFI_ERROR_NO_REPLY: // No reply
+               _D("ERROR == WIFI_ERROR_NO_REPLY");
+               break;
+       case WIFI_ERROR_SECURITY_RESTRICTED: // Restricted by security system policy
+               _D("ERROR == WIFI_ERROR_SECURITY_RESTRICTED");
+               break;
+       case WIFI_ERROR_PERMISSION_DENIED: // Permission Denied
+               _D("ERROR == WIFI_ERROR_PERMISSION_DENIED");
+               break;
+       default:
+               break;
+       }
+}
+
+void ctx::wifi_logger_t::wifi_scan_finished_cb(wifi_error_e error_code, void *user_data)
+{
+       ctx::wifi_logger_t* wifi_logger_p = (ctx::wifi_logger_t *)user_data;
+
+       time_t now = time(nullptr);
+       double seconds = 0;
+       if (wifi_logger_p->last_scan_time > 0) {
+               seconds = difftime(now, wifi_logger_p->last_scan_time);
+       }
+       std::string time_str = debug_utils::human_readable_date_time(now, "%T", 9);
+       _D("connected_to_wifi_ap = %d, during_visit = %d, last_scans_pool.size() = %d -> scan %s (from last : %.1fs)",
+                       static_cast<int>(wifi_logger_p->connected_to_wifi_ap),
+                       static_cast<int>(wifi_logger_p->during_visit),
+                       wifi_logger_p->last_scans_pool.size(),
+                       time_str.c_str(),
+                       seconds);
+       wifi_logger_p->last_scan_time = now;
+
+       int ret = wifi_foreach_found_aps_request(user_data);
+       if (ret != WIFI_ERROR_NONE) {
+               return;
+       }
+       if (PLACE_STATUS_WIFI_LOGGER_DATABASE) {
+               wifi_logger_p->db_insert_logs();
+       }
+}
+
+bool ctx::wifi_logger_t::check_wifi_is_activated()
+{
+       bool wifi_activated = true;
+       int ret = wifi_is_activated(&wifi_activated);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+       _D("Wi-Fi is %s", wifi_activated ? "ON" : "OFF");
+       return wifi_activated;
+}
+
+void ctx::wifi_logger_t::wifi_scan_request()
+{
+       int ret = wifi_scan(wifi_scan_finished_cb, this);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+int ctx::wifi_logger_t::wifi_foreach_found_aps_request(void *user_data)
+{
+       int ret = wifi_foreach_found_aps(wifi_found_ap_cb, user_data);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+       return ret;
+}
+
+wifi_connection_state_e ctx::wifi_logger_t::wifi_get_connection_state_request()
+{
+       wifi_connection_state_e connection_state;
+       int ret = wifi_get_connection_state(&connection_state);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+       return connection_state;
+}
+
+void ctx::wifi_logger_t::wifi_set_background_scan_cb_request()
+{
+       int ret = wifi_set_background_scan_cb(wifi_scan_finished_cb, this);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+void ctx::wifi_logger_t::wifi_set_device_state_changed_cb_request()
+{
+       int ret = wifi_set_device_state_changed_cb(wifi_device_state_changed_cb, this);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+void ctx::wifi_logger_t::wifi_set_connection_state_changed_cb_request()
+{
+       int ret = wifi_set_connection_state_changed_cb(wifi_connection_state_changed_cb, this);
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+int ctx::wifi_logger_t::wifi_ap_get_bssid_request(wifi_ap_h ap, char **bssid)
+{
+       int ret = wifi_ap_get_bssid(ap, bssid);
+//     _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+       return ret;
+}
+
+void ctx::wifi_logger_t::wifi_initialize_request()
+{
+       int ret = wifi_initialize();
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+void ctx::wifi_logger_t::wifi_deinitialize_request()
+{
+       int ret = wifi_deinitialize();
+       _D("%s", ret == WIFI_ERROR_NONE ? "SUCCESS" : "ERROR");
+       log(ret);
+}
+
+bool ctx::wifi_logger_t::check_timer_id(int id)
+{
+       _D("id == %d, timer_id == %d", id, timer_id);
+       return id == timer_id;
+}
+
+/*
+ * Accepted time from last callback is >= than minimum interval
+ */
+bool ctx::wifi_logger_t::check_timer_time(time_t now)
+{
+       double seconds = 0;
+       if (last_timer_callback_time > 0) {
+               seconds = difftime(now, last_timer_callback_time);
+               if (seconds < PLACE_STATUS_WIFI_LOGGER_ACTIVE_SCANNING_MIN_INTERVAL) {
+                       _D("last == %d, now == %d, diff = %.1fs -> Incorrect timer callback", last_timer_callback_time, now, seconds);
+                       return false;
+               } else {
+                       _D("last == %d, now == %d, diff = %.1fs -> Correct timer callback", last_timer_callback_time, now, seconds);
+               }
+       } else {
+               _D("last == %d, now == %d -> First callback", last_timer_callback_time, now);
+       }
+       last_timer_callback_time = now;
+       return true;
+}
+
+bool ctx::wifi_logger_t::on_timer_expired(int id, void* user_data)
+{
+       time_t now = time(nullptr);
+       _D("");
+       if (check_timer_id(id) == false) {
+               // Incorrect callback call
+               return false;
+       }
+       if (check_timer_time(now) == false) {
+               // Prevention from double callback call bug
+               return timer_on;
+       }
+       _D("connected_to_wifi_ap = %d, during_visit = %d, last_scans_pool.size() = %d",
+                       static_cast<int>(connected_to_wifi_ap),
+                       static_cast<int>(during_visit),
+                       last_scans_pool.size());
+       if (PLACE_STATUS_WIFI_LOGGER_LOW_POWER_MODE
+                       && during_visit
+                       && connected_to_wifi_ap
+                       && last_scans_pool.size() > 0) {
+               _D("trying to send fake scan");
+               if (listener) {
+                       _D("listener != false -> CORRECT");
+                       for (std::string bssid : last_scans_pool) {
+                               mac_t mac(bssid);
+                               mac_event_t scan(now, mac);
+                               _D("send fake scan (%s)", bssid.c_str());
+                               listener->on_wifi_scan(scan);
+                       }
+               }
+       } else {
+               wifi_scan_request();
+       }
+       return timer_on;
+}
+
+void ctx::wifi_logger_t::start_logging()
+{
+       _D("");
+       started = true;
+       _start_logging();
+}
+
+void ctx::wifi_logger_t::_start_logging()
+{
+       _D("");
+       if (!check_wifi_is_activated() || running) {
+               return;
+       }
+       running = true;
+
+       if (PLACE_STATUS_WIFI_LOGGER_ACTIVE_SCANNING) {
+               timer_start(interval_minutes);
+               wifi_scan_request();
+       }
+       if (PLACE_STATUS_WIFI_LOGGER_PASSIVE_SCANNING) {
+               wifi_set_background_scan_cb_request();
+       }
+}
+
+void ctx::wifi_logger_t::stop_logging()
+{
+       _D("");
+       started = false;
+       _stop_logging();
+}
+
+void ctx::wifi_logger_t::_stop_logging()
+{
+       _D("");
+       if (!running) {
+               return;
+       }
+       if (PLACE_STATUS_WIFI_LOGGER_ACTIVE_SCANNING) {
+               // Unset timer
+               timer_on = false;
+               // Remove timer
+               timer_manager::remove(timer_id);
+       }
+       if (PLACE_STATUS_WIFI_LOGGER_PASSIVE_SCANNING) {
+               wifi_unset_background_scan_cb();
+       }
+       running = false;
+}
+
+void ctx::wifi_logger_t::timer_start(time_t minutes)
+{
+       timer_on = true;
+       timer_id = timer_manager::set_for(minutes, this, NULL);
+       _D("%s (minutes=%d)", timer_id >= 0 ? "SUCCESS" : "ERROR", minutes);
+}
+
+void ctx::wifi_logger_t::on_visit_start()
+{
+       _D("");
+       during_visit = true;
+}
+
+void ctx::wifi_logger_t::on_visit_end()
+{
+       _D("last_scans_pool.clear()");
+       during_visit = false;
+       last_scans_pool.clear();
+}
diff --git a/src/place_recognition/user_places/wifi_logger.h b/src/place_recognition/user_places/wifi_logger.h
new file mode 100644 (file)
index 0000000..ce13371
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_PLACE_STATUS_WIFI_LOGGER_H__
+#define __CONTEXT_PLACE_STATUS_WIFI_LOGGER_H__
+
+#include <timer_listener_iface.h>
+#include <wifi.h>
+#include <time.h>
+#include "timer_mgr.h"
+#include <vector>
+#include <set>
+#include "wifi_listener_iface.h"
+#include "visit_listener_iface.h"
+#include "user_places_params.h"
+
+/* Database usage flag */
+#define PLACE_STATUS_WIFI_LOGGER_DATABASE false
+
+/* Active scanning usage flag */
+#define PLACE_STATUS_WIFI_LOGGER_ACTIVE_SCANNING true
+
+/* Passive scanning usage flag */
+#define PLACE_STATUS_WIFI_LOGGER_PASSIVE_SCANNING true
+
+/* Active scanning minimum interval in seconds */
+#define PLACE_STATUS_WIFI_LOGGER_ACTIVE_SCANNING_MIN_INTERVAL 10
+
+/*
+ * Low power scanning usage flag
+ * (When phone is connected to some WiFi Access Point
+ * last scan data is returned instead of new scan triggering)
+ */
+#define PLACE_STATUS_WIFI_LOGGER_LOW_POWER_MODE false
+
+namespace ctx {
+
+       class wifi_logger_t : public timer_listener_iface, public visit_listener_iface
+       {
+       public:
+               wifi_logger_t(wifi_listener_iface * listener_ = nullptr,
+                               bool test_mode_ = false,
+                               int interval_minutes = PLACE_STATUS_WIFI_LOGGER_INTERVAL_MINUTES);
+               ~wifi_logger_t();
+
+               void start_logging();
+               void stop_logging();
+
+               /* INPUT */
+               void on_visit_start();
+               void on_visit_end();
+
+       private:
+               bool test_mode;
+               wifi_listener_iface * const listener;
+               std::vector<mac_event_t> logs;
+               std::set<std::string> last_scans_pool;
+               time_t last_scan_time;
+               time_t last_timer_callback_time;
+               bool timer_on;
+               int timer_id;
+               int interval_minutes;
+               bool during_visit;
+               bool connected_to_wifi_ap;
+               bool started;
+               bool running;
+
+               void _start_logging();
+               void _stop_logging();
+
+               bool check_timer_id(int id);
+               bool check_timer_time(time_t now);
+               bool on_timer_expired(int timer_id, void* user_data);
+               static int create_table();
+               int db_insert_logs();
+               static void wifi_device_state_changed_cb(wifi_device_state_e state, void *user_data);
+               static void wifi_connection_state_changed_cb(wifi_connection_state_e state, wifi_ap_h ap, void *user_data);
+               static bool wifi_found_ap_cb(wifi_ap_h ap, void *user_data);
+               static void wifi_scan_finished_cb(wifi_error_e error_code, void *user_data);
+               static bool check_wifi_is_activated();
+               void wifi_scan_request();
+               static int wifi_foreach_found_aps_request(void *user_data);
+               static wifi_connection_state_e wifi_get_connection_state_request();
+               void wifi_set_background_scan_cb_request();
+               void wifi_set_device_state_changed_cb_request();
+               void wifi_set_connection_state_changed_cb_request();
+               static int wifi_ap_get_bssid_request(wifi_ap_h ap, char **bssid);
+               void wifi_initialize_request();
+               void wifi_deinitialize_request();
+               static void log(int error);
+               void timer_start(time_t minutes);
+
+       };      /* class wifi_logger_t */
+
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_PLACE_STATUS_WIFI_LOGGER_H__ */