-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>
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")
%if "%{?BUILD_PROFILE}" == "mobile"
BuildRequires: pkgconfig(capi-geofence-manager)
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-location-manager)
%endif
%description
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"
#ifdef _MOBILE_
#include "geofence/place_geofence.h"
+#include "place_recognition/place_recognition.h"
#endif
template<typename provider>
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;
}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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(×tamp);
+ } else {
+ timeinfo = localtime(×tamp);
+ }
+ char buffer[size];
+ if (timeinfo) {
+ strftime(buffer, size, format.c_str(), timeinfo);
+ } else {
+ snprintf(buffer, size, "NULL");
+ }
+ return std::string(buffer);
+}
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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
+}
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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__ */